トップページ⇒tech
1001コメント246KB

C言語なら、俺に聞け! <18>

■ このスレッドは過去ログ倉庫に格納されています
0001きょうはいいテンキーです。日下部陽一NGNG
漏れは38才、21年間プログラムを一生懸命作ってきた。
いろいろな言語を極めたが、一番手になじむのはCだった。
Cのことならぜんてわかるから、疑問な点があったら漏れに聞け。

だが、いちいちFAQに載った質問に応えるほど暇じゃない。
課題丸投げなら別スレにいけ。

・comp.lang.c Frequently Asked Questions
http://www.eskimo.com/~scs/C-faq/top.html

・C FAQ 日本語訳
http://www.catnet.ne.jp/kouno/c_faq/c_faq.html

Cプログラマならこれを買っとけ。
・プログラミング言語C(K&Rと呼べば通だ)
http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/yfcbookshelf-22/250-3950205-1475419

K&Rで挫折するような救いがたいやつはこれでも読め
・作ってわかるCプログラミング(アヒル本と呼べば通だ)
http://dennou.gihyo.co.jp/books/void_c/
http://www.amazon.co.jp/exec/obidos/ASIN/477411328X/249-4698746-2014711

推薦図書/必読書のためのスレッド PART3
http://pc.2ch.net/test/read.cgi/tech/1016722820/

・前スレ C言語なら、俺に聞け! <17>
http://pc.2ch.net/test/read.cgi/tech/1019372139/l50
0232デフォルトの名無しさんNGNG
>>230
#define NULL ((void*) 0)
の場合は「定数値のdefine」ではないね
0233デフォルトの名無しさんNGNG
>>232
型が違うだけで定数値でしょ
0234デフォルトの名無しさんNGNG
問題は、規格や動作じゃなくて、
exit(NULL);
とするのが、常識的なのかってことじゃないの?
0235デフォルトの名無しさんNGNG
>>234
俺は異常だと思う。
ところでintを引数にとるはずのexitでexit(NULL)の記述が出来ることが問題になる処理系では、
NULLは
#define NULL ((void*)0)
じゃなくて
#define NULL 0
とされているとみてかまわないのでは?
0236180NGNG
>>231
>>195-196 は、別に降参せんでもいいと思うが。

>>230
マッ、そう言うこっちゃ。大体、C++ にした時に Null とか言う定数を定義しち
まえば良かったのに、#define NULL 0 なんかでごまかそうとするからこんなこ
とになるんだよ。この点については Pascal がうらやましいよ。

>>207
ネタの割には、しつこいんだが。
0237デフォルトの名無しさんNGNG
null pointerが0じゃなくて特別な予約語(nullとかnilとか)
で表されていれば話が簡単だったのにね。
0238デフォルトの名無しさんNGNG
というわけでNULLは0という結論でよろしいか?
0239自作自演NGNG
>>226
eixtってなんやー
0240デフォルトの名無しさんNGNG
つまり、リッチータンのいけずぅ。
0241デフォルトの名無しさんNGNG
   _____
 /::\_____\
 |: ̄\∩`_´) \ 終わった?
 |:   :| ̄ ̄U ̄:|
0242デフォルトの名無しさんNGNG
さらば180。
0243デフォルトの名無しさんNGNG
0はいつでもNULLとみなせるが、
NULLを0とみなせるとは限らない。
0244180NGNG
>>234
議論するまでもないと思うが...。

>>238
C++ なら、それで OK。C なら、やっぱ ((void *)0) でしょ。

>>239
細けぇとこに突っ込むなよ。小姑みたいだぞ。
0245デフォルトの名無しさんNGNG
>>244
exit(NULL);だよね?
この状態ではNULLはintに暗黙に変換できなきゃ値の問題以前にコンパイルすら出来ないはず。
0246デフォルトの名無しさんNGNG
>>243
0がヌルポインタとして見なされるのは
ポインタが記述されるべきところに記述された場合のみ。
0247デフォルトの名無しさんNGNG
 __________________ 続いてたか
 |: ̄\     \★パタン
 |:   :| ̄ ̄ ̄ ̄:|
0248デフォルトの名無しさんNGNG
>>247
おいでよ、一緒に遊ぼうよ。
0249デフォルトの名無しさんNGNG
 __________________ 
 |: ̄\     \
 |:   :| ̄ ̄ ̄ ̄:| < 全然わからんもん
0250デフォルトの名無しさんNGNG
>>249
とりあえず適当なこと言えば親切な人が突っ込んでくれるから。
さ、出ておいで〜
0251デフォルトの名無しさんNGNG
      ,, ,=、  ,, , =、
     ff | }!、,、〃 / ″いやあぁぁぁぁぁ!!
      ,リ/ .ノ*´jコ`)'〃
    {{ { ′   v' 《
     ヾ.\.   \ヾ
     _,,二、》   ;  \. 三,_
  (( ゙ー=、`″〃 \. \-‐' ,))
        ゙ー=″     ゙' 一' 
0252デフォルトの名無しさんNGNG
型がどうであろうと全てのbitが0なら0になるんじゃないのか?
キャストで大きさは変わっても、bitの並びが変わることはないだろ?
0253デフォルトの名無しさんNGNG
ル━━(゚∀゚)━━プ! か?
0254デフォルトの名無しさんNGNG
>>252
((void*)0)のすべてのbitが0とは限らないよ。
0255180NGNG
>>245
それ以前に、exit(NULL) って書くか普通 ? 多くのコンパイラで、警告出しなが
らコンパイルはできるけど、コンパイルできりゃ良いって話じゃねーだろ。
0256デフォルトの名無しさんNGNG
>>254
なぜ!?
((void *)0)は0番地を指す値だろ?
0257デフォルトの名無しさんNGNG
>>255
NULLとvoidを混同していただけだろ・・・
0258デフォルトの名無しさんNGNG
NULLはポインタ型で使え
整数型んとこでNULLはいやん?
0259デフォルトの名無しさんNGNG
ループキタ━━━━━━(゚∀゚)━━━━━━ !!
0260デフォルトの名無しさんNGNG
>>256
コンパイラは0をポインタにキャストするとき適切な内部形式に変換する。
多くの実装では0なだけで、そうでないのも昔はあったそうだ。
0261デフォルトの名無しさんNGNG
>>256
だからそこが違うんだって。
たいていbit patternは0になるだろうけど、
そんな保証はないって話。
0262デフォルトの名無しさんNGNG
C言語を独学で習得しようと思うのですが
みなさんはどういう風に勉強しましたか?
私はC++Builderの使い方があまりよくわかりません
あれってやっぱり慣れなんでしょか?
それとも本を読んだりして勉強したのですか?
0263デフォルトの名無しさんNGNG
>>260
じゃあ条件式でNULLを偽とみるのは間違い?
0264デフォルトの名無しさんNGNG
とりあえずexit(NULL)はキチガイってことでよろしいか?
NULLが0とかどうかは実装依存なので無意味かと。
0265デフォルトの名無しさんNGNG
>>257
NULLとvoidをどう混同すればexit(NULL)と書けるのか
激しく問い詰めたい。

void main(){}だからreturn 〜;は使えない
↓
voidの値でexit()すれば(・∀・)イイ!

って論理か??
0266デフォルトの名無しさんNGNG
>>263
NULLは偽だよ。
0267デフォルトの名無しさんNGNG
以前ここでナルポインタは0であると保証されているわけではないと言ったら思いっきり叩かれたんだけど・・・・
C FAQ見ろとかいわれて・・・
0268デフォルトの名無しさんNGNG
NULLが偽になるのは規格で保証されている
0269デフォルトの名無しさんNGNG
>>267
ナルポインタとNULLを混同していたからでは?
0270257NGNG
>>265
きっとそうだろ。
・・・って言ったのは俺じゃないぞ!
0271デフォルトの名無しさんNGNG
例えばnull pointerがJavaみたいにnullという予約語で
表されるとしよう。

そのbit pattern(プログラマにとってはどうでも良い)が0
だとか、0番地を指しているとかいう保証は何もないよね。
実際のCでも同じ。nilのかわりに0と書くけど。
0272265NGNG
>>270書き方悪かったスマソ
0273デフォルトの名無しさんNGNG
そもそもナルポインタを作るために0を使うC言語の構文はどうかしてる。
C++の純粋仮想関数の = 0 もどうかしてる。
予約語作れよ。
0274デフォルトの名無しさんNGNG
>>264>>268
0じゃなくても偽になるの?
0275デフォルトの名無しさんNGNG
>>274
仕様上はなりません。
0276デフォルトの名無しさんNGNG
>>274
そうだよ。
if ( exp )
は
if ( exp!=0 )
と同義。
0277274NGNG
もうわけわからん・・・
0278デフォルトの名無しさんNGNG
NULLは偽 -> 偽は0 -> よってNULLは0

これで正しいと思っていたんだが・・・
0279デフォルトの名無しさんNGNG
>>262
すまんね。今このスレいそがしいので。
とりあえずオレは、本読んで、わかんないとこは知人に聞きながら、
いろいろコンパイルして試したよ。

C++Builderは、慣れるしかないかも。
0280デフォルトの名無しさんNGNG
exp!=0のとき
expがポインタならば0もポインタに変換される。
ポインタ同士の比較になるわけ。
expのビットパターンがぜんぶ0かどうかは問題じゃない。
0281デフォルトの名無しさんNGNG
>>274
FAQ読みなはれ
0282デフォルトの名無しさんNGNG
>>278
ちがうって、
NULL==0 だから NULLは偽
だよ。
0283デフォルトの名無しさんNGNG
でもさぁ、この話笑えるよな。
こんなにややこしくするなら定数0でbitパターンも全部0でいいじゃんって思うよ、ほんとに。
実際それで実害のある処理系はほとんど無いわけだし
0284デフォルトの名無しさんNGNG
ループするけど、nilという予約語を作ればベストだったのではないかと
0285180NGNG
あ〜〜〜っ、もうバカばっかし。>>280 が正解だよ。>>275 も堂々とウソ書くな
よ。
0286デフォルトの名無しさんNGNG
馬鹿はほっといてnilについて語ろう。
俺はnullのほうが好み。
でもキーの配置や文字数の関係でnilのほうが打ちやすいことがたった今判明。

とりあえず全角使いまくりのCの定数は片手で打てないので大嫌い。
0287デフォルトの名無しさんNGNG
0がNULLポインタを表現するなんて糞仕様入れた標準化委員会が間違い
0288デフォルトの名無しさんNGNG
>>283
ちゃんとした規格を作った時に、
すでに0で無いコンパイラがあったんでないの?
0289デフォルトの名無しさんNGNG
>>285

>>275が言っているのは
#define NULL 1
とかいった実装には、仕様上はなりません。規格では
#define NULL 0 /* または ((void*)0) */
なので必ず偽になる、という意味だと思うがどうか?
0290286NGNG
悪い
×全角
○大文字
0291デフォルトの名無しさんNGNG
ポインタの文脈では 0 はnull pointer (NULL ではなくて) として扱う。
単純明快だと思うけど。

俺は NULL のほうが要らないと思う。初心者向けに媚びたから
よけいに混乱した。
0292デフォルトの名無しさんNGNG
>>283
TRONチップ上のCはnull pointerの表現が0でないと聞いたような気がする。

あとは、0番地のメモリとレジスタ0が同じになってる機械(昔はイパイあっ
た)とかだとnull pointerの表現を0にするのは嫌だろうな。
0293デフォルトの名無しさんNGNG
>>291
ナルポインタの内部表現も全部0だったら、俺もそれがいいと思う。
そうでない実装があったとき激しく混乱すると思う。
(今でも十分NULLのせいで混乱してるけど)
0294ふかNGNG
基本的な質問で申し訳ないが・・・
関数のプロトタイプが必須のケースって?
漏れが思いつくのは
「2つ以上のアーカイブが相互に関数参照するとき」
以外思いつかないんだけど,あとある?
0295デフォルトの名無しさんNGNG
>>274
補足

構文的に、ifは条件式を受け取ることになってる。
if (条件式)
ね。

ここでifに条件式以外の式を渡したとき
if (式)
は
if ((式)!=0)という風に暗黙的に補われるんだ。こういう決まりなの。

んでもってifにポインタ値や、ポインタ値を返す式を渡すと、
if (ポインタ値)
は
if ((ポインタ値)!=0)
になるんだけど、
ポインタ値と0を比較するときには0はヌルポインタに置き換えられるという
ルールも適用されて、つまり、ヌルの時だけ偽、ヌル以外の時真になるわけ。

K&Rとかの文法の書いてあるページを、よーく見てみよう。
そのうちわかるようになるよ。
0296デフォルトの名無しさんNGNG
チェ━( ´∀`)・ω・) ゚Д゚)・∀・) ̄ー ̄)´_ゝ`)━ンジ!!!

話題がNULLの在り方にシフト!
0297デフォルトの名無しさんNGNG
>>294
mainよりも後ろに関数を書くときとか。
というか書け!
0298デフォルトの名無しさんNGNG
>>289
それおかしいよ。

int *p = NULL;

if (p)
が偽になる理由の説明になってない。

だいいち
#define NULL 1
でも別に規格違反ではない。
0299デフォルトの名無しさんNGNG
ハードウェアで bitパターンが all 0 でない物がNULLポインタである可能性があるんだから、
0 を NULL として扱う(内部でNULLに変換)のはあまりに強引だというだけ。
0じゃない機械があるなら変換しないでその値をNULLとして扱い、
定数NULLの値は実装依存って言う方がスッキリしてると思うんだtが
0300デフォルトの名無しさんNGNG
>>294
プロトタイプが必須なんてケースないんじゃない??
0301デフォルトの名無しさんNGNG
>>294
プロトタイプ書かないとsinやcosなんかがまともに動かない
処理系は山ほどあるだろ。

printfさえ動かない処理系もあるよ。

つか書け!
0302デフォルトの名無しさんNGNG
ところで、機械自体にナルポインタという概念があるの?
0303デフォルトの名無しさんNGNG
>>299
同意。
NULLの中身は不明ってしたほうがはるかにわかりやすい。
0304デフォルトの名無しさんNGNG
>>294
いろいろある。

void bar()
{
 foo(4);
}

void foo(double a)
{
}
なとき、プロトタイプ宣言がないと引数がうまく渡せないでしょ。

同じくプロトタイプ宣言がないと、関数の戻り値が暗黙的にintを返すことにされちゃう。
困るでしょ。

ANSIスタイルで書いてて、呼び出し前に常に関数宣言を書いておけるなら、別にいらないけどね。

0305ふかNGNG
>>297
レスさんくす。
書きたいのはヤマヤマだが,
漏れだけでシステムつくってないし〜。
あと引数の仕変が起きた時,
ヘッダファイルのプロトタイプまで直すのがカタルイ〜。
漏れは違うけど,プロトタイプに変数名まで書くやつもいるしな〜。
0306デフォルトの名無しさんNGNG
>>298
標準ライブラリ(ヘッダ)とコンパイラはセットで考えようよ。
元がNULL==0の処理系でNULL=1とした場合に、
int*p=NULL;
if(p)
が偽にならないのはしょうがないだろ
0307298NGNG
#define NULL 1
はさすがにまずいな。すまん。

#define NULL ((void *)処理系依存の0でないビットパターン)
は別に規格違反ではない、に訂正。

あ、
#define NULL ((void *)1)
は規格違反じゃないね。他のどんなポインタとも等しくなければ。
0308デフォルトの名無しさんNGNG
>>305
労力をケチるな!

> プロトタイプに変数名まで書くやつもいるしな〜。
多くのコンパイラの標準ライブラリは書いていないか?
0309デフォルトの名無しさんNGNG
staticなポインタ変数を初期化せずに使うとき0がヌルポインタだったら便利だな。
それ以外は不自然だな、という考えの基にああなったとおもわれ。

memsetでポインタをクリアするとどうなるか、ってのもあるな。
0310デフォルトの名無しさんNGNG
>>307
内部でNULLと比較を行うライブラリはすべて動作未定義になるね。
0311デフォルトの名無しさんNGNG
>>305
プロトタイプには変数名も書いたほうがいいと思う派だな、漏れ。
引数の意味がちょっとおぼろげってとき、宣言みれば確認できるし。
IDEによっては引数ヒントでポップアップしてくれるし。
0312デフォルトの名無しさんNGNG
質問です。

extern int usbmon_quit (const char*);

typedef struct {
 int (*func) (const char*);
} CmdList;

static const CmdList cmd_list[] = {
 { usbmon_quit },
};

static void*
search_command (char* buf)
{
 return cmd_list[0].func;
}

もとのソースからかなり省略していますが、ここで
search_command()の返り値の型は本来どのように記述すればよいのでしょうか?

関数へのポインタは一応分かったつもりだったんですが、
うまくいかなくて上のソースではvoid*でごまかしています。
0313デフォルトの名無しさんNGNG
>>305
かったるい??
それは引数名をわざわざ消すからだよ。
関数の宣言コピペするだけでOK。
0314デフォルトの名無しさんNGNG
たとえばstrtodとかかな。
0315デフォルトの名無しさんNGNG
>>306
それでも偽になるよ
0316デフォルトの名無しさんNGNG
>>299
ビットパターン 0 が null pointer だって教え方がまず間違ってるよ。
0317デフォルトの名無しさんNGNG
>>315
なるわけ無いじゃん。
元がNULL==0だったのに、勝手にユーザーがNULL=1にしても
確実に偽になると?
0318デフォルトの名無しさんNGNG
>>312
struct CmdList *かな?
0319デフォルトの名無しさんNGNG
>>312
typedefしたほうがいいよ。
0320デフォルトの名無しさんNGNG
>>316
>>299はそんなこと言ってないが?
0321298NGNG
>>306
いや、だからそれは違うって。

int *p=NULL;
if (p)
は偽になるが、その理由は「NULLが0だから」じゃないでしょってこと。

処理系の標準へッダでNULLを((void *)1)と定義していたとしても
int *p=NULL;
if (p)
は偽になる。
0322318NGNG
おっと、返しているのはメンバーか。
0323デフォルトの名無しさんNGNG
int (const char*);をtypedefしてしまう、とかね。
0324デフォルトの名無しさんNGNG
>>321
それなら同意だが。
ユーザーが勝手に定義し直しても・・・ってことだとオモタヨ
0325デフォルトの名無しさんNGNG
むかしC++にnilって予約語無かったっけ?
何で消えたんだろ?
0326ふかNGNG
レスあり〜。
あれ?プロトタイプに引数名は書いた方がいいのか。
今,標準ライブラリヘッダもみたけど,たしかにそうだった・・・。
んじゃ,引数名書かないことの意義は?

あと話をまとめると
・動かない処理系がある
・書かないとコンパイラではint型と認識する
・漏れが >>294 で書いたアーカイブ間で相互参照するときに,
宣言しとかないとリンクできない
くらいですかね?
0327デフォルトの名無しさんNGNG
>>326
コンパイラはプロトタイプからは引数の型しか見ないから書いても書かなくてもよい。
でも書いた方が人間には優しい。
0328デフォルトの名無しさんNGNG
あの〜、nil=不明は良いんですけど、nulはどんなビットパターンにアサインされるんですか?
ポインタという整数型にnilという状態を持たせたら、そのビットパターンは整数値として有効な範囲に
いる可能性が出てきますよね?
0329デフォルトの名無しさんNGNG
>>326
stdlib.hをインクルードしないで、
char *str;
str=(char *)malloc(478);
とかやってみな。
0330デフォルトの名無しさんNGNG
>>326
変数名が不適切なときの修正が楽。
0331デフォルトの名無しさんNGNG
>>320
>299
>ハードウェアで bitパターンが all 0 でない物がNULLポインタである可能性があるんだから

って言ってるじゃん。
■ このスレッドは過去ログ倉庫に格納されています