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/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 *型のインクリって一体何バイト進むんだ?
2022/05/15(日) 13:48:28.89ID:+dMN0zqr0
>void *型のインクリって一体何バイト進むんだ?
codepad のC言語 → 1バイト
codepad のC++ → エラー
ISO C++ forbids incrementing a pointer of type 'void*' compilation terminated due to -Wfatal-errors.
2022/05/15(日) 13:53:41.23ID:evMzyiSb0
>>486
1だったよ。char * と同じように計算していた。
お近くの gcc でお試しください。
2022/05/15(日) 14:00:59.60ID:tGTiPFBf0
即レスサンキュー
2022/05/15(日) 14:07:27.97ID:PUHmRytO0
gcc だと sizeof(void) が 1 を返したりするんだよな。
C++ だとこれがエラーになることを SFINAE のトリックに使ったりすることもあるんで、
どうやって辻褄を合わせているのかよくわからん。
2022/05/16(月) 14:17:30.76ID:KxReCtrr0
こういう質問が来るたびに自分で試せばいいのにって思う。
仕様がどうなってるのかという質問なら理解できるけど。
2022/05/16(月) 20:01:48.66ID:YQrK3HARa
いや、マニュアル読めよ...
https://gcc.gnu.org/onlinedocs/gcc-12.1.0/gcc/Pointer-Arith.html
2022/05/17(火) 11:31:17.17ID:HihepIbQd
単に好奇心で聞いてるだけだと思うよ
実用的に使おうと言うんじゃなく
というか関数ポインタも1バイトになるのかw
2022/05/17(火) 11:43:19.86ID:VUKzLr9a0
何か有用な使い道ってあるか?
2022/05/17(火) 17:06:43.60ID:FuWQL0zJ0
汎用ポインタとして void * で受けておいて
char * でキャストすることなく そのポインタを 1バイト単位で操作できたとしても
*で実体を取得する瞬間にキャスト必須になるし どうなんだろ
2022/05/17(火) 18:02:18.76ID:HihepIbQd
ただのうっかりミスだと思うんだが
修正するとコンパイルできなくなるんで仕様にしてしまったのか
2022/05/17(火) 18:51:17.67ID:Qbd65aeba
>>493
> というか関数ポインタも1バイトになるのかw
んなわけないだろw
関数ポインタは普通に4/8バイトだよ
関数のサイズが1バイトになる
http://codepad.org/zwItkWg3
2022/05/17(火) 19:17:06.37ID:kg0MHFY+0
バグからさめると別のバグの世界のような気がする。
2022/05/17(火) 20:20:31.65ID:HihepIbQd
>>497
君以外はみんなわかってる気がするw
2022/05/17(火) 21:01:08.19ID:xzGoH14A0
>>495
Cスタイルキャストだとあまり気にならないかもしれないけどC++スタイル2回重ねるのはちょっと嫌になる。
2022/05/17(火) 21:09:29.94ID:JCWwsd/Ra
>>499
関数ポインタが1バイトとか言ってたアホがいたんだけどw
てかお前意味わかってないだろ
2022/05/17(火) 21:17:57.23ID:VUKzLr9a0
>>501
文脈を踏まえれば >>493 が言ってるのは「関数ポインタでも (インクリメントで進む量は) 1 バイト」というのは理解できるだろ……。
2022/05/17(火) 21:26:34.47ID:cXB/OW/Na
文脈?

> gcc だと sizeof(void) が 1 を返したりするんだよな。

> というか関数ポインタも1バイトになるのかw

恥の上塗りかよw
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

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