トップページ⇒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
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ポインタである可能性があるんだから

って言ってるじゃん。
0332デフォルトの名無しさんNGNG
>>326
ファイルサイズをほんの少し小さくできる。
0333315NGNG
>>317=324
>>298=321とは別人だけど、321と同じようにとった
つうか、>>306の処理系云々と言うのは普通そうとると思うけど、
ユーザーが書きかえると思う人の方が多いの?
0334デフォルトの名無しさんNGNG
>>326
一宣言一行に収まって見た目が美しい。

…ってメリットにはならんな。
0335デフォルトの名無しさんNGNG
>>328
ポインタは整数型じゃないけど?
0336デフォルトの名無しさんNGNG
>>328
> ポインタという整数型に
ってのがちょっと意味不明なんだけど、
ポインタという名前の整数型の変数に?
0337デフォルトの名無しさんNGNG
>>331

>ビットパターン 0 が null pointer だって教え方がまず間違ってるよ

>>299は
「ビットパターン 0 以外のものが null pointerである可能性がある」
としか読めないが?
0338デフォルトの名無しさんNGNG
おいお前ら!
プロトタイプ宣言はきちんと書いていますか?
0339デフォルトの名無しさんNGNG
>>338
必要ならやります(というかやらざるを得ない)が、何か?
0340デフォルトの名無しさんNGNG
書かないでcprotoに任せる
0341デフォルトの名無しさんNGNG
>>312
http://www.inet-lab.org/ted/program/prog064.html#064.6
によると、
int (* search_command(char* buf))(const char*);
int (* search_command(char* buf))(const char*)
{
return cmd_list[0].func;
}
らしい。なんか奇妙な感じ。
0342ふかNGNG
>>329
。。。動きましたけど・・・(漏れも動くとはおもわなんだ)



#include <stdio.h>

int main(){
#define AL_SIZ (478)
char *str = NULL;
str=(char *)malloc(AL_SIZ);
if( !str ){
printf("alloc error\n");
return(0);
}
memset(str,0x00,AL_SIZ);
strcpy(str,"hoge hoge hoge\n");
printf("%s",str);
free(str);
return(0);
}
0343デフォルトの名無しさんNGNG
700行以上もあるmain関数は異常だとおもいますが。
0344デフォルトの名無しさんNGNG
>>338
必要無くてもやる
0345312NGNG
>>319>>323thanks
あとで試してみるよ!!
0346ふかNGNG
>>340
なんですか,それ?
0347デフォルトの名無しさんNGNG
>>342
そりゃ動くだろ。
でもコンパイラに文句言われなかったか?
ものによっては言われないのかな。
0348デフォルトの名無しさんNGNG
>>343
そのくらいは普通
0349デフォルトの名無しさんNGNG
>>346
検索しろよ。
ところで、みんな本気で書いてるのか?
機械出力させるのが自然だと思ってたんだが。
0350312NGNG
>>341激しくthanks!!
0351デフォルトの名無しさんNGNG
ハードウエアにnull pointerっていう概念…
高級言語マシンなら…

たしかWirthが作ったModula-2マシンのLilithや
Lispマシンにはあったはずだ。

今だと「dereferenceしたらトラップがかかるポインタ」っていう
くらいかな。0番地のページに保護をかけることができれば0で良い。
0352デフォルトの名無しさんNGNG
>>348
俺は200行でも以上だと思いますが。
0353デフォルトの名無しさんNGNG
>>349
関数をつくるたびにヘッダーファイルにコピペしてセミコロンをつけるだけじゃん。
0354ふかNGNG
>>347
ワーニソグもなしでした。
尤も最近のC言語コンパイラは
//コメント
とか
処理の後の変数宣言までワーニングなしで通しちゃいますからねぇ・・・
0355デフォルトの名無しさんNGNG
>>341
それで合ってるけど、猿にもわかるようにtypedefするのが親切ってもんでしょ。
0356デフォルトの名無しさんNGNG
>>341
激しく可読性が落ちないかな?
0357341NGNG
>>355-356
もちろん、typedef推奨。
オレも知らなかったので、調べただけだよぅ。
0358デフォルトの名無しさんNGNG
おっうちは Call to function 'malloc' with no prototype と出た。
0359デフォルトの名無しさんNGNG
人間が書いたプロトタイプが本体や呼び出しと食い違ってないか
を機械にチェックさせるとミスが減るけど、

機械が本体から作ったプロトタイプだとチェックにならない。
0360デフォルトの名無しさんNGNG
>>356
コメントつければ大丈夫だYO!
0361デフォルトの名無しさんNGNG
>>359
それは勘違いでは?
プロトタイプチェックしてほしいのは、その関数を使う人で、
関数を書く人にとっては自動でもいいような。
0362デフォルトの名無しさんNGNG
スレと関係ないんだけど。
うどんが一玉あるんだけど、具になりそうなものは何も無いんだ。
(卵はあるけど月見うどん嫌い)
かけうどんざるうどん、どっちにするのがいいと思う?
■ このスレッドは過去ログ倉庫に格納されています