C言語なら俺に聞け( ..
[2ch|▼Menu]
357:デフォルトの名無しさん
07/12/30 00:15:13
>>355
ポインタのメリットをすぐに理解する必要はないが,必要になったときにすぐに(少し調べて)使える程度に覚えとけ

358:デフォルトの名無しさん
07/12/30 00:17:59
ok
いま独習Cでポインタやってるんだが、まぁある程度理解してるんだが
少し、上に行くと難しいんだよな。
char *bokki ="ちんこが立つ";

printf(bokki);
って場所やってるぜ、こういうのってプロでも使うのか?

359:デフォルトの名無しさん
07/12/30 00:19:36
>>255
使うメリットが無い内は使わなくていいと思うよ
便利だから使うのであって、かつC言語をやっていればそのうち「これはポインタを使った方が楽だ」って状況が出てくる
その時に使えばいいだけの話


まあC++ならまだしも、C言語だと関数との配列の受け渡しとかで
すぐにポインタが必要な状況になるよ

360:デフォルトの名無しさん
07/12/30 00:20:34
>>355
同じアドレスを共有したいときがあるのさ
夫婦だって別々のベッドじゃいやだろ?

361:デフォルトの名無しさん
07/12/30 00:22:17
>>358
まぁリテラル文字列はstaticでconstで領域もconstしちゃうけど

362:デフォルトの名無しさん
07/12/30 00:22:19
Cは難しいなポインタが
もしかして359と360はバリバリ使えるんすか?

363:デフォルトの名無しさん
07/12/30 00:23:39
>>358
const char * str = "俺童貞";
printf("%s", str);

まあdefineの代わりにconstポインタを使うことはあるかもね
defineの代わりとしては
const char* const str = "ヤリてー";
の方がいいかね

364:デフォルトの名無しさん
07/12/30 00:25:40
すごいっすねみなさん
この頭の良さを駆使して、みなさんが作ったプログラムはどんなのありますか?
実用的で使えそうなやつっすよタブを消したり入力した文字をソートしてなんたらしたり

365:デフォルトの名無しさん
07/12/30 00:26:20
>>358
表示したい文字列に%があると見落とすかもよw

366:デフォルトの名無しさん
07/12/30 00:28:41
宇宙に浮かんでるアレの制御プログラム、を作るための支援ツールとか監視システムとか

367:デフォルトの名無しさん
07/12/30 00:29:31
ちなみに私が作ったのは
1,暗号化 2,解読 3,Quit
というやつでシーザー暗号に似た奴ですね。
まだまだへたれですよ


368:デフォルトの名無しさん
07/12/30 00:29:59
文字列のポインタは文字列の実装上使わざるを得ないのでメリットが分かりにくいと思う

369:デフォルトの名無しさん
07/12/30 00:30:44
>>366
本気で言ってるんすか?
知人の凄い人でもATMなのに人工衛星とかの制御プログラムとか次元が違いすぎる

370:デフォルトの名無しさん
07/12/30 00:32:40
最近、どっかの団体のコーディングルールとか見ると、ポインタの演算禁止とか、
ポインタのポインタらしい使いかたはしないって流れになってきてるな。
じゃPascalでも使ってればいいのにって気がするけど。

371:デフォルトの名無しさん
07/12/30 00:32:54
ポインタがどうでも良くなってきたんで。
早くファイル操作などの場所をやりたいんですが、ページを飛ばすと複雑な気持ちになるので
ポインタのページと関数のページを仕方なくやりますか

372:デフォルトの名無しさん
07/12/30 00:33:22
>>369
よく嫁
支援ツールだ
つまりだたの社内ツール

373:デフォルトの名無しさん
07/12/30 00:34:43
実用的なのは作ったこと無いな、所詮娯楽用品止まり。

374:デフォルトの名無しさん
07/12/30 00:35:23
私の書いたコードなら、世に出回っているフラッシュメモリのシェアの多くを生み出す装置の検査に使われているぜw

375:デフォルトの名無しさん
07/12/30 00:35:35
まぁ日曜プログラマならそれでいいんじゃね?
自分の腕を仕事に活かしたいと思ったら、それはそれで地獄をみることになるし

376:デフォルトの名無しさん
07/12/30 00:35:54
>>372
でもすごいっすよ
C言語を始める時期が悪かったですかね
ガキの頃に手をつけとけば良かったと後悔しますよ
Cをマスターしたら次はperlかjavaやろうかと思ってるんすよ

377:374
07/12/30 00:36:39
もっと身近なところでは、某駅ビルの駐車券発行機に使われているとか(ぉぃ

378:デフォルトの名無しさん
07/12/30 00:40:35
去年一年くらいCの仕事をやって、医療関係のシステムだったけど、ありえないくらいコードの質が
低かったから、そのシステムを導入してる病院には行かないことにしてる。怖い。

379:デフォルトの名無しさん
07/12/30 00:40:58
>>376
始めるのに早いも遅いもない
逆にガキのころはガキのころにすべき勉強なり体験なりをしなくちゃいけない
Cなんてただの道具にすぎんのですよ、偉い人にはそれがわからんのです

380:デフォルトの名無しさん
07/12/30 00:41:44
>>374
まじすか?
凄過ぎますよ、是非そういう人に基礎から教えてもらいたいんですが
まぁ無理なんでしょう、自力でやらないと意味がないし
そういうコードを書くにはCを学んでいたときに1日どのくらい書いてましたか?
あとは1日3個適当にプログラムを作るとかそういう目標とかってありましたか?

>>2373
私もそんな感じっすよ
暗号化できたーやーいって(自己満)すよね

>>375
プログラマーになったら大変そうすよね
それで食ってくのは難しいすよね

381:デフォルトの名無しさん
07/12/30 00:44:56
プログラミングの仕事は中国やらインド勢力に取られていくし、
自動生成の流れが盛んになってきているから、
プログラミングの仕事はどんどん減っていくだろうね
現に、カードにパンチしていた時代はコーディングが開発工程の8割を占めていたのに、今では2割程度

382:374
07/12/30 00:46:50
そう言えば某社のFAXに……あれはアセンブラだったな。
某社の検査装置に使われているのは……basicか。

てな具合にいろんな時期にいろんなことをやっていたから「Cを学んでいた(だけの)とき」なんてないよ。

383:デフォルトの名無しさん
07/12/30 00:47:00
娯楽用品って言っても仕事なんだけどな (´・ω・`)

384:デフォルトの名無しさん
07/12/30 00:48:11
>>381
今の日本は開発よりかも指示とかプロジェクトの提案とかそんな感じすかね?
たしかにインドとか中国はすごいっすよね。
ロシアは凄いらしいですがどうなんでしょう。
生まれる場所を間違えたな・・・



385:374
07/12/30 00:48:52
>>381
あー確かに、カードパンチの時代は「完全なる机上コーディング」をしたものを「パンチするだけ」だったな。
# 流石に学校で体験しただけだが

386:デフォルトの名無しさん
07/12/30 00:50:47
NHKのワーキングプアの番組でやってたな。
アメリカで銀行のシステムをやって年収1000万のIT技術者が、インドに仕事とられてファーストフードの店でアルバイト。


387:デフォルトの名無しさん
07/12/30 00:53:08
別にインドや中国が凄いってわけじゃなくて、単価が安いからそっちに簡単な仕事まわしてるだけだよ
難しい仕事は単価の高い日本で集中的にやる


388:デフォルトの名無しさん
07/12/30 00:53:59
やっぱ裕福な国は、それ以上求める物が無くて開発するレベルが低いんですか?
日曜プログラマが良いかな、本職は他ので。
パソコン詳しいねすごいねおっちゃんって言われればそれでいいかな

389:デフォルトの名無しさん
07/12/30 00:57:27
>>387
これからはインド人や中国人の10倍の価値のある技術がないときびしいだろうね。

390:デフォルトの名無しさん
07/12/30 01:01:40
>>388
日本を舐めすぎw
おまい、マスコミに変に影響されてるな
プログラミング力のあるなし以前に、視野の狭さが心配だよ

コーディングっていうのは単純作業なんだよ、単純作業
町工場で働く工員と同じ
指示されたものを淡々と作るだけ

じゃあ、それ以前に何をどう作るか、ってのを考えなきゃいけないよね
それを考えるのが日本の仕事

もちろん、今後すぐにプログラミングの仕事が無くなるわけじゃない
やっぱり言語や文化の壁があって、オフショア開発の管理って難しいくて、
リスクを極力避けるために、
現状は、仕様変更の激しい部分とか、重要な部分ってのは日本でコーディングしてる

391:デフォルトの名無しさん
07/12/30 01:03:10
C/C++でポインタを使わないプログラミングが想像できない

>>380
1日3個も作れるならそいつは天才か、作ったものがゴミ箱行きのカスか

392:デフォルトの名無しさん
07/12/30 01:06:13
とりあえずLinux上の適当なコマンドのソースでも読んでろ

393:デフォルトの名無しさん
07/12/30 01:08:05
UNIXコマンドのソースは俺も読んだなあ。

394:デフォルトの名無しさん
07/12/30 01:10:12
おまいはいいよ

395:デフォルトの名無しさん
07/12/30 01:14:42
ライブラリの○○.aっていうファイルから
収録してある関数名を取り出すことって可能ですかね?
あったら教えてください

396:デフォルトの名無しさん
07/12/30 01:22:21
>>395
nmコマンドでぐぐれ

397:デフォルトの名無しさん
07/12/30 02:32:38
>>391
C++ならiteratorは別とすればポインタつかわないこと多くね?

398:デフォルトの名無しさん
07/12/30 04:17:57
Java厨です。
Include文とかヘッダファイルの自動生成って出来ないもの?


399:デフォルトの名無しさん
07/12/30 05:06:09
条件にもよるが不可能では無い
頑張って作ってみれば?

400:デフォルトの名無しさん
07/12/30 07:46:20
>>396
どうもありがとうございました。

401:デフォルトの名無しさん
07/12/30 08:24:40
#define DATA "data"
と、例えば定義してexeを作ったときバイナリエディタでみても"data"を文字列として見つけられません
これはどういう形で格納されていのでしようか?

402:デフォルトの名無しさん
07/12/30 08:26:04
たとえば、
#define SRAM_A (volatile unsigned char *)0x200000
こんなのもポインタを使っているといっていいですか?
SRAM.Hの中身は、こんなのだらけなんですけど。

403:デフォルトの名無しさん
07/12/30 08:33:50
>>401
DATAを作っていなければコンパイラはobjに"data"を出力しない。
当然、出力されるEXEにも存在しない。

404:デフォルトの名無しさん
07/12/30 08:54:40
>>402
それだと「アドレス」と言いたくなるけど、まぁポインタだね。

405:デフォルトの名無しさん
07/12/30 08:58:09
>>402
組み込みなら普通は #pragma で section 名指定して、
リンカーで配置する。処理系によって違うけど
似たようなコードがあるはず。

絶対アドレスにポインタ使う必要なし。


406:デフォルトの名無しさん
07/12/30 13:24:24
趣味でGBAやったときも402みたいなことばかりやったな。

407:デフォルトの名無しさん
07/12/30 14:42:25
こんなマクロ定義してたな俺。
#define Acc08(Adr) (*(volatile unsigned char *)Adr)
#define Acc16(Adr) (*(volatile unsigned short *)Adr)
#define Acc32(Adr) (*(volatile unsigned int *)Adr)

408:デフォルトの名無しさん
07/12/30 14:50:02
DOS 時代も VRAM 使う時にそういう事してたな。

409:デフォルトの名無しさん
07/12/30 17:04:38
>>401
そもそも使ってなければプリプロセッサはコンパイラに"data"を出力しない

410:デフォルトの名無しさん
07/12/30 21:17:27
void *myMalloc(int size)
{
void *p;
p = malloc(sizeof(double) * size);
if (p == NULL) ...エラー処理;
return p;
}
と言うような関数を作ったのですが、

これに、double **a の奴と、 double *b に
a = (double **)myMalloc(size);
b = (double *)myMalloc(size);
と、つなぎ合わせる事をするのですが、
特にこれで問題は起こらないものでしょうか?

411:デフォルトの名無しさん
07/12/30 21:32:56
>>410
何かメモリがもったいないな

412:デフォルトの名無しさん
07/12/30 21:48:21
a = (double **)myMalloc(size);
のあとは、for文回して
a[i] = (double *)myMalloc(size);
と言うふうに、2次元配列を作る予定なんですが・・・

413:デフォルトの名無しさん
07/12/30 21:51:23
すみません、質問させてください。
テキストファイルを作ると同時にそのファイルから文字を読み込んで出力する・・というのをやりたいのですが、なぜか開こうとしてもすぐ画面が消えます。なにがいけないんでしょうか?
別に読み込むだけでもいいのでアドバイスお願いします。コンパイラは「Bloodshed Deb-C++」です。

414:デフォルトの名無しさん
07/12/30 21:52:39
改行が多すぎると言われたのでいくつかに分けて書きます。
#include <stdio.h>
#include <stdlib.h>
void kaku(int,int*,char*);
int main(int argc, char *argv[])
{
int ten=0;
char kekka[]="NG";
kaku(1,NULL,NULL);
kaku(2,&ten,kekka);
kaku(3,NULL,NULL);


415:デフォルトの名無しさん
07/12/30 21:53:27

FILE *fp;
char data[256];
fp=fopen("test,txt","r");
fscanf(fp,"%s",data);
fclose(fp);
printf("%s\n",data);
system("PAUSE");
return 0;
}

void kaku(int fg,int *ten,char *kekka)
{
static FILE*f;
switch(fg){
case 1:
f=fopen("test.txt","w");
break;
case 2:
fprintf(f,"%d点,",*ten);
fprintf(f,"%s\n",kekka);
break;
case 3:
fclose(f);
break;
}
}
です。長々とすみません

416:デフォルトの名無しさん
07/12/30 21:59:38
>>412
pointer to pointerを作るなら
a = (double**)malloc(size*sizeof(double*));
じゃないの?
まあ、メモリは余分に確保されてるからコーディング間違えなければちゃんと動くだろうけど。

>>413
意味が分からない

417:416
07/12/30 22:01:23
ああ、>>413>>414-415か

418:デフォルトの名無しさん
07/12/30 22:06:43
>>416
printf("%d\n", sizeof(double));
printf("%d\n", sizeof(double *));
で確認した所、 double型が8で、double *型が4でした。
ポインタだと値が違うんですね。 始めて知りましたorz

通りで動かなかったのかと・・・ 
ありがとうございました。 頑張ってみます

419:デフォルトの名無しさん
07/12/30 22:16:23
>>413-415
13行目はtest,txtじゃなくてtest.txtだろう。
fopenしたならfpがNULLかどうか必ず確認すべきだ。
system("PAUSE")というのは俺の環境にはなかったから外したら多分期待通り動いた。

420:デフォルトの名無しさん
07/12/30 22:37:38
>>419
できました!ありがとうございます!!

421:デフォルトの名無しさん
07/12/31 01:54:34
>>418
ついでにcharとchar *、shortとshort *とかもsizeofして見比べて見ると良いよ
ポインタがちょっと見えて来る

422:デフォルトの名無しさん
07/12/31 01:55:08
テキストファイルからある文字列を検索し、ヒットした文字列の直後にある数値を抜き出すコードを考えています
例えば
X= 630.20 Y= 220.20
Z= 33.25 A= 30.25
のような感じです。このうちプログラム内で定数として用いたいのが630.20や220.20、33.25に30.25です
まず1行目をfgets()でポインタ*fpに読み込んで、"X="をstrstr()で探します
その辺りまでしかぱっと思いつきません
ここから630.20を読み込もうと思うと、どのような方法があるでしょうか
宜しくお願いします

423:デフォルトの名無しさん
07/12/31 01:56:18
scanf

424:デフォルトの名無しさん
07/12/31 02:01:46
>>423
ありがとうございます
ですが、scanfはキーボードから入力したデータを読み込む奴ですよね?
テキストファイルに書いてあるものを読み込みたいのですが…

425:デフォルトの名無しさん
07/12/31 02:15:45
isdigit() 一文字ずつで調べて配列に格納して、atof() とか
トークンがスペースなら、そこまで読み込むようにして、 atof() とか

トークンをもう少し考えなおすのがいいかも、セミコロン、カンマとかにする。
strtokn()とかあった気がするが、それは調べてくれ。

426:デフォルトの名無しさん
07/12/31 02:22:41
>>424
fscanf

427:デフォルトの名無しさん
07/12/31 02:24:37
>>425
変なこと教えるなよ。
atofは数字以外に当たったら解析を終了するから、
> 一文字ずつで調べて
とかは不必要だろ。

428:デフォルトの名無しさん
07/12/31 02:29:10
>>425
ありがとうございます。isdigitでチェックして配列に格納が簡単そうですね
strtokn()もありますけど、元ファイルを変換する(というより、別ファイルを作ってそこに数値同士をカンマ等で区切るようにする?)ので、あまり使いたくないところです
最悪、strtokn()で別ファイルを一時ファイルとして作成してやるという方法がありますが…
ちょっと考えてみます。ありがとうございました

>>426
fscanfにそんな機能があったのですか、もう一回調べてきます
ありがとうございました

429:デフォルトの名無しさん
07/12/31 02:54:39
>>428
scanfはfscanfのラッパー関数みたいなもん。
scanf内でfscanfをstdinに対して処理している。
scanfでもstdinをfreopenすればファイルからの入力にできる。

430:デフォルトの名無しさん
07/12/31 09:13:36
普通strtol(), strtod()

431:デフォルトの名無しさん
07/12/31 09:43:21
#include<stdio.h>
int main ()
{
int a,b,c,i,f,d[50];
scanf("%d %d",&a,b);
switch(a*b){
case 0:
return 0;
defalt:
c=a/b;
printf("%d",c); /*19*/
break;
}
i=1;
while(i<=50){
c=a%b;
d[i]=c/b;
c=c%b;
printf("%d",d[i]);
if(d[i]==0)
f++;
else
f=0;
if(f>=2)
break;
i++;
}
return 0;
}
スミマセン!なんでコレダメなのデスカ?オシエテクダサイ!!!

432:デフォルトの名無しさん
07/12/31 09:45:12
>>431
scanf("%d %d",&a,&b);
反射神経が書いてるので違うかもシレン。

433:デフォルトの名無しさん
07/12/31 10:26:48
>>431

defalt:

↑これがだめだ。
ラベルとして認識しているはず。
default: な。


434:デフォルトの名無しさん
07/12/31 10:28:32
>>431

ちょっとずれるが、

switch(a*b){
case 0:

↑0かどうか判断したいだけなら、if文を使うべきだ。
switchにする必要なし。


435:デフォルトの名無しさん
07/12/31 12:42:18
スミマセンちなみにエラーの内容ハ”Ifに(がナイ”デス。
修正しまシタがダメデス。
書き方ノドンクササとかよりそっち教えてホシイデス。

436:デフォルトの名無しさん
07/12/31 13:03:01
>>431に「エラー」は見当たらないような・・・

437:デフォルトの名無しさん
07/12/31 13:18:59
>>435
もう一回、ifの入ってるバージョンのソース見せてくれたらなにかコメントできるかも

438:デフォルトの名無しさん
07/12/31 13:22:45
>>431
>d[50];

>i=1;
>while(i<=50){

これも駄目だな

439:デフォルトの名無しさん
07/12/31 14:25:34
437
このトウリデス
ナオラネエ!ウガァァァァァ

440:デフォルトの名無しさん
07/12/31 17:09:50
#include <stdio.h>
void test(int i);

itn main(void)
{
test(0);
return 0;
}

void test(int i)
{
if(i<10){
test(i+1);
printf("%d",i);
}
}

再帰なんですが
これ難しくて理解できないんすよ。
みなさん詳しく説明してくださいお願いします。

441:デフォルトの名無しさん
07/12/31 17:41:00
test関数は引数が10未満ならもう一度test関数を引数+1の値を使って呼び出したあと引数を出力する。
出力は「9876543210」ってなるだけかな?
10を3とかにして流れをゆっくり追って行けばわかるよ。


442:デフォルトの名無しさん
07/12/31 17:42:04
itnってなんだろうってのは置いといて、

test(0)は0+1でtest(1)を呼ぶ
test(1)は1+1でtest(2)を呼ぶ
最終的にtest(9)が9+1でtest(10)を呼ぶが、i<10じゃなくなるので何もしない
その後printfで9が印字され、8が印字され・・・最初の0が印字されて終了と
処理が戻っていく感じだな

443:440
07/12/31 18:03:00
>>441 >>442
やっぱ再帰できたほうがいいすか?
ポインタよりも再帰の方が難しい・・・



444:デフォルトの名無しさん
07/12/31 18:04:52
何が難しいのかさっぱり理解できない

445:440
07/12/31 18:11:48
何故、0123456789じゃなくて
逆になるのかが、難しい


446:デフォルトの名無しさん
07/12/31 18:13:21
>>443

感覚的に理解できないだけだと思うけど、
デバッガでステップ実行して追っていけばわかると思うよ。

ちなみに、再帰はめったに使わない。
11年ぐらい仕事でCプログラミングやってるが、
再帰を使ったのは1,2回。

447:デフォルトの名無しさん
07/12/31 18:23:52
>>445
printfを実行するのはtestを実行した後だから

ディレクトリの走査とかそれに類似したものは再帰使うなぁ
定番というか

448:デフォルトの名無しさん
07/12/31 18:30:32
デバッグ中に無限に再帰してスタック食いつぶしてデバッガがフリーズするのも良い思い出。

449:440
07/12/31 18:56:37
再帰なんて深く理解しなくていいすか?
適当にながしちまえば?

450:デフォルトの名無しさん
07/12/31 19:01:59
じゃあこれでどうだ

int sum(int n)
{
    int ret;
printf("enter sum(%d)\n", n);
    if(n == 1)
        ret = 1;
    else
        ret = n + sum(n - 1);
printf("leave sum(%d)=%d\n", n, ret);
    return ret;
}

int main()
{
    printf("sum(5)=%d\n", sum(5)); // print 1+2+3+4+5
    return 0;
}

enter sum(5)
enter sum(4)
enter sum(3)
enter sum(2)
enter sum(1)
leave sum(1)=1
leave sum(2)=3
leave sum(3)=6
leave sum(4)=10
leave sum(5)=15
sum(5)=15

451:デフォルトの名無しさん
07/12/31 19:04:18
>>449
何を目的で勉強してるかによるんじゃないかな
単位のためとかであれば流しちゃっていいと思う

452:デフォルトの名無しさん
07/12/31 19:05:08
滅多に使わないけど、再帰は階層構造を簡単に処理するには非常に便利、
この程度の基本テクニックにねを上げてるようじゃ、先は暗いよ。
諦めずに理解するべし。




453:440
07/12/31 19:11:11
>>452
理解してみます
再帰はソートっぽいんすね
>>451 >>452とか
他の人たちは
socketとかネットワークプログラムとかもへっちゃらすか?


454:デフォルトの名無しさん
07/12/31 19:18:10
「へっちゃら」の意味合いによる
ネットワーク関連のバグの修正とかは泣きそうになる

455:デフォルトの名無しさん
07/12/31 22:23:41
スタックはLIFO

456:440
07/12/31 22:31:02
test(0);


printf("%d",i);
tesxt(i+1);
の逆の再帰だと理解できます
先にprintfで0を表示してそのあとにtest0+1をして
1になってprintfで1を表示して
それを10まで繰り返すんですが

上の440のやり方だと
なぜtest(i+1);したあとprintfをやっているのに 9が最初にくるかがさっぱりなんですが
より詳しく教えてくれる人はいませんすか?

457:デフォルトの名無しさん
07/12/31 22:42:02
>>456
再帰呼び出しが終わったらどこに戻るか考えてみそ。

458:デフォルトの名無しさん
07/12/31 22:44:11
長いのでi<2でやると
test(0)→test(1)→test(2)→2は何もしないのでそのまま終了
test(1)に戻る、printf("%d",1)、test(0)に戻る→printf("%d",0)
return 0;に戻る

459:デフォルトの名無しさん
07/12/31 22:45:23
10まであると面倒だからif(i<10)のところがif(i<2)だったものとする。

test(i+1)の所に順次、関数の中身を展開していくと、

if(0<2){
if(1<2){
if(2<2){
test(2+1); // ここは実行されない。
printf("%d",2); // ここは実行されない。
}
printf("%d",1);
}
printf("%d",0);
}

になる。で、10が表示される。これ見たら分かる?

460:デフォルトの名無しさん
07/12/31 22:45:46
>>456
たぶん他の人と被ると思うけどw

test(0) が呼ばれるじゃん?
→ i<10 なので、test(1) が呼ばれるじゃん?
 → i<10 なので、test(2) が呼ばれるじゃん?
   : 中略するじゃん?
    → i<10 なので、test(9) が呼ばれるじゃん?
     → i<10 なので、test(10) が呼ばれるじゃん?
      → i<10 が成立しないので、何もせずに test(10)を抜けるじゃん?
     → printf("%d", 9) で 9 が出力されるじゃん? そんでtest(9)を抜けるじゃん?
   :
 → printf("%d", 2) で 2 が出力されるじゃん? そんでtest(2)を抜けるじゃん?
→ printf("%d", 1) で 1 が出力されるじゃん? そんでtest(1)を抜けるじゃん?
printf("%d", 0) で 0 が出力されるじゃん? そんでtest(0)を抜けるじゃん?
main() 終了じゃん?

さあ、何が出力されたかな?っと。

461:デフォルトの名無しさん
07/12/31 22:46:56
3人もかぶるとはめずらしい

462:460
07/12/31 22:47:32
ほら被ったあw

463:デフォルトの名無しさん
07/12/31 22:50:36
おまえら大晦日なのに暇人だな



いや大晦日だから暇なのか

464:デフォルトの名無しさん
07/12/31 22:52:11
初詣に出かけるまでの時間、暇で暇で仕方ない

465:デフォルトの名無しさん
07/12/31 22:53:14
休みなんて、コーディングくらいしかやること無いしね

466:440
07/12/31 22:57:43
おお!わかりやすいです。
ですが何故、繰り上がってる時にprintfが有効にならないのかが不思議です

i<10 test(0);

test(1)に繰り上がる時は test(i+1)とprintf("%d",i);をやるはずなんですが

何故printfが飛ばされてるんですか?

467:デフォルトの名無しさん
07/12/31 22:59:42
test(i+1)が終わらないとprintfに進めないじゃないか。

468:デフォルトの名無しさん
07/12/31 22:59:50
わかってないのにわかりやすいとはこれいかに


飛ばされてるんじゃなくて、test(i+1)で止まってると思えばいい
で、test(i+1)の処理が終わったら戻ってくる。

469:440
07/12/31 23:02:55
test(i+1);で10になるまでループしてると考えれば良いんですか?
それで10になったら 987654321と戻ると?

470:デフォルトの名無しさん
07/12/31 23:03:02
>>440
test は、9 から i までを出力する関数。

引数が 10 未満の時は、まず test(i + 1); とすることで 9 から i + 1 までを出力してから、その次に i を出力してるっしょ?
そういうわけで、9 から i までが出力される。
んで、10 以上の数を渡すと、if に引っかかって何も出力されない。

だまされた気分になっても気にしない。

471:デフォルトの名無しさん
07/12/31 23:07:15
test(10)は何も表示しない。
test(9)はtest(9+1)を実行してから9を表示する。つまり、9を表示する。
test(8)はtest(8+1)を実行してから8を表示する。つまり、98を表示する。
test(7)はtest(7+1)を実行してから7を表示する。つまり、987を表示する。
…中略…
test(1)はtest(1+1)を実行してから1を表示する。つまり、987654321を表示する。
test(0)はtest(0+1)を実行してから0を表示する。つまり、9876543210を表示する。

472:デフォルトの名無しさん
07/12/31 23:13:23
再帰関数を展開して1つ1つ理解しようとしても混乱するだけだよ。

例えば 9 から i までを出力する関数 hoge があるとするだろ?
それを使って test を実装しようとすると、一番簡単なのは hoge をそのまま呼ぶだけだけど、
それじゃ面白くないので 9 から i + 1 までを hoge に出力させて、
それから i だけを test 内で出力するという風にしてみよう。
そうすると

void test(int i) {
 if(i < 10) {
  hoge(i + 1);
  printf("%d", i);
 }
}

となるわけよ。これは分かるっしょ?

んで、この test っつー関数は 9 から i までを出力する関数になったわけだから、
hoge としてこの test が使えることになる。
というわけで、

void test(int i) {
 if(i < 10) {
  test(i + 1);
  printf("%d", i);
 }
}

としても同じ結果が得られるって寸法だ。

473:デフォルトの名無しさん
07/12/31 23:14:17
>>459とほとんど一緒だけど
int main(void)
{
/* test(0)開始 */
if(0<2){
/* test(1)開始 */
if(1<2){
/* test(2)開始 */
if(2<2){
/* ここは実行されない */
}
/* test(2)終了*/
printf("%d",1);
}
/* test(1)終了*/
printf("%d",0);
}
/* test(0)終了*/
return 0;
}


474:デフォルトの名無しさん
07/12/31 23:18:46
_beginthreadexでウィンドウハンドルを渡したいんですが、
どうすればいいですかね?

475:デフォルトの名無しさん
07/12/31 23:19:25
スレ違い

476:デフォルトの名無しさん
07/12/31 23:19:57
第3引数から渡すれ

477:440
07/12/31 23:21:05
なんとか理解しました

>>460さんのが分かりやすかったです

まだ完全理解したという訳ではないので勉強してみます
回答してくれた皆様ありがとうございました。

478:デフォルトの名無しさん
07/12/31 23:23:03
おそらくスタックがどんな感じなのかわかっていないかな?

iがスタック上に積まれる他に関数呼び出しによる復帰情報(ここだとtest()関数な)がスタック上に積まれるんよ
復帰情報は関数が何処に戻れば良いかを示すリターンアドレスが格納されている
ここではまだ実行されていないprintf()の直前

つまりイメージとしては
復帰←0←復帰←1←復帰←3←復帰…8→復帰←9←復帰
と積まれる(push)

でループから抜けると

今度は
復帰情報→0→復帰→1→復帰→3→復帰…8→復帰→9→復帰
と逆に飛び出してくる(pop)

つまりLIFO(Last In First Out)な訳
良くコインの入れ物として説明されている有名アレ

479:デフォルトの名無しさん
07/12/31 23:46:46
ああなんか色々間違ってるなゴメン

正しくは
push時
main復帰←0←復帰←1←復帰←2←復帰…8←復帰←9←復帰

pop時
main復帰→0→復帰→1→復帰→2→復帰…8→復帰→9→復帰



480:デフォルトの名無しさん
07/12/31 23:55:51
スタック云々言って理解できるなら、
再帰ぐらいで悩まないと思う…。

481:デフォルトの名無しさん
08/01/01 00:16:15
うぬ、そうか、、、スタック説明しないと無理か 大変だな
えーっとスタックはローカル変数を格納する為のメモリ領域で・・・
ってスレ違いだなこりゃ

スマン調べてくれとしか言いようが無い
頑張ってくれ

482:デフォルトの名無しさん
08/01/01 00:18:39
同じ関数だから混乱する。
引数が関数名だと思ってたどってみ
test(1)は test1(1)だと

483:デフォルトの名無しさん
08/01/01 00:23:13
年越し勉強会になっててワロタ

484:デフォルトの名無しさん
08/01/01 01:18:13
printf("あけおめ");

485:デフォルトの名無しさん
08/01/01 01:18:53
puts("ことよろ");

486:デフォルトの名無しさん
08/01/01 01:35:47
scanf("%d", &otoshidama);

487:デフォルトの名無しさん
08/01/01 01:39:34
^D

488:デフォルトの名無しさん
08/01/01 01:42:40
!#include <stadio.h>
int mein()
{
fprint("間違えを見つけた数×100000円お都市玉をもらえます");
}
return 0;

あけましておめでとうございます

489: 【4円】
08/01/01 01:49:08
600000GET

490:デフォルトの名無しさん
08/01/01 01:52:21
600000円が最高金額か
ダンヒルの最高値福袋2個分かよw

491:デフォルトの名無しさん
08/01/01 06:18:41
Max \700,0000- ?

492:デフォルトの名無しさん
08/01/01 06:19:18
\700,000-

493:デフォルトの名無しさん
08/01/01 13:25:28
\nが無いのを間違いと見るなら800000円かな?


494:デフォルトの名無しさん
08/01/01 13:42:07
>>474
4番目のvoid *arglistを使って渡すべし。

495:デフォルトの名無しさん
08/01/01 15:06:42
函数の()の中にvoidとかを書かないのは間違い?

496:デフォルトの名無しさん
08/01/01 15:11:54
函数の()って何だよ。
もうちょっと人に伝わる言葉で表現しろよ。

497:デフォルトの名無しさん
08/01/01 15:13:29
さーせん。
「mein()」の()の事

498:デフォルトの名無しさん
08/01/01 15:14:36
mein って何だよ

499:デフォルトの名無しさん
08/01/01 15:15:15
こっちのセリフです><

500:デフォルトの名無しさん
08/01/01 15:17:14
main

501:デフォルトの名無しさん
08/01/01 15:17:39
>>497
それだけじゃ、宣言か定義か呼び出しかすら分からないわけだが・

502:デフォルトの名無しさん
08/01/01 15:19:24
いえ、>>488のことですが・・・

503:デフォルトの名無しさん
08/01/01 15:21:26
別に何の間違いでもないだろ

504:デフォルトの名無しさん
08/01/01 15:22:46
( ) 内に何も書かなかった場合

○ プロトタイプ宣言
 引数がどうなっているか不明であることを表す。
 その後具体的な引数を指定した宣言や定義が現れない限り、
 この関数を呼び出す時、実引数は可変長引数の時と同じように扱われる。

○ 関数定義
 規格上は void であると見なされることになっている。
 ただし、上記に書いた通りの動作を起こすコンパイラもある。

○ 関数呼び出し
 そもそも ( ) 内に void と書いて呼んではならない。

505:440
08/01/01 16:48:42
また質問っす
#include <stdio.h>
#include <string.h>
int ko(char *p);
int main(void)
{
char str[80];

gets(str);
printf("%d\n",ko(str));
return 0;
}
int ko(char *p)
{
int a;
a=0;
while(*p){
a++;
p++;
}
return a;
}
なんですが
while(*p)なんですが
str[80]に入力した文字をどのように繰り返してるんでしょうか?
while(*p)だと全然理解ができません
入力した文字列の\0(ヌル文字まで繰り返すんでしょうか?)


506:デフォルトの名無しさん
08/01/01 16:57:16
while(*p != '\0') { } と同じ。

507:440
08/01/01 17:00:23
ありがとうございます
*pとかよくわかりずらくて参考書にそんなようなこと書いてなくて
次はforでやってみようかと思います

508:デフォルトの名無しさん
08/01/01 17:00:32
>>505
・C言語では偽が0、真が0以外
・whileは条件が真(つまり0以外)の間、ループを続ける
・C言語の文字列(char配列)はヌルターミネートといって最後にヌル文字('\0')が入っている
・ヌル文字の文字コードは0
・*は間接参照演算子

つまり
>入力した文字列の\0(ヌル文字)まで繰り返す
で正しい。
ヌル文字ではなかったらaをインクリメントし、ついでにpを進める、ということを繰り返す
まあ(半角)文字数を調べる関数だね

509:440
08/01/01 17:06:50
>>508
あ!だからヌル文字で終わるんですね
ヌル文字=0って事を・・・

文字列とかが入るとややこしくなるんで
これを使えば特定の文字の数を数える関数とかへっちゃらっすね

510:デフォルトの名無しさん
08/01/01 17:25:47
でも、ちゃんと '\0' と比較した方が読みやすいから比較しようぜ

511:デフォルトの名無しさん
08/01/01 17:35:04
そうだね。
こんな読みにくいコード書いても、読みやすいコードに比べて実行速度が速くなる訳じゃないもんね。


512:440
08/01/01 17:42:21
実行速度ってどうなんすか?
僕が作るプログラムではそこまでイライラするほどかからないんすが

513:デフォルトの名無しさん
08/01/01 17:54:41
全く変わらん。

514:デフォルトの名無しさん
08/01/01 19:16:56
#include <stdio.h>
int main(void)
{
  while(1)
  {
    printf("おまいら\n");
    printf("あけましておめでとう!\n");
  }
  return 0;
}

515:440
08/01/01 19:18:16
ネットワークプログラム作りたいんすよね
どんな過程でネットワーク系に入りますか?
まずC言語の文法など覚えてたらすぐネットワーク系のプログラムとかやりますかね?

516:デフォルトの名無しさん
08/01/01 19:27:54
ネットワークプログラムは結構めんどくさい。文法覚えただけでは苦戦する。
でも、目的を持って難題に立ち向かうのが上達の秘訣だとおもう。
コードを書いていれば、何が必要かだんだんとわかってくる。
すぐに作れなくてもあきらめないことが重要だよ。


517:デフォルトの名無しさん
08/01/01 19:47:55
#if
#else if
#end if

の使い方がわかりません!
どういうときに使うんですか!

518:デフォルトの名無しさん
08/01/01 19:51:35
以下の★1と★2のやり方で結果が同じになるのはどうしてなんでしょうか?
有識者の方ご教授をお願いします。

#include<stdio.h>

void * func(void *p){

printf("□■□func開始□■□\n");
printf("pのアドレス = %p\n",p);
printf("p = %d\n",(int)p);
(int)p += 100;
printf("p = %d\n",(int)p);
printf("□■□func開始□■□\n");

return NULL;

}
int main(void){

int number = 30;

printf("numberのアドレス = %p\n",&number);
func((void *)number);★1

return 0;

}


519:デフォルトの名無しさん
08/01/01 19:52:05
#include<stdio.h>

void * func(int *p){

printf("□■□func開始□■□\n");
printf("pのアドレス = %p\n",p);
printf("p = %d\n",*p);
*p += 100;
printf("p = %d\n",*p);
printf("□■□func開始□■□\n");

return NULL;

}
int main(void){

int number = 30;

printf("numberのアドレス = %p\n",&number);
func(&number);★2

return 0;

}


520:デフォルトの名無しさん
08/01/01 19:58:22
>>517
#define VER 2
#if VER < 2
//古いコード
#else
//新しいコード
#endif

みたいにソースを丸ごと切り替えるときに使ったりする
慣れると便利。

521:440
08/01/01 19:59:01
>>514
それは、おまいら あけましておめでとうを無限ループですね?
while(1)なので

522:デフォルトの名無しさん
08/01/01 19:59:45
>>518
1はちゃんと動くのか?

523:デフォルトの名無しさん
08/01/01 20:03:15
>>522
*(int*)p += 100;
とすると、同じ結果が出るね。

524:デフォルトの名無しさん
08/01/01 20:05:54
>>517
デバッグ時にコードを一時的に無効化したり有効化するのに便利だね。
/* */とは違って、入れ子にできるから楽

#if 0
hoge();
hoge2();
#endif


525:デフォルトの名無しさん
08/01/01 20:07:40
>>523
ほんとに
func((void *)number);★1
こうなのか?

526:デフォルトの名無しさん
08/01/01 20:11:00
>>525
たしかに。&がないと通らないね。

527:デフォルトの名無しさん
08/01/01 20:12:32
>>523
怒られるんだけどw

528:デフォルトの名無しさん
08/01/01 20:25:21
>>520 >>524
ありがとうございます!
ということは int VER みたいなフラグを作っておいて使うんですね!

#if 0
とか参考にしてたソースに出てきてわからなかったです
ありがとうございました!

529:デフォルトの名無しさん
08/01/01 20:42:21
>>528
>int VER みたいなフラグ
駄目です、それじゃ使えません

530:デフォルトの名無しさん
08/01/01 20:46:59
>>523
*(int*)p
それは参照先がアレじゃないか?

531:デフォルトの名無しさん
08/01/01 20:52:07
>>518
そのこぴぺされたコードで、コンパイルして実行できるか、もう一度確認してみてくれないか?
ちなみにWindows?もしかしてDOS?


532:デフォルトの名無しさん
08/01/01 20:53:06
>>529
orz
使い方おしえてくだしあ

533:デフォルトの名無しさん
08/01/01 20:55:26
>>532
>>520

ただの置換だと思えばいい

534:440
08/01/01 21:01:52
viみたいなエディタ作るには
1人じゃ無理すかね?

535:デフォルトの名無しさん
08/01/01 21:03:12
>>532
プリプロセッサと呼ばれる機能なのだ。
#defineはマクロで、文字列の置き換え
#define VAR 2
と書くと、今後ソースのVARは2という文字に置き換えられる。

#ifは条件付コンパイル。式が0でなければ有効となる。
#if VAR>1
と書くと、以下と同意になる。
#if 2>1
となって、式の結果は、1なので、有効となる。

536:デフォルトの名無しさん
08/01/01 21:03:21
viみたいなエディタなら無理じゃない

537:440
08/01/01 21:05:24
画面上に色とかつけたりしてるのは、あれはC言語でやってるんすかね?
viで色とかが使えるすがスキームなど色文字を表示することは可?

538:デフォルトの名無しさん
08/01/01 21:06:45
>>537
DOSなら、エスケープシーケンスじゃないか?


539:デフォルトの名無しさん
08/01/01 21:14:13
WindowsならコンソールAPI

540:440
08/01/01 21:15:29
Linuxじゃ無理すか?
たしかにwindowsだと猫でもわかるC言語に書いてありましたが

541:デフォルトの名無しさん
08/01/01 21:18:55
猫か…

542:デフォルトの名無しさん
08/01/01 21:21:45
>>540
linux
エスケープシーケンス使えるよ
printf("\033[31mhogehoge\n");
って感じで

543:デフォルトの名無しさん
08/01/01 21:25:50
VT100か

544:デフォルトの名無しさん
08/01/01 21:25:59
>440
ちょっとは自分の頭を使って集中して物を考えたり調べも伸したりする習慣をつけろよ

545:440
08/01/01 21:47:36
>>542
すげーっすね!
できましたよ
エスケープシーケンスで調べてきます

>>544
以後気をつけます

546:デフォルトの名無しさん
08/01/02 00:02:28
>>523

左辺値にキャストはできないだろ?


547:デフォルトの名無しさん
08/01/02 09:04:56
>>546
これを実行してみてほしい

#include<stdio.h>

int main(void){
long num=1234;

*((char*)&num)+=65536+256;
printf("%ld\n", num);
*((short*)&num)+=65536+256;
printf("%ld\n", num);

return 0;
}

548:デフォルトの名無しさん
08/01/02 09:59:34
キャストしたものは左辺値じゃないけど、* をつけたから左辺値で通るんだよ。

549:デフォルトの名無しさん
08/01/03 22:28:47
#include <stdio.h>
#include <malloc.h>
main(togo,toog)
int togo;
char *toog[];
{char *ogto, tgoo[80];FILE *ogot; int oogt=0, ootg, otog=79,
ottg=1;if ( togo== ottg) goto gogo; goto goog; ggot:
if ( fgets( tgoo, otog, ogot)) goto gtgo; goto gott;
gtot: exit(); ogtg: ++oogt; goto ogoo; togg: if ( ootg > 0)
goto oggt; goto ggot; ogog: if ( !ogot) goto gogo;
goto ggto; gtto: printf( "%d goto \'s\n", oogt); goto
gtot; oggt: if ( !memcmp( ogto, "goto", 4)) goto otgg;
goto gooo; gogo: exit( ottg); tggo: ootg= strlen(tgoo);
goto tgog; oogo: --ootg; goto togg; gooo: ++ogto; goto
oogo; gott: fclose( ogot); goto gtto; otgg: ogto= ogto +3;
goto ogtg; tgog: ootg-=4;goto togg; gtgo: ogto= tgoo;
goto tggo; ogoo: ootg-=3;goto gooo; goog: ogot= fopen(
toog[ ottg], "r"); goto ogog; ggto: ogto= tgoo; goto
ggot;}
これは何ですか?

550:デフォルトの名無しさん
08/01/03 23:13:44
たしかIOCCCのプログラム。別に何ってわけじゃない。

551:デフォルトの名無しさん
08/01/04 00:00:33
頭が物故割れた

552:デフォルトの名無しさん
08/01/04 00:24:50
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
 char *position, line[80];
 FILE *fp;
 int counter=0, num, maxbuf=79;
 if ( argc == 1) {return 1;}
 fp= fopen(argv[ 1], "r");
 if ( !fp) {return 1;}
 position= line;
 while ( fgets( line, maxbuf, fp)) {
  position= line;
  num= strlen(line);
  num-=4;
  while (( num > 0) && ( !memcmp( position, "goto", 4))) {
   position= position +3;
   ++counter;
   num-=3;
   ++position;
   --num;
  }
 }
 fclose( fp);
 printf( "%d goto \'s\n", counter);
 return 0;
}

たぶんこういうこと

553:デフォルトの名無しさん
08/01/04 00:40:09
まちがえた、・・・まぁいいか・・・

554:デフォルトの名無しさん
08/01/05 01:12:12
Javaを半年ほどやってCを最近始めた素人です。

同じソースファイル内でも関数の定義位置が違うだけで、
コンパイラが、関数宣言ないよー。という警告をするのが、
いまいち慣れないのですが。

static宣言な、ファイル内スコープの関数なんかでも、
プロトタイプ宣言ってきちんとしたほうが良いのでしょうか。

手元にあるC言語入門だと、main関数を最後のほうに、
定型的な計算用の関数等を、頭のほうにもってきて、
プロトタイプ宣言を書かないようしているのですが、
皆様はどういった書き方をしておられるのでしょうか・・・。

555:デフォルトの名無しさん
08/01/05 01:14:41
>>554
基本的に、ソースファイルの書き方は一貫性が大事だと思っている。
だから、一貫性を持って読みやすければそれでOKだ。

556:デフォルトの名無しさん
08/01/05 01:29:27
>>554
おぃ… どのportでaccessしろと云うのだ?

557:デフォルトの名無しさん
08/01/05 01:51:07
URLリンク(www.microsoft.com)
から.msiインスコしたまではいいですが、ここからどうすればアプリとして起動できますか?
よく分からないままMS Visual C#2008入れました。
最終的にやりたいのは、nCrで任意のnとrを最初に指定して、.txtファイルで1行毎に記述した多数の序数x(1≦x≦nCr)を組み合わせ化して別の.txtファイルにsaveすることです。

558:デフォルトの名無しさん
08/01/05 02:09:33
方向音痴な初心者です
因みに… '/usr/share/doc/man1/或.zg
個人の計算では恐らく'/usr/share/doc*
全てを読み込む様に為っていた筈…

559:デフォルトの名無しさん
08/01/05 02:20:37
最後の状態…
1・再起動がBIOSに到達せず再起動…
2・停止がBIOSに到達せず停止の筈が再起動…
3・RANを切らないと停止せず…

560:デフォルトの名無しさん
08/01/05 02:25:06
斯様に考えてもfile内に.pngを埋め込むのは無理と考えerror_fileを削除の末…
此の顛末…

561:デフォルトの名無しさん
08/01/05 02:31:08
次の質問をどうぞ

562:557
08/01/05 02:42:49
see me(>>557) plz!

563:デフォルトの名無しさん
08/01/05 02:55:06
>>557>>562
ここはC#のスレではありませんよ

564:557
08/01/05 03:49:11
>>563
Spcially sorry, sir.

565:デフォルトの名無しさん
08/01/05 07:32:27
>>554
> 手元にあるC言語入門だと、main関数を最後のほうに、
> 定型的な計算用の関数等を、頭のほうにもってきて、
> プロトタイプ宣言を書かないようしているのですが、
> 皆様はどういった書き方をしておられるのでしょうか・・・。

基本的に読むときのことを考えて書く。
文章は上から下へ向かって読む。
だからプロトタイプ宣言も書いてmainの下に呼び出す関数を書く。

よく見るif (0 == a) みたいなやり方(=を書き間違えるミスを防ぐやつね)
もバッドノウハウだと思う。

566:デフォルトの名無しさん
08/01/05 09:07:16
>>565
最後の2行は同意するが、関数をボトムアップで書くのは臨機応変でありだと思う。


次ページ
最新レス表示
スレッドの検索
類似スレ一覧
話題のニュース
おまかせリスト
▼オプションを表示
暇つぶし2ch

5373日前に更新/237 KB
担当:undef