C言語なら俺に聞け(入門篇) Part 25 at TECH
C言語なら俺に聞け(入門篇) Part 25 - 暇つぶし2ch39:デフォルトの名無しさん
08/02/21 00:46:37
>>38
いや、なんとなくです。
サンプルソースとか見ても、普通はそんなにstaticがついていない気がするし。

40:デフォルトの名無しさん
08/02/21 00:47:11
普通そんなに関数名衝突しないだろ

41:デフォルトの名無しさん
08/02/21 00:47:23
サンプルは適当に作ってるから書いてない事もある。
真面目に書く場合は公開しない関数には static を付けるのが普通。

42:デフォルトの名無しさん
08/02/21 01:03:34
static付けたプロトタイプ宣言を書いといて、
定義は付けずに書けばどう?

43:デフォルトの名無しさん
08/02/21 02:12:09
これに於いて


"スタック領域

戻り番地3
変数
戻り番地2
戻り番地1

       "

戻り番地とは、どういう意味なんでしょうか?



44:デフォルトの名無しさん
08/02/21 02:15:07
retで戻る場所

45:デフォルトの名無しさん
08/02/21 02:16:18
関数から帰ってきて再開する場所
void g() {...}
void f(){
 g() ;
r1:
 g() ;
r2:
}
上のgの中を実行中は

"スタック領域
r1

下のgの中を実行中は

"スタック領域
r2

f内の中を実行中はスタック領域=空

46:43
08/02/21 02:16:50
>>44
ん???

47:43
08/02/21 02:19:26
>>45
詳しく、ありがとうございます

ですが、どうしてこれが”戻る”っているのでしょうか?

48:デフォルトの名無しさん
08/02/21 02:21:29
if(argc > 1) とは、argcが1より大きければ~でしょうかね

49:デフォルトの名無しさん
08/02/21 02:24:56
>>47
関数gにいってr1またはr2に戻ってくるから

50:デフォルトの名無しさん
08/02/21 02:26:59
>>48
そのとおりだ、見ての通りだ
引数一個の時は、実行ファイル名と引数合わせて二個、argc==2だから注意しろ

51:デフォルトの名無しさん
08/02/21 02:28:31
>>50
さんくすです

52:43
08/02/21 02:33:49
>>49
ですが、これだと戻り番地が複数ありますよね???


"スタック領域

戻り番地3
変数
戻り番地2
戻り番地1

       "

53:デフォルトの名無しさん
08/02/21 02:37:45
>>52
あなたが手を出すには、まだ早すぎるのかも知れません
どんなに説明していても、読まないみたいだし

54:デフォルトの名無しさん
08/02/21 02:38:37
>>52
i()
{
今ここを実行中、ここが終わったら"戻り番地3"へ
}
h()
{
 i();
戻り番地3:
}
g()
{
 変数宣言 変数 ;
 h();
戻り番地2:
}

f()
{
 g();
戻り番地1:
}


55:デフォルトの名無しさん
08/02/21 02:45:37
>>52
つまらないアドバイス
プログラムに関数がなく、gotoだけで何とかしたいと思ったらどうする?
実際CPUによってはマシン語にgotoしかないケースもある、その代り今、実行している位置を変数に記録できるとする。
戻り番地はある種の変数だ。goto label のとび先 label を格納することができる。
これで関数同様の処理の流れを作ってみよ
一日ゆっくり頭を悩ませるがよい

56:43
08/02/21 03:58:14
>>53
確かに、まだレベルが達していませんでした。

>>54->>55
何とか何となくですが、理解できました。
gotoと参考書に載ってませんので、レベルを上げてから
深く考えてみます

ありがとうございました。。。


57:デフォルトの名無しさん
08/02/21 05:16:32
UNIXはCで作られているのでしょうか?

58:デフォルトの名無しさん
08/02/21 05:48:44
>>39
どのサンプルを見ているのか判らないけど、
汎用的なライブラリーとかソースみると間違いなく
ファイル内で完結する関数、変数にはstaticついてるよ

というかついてないと怖いと思う

59:37
08/02/21 09:56:06
>>58
なるほど。
そういうものってことですね。
ありがとうございました。

60:デフォルトの名無しさん
08/02/21 14:05:42
整数型の変数に最大値以上の数を入れようとした時、影響があるのはその変数だけでしょうか?
例えばunsigned intの最大値で111...111となってる所に1を足したら000...000となってしまうみたいですが、
この時となりのメモリーに1が繰り上がってしまうってことはあるんでしょうか?

61:デフォルトの名無しさん
08/02/21 14:09:25
配列使って試してみたら?

62:デフォルトの名無しさん
08/02/21 14:48:21
>>60
大丈夫、当該メンバ以外は影響受けません。

63:デフォルトの名無しさん
08/02/21 14:59:57
>>61-62
ありがとうございます。
なるほど、配列だと隣のメモリにおかれるから確認に使えるんですね。
自分でも試して見ます。

64:デフォルトの名無しさん
08/02/21 15:26:22
>>63
実践コードでは、良い悪いは抜きにして、それを前提にしたコードがかなりあるので確り覚えておくが吉。
二の補数でググッておけ

65:ててて
08/02/21 18:24:29
memcmpについて質問です

char *han1;
char *han2;

char temp1[81];
char temp2[81];

han1 = fgets(temp1,81,Fp1);
han2 = fgets(temp2,81,Fp2);
となっていた場合に文字数81は

memcmp(han1,han2,81)と書いていいんでしょうか?
最後の文字のNULLを飛ばして80
memcmp(han1,han2,80)とどっちなのか悩んでいます
指摘お願いします

66:デフォルトの名無しさん
08/02/21 19:20:53
むしろstrncmp

67:ててて
08/02/21 19:24:24
strncmpをmemcmpに変えてっていう問題なんです
すみません

68:デフォルトの名無しさん
08/02/21 19:31:29
試せば?

69:デフォルトの名無しさん
08/02/21 19:45:48
まぁ、80でいいけど81だろうな。

70:デフォルトの名無しさん
08/02/21 19:48:02
実は80も81も不正解、な気がする。


71:ててて
08/02/21 19:50:46
ええ!?

ちなみに試せる環境がありません

72:デフォルトの名無しさん
08/02/21 20:06:50
そりゃぁ、strcmp()じゃない時点で不正解だ。

73:ててて
08/02/21 20:09:26
ううむ
まあとりあえず81って書いておきますw

情報ありがとうございましたw

74:デフォルトの名無しさん
08/02/21 20:12:23
入力行が80文字未満だとtemp1 temp2にゴミが残るからねえ。


75:ててて
08/02/21 20:18:34
とは思うんですが入力のほうは指定ないので少なく書いても幅が広がってしまうだけのようなきもするんですよね

76:デフォルトの名無しさん
08/02/21 22:29:08
>>75
memcmp(han1,han2,strlen(han1))

77:デフォルトの名無しさん
08/02/21 22:33:13
#include <stdio.h>
int main(void)
{
  char str[80];
  int i, spaces;
  char *p;
  printf("文字列を入力してください: ");
  gets(str);
  spaces = 0;
  p = str;
  while(*p){
      if(*p==' ') spaces++;
      p++;  /* このポインタのインクリメントは"*p++;"としても
               プログラムは正しく動作します。なぜですか?*/
  }
  printf("スペースの数: %d", spaces);
  return 0;
}

すいません。教えてください。

78:デフォルトの名無しさん
08/02/21 22:38:43
* よりも ++ の方が演算の優先順位が上だから。
*p++ってのは*(p++)と等しい。

79:77
08/02/21 22:40:33
>>78
すばやい回答、ありがとうございました。m(_ _)m

80:ててて
08/02/21 22:41:18
>>76
なんという
そうかーなるほど・・・
うう、ひらめきって大事ですね

81:デフォルトの名無しさん
08/02/21 22:45:01
char temp1[81] = {'\0'};

82:デフォルトの名無しさん
08/02/21 22:46:58
>>81
temp1[81] == "abcde\0\0";
temp2[81] == "abcde\0f";
このとき文字列としては


83:デフォルトの名無しさん
08/02/21 22:48:12
途中で送信してもうた...

>>82 のとき文字列としては等価と判定せねばなるまい

84:デフォルトの名無しさん
08/02/21 23:40:51
memcmp(han1,han2,strlen(han1))の場合
han1が多い時とhan2が多いときで誤差でない?

85:76
08/02/21 23:44:50
>>80
訂正
memcmp(han1,han2,strlen(han1)+1)

86:84
08/02/22 00:27:26
han1が10文字
han2が20文字

han1が20文字
han2が10文字

の時にmemcmpだとゴミが入ってしまって無理じゃないかね?ってことね

87:デフォルトの名無しさん
08/02/22 00:29:37
違いを検出するだけでいいなら、memcmp()でも問題ないね。

88:ててて
08/02/22 09:57:29
han1 = fgets(temp1,81,Fp1);
han2 = fgets(temp2,81,Fp2);
と、なっているところでテキストファイル同士比べる時に、
han1 = [aaaaaaaaaa]
han2 = [aaaaaaaa]
などなっていても実際80文字分(1行分?)までの区切りなので初期化する必要ってありますか?
一応比較して結果が0なら比較内容同じ、-1か1なら違うとでるようにするだけなのでfgetの文字数と同じなら大丈夫な気がするような・・・


89:デフォルトの名無しさん
08/02/22 10:00:40
短いほうが\0で終わってるわけだから
そこまでが同じならば短いほうが小さい、という結果になる
なのでどっちの長さを指定してもいいが、\0まで含めることが必要。
\0を超えての比較は意味が無いので、バッファのサイズで比較するのは間違い。

90:ててて
08/02/22 10:52:10
なるほど~

それじゃあ、そろそろ答え81って書いて提出します
みなさんのおかげでいろいろわかりました
どうもありがとうございました

91:デフォルトの名無しさん
08/02/22 11:26:14
>>90
han1[]="abcd\0e";
han2[]="abcd\0f";

92:ててて
08/02/22 12:21:24
>>91
の場の場合もあるにはありますよね
そこら辺の指定はまったくないんですよね

問題文
以下のプログラムは起動時に指定された2つのテキストファイルを比較し、
違う行があればその行番号を表示するプログラムです。
空白部分を埋めて、プログラムを完成させなさい。
という文章で自分で strcmp のバージョンは穴埋めはできたと思います

問題2
問題1のプログラムにおいてstrcmpを使用して読み込んだ2つのレコードが同じかどうか判断しています
これをmemcmpを利用したロジックに作り直しなさい

それで比較する部分のstrcmpをmemcmpに変えて書いたんですが読み込みするテキストファイルの指定は全くありません
それで文字列分指定すればいいかなーと思っていたんですが・・・

>>90のようにそこまで深く考えたほうがいいのでしょうか?
意地悪問題すぎる

93:デフォルトの名無しさん
08/02/22 12:24:05
だから単に片方のをstrlen()+1すればいい
strlenも使用不可なのかな?でも自作するくらいならmemcmpも使わんしなw

94:ててて
08/02/22 13:40:00
>>93
strlenは使えます

と言うか勘違いしてましたw
それで当たってますね

han1 = aaa\0
han2 = aaab\0
memcmp = (han1,han2,strlen(han+1))
だと返す変数0になりません?
と勘違い

文字数で違うなら\0の部分で0以外返しますし
文字が違うならやっぱり0以外返しますね

答えにそうかいて出します
ちゃんと理解して解決しました
本当にありがとうございます

95:デフォルトの名無しさん
08/02/23 01:47:49
大きい二次元配列の初期化ってどうやればいいんですか?

char buf2[20][20];char buf[256];
double dat[10000];

とかだったら。

96:デフォルトの名無しさん
08/02/23 02:06:36
>>95
ループで各要素に初期値を代入する。
2次元配列の場合は2重ループで初期値を代入する。

char buf[256];が文字列だったら、strcpy(buf, "");

97:デフォルトの名無しさん
08/02/23 02:09:13
その前に、本当に初期化する必要があるかどうかチェックしてね。
無駄に初期化する人が多いから。

98:デフォルトの名無しさん
08/02/23 02:15:11
>>96
それってstrcpy使う必要あるのか?

99:デフォルトの名無しさん
08/02/23 02:22:59
初期化することって規約があることもあるんだぜ・・・。

100:デフォルトの名無しさん
08/02/23 02:25:44
初期化する必要ない場合ってどういう場合?

LINUXでいいデバッガない?

101:デフォルトの名無しさん
08/02/23 02:26:19
初期化する必要ない場合は初期化する必要ない場合

102:96
08/02/23 02:26:53
>>98
ヌル文字での初期化の場合ね。
buf[0] = '\0'
でもいいんだが、好みの問題。

103:デフォルトの名無しさん
08/02/23 02:29:08
double data[10000]={0}だと初期化できてないみたいなエラーでるけどこれは
範囲あるの?

104:デフォルトの名無しさん
08/02/23 02:29:32
>>102
最適化すればオーバーヘッドなくなるのかな?
まぁもともと無視できるほどの差だろうけど

105:デフォルトの名無しさん
08/02/23 02:30:57
>>103
規格では全て 0 で初期化されるはずだが。
警告出すコンパイラならあるけど。

ただ、コンパイラが糞だと知らん。

106:デフォルトの名無しさん
08/02/23 02:34:47
セミコロンがないとかじゃないよな

107:デフォルトの名無しさん
08/02/23 03:15:36
URLリンク(www.shinetworks.net)

この、12行目~16行目までの解説をお願い致します。
特に解らないのが、12行目の" if(argc > 1) { "の部分です。
配列argcが1より大きければ、と言う言でしょうか?

108:デフォルトの名無しさん
08/02/23 03:19:31
コボラーさんがC言語覚えるのは結構大変?


109:デフォルトの名無しさん
08/02/23 03:19:36
文字列の長さも確認せずに strcpy はやばいだろ。

110:デフォルトの名無しさん
08/02/23 03:20:38
大変? とか気にしてる時点で脈は無いわ。

111:デフォルトの名無しさん
08/02/23 03:28:52
>>107
argcはコマンド引数の数+1。

コマンド行がhogeのときargcは1。
コマンド行がhoge arg1のときargcは2。

だからif(argc > 1)とはコマンド引数がひとつ以上あるということ。


112:デフォルトの名無しさん
08/02/23 04:27:04
>>111
サンクスです

113:デフォルトの名無しさん
08/02/23 04:28:35
>>111
>>だからif(argc > 1)とはコマンド引数がひとつ以上あるということ。
ないときは、あるんですかね?

114:デフォルトの名無しさん
08/02/23 04:31:58
ないときはないよ。そんときは、argcが1になる。

115:デフォルトの名無しさん
08/02/23 04:41:37
>だからif(argc > 1)とはコマンド引数がひとつ以上あるということ。
いや,2つ以上だろ.もしくは1つよりも多く.

116:デフォルトの名無しさん
08/02/23 04:42:24
argc==2なら引数は1だろ。

117:デフォルトの名無しさん
08/02/23 05:09:25
?                  ↓-此れは?
006: int main(int argc,char *argv[]


>>113
ああああああぁぁあぁ…   永遠に繋げていく事か"!

if( argc > 1, argv > 1, argc > 1) = argc[1]


118:デフォルトの名無しさん
08/02/23 06:45:19
頭が混乱してきた…整理ついたら、出直してきます 
ありがとうございました


最新レス表示
レスジャンプ
類似スレ一覧
スレッドの検索
話題のニュース
おまかせリスト
オプション
しおりを挟む
スレッドに書込
スレッドの一覧
暇つぶし2ch