最近FirefoxだとTwitterよりKarotterの方が安定している
最近FirefoxだとTwitterよりKarotterの方が安定しているめんくり
@menkuri
Don't be evil. C言語をメインに書いている趣味プログラマ。たまにRustも書きます。
公開投稿・作品
Gemini、意外と皮肉が通じていい https://gemini.google.com/share/97a9e8802908
Gemini、意外と皮肉が通じていい https://gemini.google.com/share/97a9e8802もちろん char hello[] = "hello"; char* hello_ptr = hello; // decay, hello = &hello[0] とした場合は hello_ptr の指す先はスタック領域の配列になっているので、 hello_ptr[2] = 'L'; のように書き換え可能であり、char* だからといって必ず const を付けるわけではない 3/3
もちろん char hello[] = "hello"; char* hello_ptr = hello; // decだからアクセス方法も違うし、中身を書き換えられるかどうかも違う (前者は静的領域の文字列リテラルなので書き換え不可、後者はスタック領域の配列なので書き換え可) 間接参照した先が書き換え不可能な上のケースは、必ずデータ型の方に const を付けるべき const char* hello = "hello"; こうすることで書き換えようとするとコンパイルエラーで止めることができる 2/n
だからアクセス方法も違うし、中身を書き換えられるかどうかも違う (前者は静的領域の文字列リテラルなので書き換え不可、後者#Cプログラミングの落とし穴 char* hello = "hello"; char hello[] = "hello"; どっちも同じことをやってるように見えて全く違うのが怖いポイント 上は文字列のある静的領域へのポインタになってるけど、下は文字列が格納された配列を作ってる (なお、C言語の文字列は最後に \0 という文字を含むため、長さ6の配列が確保されていることに注意) 1/n
#Cプログラミングの落とし穴 char* hello = "hello"; char hello[] = "hello"int (*a)[16][32] という書き方もできる (というか decay を考えるとこれが一番実態としては正しい) けど、これはこれで3次元の配列だとわかりにくすぎるので、やっぱりしないかなあ 5/5
int (*a)[16][32] という書き方もできる (というか decay を考えるとこれが一番実態としては正しい)今度は別の引数で大本の配列のサイズ(先ほどの例では 8)を渡さないといけない(size_t len のように)ことを忘れがちになる(decay の影響で 8 は無視されているため) なので私は int a[][16][32] みたいな最初だけサイズを書いていないことを明示した書き方にしがち (書いていないから「別で渡せよ」という意味合いを持たせている) 4/n
今度は別の引数で大本の配列のサイズ(先ほどの例では 8)を渡さないといけない(size_t len のように)ことを忘れ多次元配列は引数に渡す時も地味に複雑 配列がポインタに decay されてしまうので大本の配列のサイズはあっても意味がないけど、要素の配列のサイズは型の一部だから書かれていないとエラーになる とりあえず多次元配列を渡す時は全部サイズを書いておけば ex. int a[8][16][32] エラーは防げるのだけど、 3/n #Cプログラミングの落とし穴
多次元配列は引数に渡す時も地味に複雑 配列がポインタに decay されてしまうので大本の配列のサイズはあっても意味がな実際、以下のコードでも上記のものと同じ意味になる int calender[12][31]; typedef int (*calender_t)[31]; calender_t monthp; monthp = calender; typedef からわかるように、型指定子に [31] が含まれてしまっている 2/n
実際、以下のコードでも上記のものと同じ意味になる int calender[12][31]; typedef int (int calender[12][31]; int (*monthp)[31]; monthp = calender; C言語では二次元配列は配列に配列が入ってる、配列型の配列になっている それをポインタで扱おうとすると要素となる配列のサイズが型名に含まれるというなかなかに気持ち悪いことになる 1/n #Cプログラミングの落とし穴
int calender[12][31]; int (*monthp)[31]; monthp = calender;