C言語なら俺に聞け 158

■ このスレッドは過去ログ倉庫に格納されています
2021/12/25(土) 12:11:46.61ID:xxeaCAplM
!extend:checked:vvvvv:1000:512
(新スレ立ての際上記コマンドを2行書き込んでください)
C言語の話題のみ取り扱います C++の話題はC++スレへ
質問には最低限の情報(ソース/コンパイラ/OS)を付ける
数行で収まらないソースは以下を適当に使ってURLを晒す
https://paiza.io/
https://ideone.com/
http://codepad.org/

C17
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4713.pdf

C11
http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1570.pdf

C99
http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf
http://kikakurui.com/x3/X3010-2003-01.html

C FAQ 日本語訳
http://www.kouno.jp/home/c_faq/

JPCERT C コーディングスタンダード
https://www.jpcert.or.jp/sc-rules/

※前スレ
C言語なら俺に聞け 157
https://mevius.5ch.net/test/read.cgi/tech/1624846971/
VIPQ2_EXTDAT: checked:vvvvv:1000:512:: EXT was configured
2022/03/20(日) 22:54:16.07ID:pl7vy6aed
>ちょうどぴったりでreadしたあとに、つぎのreadをせずに知りたい

そもそもreadが終端まで来たらつぎにreadしてもファイルアクセスせずに0を返すから同じだろう
2022/03/20(日) 23:19:06.05ID:dAApHicf0
>>372
よく分かりました
ありがとうございます
2022/03/21(月) 16:21:59.97ID:nqBLTVDb0
>>387
後出し情報であれやけど
readしたデータをどこかに送信、最後のデータには最後フラグを立てる
みたいなやつなので、ぴったりのときに困ってたんよ

バッファを2面用意して、すぐ送信せず常に1回貯めて送信するのが
正解なんだろうなぁ・・・ まあいいけど
390デフォルトの名無しさん (ワッチョイ 2910-tpIf)
垢版 |
2022/03/21(月) 17:02:36.51ID:geQt3ukX0
ファイルサイズと読み出し位置から残りサイズ計算するぐらいか?
2022/03/21(月) 18:07:17.68ID:bPJRBgFUM
>>389
ファイルサイズわかってるならlseek(fd, 0, SEEK_CUR) で現在位置調べりゃいいだけかと
2022/03/21(月) 21:41:26.44ID:nqBLTVDb0
一応、ファイルじゃないときのことも考慮したかった
2022/03/21(月) 22:38:50.94ID:j56ex+kVd
ファイルディスクリプタが0とか"/dev/stdin"という名前のファイルを考慮し始めたらそれはもう無理じゃ?
394デフォルトの名無しさん (ワッチョイ 5336-yL30)
垢版 |
2022/03/21(月) 23:41:34.24ID:/12E7ImH0
なんかバグやセキュリティホールの温床になりそうだな。
2022/03/21(月) 23:55:00.11ID:avj/Dp0k0
キャッシュとか、同期・非同期処理とか、ブロックされる・されないとか、
ブロックデバイス・シーケンシャルかとか、リダイレクト・パイプとか、
共有の有無とか、メモリ内共有かどうかとか、

そんな事を考えだしたら、キリがない

なんせ、Linux API の7割は、IO の説明だから、10年以上掛かる
396デフォルトの名無しさん (ワッチョイ 13ad-bSSa)
垢版 |
2022/03/22(火) 02:05:16.87ID:vyk85loe0
1バイト単位なら fdopen() しちゃって FILE * でバッファリングさせた方が楽だな。feof() も使えるし。
1バイト単位ではなく1000バイト単位とか、大きい塊でバッファリングする必要がある場合は自作して feof() みたいなチェックができるようにする。
(それでも FILE * でのバッファリングがあった方が遅いストレージにあるファイルなら読み出し効率上がると思うが)。
2022/03/24(木) 22:37:34.92ID:jD8pMP9K0
以下はライブラリバージョンが1より大きければ処理を有効する例です
#if LIBRARY_VERSION > 1

#endif

この「LIBRARY_VERSION」は何者ですか?
どこに定義されているのでしょうか?
2022/03/24(木) 23:58:11.94ID:ItLF0V9z0
>>397
少なくとも標準仕様ではどこにも定義されてないです
説明のための例では?
2022/03/24(木) 23:59:45.82ID:bdM8JANZ0
MSVC環境ならカーソル合わせてF12キー押せばいい

gccとかは知らん
2022/03/25(金) 00:14:08.19ID:sET9XTXv0
>>397
独習Cからの抜粋と予想して記載します

複数の開発環境で同じヘッダファイルを使用する際の
ライブラリバージョンの差異でエラーとなるのを防ぐための
テクニックです

各自が自分の開発環境に合わせて
#define LIBRARY_VERSION 1などと
定義する必要があります
2022/03/25(金) 06:50:38.08ID:0hAphrOld
いえ、それはそのライブラリの作者(メンテナンスしてる人)が標準ヘッダ内で定義すべき内容です
ユーザーは>>397を自分のファイル内で使用してバージョンの差異を吸収できます
402デフォルトの名無しさん (ワッチョイ 3696-VQaK)
垢版 |
2022/03/26(土) 01:22:16.42ID:EYuSPLit0
>>398,400,401
説明のための例のようですね、失礼しました
あと、この定数が未定義の場合の値は0になるのですね
そのあたりを理解していませんでした
どうもありがとうございました
2022/03/26(土) 16:05:05.08ID:EYuSPLit0
コンパイル(リンク)時に、同じプロジェクト内の別ソースの関数などを呼び出せるのはなぜ?
インクルードして教えてる訳でもないのに、もしかして全ソースを探しに行ってるんですか?
2022/03/26(土) 17:27:18.26ID:T/pJeR6z0
全ソースから探し出すのがリンク
includeとかで関数宣言だけは見えるようにする必要はあるが。

main.c
-----------
char* func(int size);
int main(){
char* p=func(16);
}
-----------

funcという名前の関数は、
前方宣言(1行目)してるのでリンク時に探しに行く。

リンク時の解決用に定義した関数(とその実装)を.objファイルに一覧としてまとめる。

リンクという作業では、.objと.libと.dllから"func"という名前の関数を探し出す。
見つからなかったり2つ以上見つかったらリンクエラーになる。

古いCだと前方宣言がなければ int func(); 決め打ちで前方宣言扱いしたりする。
2022/03/26(土) 18:26:49.41ID:kmPIEuI7d
>>403
(古典的な)Cではアセンブラソースに変換してアセンブル→リンクされるが
通常の関数名や変数名はアセンブラのグローバルシンボルに変換され
リンク時に他のアセンブラソースから参照できるようになる
一方関数内のローカル変数やstatic宣言された関数や変数はローカルシンボルとして扱われ他のアセンブラソースからは参照できなくなる
2022/03/26(土) 23:45:36.64ID:EYuSPLit0
よく分かりました、ありがとうございました
2022/03/27(日) 21:02:14.58ID:angONFKk0
グローバル変数の修飾子の意味は次の意味で合っているでしょうか?

修飾子なし:変数の実体を定義
extern修飾子:定義済みの変数を参照する
static修飾子:変数の実体を定義して、その変数を他のファイルからexternさせない
2022/03/28(月) 11:08:20.21ID:c4HYTfCO0
適当にググって見つかったexternとstaticの解説

ttps://daeudaeu.com/extern/
ttps://daeudaeu.com/static/
2022/03/29(火) 00:24:04.59ID:c+1KPnOj0
>>408
そのサイト含めいろいろ見て、それをまとめたのが>>407です
念のためどなたかに確認していただこうかと思って書き込みました
2022/03/29(火) 06:11:36.84ID:7UUvIzLId
そんなに信用されてもw
411デフォルトの名無しさん (ワッチョイ b110-UE6D)
垢版 |
2022/03/29(火) 08:18:01.14ID:C0VnxRTv0
自分で色々なパターンでコンパイルして確認しないのかな?って思う。
2022/03/29(火) 08:55:46.71ID:tKmNrPY6d
正確な意味を知るには解説サイト見て回るより規格書見るほうがいい

http://real-c.info/indexDesc.html
2022/03/29(火) 13:03:41.11ID:M0Gs9C4cM
llvm-14 の、ソースツリーの外にcmake ディレクトリができる下品な感じ、なんとかならないの?
2022/03/29(火) 15:17:04.78ID:X58TTE+20
>>413
cloneしたディレクトリの直下にbuildディレクトリ作ってそこでcmake 〜 ../llvmじゃいかんの?
今どきソースのディレクトリで直接ビルドしないのは下品というより上品ではないですか
2022/03/29(火) 18:15:06.70ID:U1DxU1KgM
>>414
>ソースツリーの外に

下品
2022/03/29(火) 18:20:46.45ID:1zZAboUWM
ソースツリーの中にbuildフォルダ作るのは上品なん?
2022/03/29(火) 18:47:55.98ID:4oPH291+0
autotools でも out-of-tree build は出来るようにするのが一般的な作法。
あらゆるプロジェクトでそうしているというほどではないと思うけど、ごく普通にある。
2022/03/29(火) 22:23:02.11ID:X58TTE+20
https://llvm.org/docs/CMake.html を見るとソースフォルダの外でビルドしなきゃいけないような感じに書いてあるけど、
https://clang.llvm.org/get_started.html を見るとリポジトリ直下にbuild作ってそこでビルドすればいいように書いてあるから、llvmはお上品にビルドできるのですわ
2022/04/01(金) 12:18:00.47ID:BXJ/mUbsM
llvm-14
まだゴミw
色んなものがダメになるw
2022/04/12(火) 19:31:59.59ID:B1tFLWvv0
char buf[256];
memset(buf, NULL, sizeof(buf));・・・(1)
memset(buf, 0, sizeof(buf));・・・(2)

(1)と(2)同じ事をしていると思うのですが、どっちで記述するのがメジャーですか?
2022/04/12(火) 19:35:46.65ID:Dt0TGPDOd
NULLはポインタだから(2)が正しいよ。
2022/04/12(火) 20:06:33.56ID:5njWaFr40
>>420
言語仕様に厳密にいうと前者で初期化しようとした場合に buf が 0 で初期化されることは保証されないし、
コンパイルエラーになることもありうる。

整数定数式の 0 がポインタに変換したときに空ポインタになることは保証されるので
NULL が単に #define NULL 0 として定義している環境もよくあるんだが、
仕様上の NULL は「処理系定義の空ポインタ定数に展開する」ということになっていて
整数の 0 を書ける文脈に NULL を書いて通るとは限らないんだ。

そんで「整数定数式の 0」がポインタに変換されたときに空ポインタになることは保証されるが、
定数式ではない文脈での整数の 0 は空ポインタになることは保証されていないし、
逆に空ポインタを整数に変換したときに 0 であるとも限らない。
if 文などの制御式としてポインタを置いても問題ないのは C の制御式は !=0 が補われたかのように動作するというルールのおかげ。
2022/04/12(火) 20:07:57.92ID:B1tFLWvv0
>>421-422
お早いレスサンクス
わかりました
2022/04/20(水) 22:16:48.28ID:vxzn/db60
>>422
>整数の 0 を書ける文脈に NULL を書いて通るとは限らないんだ。
可変長引数にあるあるの最後に (char *)0 (なんで char * なんだ?)なんかがいい例ですね
2022/04/22(金) 15:01:50.27ID:YxI2bgUE0
(ソースtt.c)
#include <stdio.h>
#include <math.h>

void main()
{
double d;
int a;

d = 1.234;
a = round(d);
printf("%d\n", a);
}

$gcc tt.c
/tmp/cc0NPwg6.o: 関数 `main' 内:
tt.c:(.text+0x23): `round' に対する定義されていない参照です
collect2: error: ld returned 1 exit status

こんな短いソースなのに解決できない。助けてー(´・ω・`)
OSはLinuxです
2022/04/22(金) 15:04:48.71ID:SxzvmxoM0
どうせリンクしてないとかそんなんだろ
2022/04/22(金) 15:05:51.08ID:BJPJNuGwd
>>425
古いコンパイラにはroundがないかもしれない。
2022/04/22(金) 15:06:16.30ID:BJPJNuGwd
-lm
2022/04/22(金) 15:12:16.74ID:SxzvmxoM0
gccなら -lmで動的リンクする簡易オプションがある、プログラム内だけで完結したいならコンパイラ付属のmathライブラリのソースも含めてコンパイル
2022/04/22(金) 15:14:29.72ID:SxzvmxoM0
動的リンクだとmathは浮動小数点の扱いが実行環境に依存するので静的リンク推奨
2022/04/22(金) 15:26:22.00ID:YxI2bgUE0
ありがとう
gcc tt.c -lm
でコンパイル通りました。
2022/04/22(金) 15:44:53.29ID:I04xh82td
割とよく使う標準ライブラリなのに一々リンク方法をユーザーに選択させるという事の意義を考えるように、おまじないじゃないぞ
2022/04/22(金) 17:13:59.15ID:RFW8R+x+d
roundかtruncかfloorかはたまたceilかもしれないrintとその一味のヤバいやつら
こんなもんさっさと追放しろよ
2022/04/22(金) 17:31:11.41ID:SxzvmxoM0
整数型で表せない整数をdoubleで表したい時も稀にある
どうせ前後の整数(±1)は表せない不連続すきっ歯領域だし、どう丸まろうが影響無い部分だよ、って意図の明示に
2022/04/22(金) 17:49:02.83ID:SxzvmxoM0
用途は思い浮かばないでもないが、適切に使われてないケースが多分99%
2022/04/23(土) 13:45:19.22ID:+Gd9xYyP0
表せないときは整数型多倍長処理作る
437デフォルトの名無しさん (ワッチョイ 2cae-E6ke)
垢版 |
2022/04/24(日) 11:54:23.21ID:S9c+iUdl0
GMPでそ
C++じゃないとちょっと使いにくいけど
2022/04/24(日) 15:18:10.66ID:Qwrn6LYl0
>>437
激しく同意
https://mevius.5ch.net/test/read.cgi/tech/1434079972/84
2022/04/25(月) 03:24:41.99ID:LAuA6+3Dd
多倍長整数とか言ってる人は意図汲めてなくね?

正確性も表現力も不要だけど、それでも整数に相当する巨大数が要るのは極を利用した求根アルゴリズム(方程式解法)とかでしょうよ

たとえば、求めたい関数fの根がその逆数関数1/fの極と等しい事を利用するとか

もしdoubleの範囲を多倍長整数/任意桁数演算で308桁を陽に扱必要があるけど、そもそも極判定は指数部のみで行えるわけで、各桁の数字を陽に保持する意味が無い


一方で指数が巨大なdoubleを生で足すのは悪手
丸めれば各々の積分経路での評価値は真値から一旦遠ざかるけど、一貫した丸めを行う限りは10000万回も足せば互いに相殺されて均される
2022/04/25(月) 03:38:21.89ID:LAuA6+3Dd
ちょっと拵えすぎたような設定だったかもしれないけど、300桁を陽に保持して、ハードウェアの恩恵も無しに一万回加算とか、向かないどころかあまりにも非現実的過ぎる例もある
という例程度に

あとdouble使ってればinfが返ってくる可能性があるのが最大の利点
もしinfを引き当てられれば、それを与正入力がその浮動小数点実装における最高精度の解だと理論的に保証される
2022/04/25(月) 03:44:18.07ID:LAuA6+3Dd
訂正と補足
それを与正→与えた入力

(1/f)(x)→inf

f(x) → 0

fの根はそのx
は論理的に同値
2022/04/25(月) 05:05:51.34ID:ueJIdSJ50
INF見付かれば恣意的に収束/発散閾値を調整しなくてエレガントだよな

俺は素性の事前に分かってて留数定理使えるような関数くらいしか扱わないから、気にせずそのまま足しちゃうわ

積分経路は(楽だから)正方形に取り、均等に4分割して極のある範囲を再帰的に絞り込んでる、下手にニアミスしたりするとかえって桁落ちしたりして整数倍からズレる
±0.1くらいなら、きっと極を囲めてるものと想定

Cで数値計算入門みたいな本で勉強してるけど、浮動小数点の特殊値とかエラーの扱いとかの記述が一切抜け落ちてて困る
2022/04/25(月) 19:15:48.77ID:o7ajKrF0d
実質ハードの実装に収束(発散)判定任せて綺麗に見えてるだけだがな
しかし比較無しに符号、複素数なら東西南北まで得られるのは便利
2022/05/09(月) 06:57:39.16ID:Egg1/KgR0
20年くらい前、Windows98が使われてた頃なんですが
char s = ''; // ←シングルクォーテーション2個
っという書き方が許されてた記憶があるんですが、記憶違いかな?
今Linux上のgccでコレをコンパイルすると「error: empty character constant」になる
2022/05/09(月) 07:35:16.71ID:QnLN+NJ0a
あえてなのかバグなのかは知らんけど20年前のコンパイラがそういう記法を通してたってだけだろ
2022/05/09(月) 08:27:27.53ID:Egg1/KgR0
>>445
冷静に考えてみたらコンパイラもOSも違うからそういうことだな
2022/05/09(月) 10:42:17.80ID:qGH53jdv0
''で何が代入されるの?
2022/05/09(月) 11:12:38.36ID:DLFHVgdp0
'\0' や 0 と同等の動作なんかねぇ
2022/05/09(月) 11:15:27.95ID:DuxsXAR8M
普通に考えれば空文字だと思う
2022/05/09(月) 11:35:54.50ID:lTlzTKNA0
NULL 「何もないよー」な意味をあらわす単語
空文字 長さ0文字の文字列のこと

この解釈でOK?
2022/05/09(月) 11:37:44.15ID:DLFHVgdp0
文字と文字列は違う 今話題に上がってるのは文字のほう
2022/05/09(月) 12:02:23.30ID:ItS/vT2KM
長さ0文字の文字列なら""(ダブルコーテーション)では?
2022/05/09(月) 14:03:39.88ID:KBCMvYUWa
>>448
まあそれが一番ありがちかと
2022/05/09(月) 17:13:19.74ID:9vSL2/iz0
>>444
言語仕様にはそれを通す規定は見つからないな。
少なくとも一文字は必要であることになってる。
C89 ではすでにそうなってるし、後の仕様でも変更はない。
出来る処理系があったのだとしたらあくまで処理系の拡張。

「たとえば 'ab' などのように二文字以上を含む場合は処理系定義」という意味の規定はあるので
雑に任意個の文字を受け付けるようにしたらうっかり 0 個も通してしまったとか、
意図的ではない挙動 (コンパイラのバグ) だった可能性もあるし。
455デフォルトの名無しさん (ワッチョイ 2e02-ltxK)
垢版 |
2022/05/09(月) 17:32:30.12ID:x5IK3MV30
立方根を自作関数で求める方法教えてください、、、、、
2022/05/09(月) 17:46:08.50ID:9vSL2/iz0
>>455
要件次第だけど実装が一番簡単なのは log を使うことだと思う。
457デフォルトの名無しさん (ワッチョイ 2e02-ltxK)
垢版 |
2022/05/09(月) 17:47:02.53ID:x5IK3MV30
>>456
ニュートン法を使いたいです、、
2022/05/09(月) 17:50:27.78ID:9vSL2/iz0
>>457
方法がわかってるなら何をききたいの?
2022/05/09(月) 18:03:26.90ID:jsi1f5HY0
何も入っていない変数が作れます
2022/05/09(月) 18:36:55.77ID:4JqWZIdB0
だからその
> 何も入っていない
は0から0xffのうちの何なのよ。
1 Byteの領域はあるんでそ。
2022/05/09(月) 18:39:59.52ID:jsi1f5HY0
そこは未知の領域
2022/05/09(月) 19:59:08.45ID:UxqgrJa1a
>>460
ネタに全力で食いつくなよw
2022/05/09(月) 20:46:46.66ID:poYUryAv0
一番簡単なのは挟み撃ちだと思うけどな
1の三乗は
0.5の三乗は
と1/2づつ狭めていく
2022/05/10(火) 09:30:11.65ID:79aB+w7Md
>>450
NULLはポインターに代入できる「無意味な位置」を表すアドレス
2022/05/10(火) 11:28:15.81ID:dIEMLhL70
だいぶんボケたことを書いてしまった。 (>>456)
式変形をする必要すらなく pow ひとつで良かった。

double cube_root(double x) {
return pow(x, 1.0/3);
}
2022/05/10(火) 19:36:27.76ID:gxi5OEx30
それを自作関数で求めるとは言わんやろ
467デフォルトの名無しさん (ワッチョイ 6aad-zDU0)
垢版 |
2022/05/10(火) 23:29:45.70ID:CQsKbFR90
言うだろう
2022/05/11(水) 06:53:21.08ID:zyEQjrH3d
コンビニ弁当買ってきて料理したというレベル
2022/05/11(水) 10:08:25.28ID:jCepvp6u0
通はコンパイラの自作から始める?
2022/05/11(水) 10:35:21.30ID:a8uVrD+/M
情報学科ならCPU設計からだよ
2022/05/11(水) 10:39:55.99ID:3yHJq16kM
CPU設計だと情報学科なのか電子工学科なのか微妙なところ
2022/05/11(水) 10:43:04.06ID:jCepvp6u0
CPU設計ソフトを作る事から
2022/05/11(水) 12:00:05.99ID:2wozbOYLd
普通は自作関数作りたいんですって言ったら
>>463みたいなアルゴリズムを求めてるだろ
何の用途かは知らんが
2022/05/11(水) 12:53:38.63ID:rJ/SGv8Sa
>>471
素子の物理設計からなら電子工学
アーキテクチャからなら情報工学
じゃね?
まあ素子の物理設計なんてやってる学校があるかどうかは知らんけど
2022/05/11(水) 12:57:11.03ID:3n2UFvlUM
CPU設計の半導体物性や加工技術は情報学科の範疇外だと思う
2022/05/11(水) 21:22:30.22ID:Uorg83Yar
>>455
もう解決したってことでいいよね
2022/05/11(水) 23:25:04.32ID:eEErnLrt0
>>457
精度を組み込み関数より高めたいのかな?
なら一回で十分だよ、ループする必要も収束を確かめる必要もなくて、
y-=fx / f'x
だけで数桁精度が上がる
478デフォルトの名無しさん (ワッチョイ 73d2-U1YL)
垢版 |
2022/05/12(木) 00:07:01.33ID:a2iZs8ls0
たぶんニュートン法を使いたいけどアルゴリズムを実装できないだけだと思うな
2022/05/12(木) 00:13:44.54ID:rHUhttMxr
反論がないし解決したってことで
2022/05/12(木) 03:09:36.14ID:DwGZHhAI0
simulink coderが便利すぎて手打ちする気にならない件
481デフォルトの名無しさん (ワッチョイ 6fbd-EjCo)
垢版 |
2022/05/14(土) 10:01:08.50ID:JFqjXnq80
>>444
許されていないよ

char *ss = “”;
char ch = ‘a’;

の記憶違いでしょう
2022/05/14(土) 10:23:10.43ID:yelWKEO3d
char ch = NULL;
という書き方ならよく見かけた
これはもちろん間違いなのだが
2022/05/14(土) 15:45:11.14ID:fRXCxvkXd
>>444
これどうなったの
484デフォルトの名無しさん (ワッチョイ e3ad-lIli)
垢版 |
2022/05/15(日) 13:21:26.16ID:evMzyiSb0
'' が使えるかどうかはコンパイラ次第なのでは?
文法的にダメだろうがなんだろうが使えるようにコンパイラ作られたらそれまでだし。

そういやGCCにも void * の変数に ++ とかの計算が出来たりして衝撃を受けたことがあったなあ。
他のコンパイラでコンパイルしてエラーになって発覚。
2022/05/15(日) 13:31:38.71ID:+H3bKj0ad
キャスト式に代入とかね
2022/05/15(日) 13:39:44.18ID:tGTiPFBf0
void *型のインクリって一体何バイト進むんだ?
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

ニューススポーツなんでも実況