K.Maebashi's BBS

ご自由に書き込んでください。雑談も可。
テスト書き込みの類はテスト用掲示板にどうぞ

[日付順表示] [日付順インデックス] [スレッド順インデックス]

新規投稿 | 開設者ホームページへ戻る | ヘルプ

[2381] C言語の配列とポインタの話題
投稿者:mhash
2024/07/01 02:59:33

togetterに配列の添字演算子はポインタ演算のシンタックスシュガーだよ、という記事が載っていました。 意外と知られていないみたいです。 https://togetter.com/li/2393030
[この投稿を含むスレッドを表示] [この投稿を削除]
[2380] Re:ポインタ完全制覇の質問
投稿者:(ぱ)こと管理人
2024/05/27 21:16:14

>C の場合 >変数定義で要素数を書かない場合(上記 static int a[]; が該当)には当該変数は >不完全型な仮定義 (tentative definition) になる・・・と言いたいところなんですが > static がある場合には仮定義にならず一発定義になります。 確認しました。ここについてはこれですかね。 | 6.9.2 外部オブジェクト定義 … | オブジェクトに対する識別子の宣言が仮定義であり,内部結合をもつ場合, | その宣言の型は不完全型であってはならない。 これを普通に読むと、 static int a[]; はそれ自体でコンパイルエラーになりそうなものですが (まあ実際、役に立たないと思いますし)、 | 大きさの分からない配列型は,不完全型とする。その型は,それ以降のその型の | 識別子の宣言(内部結合又は外部結合をもつ)で大きさを指定することによって, | 完全となる。 こっちでは(内部結合でも)それ以降の宣言で大きさを指定すればよい、 とあるようで、これがどういう時に有効なのか、読み解けていません…
[この投稿を含むスレッドを表示] [この投稿を削除]
[2379] Re:ポインタ完全制覇の質問
投稿者:(ぱ)こと管理人
2024/05/25 08:10:03

いつもありがとうございます。 >C の場合 >変数定義で要素数を書かない場合(上記 static int a[]; が該当)には当該変数は >不完全型な仮定義 (tentative definition) になる・・・と言いたいところなんですが > static がある場合には仮定義にならず一発定義になります。 >また、要素数についてはコンテキスト次第で解釈が変わってよいところです。 >とあるコンテキストではこれを int a[1]; と読んでよいことになっています。 >別のコンテキストではこれを不完全型と読んでよい(要素数未知)ことになっています。 この週末は出かけますのでこのあたり帰ってきたら確認します……
[この投稿を含むスレッドを表示] [この投稿を削除]
[2378] Re:ポインタ完全制覇の質問
投稿者:774RR
2024/05/24 13:10:59

この辺 C と C++ で微妙に仕様が違うところピンポイントで踏み抜いているのでいろいろわけわからんことになっています。今この瞬間には C 言語仕様書 JIS X 3010 ならびに C++ 言語仕様書 JIS X 3014 にアクセスできないので記憶とコンパイラの挙動だけで話をします。 サンプルソース tentative.c ないしは tentative.cpp static int a[]; static int a[4]; unsigned long f() { return sizeof a; } C の場合 変数定義で要素数を書かない場合(上記 static int a[]; が該当)には当該変数は不完全型な仮定義 (tentative definition) になる・・・と言いたいところなんですが static がある場合には仮定義にならず一発定義になります。また、要素数についてはコンテキスト次第で解釈が変わってよいところです。とあるコンテキストではこれを int a[1]; と読んでよいことになっています。別のコンテキストではこれを不完全型と読んでよい(要素数未知)ことになっています。詳細は言語仕様書を読まないと出てきません(覚えていません)。 cygwin64 にて $ gcc --version gcc (GCC) 11.4.0 // 以下略 $ gcc -W -Wall -pedantic -O -S tentative.c tentative.c:1:12: error: array size missing in 'a' 1 | static int a[]; | ^ tentative.c:2:12: error: conflicting types for 'a'; have 'int[4]' 2 | static int a[4]; | ^ tentative.c:1:12: note: previous declaration of 'a' with type 'int[1]' 1 | static int a[]; | ^ tentative.c:1:12: warning: 'a' defined but not used [-Wunused-variable] $ ということで gcc-11.4.0 は先の例を static int a[1]; と読んでいます。本当にそう読んだのかアセンブラコードで確認したいところですが、残念ながらコンパイルエラーになっているので確かめられません。 C++ の場合 C にあった仮定義がなくなっている関係で int a[]; は個数不定な「変数定義」になります。なのでこの時点でコンパイルエラー。更に ODR (one definition rule) も適用され int a[4]; と矛盾しここでもエラーになります。 $ g++ -W -Wall -pedantic -O -S tentative.cpp tentative.cpp:1:12: error: storage size of 'a' isn't known 1 | static int a[]; | ^ $ あるいは Visual Studio 2019 の VC++ だと D:\work\tmp>cl -W4 -Ox -c tentative.c Microsoft(R) C/C++ Optimizing Compiler Version 19.29.30154 for x64 Copyright (C) Microsoft Corporation. All rights reserved. tentative.c tentative.c(1): error C2133: 'a': サイズが不明です。 D:\work\tmp>cl -W4 -Ox -c tentative.cpp Microsoft(R) C/C++ Optimizing Compiler Version 19.29.30154 for x64 Copyright (C) Microsoft Corporation. All rights reserved. tentative.cpp tentative.cpp(1): error C2133: 'a': サイズが不明です。 tentative.cpp(2): error C2086: 'int a[]': 再定義されました。 tentative.cpp(1): note: 'a' の宣言を確認してください tentative.cpp(4): error C2070: 'int []': sizeof オペランドが正しくありません。 というわけで不完全型な変数定義になる static int a[]; は書いちゃダメ、コンパイラ次第で挙動が違う、でしょう。まあコンパイルエラーになってくれるので、実行するまでわからないという最恐な事態には陥らなくて済みそうです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[2377] Re:ポインタ完全制覇の質問
投稿者:sasaki
2024/05/17 16:47:21

>>OS : Windows10 Enterprise (ver 22H2) >>コンパイラ: gcc 6.3.0 > >ちょっと調べてMinGWはgcc 6.3.0って古すぎないかという記事を見かけたので、 >https://stackoverflow.com/questions/68360901/why-is-the-latest-mingw-gcc-version-6-3-0 > >MinGWなら6.3.0があるのかな、とosdn.netからmingw-get.exeとやらを入手して >6.3.0をインストールしようとしたのですがないと言われて >7.3.0-1を(むりやり)動かしたら再現しました。正直驚きました。 > >>#include <stdio.h> >> >>static int a[]; >> >>int main() >>{ >> >> return 0; >>} > >これだと配列aのサイズが決まっていないわけで、ではコンパイラはaのサイズを >いくつだと思っているのか確認しようと > > printf("sizeof a..%d\n", sizeof(a)); > >とやってみると、 >invalid application of 'sizeof' to incomplete type 'int[]' > >と言われます。aがincomplete type(不完全型)だと言っています。 > >これについては規格でも「6.2.5 型」のところで > >| 大きさの分からない配列型は,不完全型とする。その型は,それ以降のその型の >| 識別子の宣言(内部結合又は外部結合をもつ)で大きさを指定することによって, >| 完全となる。 > >という記載があるので、以下のようにint a[10];を追加したら、 >gccの9.4.0でもコンパイルが通って、「sizeof a..40」と表示されました。 > >#include <stdio.h> > >static int a[]; > >static int a[10]; > >int main() >{ > printf("sizeof a..%d\n", sizeof(a)); > return 0; >} > >それにしても、staticなのにこの.c内でサイズ指定して完全型にならないのなら、 >やっぱりコンパイルを通してはダメだと思うのですが…… >なので最近のgccではエラーにしているのだと思います。 >私も勉強になりました。ありがとうございました。 ご回答ありがとうございます。 私のgccそんなに古かったとは… 環境構築の際に、どこかの参考サイトの書いてあるがままにインストールしていました。(反省します) gccを13.2.0に更新して試してみたところ、前橋様と同じ挙動になりました。 こちらこそ変な質問に丁寧にご対応頂きありがとうございました。
[この投稿を含むスレッドを表示] [この投稿を削除]
[2376] Re:ポインタ完全制覇の質問
投稿者:(ぱ)こと管理人
2024/05/17 00:46:58

>OS : Windows10 Enterprise (ver 22H2) >コンパイラ: gcc 6.3.0 ちょっと調べてMinGWはgcc 6.3.0って古すぎないかという記事を見かけたので、 https://stackoverflow.com/questions/68360901/why-is-the-latest-mingw-gcc-version-6-3-0 MinGWなら6.3.0があるのかな、とosdn.netからmingw-get.exeとやらを入手して 6.3.0をインストールしようとしたのですがないと言われて 7.3.0-1を(むりやり)動かしたら再現しました。正直驚きました。 >#include <stdio.h> > >static int a[]; > >int main() >{ > > return 0; >} これだと配列aのサイズが決まっていないわけで、ではコンパイラはaのサイズを いくつだと思っているのか確認しようと printf("sizeof a..%d\n", sizeof(a)); とやってみると、 invalid application of 'sizeof' to incomplete type 'int[]' と言われます。aがincomplete type(不完全型)だと言っています。 これについては規格でも「6.2.5 型」のところで | 大きさの分からない配列型は,不完全型とする。その型は,それ以降のその型の | 識別子の宣言(内部結合又は外部結合をもつ)で大きさを指定することによって, | 完全となる。 という記載があるので、以下のようにint a[10];を追加したら、 gccの9.4.0でもコンパイルが通って、「sizeof a..40」と表示されました。 #include <stdio.h> static int a[]; static int a[10]; int main() { printf("sizeof a..%d\n", sizeof(a)); return 0; } それにしても、staticなのにこの.c内でサイズ指定して完全型にならないのなら、 やっぱりコンパイルを通してはダメだと思うのですが…… なので最近のgccではエラーにしているのだと思います。 私も勉強になりました。ありがとうございました。
[この投稿を含むスレッドを表示] [この投稿を削除]
[2375] Re:ポインタ完全制覇の質問
投稿者:sasaki
2024/05/16 09:30:26

ご回答いただきありがとうございます。 >初期化とは関係なく、配列にはサイズが必要です。 >サイズを入れない空の[]が書ける場所は、「ポインタ完全制覇」なら「3-5-3 空の[]について」で >説明している以下の箇所です。 > >1.関数の仮引数の宣言 >2.初期化子により配列のサイズが確定できる場合 >3.グローバル変数をextern宣言する場合 > >ここで、1はポインタに読みかえられるのでそもそも配列ではなく、 >2と3は、初期化子でサイズがわかったり、別のコンパイル単位にサイズが書いてあることが >期待できる、という理由で空の[]が書けます。 >extern宣言ではないグローバル変数の定義で、初期化子も書かなければ、 >やはりサイズは必要です。 >関数外に、単に > >int a[]; > >と書いて、仮にコンパイルが通ったとして、この配列の要素数はいくつであるのが適当でしょうか? >「少なくとも一つは0が代入され、int a[] = {0};と同義」になったとしても、 >別に便利でもないのではないでしょうか。 確かにおっしゃる通りです。 配列とポインタを混同して勝手におかしな解釈をしていることに気づきました。 ご指摘いただきありがとうございます。 「3-5-3 空の[]について」、「3-6 配列とポインタは別物だ!!」を肝に銘じておきます。 >>②①のあとに、グローバル変数であることが重要なのではなく静的変数であることが重要なのではと考え、 >> 試しにstatic int a[];としたら、これはコンパイルが成功しました。 > >これは普通にコンパイルが通らないのでは、と思います。 > >私がgcc 9.4.0で試したところ、 >関数外にstatic int a[];と書いたら以下のエラーが出ました。 > >test.c:3:12: warning: array ‘a’ assumed to have one element > 3 | static int a[]; > >関数内だと以下です。いずれにしてもエラーです。 > >test.c:6:16: error: storage size of ‘a’ isn’t known > 6 | static int a[]; > >sasakiさんの環境でエラーにならないようでしたら、環境(OS, コンパイラ、コンパイラのバージョン)を >教えてください。また、ソースをまるごとここに貼ってください。 下記の通りです。 【環境】 OS : Windows10 Enterprise (ver 22H2) コンパイラ: gcc 6.3.0 【ソースコード】 #include <stdio.h> static int a[]; int main() { return 0; }
[この投稿を含むスレッドを表示] [この投稿を削除]
[2374] Re:ポインタ完全制覇の質問
投稿者:(ぱ)こと管理人
2024/05/15 22:20:25

>①前回ご教示頂いた内容の私なりの解釈では、グローバル変数などの静的変数は初期化しなかった場合、 > 算術型の変数は0で初期化されると理解しました。 > であれば、int a[]も関数外で宣言することにより、プログラマが初期化しなくてもグローバル変数 > として自動的に初期化され、JIS X 3010:2003「6.7.8 初期化」のc)d)の合わせ技により、配列内に > 少なくとも一つは0が代入され、int a[] = {0};と同義になるのではと思い、関数外であればint a[]; > を宣言できるのではと考え、試しに関数外に宣言してみたのですがコンパイルエラーになりました。 > 前述【超重要!!】の内容はやはり正しいとして、今回私が疑問に思い行った実験は初期化の考え方が > 間違っているのでしょうか? 初期化とは関係なく、配列にはサイズが必要です。 サイズを入れない空の[]が書ける場所は、「ポインタ完全制覇」なら「3-5-3 空の[]について」で 説明している以下の箇所です。 1.関数の仮引数の宣言 2.初期化子により配列のサイズが確定できる場合 3.グローバル変数をextern宣言する場合 ここで、1はポインタに読みかえられるのでそもそも配列ではなく、 2と3は、初期化子でサイズがわかったり、別のコンパイル単位にサイズが書いてあることが 期待できる、という理由で空の[]が書けます。 extern宣言ではないグローバル変数の定義で、初期化子も書かなければ、 やはりサイズは必要です。 関数外に、単に int a[]; と書いて、仮にコンパイルが通ったとして、この配列の要素数はいくつであるのが適当でしょうか? 「少なくとも一つは0が代入され、int a[] = {0};と同義」になったとしても、 別に便利でもないのではないでしょうか。 >②①のあとに、グローバル変数であることが重要なのではなく静的変数であることが重要なのではと考え、 > 試しにstatic int a[];としたら、これはコンパイルが成功しました。 これは普通にコンパイルが通らないのでは、と思います。 私がgcc 9.4.0で試したところ、 関数外にstatic int a[];と書いたら以下のエラーが出ました。 test.c:3:12: warning: array ‘a’ assumed to have one element 3 | static int a[]; 関数内だと以下です。いずれにしてもエラーです。 test.c:6:16: error: storage size of ‘a’ isn’t known 6 | static int a[]; sasakiさんの環境でエラーにならないようでしたら、環境(OS, コンパイラ、コンパイラのバージョン)を 教えてください。また、ソースをまるごとここに貼ってください。
[この投稿を含むスレッドを表示] [この投稿を削除]
[2373] Re:ポインタ完全制覇の質問
投稿者:sasaki
2024/05/15 17:16:34

お世話になっております。 また質問をさせてください。(2つあります) 本書P210の【超重要!!】で「int a[]がint *aと同じ意味になるのは、唯一、関数の仮引数の宣言の場合だけ」 という所を読み、2つ実験をしてみて疑問に思った内容の質問です。 ①前回ご教示頂いた内容の私なりの解釈では、グローバル変数などの静的変数は初期化しなかった場合、  算術型の変数は0で初期化されると理解しました。  であれば、int a[]も関数外で宣言することにより、プログラマが初期化しなくてもグローバル変数  として自動的に初期化され、JIS X 3010:2003「6.7.8 初期化」のc)d)の合わせ技により、配列内に  少なくとも一つは0が代入され、int a[] = {0};と同義になるのではと思い、関数外であればint a[]; を宣言できるのではと考え、試しに関数外に宣言してみたのですがコンパイルエラーになりました。  前述【超重要!!】の内容はやはり正しいとして、今回私が疑問に思い行った実験は初期化の考え方が  間違っているのでしょうか? ②①のあとに、グローバル変数であることが重要なのではなく静的変数であることが重要なのではと考え、  試しにstatic int a[];としたら、これはコンパイルが成功しました。  これにより余計に頭がパンクしそうなのですが、静的変数であることを明示するとint a[]がint *aと同義  になるのでしょうか? お手数ですがご教示のほどお願いいたします。
[この投稿を含むスレッドを表示] [この投稿を削除]
[2372] Re:ポインタ完全制覇の質問
投稿者:sasaki
2024/05/13 11:56:08

ご回答いただきありがとうございます。 添付してくださった参照先(JIS X 3010:2003「6.7.8 初期化」)も確認しました。 〇ローカル変数や自分で領域を確保した動的変数は、プログラマが初期値を指定しなかった場合、その値は不定。 〇グローバル変数などの静的変数は、プログラマが初期値を指定しなかった場合、  ・算術型(int型等)…初期値0 ・ポインタ型…初期値NULL と、理解しました。 ご教示いただきありがとうございました。
[この投稿を含むスレッドを表示] [この投稿を削除]
[2371] Re:掲示板が停止していました
投稿者:(ぱ)こと管理人
2024/05/11 09:58:53

ログを見ると、05/11 06:09くらいまでこの掲示板は動いた形跡があって (spamよけ認証エラーが出ていた。こんな過疎掲示板にもspamだけは来るのです)、 06:16くらいに、dnfの自動更新が動いていたので、そのせいっぽいですね。 自動更新はちょくちょく起きるので、今回だけこうなった理由は結局わかりませんが。
[この投稿を含むスレッドを表示] [この投稿を削除]
[2370] 掲示板が停止していました
投稿者:(ぱ)こと管理人
2024/05/11 08:36:25

昨晩から今朝にかけてこの掲示板が停止していたようです。 先ほど確認したらTomcatが動いていなかったので、起動したら 動くようになりました。 原因自体は調査中です。ご迷惑をおかけしました。
[この投稿を含むスレッドを表示] [この投稿を削除]
[2369] Re:ポインタ完全制覇の質問
投稿者:(ぱ)こと管理人
2024/05/10 22:59:16

>書籍ポインタ完全制覇でC言語を勉強中の者です。 はじめまして。読んでいただきありがとうございます。 >該当の書籍のP-130-131のサンプルプログラムList2-9について質問なのですが、 >使用済みの数字かどうかを判定するフラグused_flagの初期値を最初にゼロにしている >訳ではないのに、33行目のループの最初で0と判定してif文の中身を実行できるのは >どうしてでしょうか? このused_flagはグローバル変数であり、グローバル変数は静的記憶域期間を持ちます。 静的記憶域期間を持つ変数については、プログラムの起動時に初期化されることが 規格で規定されています。 JIS X 3010:2003「6.7.8 初期化」より。 | 静的記憶域期間をもつオブジェクトを明示的に初期化しない場合,次の規定に従う。 | a) そのオブジェクトの型がポインタ型の場合,空ポインタに初期化する。 | b) そのオブジェクトの型が算術型の場合,(正又は符号無しの)0 に初期化する。 | c) そのオブジェクトが集成体の場合,各メンバにa)~d)の規定を(再帰的に)適用し |  初期化する。 | d) そのオブジェクトが共用体の場合,最初の名前付きメンバにa)~d)の規定を | (再帰的に)適用し初期化する。 used_flagはintの配列なので、c)とb)の規則の合わせ技で0に初期化されます。 >自分なりに調べると、特にプログラマが初期値を指定しない場合の初期値は >不定となるそうなのですが、それが何か関係しているのでしょうか。 自動記憶域期間を持つ変数(ローカル変数)や、malloc()でヒープに確保した領域は、 明示的に初期化しない限り値は不定になります。 2章で説明している通り、ローカル変数の領域は関数の呼び出しのたびに確保されますし、 ヒープの領域はmalloc()のたびに確保されます。こういう領域を毎回ゼロとかでクリア するのは性能的に問題が出るかもしれませんが、静的記憶域期間をもつ変数はプログラムの 起動時に1回だけ初期化すればよいので性能上も問題ない、という判断なのかと思います。
[この投稿を含むスレッドを表示] [この投稿を削除]
[2368] ポインタ完全制覇の質問
投稿者:sasaki
2024/05/10 14:56:41

書籍ポインタ完全制覇でC言語を勉強中の者です。 該当の書籍のP-130-131のサンプルプログラムList2-9について質問なのですが、 使用済みの数字かどうかを判定するフラグused_flagの初期値を最初にゼロにしている訳ではないのに、33行目のループの最初で0と判定してif文の中身を実行できるのはどうしてでしょうか? 自分なりに調べると、特にプログラマが初期値を指定しない場合の初期値は不定となるそうなのですが、それが何か関係しているのでしょうか。 お手数ですが、ご教示頂きたくお願いいたします。
[この投稿を含むスレッドを表示] [この投稿を削除]
[2367] Re:ポインタ完全制覇 LIST 4-4 realloc.c
投稿者:トト
2024/03/11 21:13:50

返信が遅くなりまして、すみません。 昨夜,投稿に気づきました。 指摘して頂きありがとうございます。 違った解釈をしていました。 【 指摘前(c言語 サイト参照) 】 [Ctrl]+[z]... Mac ↓ “ [1] + Stopped ./a.out  ” ... 停止(Macターミナル表示) [fg] 又は [fg 1] と入力。        ... 再開 ↓ (例)(Macターミナル表示) variable_array[0]..12 variable_array[1]..2 variable_array[2]..1              :              : をしていまし。 >ちょっと不安を感じるのですが、このプログラムで「一時停止、再開動作」を >しているのは、fgets()のところで入力待ちの時に一時停止、入力してENTERを >押したら再開、というところです。しかしこれはgetchar()だろうが >scanf()だろうがfgets()だろうがキーボードで入力待ちになったら発生することです。 > >while (fgets(buf, 256, stdin) != NULL) { > … > >というループが終了するのは、見ての通りfgets()がNULLを返した時です。 >fgets()がNULLを返すのは、ファイルの終わりが来た時で、標準入力 >(デフォルトではキーボード)で、ファイルの終わり(EOF: End Of File)を >示す手段が、WindowsではCtrl+Z、ENTERだということです。 >Macは私は持ってませんが、ターミナルでEOFを示す方法は、(UNIXと同じく) >Ctrl+Dだと思います。 【 指摘後 】 [ Ctrl ] + [ D ]でした。 EOFを入力する手段とは知りませんでした。 (もしかした今まで学習サイトで目にしているのに、忘れているのかもしれません) 質問の仕方が初めから「どうしたらwhile(...(stdin)...!=NULL)ナルを返せますか?(Mac使用)」と、 私が聞ければよかったです。お手間取らせました。 不安を感じて指摘して頂きありがとうございました。
[この投稿を含むスレッドを表示] [この投稿を削除]
[2366] Re:ポインタ完全制覇 LIST 4-4 realloc.c
投稿者:(ぱ)こと管理人
2024/03/03 23:56:35

>>①で、入力を終えるには、Windowsなら、数値をいくつか入力後、 >>Ctrl+Z を押してからENTERを押してください。 > >このような一時停止、再開操作をするプログラムを初めて知りました。 >while(...,stdin)で、たしかに終わりどころは・・・・と思ってもいました。 ちょっと不安を感じるのですが、このプログラムで「一時停止、再開動作」を しているのは、fgets()のところで入力待ちの時に一時停止、入力してENTERを 押したら再開、というところです。しかしこれはgetchar()だろうが scanf()だろうがfgets()だろうがキーボードで入力待ちになったら発生することです。 while (fgets(buf, 256, stdin) != NULL) { … というループが終了するのは、見ての通りfgets()がNULLを返した時です。 fgets()がNULLを返すのは、ファイルの終わりが来た時で、標準入力 (デフォルトではキーボード)で、ファイルの終わり(EOF: End Of File)を 示す手段が、WindowsではCtrl+Z、ENTERだということです。 Macは私は持ってませんが、ターミナルでEOFを示す方法は、(UNIXと同じく) Ctrl+Dだと思います。
[この投稿を含むスレッドを表示] [この投稿を削除]
[2365] Re:ポインタ完全制覇 LIST 4-4 realloc.c
投稿者:トト
2024/03/03 00:13:44

今回も教えて頂きありがとうございます。 >①で、入力を終えるには、Windowsなら、数値をいくつか入力後、 >Ctrl+Z を押してからENTERを押してください。 このような一時停止、再開操作をするプログラムを初めて知りました。 while(...,stdin)で、たしかに終わりどころは・・・・と思ってもいました。 下段、for文内でインクリメントされたsizeを使っていることからも納得です。 「入力するたび・・・イメージしています。」な訳ないですよね。 学習ではMac gccを利用してます。 おかげで操作法の副産物も得る事ができました。 free()の詳細もありがとうございました。 重ねて御礼申し上げます。 「25年くらい前・・・」恐れ入ります。
[この投稿を含むスレッドを表示] [この投稿を削除]
[2364] Re:ポインタ完全制覇 LIST 4-4 realloc.c
投稿者:(ぱ)こと管理人
2024/03/02 02:08:03

> ①第4章、List 4-4 realloc.c(p238)でint型の値(数値)を入力しても、 >17行目〜19行目のprintf("variable_array[%d]..%d¥n", i, variable_array[i]);が >表示されません。 このプログラムは、数値を入力するwhileループが11~15行目にあり、 そのwhileループが終わった後、17~19行目に、配列の内容を表示する forループがあります。whileループが終わってからforループが始まるので、 値(数値)を入力するたびに何かが表示されるわけではありません。 このプログラムは、 ①ユーザが数値をいくつか入力する。いくつ入力するかはわからない。 ②ユーザが数値の入力を終えたら、入力された数値を全部表示する。 というものです。①が終わってから②を実行します。 ①でユーザがいくつ数値を入力するかわからないから、realloc()で 配列を伸ばしていく、というのが趣旨です。 ①で、入力を終えるには、Windowsなら、数値をいくつか入力後、 Ctrl+Z を押してからENTERを押してください。 > ②List4-3,4-4でfree(variable_array);と私は記述を加えました。 >本章でfree()を使われていないのはどのような理由からでしょうか。 >入門者向け学習サイトでは「必ずfree()」,「プログラム終了時に消える」、 >様々な事が書かれています。 それについては25年くらい前にここに書きました。 https://kmaebashi.com/programmer/c_yota/malloc.html WindowsでもLinuxでも、まともなOSならプログラム終了時にはfree()しなくても 解放してくれるので、たとえばライブラリとして再利用することなど考えられない 書籍のサンプルコードでは、free()は不要だと私は考えています。 当時のfj.comp.lang.cのやりとりも検索したら残っていました。 https://groups.google.com/g/fj.comp.lang.c/c/G4HRnHTdImg?pli=1 まあ、これぐらいもめる話ではあるので、深入りしないほうが無難かと思います……
[この投稿を含むスレッドを表示] [この投稿を削除]
[2363] ポインタ完全制覇 LIST 4-4 realloc.c
投稿者:トト
2024/02/29 23:14:47

 前回、!isalnumの件で伺った者です。 教えて頂き、ありがとうございました。  今回も「ポインタ完全制覇」内の本章の主旨からずれてますが、 自力解決できない箇所があり、申し訳ありませんが二つ質問さてください。  ①第4章、List 4-4 realloc.c(p238)でint型の値(数値)を入力しても、 17行目〜19行目のprintf("variable_array[%d]..%d¥n", i, variable_array[i]);が 表示されません。 試しに11行目、while分のブロック内で15行目に printf(" VARIABLE_ARRAY[%d] = %d\n", size-1, variable_array[size-1]);と記述を加えたら、 int型の値を入力する度に上記printf文は表示されます。  List4-4の正しい表示結果は、値(数値)を入力するたびに18行目のprintf文が表示される イメージをしています。 なぜ18行目のprintf文が表示されないのか教えてください。 又、私の理解不足がありましたらご指摘ください。 ②List4-3,4-4でfree(variable_array);と私は記述を加えました。 本章でfree()を使われていないのはどのような理由からでしょうか。 入門者向け学習サイトでは「必ずfree()」,「プログラム終了時に消える」、様々な事が書かれています。 教えて頂けたら幸いです。 今回もこのようなレベルですみません。
[この投稿を含むスレッドを表示] [この投稿を削除]
[2362] Re:unix 用ソースコードのダウンロード
投稿者:ken
2024/02/23 04:19:07

早速のご対応、ありがとうございました。 無事、ダウンロードできました。 >ken様 >ご指摘ありがとうございます。 >>本書購入後にunix 用のソースコード(https://kmaebashi.com/seiha2/src_unix.tgz)を >>ダウンロードしようとしているのですが、 >>Not found が返されます。 > >経緯はわかりませんが、取り急ぎ復元しました。 >ただ、現在復元した版だと、p.258 Lis4-13 read_line.cの、以下の問題が >直っていないようです。 >https://kmaebashi.com/seiha2/seigo.html#p258 > >申し訳ありませんが修正のうえご利用ください。 >Windows版のsrc_win.zipは直っているのかと思ったら、そちらもそのままでした。 >連休中に対応します。 > >ご迷惑をおかけしまして申し訳ありません。
[この投稿を含むスレッドを表示] [この投稿を削除]
[2361] Re:unix 用ソースコードのダウンロード
投稿者:(ぱ)こと管理人
2024/02/23 01:30:01

ken様 ご指摘ありがとうございます。 >本書購入後にunix 用のソースコード(https://kmaebashi.com/seiha2/src_unix.tgz)を >ダウンロードしようとしているのですが、 >Not found が返されます。 経緯はわかりませんが、取り急ぎ復元しました。 ただ、現在復元した版だと、p.258 Lis4-13 read_line.cの、以下の問題が 直っていないようです。 https://kmaebashi.com/seiha2/seigo.html#p258 申し訳ありませんが修正のうえご利用ください。 Windows版のsrc_win.zipは直っているのかと思ったら、そちらもそのままでした。 連休中に対応します。 ご迷惑をおかけしまして申し訳ありません。
[この投稿を含むスレッドを表示] [この投稿を削除]
[2360] unix 用ソースコードのダウンロード
投稿者:ken
2024/02/22 06:28:33

お世話になります。 本書購入後にunix 用のソースコード(https://kmaebashi.com/seiha2/src_unix.tgz)をダウンロードしようとしているのですが、 Not found が返されます。 ご確認いただけますでしょうか。 よろしくお願いします。
[この投稿を含むスレッドを表示] [この投稿を削除]
[2359] Re:無題
投稿者:(ぱ)こと管理人
2024/02/17 16:17:18

>行末に「^」が入っているのは、私がこれをバッチファイルにしたからで、 >バッチファイルではコマンドの途中で開業を入れる時には「^」を書くからです。 以下のページですね。ご指摘ありがとうございます。修正いたしました。 https://kmaebashi.com/programmer/accesscounter/index.html
[この投稿を含むスレッドを表示] [この投稿を削除]
[2358] 無題
投稿者:rike1019
2024/02/17 02:36:29

行末に「^」が入っているのは、私がこれをバッチファイルにしたからで、バッチファイルではコマンドの途中で開業を入れる時には「^」を書くからです。 誤 開業 正 改行
[この投稿を含むスレッドを表示] [この投稿を削除]
[2357] Re:インターネット上を流れるデータ構造の表現について
投稿者:mhash
2024/01/21 10:44:43

早速のご回答、ありがとうございます。 >>上記例にあげたUDPパケット構造の0~63目までのヘッダ構造の図は、一行32ビット幅で >>書かれているのですが、実際のサーバーやクライアントのメモリは8ビット1バイトの >>配列構造な訳なので、どう解釈したら良いのかネット検索で調べても良く分からなかった >>です。(インターネットではビッグエンディアンなので) > >「インターネットではビッグエンディアンなので」と書いておられるとおり、 >インターネット(TCP/IP)でポート番号やIPアドレスをやりとりする際は、 >ビッグエンディアンで表現するよう定められています。 >これをネットワークバイトオーダーと呼びます。 > >https://atmarkit.itmedia.co.jp/icd/root/72/116970472.html > >>私の仮の理解ですが、以下のようになると思って良いでしょうか? > >なので、これで合っています。 ありがとうございます。安心しました。 >ネットワークバイトオーダーという規定(デファクトですが)をご存じなくて >「どうやってバイトオーダーが違うかもしれないマシン間でデータをやり取り >しているのだろう?」という意図の質問なのかと思いましたが、 >「インターネットではビッグエンディアンなので」とあるのでそれはご存じのようで、 >これで回答になっておりますでしょうか? はい。TCP/IPではバイトオーダーがビッグエンディアンであることは理解していましたが TCPやUDPやらを検索して出てくる図の読み方が分からなかったので、そこの質問でした。
[この投稿を含むスレッドを表示] [この投稿を削除]
[2356] Re:インターネット上を流れるデータ構造の表現について
投稿者:(ぱ)こと管理人
2024/01/21 09:17:34

>上記例にあげたUDPパケット構造の0~63目までのヘッダ構造の図は、一行32ビット幅で >書かれているのですが、実際のサーバーやクライアントのメモリは8ビット1バイトの >配列構造な訳なので、どう解釈したら良いのかネット検索で調べても良く分からなかった >です。(インターネットではビッグエンディアンなので) 「インターネットではビッグエンディアンなので」と書いておられるとおり、 インターネット(TCP/IP)でポート番号やIPアドレスをやりとりする際は、 ビッグエンディアンで表現するよう定められています。 これをネットワークバイトオーダーと呼びます。 https://atmarkit.itmedia.co.jp/icd/root/72/116970472.html >私の仮の理解ですが、以下のようになると思って良いでしょうか? なので、これで合っています。 ネットワークバイトオーダーという規定(デファクトですが)をご存じなくて 「どうやってバイトオーダーが違うかもしれないマシン間でデータをやり取り しているのだろう?」という意図の質問なのかと思いましたが、 「インターネットではビッグエンディアンなので」とあるのでそれはご存じのようで、 これで回答になっておりますでしょうか?
[この投稿を含むスレッドを表示] [この投稿を削除]
[2355] インターネット上を流れるデータ構造の表現について
投稿者:mhash
2024/01/21 05:14:31

題記の件、TCP/IPモデルに則ったネットワーク(インターネット)上で、特定のデータ構造(IPヘッダやTCPヘッダやUDPヘッダ、あるいは個別のファイルフォーマット等)がどのように各コンピュータの内部で表現されるのかお聞きしたいです。 具体例として、仮にインターネット上の各ホストが全て1バイト=8ビット(1オクテット)のマシンだったとして、たとえばUDPヘッダ(Wikipediaリンク: https://ja.m.wikipedia.org/wiki/User_Datagram_Protocolの「仕組み」-「パケット構造」の章を参照)ってどうメモリ上にマッピングされるのか?ということが分からないです。 上記例にあげたUDPパケット構造の0~63目までのヘッダ構造の図は、一行32ビット幅で書かれているのですが、実際のサーバーやクライアントのメモリは8ビット1バイトの配列構造な訳なので、どう解釈したら良いのかネット検索で調べても良く分からなかったです。(インターネットではビッグエンディアンなので) 私の仮の理解ですが、以下のようになると思って良いでしょうか? 0バイト目:「宛先ポート番号」の上位8ビット分を格納 1バイト目:「宛先ポート番号」の下位8ビット分を格納 2バイト目:「送信元ポート番号」の上位8ビット分を格納 3バイト目:「送信元ポート番号」の上位8ビット分を格納 4バイト目:「チェックサム」の上位8ビットを格納 5バイト目:「チェックサム」の下位8ビットを格納 6バイト目:「データ長」の上位8ビットを格納 7バイト目:「データ長」の下位8ビットを格納 初歩的な質問で恐縮ですが、よろしくお願いいたします。
[この投稿を含むスレッドを表示] [この投稿を削除]
[2354] Re:! isalnum(ch);
投稿者:トト
2024/01/09 12:02:14

こんな早くに返信して頂きありがとうございます。 11行目の波括弧を付け加えて頂き”読み飛ばしている感じ”がわかりました。 気持ちが晴れました。 ツッコミもありがとうございます。 周りにプログラミングする人がいなく、そのような会話をすることもない為、 自分だけ分かっていればと頭の中では『インスウ、インスウ・・・』、つい出てしまいました。 ご指摘ありがとうございます。
[この投稿を含むスレッドを表示] [この投稿を削除]
[2353] Re:! isalnum(ch);
投稿者:(ぱ)こと管理人
2024/01/09 00:59:36

>はじめまして。 はじめまして。質問ありがとうございます。 >List 1-10 get_word.c内の >上記の!isalnum(ch)が(真)の為、20行目のbuf[len]=ch;には >入力(stdin)時に文字以外の記号などがあれば格納されしまうと思うのです。 英数字以外の記号などが来た場合、isalnum(ch)はfalseですから、 それに!を付けた「!isalnum(ch)」は真になります。 そして、「!isalnum(ch)」が真(かつファイルが終わらない)間、 11~12行目のループがぐるぐる回りますから、英数字以外の文字を読み飛ばすことになって、 17行目では「ここで,chには,単語の最初の文字が格納されている」ことになります。 ええと、11行目のwhile文について、波括弧を省略したのが誤解を招いたでしょうか。 10: /* 空白文字の読み飛ばし */ 11: while ((ch = getc(fp)) != EOF && !isalnum(ch)) { 12: ; 13: } これなら、読み飛ばしている感じがつかめるでしょうか。 ところで、細かいツッコミですみませんが、 >1-4-6「関数の因数として配列を渡す(つもり)」 正しくは「因数」ではなくて「引数」ですが、誤変換さておき、 「引数」の読みは「ひきすう」です。念のため。
[この投稿を含むスレッドを表示] [この投稿を削除]
[2352] ! isalnum(ch);
投稿者:トト
2024/01/08 21:24:11

はじめまして。 c言語を学んでいる者です。 入門学習サイト内で『c言語ポインタ完全制覇』を紹介されていたので、併せて学んでいます。 5章「連結リスト版」では苦戦しましたが、新たなポインタの利用法を知ることができました。  只今、理解を深めるため再度、頭から読み進めています。 理解できてない箇所がいくつかあり自力で解決できず投稿しました。 << 質問 >> 1-4-6「関数の因数として配列を渡す(つもり)」 List 1-10 get_word.c内の 11行目 while((ch=getc(fp))!= && !isalnum(ch));で /*空白文字の読み飛ばし*/が出来る仕組みが理解できずに苦戦しています。 大変恐縮ですが解釈の仕方を教えて頂けたら幸いです。 上記の!isalnum(ch)が(真)の為、20行目のbuf[len]=ch;には 入力(stdin)時に文字以外の記号などがあれば格納されしまうと思うのです。 しかし、buf[len]=ch;には単語の最初の文字が格納され、 結果、プログラムの意図どおり単語のみが表示されます。 このようなレベルですみません。
[この投稿を含むスレッドを表示] [この投稿を削除]