1 :
デフォルトの名無しさん :
2009/02/07(土) 08:23:42
CrossePAC is command line driven. Each CrossePAC command starts with the name of the program, CPAC, followed by a series of parameters. If you type CPAC without any parameters, you see the following short help screen: Usage Syntax: CPAC <command> [<options>] <PACfile> <file>* -<file>* <command> = Add | eXtract | DELETE | List | ListMore | Replace | View | reFormat | Print | Help | ? <options> = Format={Text | Ascii | Binary} Blksize=nn eXCludechars=<character list> +/-Subdirectories +/-UsePath +/-UseDevice +/-Overwrite MessageLevel={All|Warnings|Errors|None} OutPath=<pathname> StorePath={Full|Recursed|None} <PACfile> = Name of PAC file to use. Wildcards not permitted Extension of .PAC will be assumed <file> = [<filespec> | IndeXfile=<filename>] -<file> = filename or wildcard to exclude <character list> = List of characters or decimal equivalents specified as \"\\nnn\" where nnn is the decimal value of the character <filespec> = Explicit file name or wildcard specification <filename> = Explicit file name これはどういうことですか?
4 :
2 :2009/02/07(土) 09:55:18
5 :
2 :2009/02/07(土) 11:00:50
自己解決しますた。
>>2 の頭はどのようになっているのですか?
AAで答えて
単純に1を加算する処理を書きたいのですが、一番処理が速いのはどれなんですか? 1.cnt += 1; 2.cnt++; 3.++cnt;
今のコンパイラならどれも同じだろう
cntの型によるかも。 組み込み整数型なら多分どれも一緒。
11 :
10 :2009/02/07(土) 15:34:39
あ、C言語スレだったか。
12 :
7 :2009/02/07(土) 15:42:15
>>8 ,9,10
レスありがとうございました。
加算したかった型はint型です。
どれでも同じみたいですね。
今はコマンドプロンプトで動かすプログラムしかできないのですが、 exeをダブルクリックして起動するような一般的なプログラムにするのは難しいのでしょうか? 具体的には、 1.起動 ↓ 2.参照からcsv形式のファイルを選択 ↓ 3.そのファイルをargv[1]に入れる ↓ 4.プログラム実行 ↓ 5.終了 みたいなことだけ出来ればいいのですが・・・。
>>13 ダブルクリックで動かないのか? OSは何?
exeと言っているからにはWindowsじゃないのか?
「参照」とはなんだ? 「起動」と「実行」は何が違うんだ?
>>14 OSはXPです。
普段はコマンドプロンプトを開いて、cdコマンドでexeファイルのある場所まで移動して、
そこでプログラム名とコマンドライン引数を入力して実行しています。
exeダブルクリックでウインドウを開いたりさせる方法を全く知らないということです。
コンパイルを行えばexeファイルはできますが、
ダブルクリックしてもコマンドプロンプトらしきものが一瞬ちらつくだけで終わってしまいます。
コマンドプロンプト上で動く、CSVファイルを集計してファイルに書き込みを行うプログラムは作ってみたのですが、
このプログラムではコマンドライン引数に、直接CSVファイルを指定しなければなりません。
これをもっとわかりやすく、exeダブルクリックから実行して、
よくある参照ボタンからファイルを選択してOKボタンを押し、集計結果をファイルに書き出すようにしたいんです。
>>15 csvファイルをexeにドロップしてみては?
sscanf()を使って文字列から改行を取り除く char str[] = "Hello\n"; sscanf(s, "%s",s); という風にやってもいいんでしょうか?
空白などでも切れるがそれでも良ければ。
>>17 sscanf(str, "%[^\n]", s)
>>18 sscanf(str, "%s ", s);
でいいの?
>>15 とりあえず画面にウィンドウを表示する方法を調べよう
それからコンソールアプリも中で無限ループさせておけばダブルクリックで実行結果が表示されたままにできるしGUIのアプリも中で無限ループしてるから表示されたままになる
>>21 で、自分でコンパイルしてみて、どの辺が予想外の反応してるの?
24 :
17 :2009/02/07(土) 17:14:51
すいません。sとstrを間違えてました。
char str[] = "Hello\n";
sscanf(str, "%s",str);
strから読み込んだのをstrに入れるというような使い方はできるんでしょうか?
期待通りに改行はとれたんですけど、なんか変だなぁと。
fgetsで入力された文字列から改行を無くす方法をあれこれと勉強しててsscanf()で
疑問に思った次第です。
>>18 入力の時点でスペースを入力されることをすっかり考えてませんでした。
>>20 スキャン集合も勉強したのにすっかり忘れてました
25 :
13 :2009/02/07(土) 17:23:28
あと、コマンドプロンプトから実行するだけでなく、 EXEファイルへのドラッグアンドドロップや関連付けでも argvからファイル名を取り出せることを知ると楽しいと思う。
http://wisdom.sakura.ne.jp/programming/c/c24.html の最初の例題のprintf関数の所の引数を*ary[get_n]にして↓
#include <stdio.h>
int main() {
int get_n;
char *ary[] = { "デ・ジ・キャラット" , "プ・チ・キャラット" , "ラビアンローズ" };
printf("どんな娘がお好み?\n");
printf("目からビーム = 1\n突っ込みトラ娘 = 2\nサイコロ少女 = 3\n");
printf("1〜3の半角英数>");
scanf("%d",&get_n);
if (( get_n <= 3 ) && ( get_n >= 1))
printf("あなたは%sさんが好きなのですね☆" , *ary[get_n - 1]);
else printf("不正な値です");
return 0;
}
実行したらエラーで強制終了しました。
いまいちポインタ配列とprintf関数の引数指定が理解できてないので
何がだめなのかわかりません。
ary[get_n - 1]ではなく*ary[get_n - 1]ではダメな理由を教えて下さい。
%s は文字列、つまりcharの配列(の先頭アドレス)が渡されることを期待している。 *ary[n] は、ary[n]という文字列の、先頭の1文字を意味する。
>>28 丁寧に解説していただきありがとうございます。
二行目が初めは理解できなかったのですが、なんどか例題と見合わせてるうちに
なんとなくわかりました。
*ary[n]は文字列、ary[n]は文字列へのポインタって勘違いしてました。
無造作に「配列へのポインタ」とか「文字列へのポインタ」とか「文字列」とか言う場合、 それは大抵「配列(文字列)の先頭要素へのポインタ」を意味する
宣言文とそれ以外の文では * 演算子の意味が違います。 似てるけど違います。 char *p = "abcd"; putchar(*p);
というか宣言文の * は演算子じゃねーや。
ちなみに俺は、少しでも複雑だと感じたら、一時変数を使う場合が多い。 例えばこの場合だと(あまり複雑ではないが) if (get_n...) { char *s = ary[get_n - 1]; printf(..., s); } もし何らかの勘違いミスがあっても コンパイラのエラーメッセージが代入の行を示してくれるのでわかりやすい。 この場合に char *s = *ary[..]; だと、コンパイラが意味のあるエラーメッセージを出してくれるはず。 まあループの中などでレジスタ割付に期待する面も無くはないが その辺はコンパイラの最適化がやってくれる場合もある。 もちろん、一時変数自体は可読性を落とす要因にもなるので バランスを考えてのことになる。 特に宣言と使用箇所が分離するようだとまずい。
C言語を学ぶにあたり初心者でもわかりやすい本とかを教えてくれると助かります。
http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/8846.txt 座標をtxtファイルに書き込み、頂点をつなぎ合わせた多角形の面積を求めるプログラムです。
例えば引数に使うtxtファイルに
4 2
0.00000 0.00000
0.00000 1.00000
1.00000 1.00000
1.00000 0.00000
と入力しておくとしてこのプログラムを実行すると
V_{1}( 2.00, 0.00)
V_{2}( 0.00, 0.00)
V_{3}( 1.00, 1,00)
V_{4}( 1.00, 1.00)
menseki: 0.500000
となってしまいます。
txtファイルに入力した座標と出力される点の座標が異なってしまいます。
txtファイルに入力した値を正しく出力させるには、どこをどう直せばいいのでしょうか?
fp = fopen(fname,"r"); fscanf(fp,"%d",n); *v = (double **)malloc(sizeof(double *)*((*n)+1)); int m; ←☆ fscanf(fp,"%d",m); ←☆ for (i = 1; i <= *n; i++) (*v)[i] = (double *)malloc(sizeof(double)*m); ←☆ for (i = 1; i <= *n; i++) fscanf(fp,"%lf%lf",&((*v)[i][0]),&((*v)[i][1])); fclose(fp);
ありがとうございます!助かりました!
40 :
デフォルトの名無しさん :2009/02/08(日) 20:58:27
丸投げスレからきました。 以下の文で教えて欲しいです。 memcpy(&byteData ,pTimData ,2 ); /* pTimDataからbyteDataへコピー */ byteData = byteData & 0x7c00; /*15bit分のマスクを掛ける。*/ byteData = byteData >> 12; /*12bit移動*/ read(byteData, bmpData, sizeof(short));/*処理後のデータを格納*/ /*次の2byeを格納するためループ。全て格納し終えたらループから抜け出す*/ memcpyでpTimDataからbyteDataへ2byte分切り出した後 論理積でマスクをかけビットシフトしたあと、bmpDataに格納するというものなのですが このままだと2byte分だけbmpDataに格納して処理を終了してしまいます。 処理後の全pTimDataのデータをbmpDataを入れたいのですが、どのようなループ文を書いたらいいのでしょうか?
char* pTimeData; なら pTimeData += 2; して先頭に。
scanf、gets でエンター( \n ) だけを拾いたいんだけど、どうすればいいのですか? 今、エスケープシーケンスを習っていてエンターを押したら表示が消えてメニュー に戻るようにしたいんです。
>>42 if (strlen(s) == 0) {
/* エンターだけ */
}
ダメかorz
>>42 エンターのみを押したとき、getsならバッファに'\0'が入るから'\0'でチェック。
strlenで文字長0でもいい。
scanfだとエンターのみだとscanfを抜けてこないからダメ。
getsを使って'\0'のみか、stdinに対してfgetsをして'\n'のみかをチェックすればよろしいのでは。
getchar()でもscanf("%c", & ch)でもいいと思うが。
&で&が出るよ、めんどくさいかw
他の関数にint型の変数を渡すとき コピーされて渡されるのですか? それともアドレスが渡されるのですか?
値を渡すとコピー アドレスを渡すとアドレス
>>48 関数の呼び出しでは ど ん な と き も 引数に与えた値がコピーされて渡される。
その値が整数であるか実数であるか構造体であるかポインタであるかは別の問題。
処理が早い方をこれから学ぼうと思ってるんですが、C、C++、JAVAで一番高速なのを教えてください。
52 :
デフォルトの名無しさん :2009/02/09(月) 17:57:31
オリジナル関数が先で、関数mainがあとの場合、問題なく呼び出せるが 二つの関数の位置を単に逆にすると 「プロトタイプ宣言のない関数' 'の呼び出し(関数main)」というエラー メッセージが出るのはどうして? すなわち、 オリジナル関数が先だとなぜ関数の型の宣言は必要ないかが分かりません。 ちなみに本の説明は「オリジナル関数を呼び出す前にその本体が書かれて いると、関数の型がわかる」というものです。
>>51 CとC++が同じ。その中ではJavaが劣る。
>>52 コンパイラは上から下にしかコードを読まないから。
関数本体の記述の段階で 戻りの型(と 引数の型) が確定するから
>オリジナル関数 誰の本か知らないけど、激しくインチキ臭い…
56 :
デフォルトの名無しさん :2009/02/09(月) 18:30:15
52
>>53 ありがとうございます。ご指摘に沿ってもう一度考えます。
57 :
デフォルトの名無しさん :2009/02/09(月) 18:47:28
初心者スレで無職なのバカにされたからこんどからここを巣にするわ
>52がエラーならスレ違いだな。
C用の関数インターフェースで宣言しておいて、実装でC++の例外投げたりした関数は、 どのようなC言語環境からでも呼び出せるのですか? 例外は関数外には送出しないとしてください。
static変数の多様による弊害ってありますか
マルチスレッド対応でなくなるとか、 DLLにしたときはどうなんだろう。まずくないか?
printfの有無でプログラムの実行結果が変わる場合に原因として考えられることは何がありますか
DLLはなんかまずいことがあるのかな?
>>66 モジュール化が不完全になる
strtok 見たいに利用者側がなに突っ込んだか把握してなきゃいけないのばっかだとわけわからないことに
>>71 デバッグ用に簡単なメッセージと変数の値しか表示していない場合でお願いします
>>73 printfを実行するかしないかで処理時間が違うとか?
>>73 ifとかwhileの直後がprintfの単文のとき
>>76 printfとは無関係などこかの処理で、ということですか。
その場合どうやってバグ発生箇所を特定すればよいでしょうか
具体的にはどう動作が変わってるの?
printfがあると正常動作し、printfを削除すると以上終了します
>>79 初期化していない変数を参照している可能性がある。
ある関数を呼んだ場合と呼ばない場合でスタックの状況が変わってしまうからだ。
コンパイル時にWARNINGが出ていたら、それをすべてチェックする。
以上じゃなくって、どう異常になるの?
>>79 どっかでリターンアドレスを壊してるんだろうな。
デバッカが使えるなら、スタックのリターンアドレスのある場所に
ブレークポイントかけるとかできるかも。
>>80 warningは全て消しているので、ポインタ関係ですかね。。面倒そう。。
>>82 デバッガは使わないでprintfデバッグばかりでやってきたので、
これを機会にちょっと調べてみます。
情報提供ありがとうございました。
>>83 デバッガを使わなくても構わないよ。
そもそも、printf()すると巧く動くと言うことはどこかコードが間違っていると言うことだから。
printf()の代わりに、単にputchar()にしてみても動くかどうか辺りから始めてみたら?
# なんとなく、マクロの可能性も含めて副作用の罠に嵌っているだけの気がする。
グローバル変数の管理なんだけど ---global.h--- void set_foo(int); int get_foo(void); ------------ ---global.c--- #include "global.h" int foo = 0; void set_foo(int bar){ foo = bar; } int get_foo(void){ return foo; } ------------ ---main.c--- #include "global.h" int main(void){ set_foo(hoge); printf("%d", get_hoge()); return 0; } ----------- みたいなアクセス関数をいちいち全部つくったほうがいいのかな? 後々排他処理を加えたりするとしたら用意したほうが安全なんだろうけど マルチスレッドを使わないときは意味がないような気がして・・・
変数管理について特別な判定や処理をかませるのでなければ必要ない マルチスレッド対応は必要になってから考えろ
そこまでやるならグローバル変数である必要がなくなるから、staticにしておくべき。
文字列の配列を動的に割り付けるにはどう書いたらいいんでしょうか?
malloc
>>88 「文字列の配列」の意味するところによって異なる。
文字配列の配列が欲しいのか、文字配列とそれを指すポインタの配列が欲しいのか、
既にある文字配列を指すポインタの配列が欲しいのか、はっきりすること。
>>90 複数の文字列を返す関数を書きたいので
その戻りを受け取るための変数をつくりたいんです。
char* の配列を malloc して、 そのそれぞれの要素に文字列を malloc して入れる。
言い回しにひっかかりお覚えるですぅ
そのへんは自分で考えるですぅ わざと言葉を足りなくしてる
95 :
デフォルトの名無しさん :2009/02/10(火) 22:00:18
THE・考える力
お願いします。
おすすめのメタ構文変数名を教えてください。
>>97 foo bar baz qex hoge piyo fuga ...
99 :
デフォルトの名無しさん :2009/02/10(火) 22:05:43
hage
zura
>>91-99 は意識的に発声を ゆっくり にして思考は もっと 高速にすべきだな
hoge hige hage
>>92 ありがとうございます。
ちょっとイメージできました
ぐぐってみます。
sine
C++>>>>越えられない壁<<<<C
cosine
> C++>>>>越えられない壁<<<<C で、どっちが偉いんだ?
>>92 もし文字列の最大長が固定でよいなら
char (*p)[LEN];
と宣言して
p=malloc(LEN*count);
func(p);
のようにする。
文字列の長さも動的に決定したいなら、
char **p;
と宣言して
p=malloc(sizeof(char *)*count);
for(int i=0 ; i < count ; i++) p[i]=malloc(len);
のようにする。
いずれにせよ忘れずにfree()すること。
>>108 ありがとうございます!
なんとなくイメージできました。
まだよく理解できないんで勉強してみます。
>>105 ありがとうございます!
なんとなくイメージできました。
まだよく理解できないんで勉強してみます。
ありがとうございます! なんとなくイメージできました。 まだよく理解できないんで勉強してみます。
>>111 ありがとうございます!
なんとなくイメージできました。
まだよく理解できないんで勉強してみます。
>>109 ありがとうございます!
なんとなくイメージできました。
まだよく理解できないんで勉強してみます。
ここは組込SQLの質問しても良い所ですか?
>>117 だめなところです。
データベース関連スレにどうぞ。
で、どんな質問?
>>118 駄目なとこですか。すいませんでした。
単純に、
SELECT INTOでホスト変数に入れた場合と、
CURSOR使った場合と、
どっちが速いのかなと思っただけです。
>>119 SELECT INTOは一行しかとれないのでは?
複数行ある時にはCURSORを使う。
1行しかない時にはどちらも同じ。
>>120 ですよね。
カウント取るのにINTOからCURSORに修正しろって指示されて、
なんの意味があるのかと思った次第で。
とりあえず、なんか弊害あるのかはもう少し調べて見ますけど
結局一緒ですよね。
ありがとうございました。
基本的なことだと思うのですが、以下のプログラムで scanf("%s", MojiC); の箇所で 8 [main] test1 3524 _cygtls::handle_exceptions: Error while dumping state (probably corrupted stack) Segmentation fault (core dumped) というエラーが出てしまうのですが何がまずいのでしょうか? ポインタの話だと思うのですが、教えてください。 #include <stdio.h> #include <stdlib.h> int main(void) { char MojiA[100]; char MojiB; char *MojiC; printf("MojiA = "); scanf("%s", MojiA); printf("MojiB = "); scanf("%s", &MojiB); printf("MojiC = "); scanf("%s", MojiC); // printf("atoi(MojiA) = %d\n", atoi(MojiA)); // printf("atoi(MojiB) = %d\n", atoi(MojiB)); // printf("atoi(&MojiC) = %d\n", atoi(&MojiC)); return(0); }
char *MojiC = malloc(sizeof(MojiA));
printf("MojiB = "); scanf("%c", &MojiB);
>>124 三つ目の入力が出ませんどうしたらいいですか?
char *MojiC; ↓ char *MojiC = MojiA + 50;
2つ目の改行が3つ目に入ってるんじゃないの?
もう一回入門書読んで来いってレベル
printf("MojiA = "); scanf("%s", MojiA); printf("MojiB = "); scanf(" %c", &MojiB); printf("MojiC = "); scanf("%s", MojiC);
131 :
122 :2009/02/11(水) 17:15:16
>>128 もともとは、atoi関数の引数と返り値の関係を調べたくて
下記のコードを書いたら
Segmentation fault (core dumped)
エラーが出たので、何がまずいのか調べようと
>>122 のようにscanf関数に与える引数をいろいろ試していました。
自分としては
char *MojiC;
scanf("%s", MojiC);
とすれば、scanf関数はMojiCというポインタを受け取るから
問題ないのではと思っています。
int main(void)
{
char *MojiC;
printf("MojiC = "); scanf("%s", MojiC);
printf("atoi(MojiC) = %d\n", atoi(MojiC));
return(0);
}
>>131 ポインタを受け取っても、ポインタの指す先がなければ、問題ありだろ。
そのプログラムでMojiCが何処を指してるか理解してる?
住所がわかっても、建物がなければ誰も入れない。 ていうかそのコードだと、住所すら意味不明。地球上のどこか、ってのと同じ。
>char *MojiC; この時点で未初期化の適当な数字が入っている >scanf("%s", MojiC); その数字のアドレスの場所に入力した文字列が書き込まれる。
135 :
122 :2009/02/11(水) 17:39:28
自分なりに考えました。 int main(void) { char *MojiC; printf("MojiC = "); scanf("%s", MojiC); printf("atoi(MojiC) = %d\n", atoi(MojiC)); return(0); } というコードで実行後、文字列を入力してエラーが出た理由は、 char *MojiC; のところで、アクセスしてはまずい適当なアドレス値がMojiCに代入されてしまい、 scanf("%s", MojiC); のところでMojiCが指すオブジェクトにアクセスできなかったからでしょうか? 今ちょっと試していたら、上のコードに char c; を追加した int main(void) { char c; char *MojiC; printf("MojiC = "); scanf("%s", MojiC); printf("atoi(MojiC) = %d\n", atoi(MojiC)); return(0); } というコードだと実行後、文字列を入力してもエラーが出なかったのですが、この理由は、 char *MojiC; のところで、アクセスしても問題ないアドレス値がMojiCにたまたま代入されたので scanf("%s", MojiC); のところでMojiCが指すオブジェクトに問題なくアクセスできたからでしょうか?
136 :
122 :2009/02/11(水) 17:49:39
あと確認ですが int main(void) { char *MojiC; printf("MojiC = "); scanf("%s", MojiC); return(0); } というコードだと、MojiCのアドレスが不定で、 MojiCが指す先にアクセスできる保証がないから、 scanf("%s", MojiC); はアクセスできないところにアクセスすることにつながるので問題である(エラーが出る)。 int main(void) { char MojiC; printf("MojiC = "); scanf("%s", &MojiC); return(0); } というコードなら、char MojiC;のところで MojiCのアドレスはアクセスできるアドレスになることが決まるので scanf("%s", &MojiC); は問題ない。 ということでしょうか? まだまだポインタの基本がわかっていないのでもうチョット勉強します。
明示的に確保していないメモリ領域でなければ、 データを保存などしてはいけない。 たまたま問題がなかったなどという恥ずかしい発言はやめたまえ。
char MojiA[100]; char *MojiC; MojiC = &MojiA[0]; printf("MojiC = "); scanf("%s", MojiC); これでもいい。
char は文字型変数。 scanf の %s は文字列を受け取る指定。 つまりバグってる。
>>136 問題あり。
char MojiC は1バイトしか領域がないから、その後ろの領域をぶち壊してる。
ぶち壊した領域にたまたま何も無かったから目に見えることがおきなかっただけ。
同じ事を何度も言わなくていいよ
こういうメモリ領域ぶっ壊すようなプログラムって実際実行してもあんまり実害ないの? それとも偶然なんともないこともあれば偶然重大な被害をもたらすこともある?
>>142 #include<stdio.h>
int main(void){
volatile int a=2, b=3, c=4;
for(;a;a--){
(&b)[1]=b;
printf("a=%d\n", a);
}
for(;c;c--){
(&b)[1]=b;
printf("c=%d\n", c);
}
return 0;
}
>>142 駅で刃物振り回すキチガイがいたら、
ケガ人が出ていなくても、マズイだろ?
>>143 こ、これなに・・・?
volatile修飾子って初めて見たからググってみたら最適化を抑止するのか。
怖くて実行できない><
>>144 まぁそうなんだけど、大抵エラーウィンドウが出てなんもおこらないままだからさ〜
>>142 自分の内部を壊しながら動いてるわけだから、一見して死ぬはずのないところで死ぬ。free()したときとか。
なんともないときがあるのは、たまたま壊した部分を動かさなかっただけ。
DVD+HDDレコーダのDVD部分が壊れてても、DVDを使わなきゃ気付かないように。
あと、死ななくてもデータがいつの間にか壊れてたりする。
時間が経ってから壊れてることに気付くと、バックアップも含めて全部壊れてたりする。
自分のdata領域限定の破壊でも ファイル操作API含んでるだけで偶然が重なって boot.ini消しちまったとか 簡単にあり得るからね。
ポインタ怖すぎ これじゃあ学習できないよ
C#へどうぞ
ためしに適当なポインタ宣言してfreeするプログラム実行したらフリーズしかけたあああ マジこええ
charやintなどの変数は 数値を代入する変数で それに*が付くと(char*, int*)アドレスを代入する変数 例: ○ char hoge = 10; × char hoge = &MojiB; × char* phoge = 10; ○ char* phoge = &MojiB;
いきなりどうした
154 :
デフォルトの名無しさん :2009/02/11(水) 21:08:16
>>142 PC上だと共有メモリとか使ってない限りは
OSが上手いことしてくれるから大丈夫。
組込みでやっちまったら暴走する。
最悪火事とか起こって人が死ぬ。
155 :
122 :2009/02/11(水) 21:16:35
>>140 ご指摘頂きありがとうございます。
変換指定子を十分意識できていませんでした。
たびたび申し訳ありませんが、
>>136 を一部改良した、以下の2つのコードについての私の理解を以下に記載しました。
私の理解に問題がないか、回答よろしくお願いします。
int main(void)
{ char *MojiC;
printf("MojiC = "); scanf("%c", MojiC);
return(0); }
では、char *MojiC; の箇所でMojiCに適当なアドレス値が入る(明示的なメモリ領域は確保されない)。
このとき、アクセスしてはいけない(あるいは存在しない)アドレス値がMojiCに割り当てられると、
scanf("%c", MojiC); の箇所で、キーボードから入力された文字をアクセスしてはいけない(あるいは存在しない)メモリ領域に
書き込もうとするが、アクセスできないので Segmentation fault (core dumped) というエラーが発生した。
このような、明示的に確保されていない領域へアクセスすることになるプログラムは作ってはならない。
int main(void)
{
char MojiC;
printf("MojiC = "); scanf("%c", &MojiC);
return(0);
}
では、char MojiC; の箇所でchar型のMojiCを格納するためのメモリ領域が明示的に確保される。
scanf("%c", &MojiC); の箇所で、MojiCのために確保された1バイトの領域にキーボードから入力された文字が保存される。
配列の要素以上のアドレスにアクセスするとどうなるの? 日本語でおkは無しにしてくれ
WIN32APIだけはマジわけわかんね あんなの全部理解してる人いるのか?
>>157 理解できなくても リファレンスを見て扱えればいいんじゃねえの
>>156 処理系依存
ただしポインタは配列末尾 + 1 や、配列先頭 -1 を正しく指すことが保証されている。
内容書き換えはダメだが。
func1(int n, ...); func2(int n, ...); を作って func1から...をfunc2に渡すにはどうすれば?
>>161 方法は無い。
printf/vprintfみたいに、予め...版とva_args版の両方を作っておくのが常套手段。
>>155 多分、合ってる。厳密には char *Mojic の場合でも char*型の値
1つ分のメモリ領域が明示的に確保されるけどね。
>>156 いろいろな事が起こる。
OSが許可していない領域にアクセスすると、保護違反でプロセスが強制終了。
スタック、コード等を書き換えてプログラムを暴走させたり、OSの特権を奪ったりできる。
>>157 理解してるけど、暗記はしていない。良く使うAPIの数は、そんなに多くないから
長くやっていれば自然に覚える。基本的に過去のプログラムをコピペして使う。
使い方を忘れた時だけリファレンス参照。
自分の場合、リファレンスを見る前にググって人のコードを見るほうが多いな。
>>156 処理系依存なので、OSやコンパイラの種類によって結果は違うが、
以下はWindows XP + Cygwin GCC 3.4.4 (最適化無し)で実験した結果。
自分の環境ではどうなるか、実際に動かして試してくれ。
#include <stdio.h>
int main(void) {
volatile int count = 1;
volatile int ia = 10;
volatile char sa[4] = "";
volatile int ib = 20;
volatile char sb[4] = "";
volatile int ic = 30;
for (;;) {
printf("%d:sa> ", count);
scanf("%s", sa);
printf("%d:sb> ", count);
scanf("%s", sb);
printf("[%d][%s][%d][%s][%d]\n", ia, sa, ib, sb, ic);
count++;
}
return 0;
}
1:sa> aaa ← 3文字入力。末尾に'\0'が付くので4バイトになる。
1:sb> bbb ← 同上。
[10][aaa][20][bbb][30] ← 問題なし。
3:sa> aaaaaa ← 6文字入力。同7バイト。
3:sb> bbbbbb ← 同上。
[24929][aaaaaa][25186][bbbbbb][30] ← 配列の範囲をはみ出してia, ibを壊した。icは無事。
1:sa> aaaaaaaaaa ← 10文字入力。同11バイト。
24929:sb> bbbbbbbbbb ← 同上。saをはみ出し過ぎてcountまで壊した。(実はこのとき、iaも壊してる)
[1633771873][bb][1650614882][bbbbbbbbbb][30] ← sbをはみ出し過ぎて、ibだけでなくsaも壊した。
>>165 補足。コピペしたのを一部削ったので、countの表示がずれてるが無視してくれ。
>>167 step()関数から戻ってきてから実行される。
検索のヒント:「再帰」
そのコードは、初心者には読み難いトリッキーなところがあるから余りお勧めできないが。
>>161 仕様に反しないで行う方法はないが
スタックフレームのメモリ全体をそのまま渡すことで大抵の環境では動かすことが出来る。
ただし、この文章の意味がわからないようなら諦めたほうが無難。
コードを示すのは簡単だけど、意味がわからなければバグの元だから。
unsigned int 変数名; は解りますが unsigned 変数名; だとどうなるのですか?
>>170 unsigned int と同じ
省略時には int と解釈される
172 :
デフォルトの名無しさん :2009/02/12(木) 17:15:52
お願いします #include <stdio.h> int uru(int seireki) { int x; if (seireki % 4 != 0) { x = 0; } else if (seireki % 100 != 0) { x = 1; } else if (seireki % 400 == 0) { x = 1; } else { x = 0; } return x; } void main() { int y; y = uru(2004); printf("%d", y); } コンパイルしようとすると、printf("%d", y);が 「不正な文字」のようですが、分かりません。
173 :
167 :2009/02/12(木) 17:19:23
>>168 再帰について調べてみましたが・・・、難しいです。
とりあえず、途中で行き詰まった時のやり直しをそこで行っているということですね。
ありがとうございました。
×void main() ○int main()
l=という演算子はどんな意味でしょうか?
A |= B は A = A | B と同じ
178 :
デフォルトの名無しさん :2009/02/12(木) 18:14:46
#include #これはなんと読みますか?
シャープじゃないの? しゃーぷいんくるーど
正しくはないな
>>178 いげたとかシャープとか
でも普通読まない
意味が通じればなんでもいい インクルード ストリングエイチと言ってinclude stringhなんて書くのはアホ以外の何でもない
読み方についても色々と質問していいのなら、俺も聞きたい事あるんだけど
あのぉ、 別ファイルで宣言した構造体の配列を extern struct info info_list[]; sizeof(info_list); とやるとまぁ当然コンパイルエラーになるんですが、 配列のサイズを知る方法はありますかね?
[a.h] -------------------- #defube INFO_SIZE 10 extern struct info info_list[INFO_SIZE]; [a.c]-------------------- #include "a.h" struct info info_list[INFO_SIZE]; ------------------------ [b.c] #include "a.h" : :
× #defube ○ #define
gettimeofday関数の 戻り値をミリ秒単位に変換したいのですが どうしたらいいですか?
>>190 何から何まで間違ってる
gettimeofdayのマニュアルを読み直すこと
>>190 マイクロをミリにしたいなら1000で割る
1000マイクロ = 1ミリ
193 :
デフォルトの名無しさん :2009/02/13(金) 15:45:57
AVRマイコン総合スレ Part13
http://science6.2ch.net/test/read.cgi/denki/1231687664/343- 上のAVRというマイコンのスレで、volatile付き構造体の動作が
おかしいんじゃないかって話題が出たのですが、
どう解釈するのが正しいんでしょうか?
コンパイラはgccです。gccのバージョンは不明ですが恐らく3か4。
要約すると、
割り込み中にvolatile付き構造体変数を更新して、外からその変数の
構造体メンバを参照したとき、上手く反映されないというものです。
1) C言語の仕様(構造体メンバ変数個別にvolatileを付けるべき)
2) gccのバグ
3) AVRのポーティングバグ
4) その他
195 :
test ご迷惑おかけします :2009/02/13(金) 17:03:26
おすぎおおたあああぞえそうぜおぅあずあ【 늚는닿늖닒녪늑ꛩꡑ늙늂늂늃닿늘 〜〄【〛〖〞〔】『、뉻뉼뉤뉰뉻뉶뉾뉴뉱뉸
196 :
デフォルトの名無しさん :2009/02/13(金) 17:34:20
i=2,j=40とかだと0になるんですけど。 桁数が大きくなった場合はどうすればいいのでしょうか? #include<stdio.h> int kansu(int,int); main(){ int i,j; for(;;){ printf("整数ij(i^j)を入力(i<0:終了)>"); scanf("%d%d", &i,&j); if(i<0)break; else if(i==0) printf("%d^%dの時、下1桁目の値=0\n",i,j); printf("%d^%dの時、下1桁目の値=%d\n",i,j,kansu(i,j)); } printf("Good bye!\n"); } int kansu(int i,int j) { int k,keta=0; keta=i; for(k=1;k<j;k++){ keta*=i; } keta = keta%10; return keta; }
- keta *= i; + keta = (keta * i) % 10;
>>1 C言語でアスペクト思考プログラミングってどうやるの?
自分でコンストラクタとデストラクタ相当を関数の最初と最後に置けばいい
200 :
196 :2009/02/13(金) 19:15:51
>>197 ありがとうございました。無事できました。
平均を出したいのにどんどん加算されてしまうので、 直したいです。 #include<stdio.h> #define STUDENTS 3 #define EXAMS 4 main(){ int i,j,total=0; float avgGrade[STUDENTS]; int studentGrades[STUDENTS][EXAMS]={77,68,86,73,96,87,89,78,70,90,86,81};/*各学生の平均点*/ /*平均*/ for(i=0;i<STUDENTS;i++){ for(j=0;j<EXAMS;j++){ total+=studentGrades[i][j]; avgGrade[i]=(float)total/EXAMS; } printf("学生%dの平均点は%.2f\n",i+1,avgGrade[i]); } }
202 :
デフォルトの名無しさん :2009/02/13(金) 21:30:28
scanf関数の連続使用ができない。一度は入力できても二度目の入力が勝手に改行するんだもん。 なぜそうなるかはわかってるんだが、もはや標準ライブラリではないだろ。 ライブラリから消せよ。
>>201 total=0;
あと、配列の初期化がおかしい
コンパイラに文句言われるだろ?
205 :
デフォルトの名無しさん :2009/02/13(金) 21:50:11
#include<stdio.h> #define STUDENTS 3 #define EXAMS 4 void main(void){ int i,j,total=0; float avgGrade[STUDENTS]; int studentGrades[STUDENTS][EXAMS]={{77,68,86},{73,96,87},{89,78,70},{90,86,81}};/*各学生の平均点*/ /*平均*/ for(i=0;i<STUDENTS;i++){ for(j=0;j<EXAMS;j++){ total = total + studentGrades[i][j]; } avgGrade[i]=(float)total/EXAMS; printf("学生%dの平均点は%.2f\n",i+1,avgGrade[i]); } } これでいけるはず。コンパイルしてません
206 :
デフォルトの名無しさん :2009/02/13(金) 21:51:55
#include<stdio.h> #define STUDENTS 3 #define EXAMS 4 void main(void){ int i,j,total=0; float avgGrade[STUDENTS]; int studentGrades[STUDENTS][EXAMS]={{77,68,86},{73,96,87},{89,78,70},{90,86,81}};/*各学生の平均点*/ /*平均*/ for(i=0;i<STUDENTS;i++){ for(j=0;j<EXAMS;j++){ total = total + studentGrades[i][j]; } avgGrade[i]=(float)total/EXAMS; printf("学生%dの平均点は%.2f\n",i+1,avgGrade[i]); total = 0; } }
208 :
201 :2009/02/13(金) 22:33:29
209 :
赤西仁 :2009/02/13(金) 22:47:36
1年間悩んでます。お力をお貸しください。 アークザラッドUというタイトルのゲームの、ゲーム画像(歩行画像など)を抽出したいのですが、 かれこれ1年ほど経ちますが、なかなかうまくいきません。 *もちろん抽出した画像は個人範囲内で利用するつもりです。 ◆試してダメだったこと ネット上からダウンロードできる、ありとあらゆる抽出系ツールを試した。 (ちなみに他のゲームはほとんど抽出可能) ◆教わったこと ・アークザラッドUは独自の画像形式を使っているから抽出できない。 ・PS上で表示されてるということは絶対に摘出はできるはず。 ◆抽出は不可能ではないということを知ったとき 2ちゃんねるで質問したところ、 ある方が実際にキャラクターの歩行画像を抽出して 私が立てたスレにアップしてくださいました。 スクリーンショットじゃ嫌なんです。どうか皆さん、お力をお貸しください。
マルチは市ね
211 :
デフォルトの名無しさん :2009/02/13(金) 22:53:50
マルチは別に構わんが、たったの1年か
ディスプレイをカメラや携帯で撮影すればいい。
>>209 ネット上の知を駆使してダメなんだから、無理なんじゃないの?
俺ならできそうだな
215 :
赤西仁 :2009/02/13(金) 23:50:02
しかしそのゲーム持ってないんだ
もう一年やってだめだったらやってやるよ
あー、俺も出来るわそれ ゲーム持ってないけど
抽出できたとか言ってスクショ上げるんだろ
220 :
赤西仁 :2009/02/14(土) 00:02:21
やはりプログラミングの知識がないとできないのでしょうか?
221 :
デフォルトの名無しさん :2009/02/14(土) 00:03:46
ここはプログラムを作る人のための板です どっかいってください
スクリーンショット撮る方が面倒だ
ゲームさえ手に入ればなぁ
発想が貧困だな 画像抽出が無理なら別の方法を考えろよ PSで表示できるということは・・・
確かにものがなきゃ調べられもしないしどうにもならんわな
>>224 抽出意外に全パターン取り出すのは大変だろう
>*もちろん抽出した画像は個人範囲内で利用するつもりです わざわざこういうこと書くやつに限って違法行為するよね
233 :
赤西仁 :2009/02/14(土) 00:33:32
ゲームの中身の一部をアップしたら違法ですか? 画像データがいっぱい埋め込まれてるファイルをアップしたいんですが
著作者に許可をとればOK
>>233 そのゲームが他人の著作物なら、一部でも無断でアップしたら違法
#define test(h) h->data と #define test(h){ h->data} って動作かわりますかね?
後者はコンパイルエラーになるだろう
はい。
>>237 すいません
#define test(h){ h->data; }
でした
大雑把に言えば、後者の場合、ifとかforとかの中、式でなければならないとこで使えなくなる。
h->data; で何がしたいの?
for(i = 0; i < n; i++, test(h)) { ... } if(hoge(h)) hoge(h); else a = hoge(h); 全然違うお
hoge(h) じゃないや test(h) だった
俺のかわりに間違い修正するなよw ショックだ
うぜえなこいつ
∧_∧ / ̄ ̄ ̄ ̄ ̄ ( ´∀`)< オマエモナー ( ) \_____ | | | (__)_)
いやおまえうぜえって
マクロ定義を if と同じ間隔で { } で囲んでいるのだろうか。 プリプロセッサディレクティブを if などの構文と同じものだと勘違いしているように見えるな。
249 :
赤西仁 :2009/02/14(土) 01:06:17
誰かアークザラッドをブックオフで買ってやってくれませんか? お礼はかなりします。 本当にします。約束します。
誰が誰に買ってやるのか?
>>249 いいかげんスレ違いですよ
2chで聞くのは諦めてメーカーや知人に頼んでみてはどうですか
>>249 SSを切り抜けばいい
一年もかからず終わるだろw
253 :
デフォルトの名無しさん :2009/02/14(土) 01:18:11
if( a == 1); { f(); g(); } こんなコードでもコンパイルが通るらしい。謎だ
#define test(h) h->data こんなコード危険だから書くな
>>253 そのコードはこう書いても同じこと。
if (a == 1) {}
f();
g();
要は、ブロック化は任意に行なえるのでそうなる。
257 :
デフォルトの名無しさん :2009/02/14(土) 01:27:22
258 :
赤西仁 :2009/02/14(土) 01:27:40
>>256 zaken@e.email.ne.jp
メールください
zと@は半角で。
259 :
赤西仁 :2009/02/14(土) 01:30:07
すみません z.emailでした
>>260 f()やg()がマクロだとスコープの影響を受けるかもしれないけど、それは「違う」と言えないでしょ。
いや、違うでしょ。 結果として動作が同じになるかもしれないけど、 少なくともコード上ではスコープは違う。
>>262 「f()やg()がマクロだとスコープの影響を受けるかもしれない」
ってどういう場合、具体的な例で説明して
#define f(x) int a = x
COM とかだと平気でやってそうだから笑えない。
>>267 {}で囲ってるんだからあたり前。マクロとか関係ない。
>>268 >>267 ×{}で囲ってるんだからあたり前。マクロとか関係ない。
○{}で囲ってないんだからあたり前。マクロとか関係ない。
>>259 スレ違いと言われてるのにいつまでやる気だボケ。
C言語と何の関係もないだろう。
>>270 「#define f(x) int a = x 」この例ではそうなるだけで
>>253 と
>>255 では違う。(厳密も何もない、まったく別物です)
>>272 >253と>255では何が違うのですか?
>>261 「f()やg()がマクロだと」って限定する意味がわからん。
>>274 それが>253と>255においてどんな影響があるのですか?
全く影響がないなら、違うと言えない気がするのですけど。
しつこいぞ
>255が自作関数内でもmain()のスコープ内なんですか? つーか、>253がmain()内でもmain()のスコープ外なんですか? もう少し整理してから書いてください。
_ ∩ ( ゚∀゚)彡 スコープ、スコープ ⊂彡
>>279 >
>>255 が自作関数内でもmain()のスコープ内なんですか?
mainでも他の関数でもいい。
>>255 のコードが存在するスコープにある。
>つーか、>253がmain()内でもmain()のスコープ外なんですか?
あ〜言い方が悪かった、{}で囲まれてるから別スコープってこと
そのブロックはmain(){}のスコープ内にあるかもしれんし
別のスコープ内にあるかもしれん。(書かれてない部分はしらん。)
>>255 int main()
{
if (a == 1) {}
f();
g();
}
>>253 int main()
{
if (a == 1);
{
f();
g();
}
}
として説明してる。
282 :
281 :2009/02/14(土) 15:09:23
283 :
デフォルトの名無しさん :2009/02/14(土) 16:56:53
マイクロソフトでは、入社試験で答えがひとつでない、 や質問文だけで答えが導けず条件をつけたり、面接官に訊ねなければならないなどユニークな面接試験を行っているらしい。 マイクロソフト入社試験 面接官 ウィリアム・ヘンリー 問 以下のC言語プログラムの違いを論じよ --- <0> --- void main(){ foo(x,y); Foo(x,y); } --- <1> --- void main(){ if(1) { foo(x,y); Foo(x,y); } } --- <2> --- void main(){ do{ foo(x,y); Foo(x,y); }while(0); } こんなのあったら、どうする?
284 :
デフォルトの名無しさん :2009/02/14(土) 17:06:53
ポインタのことなんですが int i; i=20; なんですが int i; &i=20; メモリアドレスにアクセスするには&をつけるんですが なぜ変数をセットする場合 &をつけずに値をきめられるんでしょうか教えてください。
285 :
晒し :2009/02/14(土) 17:17:36
>>284 ポインタの知識がなさ過ぎる。
int i; &i = 20;
これコンパイルエラーにならないか?以下のわからない部分言ってみな
&iはiのアドレスで、iはiという箱を指す。アドレスに直値放り込んじゃだめ。
int i; i = 20; //OK 普通の値代入
int j; &j= 20; //NG アドレスへの値の代入????
int &k; k=i; //NG??でもないけど原則だめ(int*にintの値を代入)
/* */ k = &i; //OK ポインタ変数へのアドレスの代入
/* */ i = k; //NG??でもないけど原則だめ(intにint*の代入)
/* */ i = *k; //OK int型にアドレスを参照した値を代入
>>283 0番のプログラムを基本とすると、1番は最適化で0番と同じになると期待すると、ビルドするしないの
切り替えを1文字書き換えで実現できて便利なコーディングスタイルといえる。
2番も機能的には同じだが、コンティニューした場合の挙動が意図した条件にマッチしなくなってくるため
あまり推奨しない。
x^2-5x+6を前進差分を用いたニュートン法で解け、という課題が出題されたんですが error C2064: 302 引数を取り込む関数には評価されません。 と、エラーが出て躓きました。 どこがまずいのかご教授願います。 #include<stdio.h> #include<math.h> main() { double y,yy,x,d,h,e,x1,x0; y=x*x-5*x+6; yy=((x+h)(x+h)-5*(x+h)+6-y)/h; h=0.001; x0=1.0,5.0; e=0.000001; printf("%f %f %f",x,x+h,yy); for(;;) { x1=x-y/yy; d=x1-x; if(fabs(d)<=e)break; } printf("%f\n",x); }
↑コンパイラはVisual C++ 2008 Express Editionです。
yy=((x+h)(x+h)-5*(x+h)+6-y)/h;の)(は)*(だね。
> x0=1.0,5.0; ↑は何?x1の書き忘れでもないだろうが・・・・・必要なきゃ消せば?
x0=1.0,x=5.0; y=x*x-5*x+6; yy=((x+h)(x+h)-5*(x+h)+6-y)/h; h=0.001; って感じかな?xが初期化されてないのに式で使われてるね。
ちょっと気になったんだけど y=x*x-5*x+6; yy=((x+h)(x+h)-5*(x+h)+6-y)/h; この2行は後のループのところで評価されるわけじゃないよ
>>290 初期値を与えないと解けない気がして……
皆さんの意見をもとにいくらか書き直してみましたが、どうにもうまく行きません
#include<stdio.h>
#include<math.h>
main()
{
double y,yy,x,d,h,e,x1,x0;
x0=1.0,5.0;
h=0.001;
e=0.000001;
y=x*x-5*x+6;
yy=((x+h)*(x+h)-5*(x+h)+6-y)/h;
for(;;)
{
x1=x0-y/yy;
d=x1-x0;
if(fabs(d)<=e)break;
y=x*x-5*x+6;
yy=((x+h)*(x+h)-5*(x+h)+6-y)/h;
}
printf("%f\n",x1);
}
'aaa.exe': 'C:\Users\yuma\Documents\Visual Studio 2008\Projects\aaa\Release\aaa.exe' を読み込みました。シンボルが読み込まれました。
'aaa.exe': 'C:\Windows\System32\ntdll.dll' を読み込みました
'aaa.exe': 'C:\Windows\System32\kernel32.dll' を読み込みました
'aaa.exe': 'C:\Windows\winsxs\x86_microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.30729.1_none_e163563597edeada\msvcr90.dll' を読み込みました
スレッド 'Win32 スレッド' (0x3dc) はコード -1073741510 (0xc000013a) で終了しました。
プログラム '[2196] aaa.exe: ネイティブ' はコード -1073741510 (0xc000013a) で終了しました。
x0 = 1.0, 5.0;はx0 = 1.0;と書くのと同じこと。 関数呼出の括弧内以外での式の中に置かれたカンマには、式を複数並べる効果しかない。
if ( A || B ) この場合、Aが真であればBは評価されないことが保障されるのでしょうか
はい
298 :
295 :2009/02/14(土) 20:41:18
>>294 ありがとうございます
その他のみなさんもありがとうございました
解決できるように考えてみます
300 :
デフォルトの名無しさん :2009/02/14(土) 21:12:45
質問です #include <stdio.h> int *sub(void) { int ad; int *p = &ad; return(p); } void main(void) { int *p = NULL; p = sub(); printf("p -> %p",p); } sub関数内のローカル変数のアドレスを取得したいのですが、なぜかmain関数ではNULL値が 表示されてしまうのです。さぁみんなで考えようではありませんか
NULLは表示されないと思うが、やっちゃだめだろw
303 :
デフォルトの名無しさん :2009/02/14(土) 21:23:46
>>302 どこかまずいところがあるんでしょうか。
ポインタのお勉強ということで、思いつきで作ってみました。
で、意図した動作にならないので何がまずかったのか・・。←いまここ
304 :
デフォルトの名無しさん :2009/02/14(土) 21:25:41
>>300 > NULL値が表示され
どこの処理系でだよ? でたらめじゃねえだろうな
つりだろ
>sub関数内のローカル変数のアドレスを取得したいのですが、 ローカル変数のアドレスは、関数から脱出した時点で無効です。諦めましょう。 >なぜかmain関数ではNULL値が表示されてしまうのです。 普通、不定値が表示されると思うけどまぁいいや。 >さぁみんなで考えようではありませんか 釣り?
307 :
デフォルトの名無しさん :2009/02/14(土) 21:35:23
釣りじゃないのに。でも
>>306 の回答で自己解決しました。
関数内で宣言されたローカルはその関数内で有効で、関数を抜けると無効になるんですね。
サンクスです
いや、ローソンで
>釣りじゃないのに。でも
>>306 の回答で自己解決しました。
すげぇ、他人のレスに書いてある回答を読んだだけで自己解決だって言っちゃってるよ。
きっと、他人のプログラムをコピペしても、自作って言い張るんだろうな。
310 :
デフォルトの名無しさん :2009/02/14(土) 21:44:27
サンクスといってるんだから、そのままの意味でとらえられても困る。
解決って、リターン値がNULLになった理由がわからないと解決じゃないだろ。
312 :
デフォルトの名無しさん :2009/02/14(土) 21:48:40
>>311 知りたかったのは、別関数のローカル変数のアドレスを取得できるかということです。
>>293 ビルドエラーになるし ワーニングがでる
それをなくしてから実行すべきだと思う
315 :
デフォルトの名無しさん :2009/02/14(土) 21:55:49
>>313 ローカル変数の頭にstaticをつけることですね!
自分の知りたいことがわかればそれでいいってどういう了見だよって思うけど、 どうせ処理系がどうとか、細かいことは質問に答えられないってレベルだろうし、 どうでもいいか。
サークルKのKって何?
>>315 static つけなくてもいいよ
アドレスを得ることは可能
関数を抜けた時点でそのアドレスに意味が無くなるだけで
>>315 とりあえず「ローカル変数 スタック」でググれ
>>303 なにもまずくないよ。ただしNULLが表示されるのはおかしい。
>>319 ローカル変数 static でぐぐったり
auto 変数とかもぐぐれ
323 :
デフォルトの名無しさん :2009/02/14(土) 23:00:53
>>307 NULL が出たという話はでたらめだったのか、本当なのかはっきりしろ!
自演乙
俺も NULL が表示されたってどういう意味なのすっごい気になる
0
void *sub2(void *arg) { printf("%d", (int)*arg); } sub() { int a = 1; pthread_t tid; pthread_create(&tid, NULL, sub2, (void *)&a); pthread_join(tid); }
error: too few arguments to function ‘pthread_join’
329 :
デフォルトの名無しさん :2009/02/15(日) 00:17:18
>>323 、325
NULLは表示されません。不定値が表示されます。
330 :
デフォルトの名無しさん :2009/02/15(日) 00:20:45
331 :
デフォルトの名無しさん :2009/02/15(日) 00:26:25
>>300 の本人です。
ソース張る前にあちこちいじっていたので、その余分なコードを削除して
貼り付けたのが
>>300 なので、300に掲載されているコードを実行すると不定値が表示されました。
でたらめいってすみませんでした。
332 :
デフォルトの名無しさん :2009/02/15(日) 00:27:57
余分なコードというのは、デバッガ用にprintf関数を入れたやつです。
334 :
デフォルトの名無しさん :2009/02/15(日) 00:30:59
>>333 なるほど。でも意味のないアドレスなので、不正領域へのアクセスになるか。
>>334 >>300 ではポインタの参照先をアクセスしていないので全く問題ない。
アドレスを表示したかったんだろ?不正でも何でもない。完全に正しい動作。
ローカル変数のアドレスとして意味のあった完全に正しいアドレス。
337 :
デフォルトの名無しさん :2009/02/15(日) 00:36:42
>>335 なるほど、参考になりました。
おかげさまでC言語のスキルが0.3upしました。
>>333 実行環境に依って値が変わるわけで
不定値の定義にもよるな
339 :
デフォルトの名無しさん :2009/02/15(日) 01:10:06
>>331 あちこちいじる前には NULL が出ていたのか?
>>338 特定の実行環境でのローカル変数のアドレスを返すことを目的とした特定の関数の実行時のローカル変数の確定したアドレスを返しているわけだから、
仕様通りの完全な値であって、不定値ではない。
パラメータによって戻り値が変わるからと言って、それを不定値とは言わないだろう。
//+2を取得する関数
int get_plus_2(int i) { return i+2; }
//ローカル変数のアドレスを取得する関数
int* get_local_variable_address() { int i; return &i; }
341 :
339 :2009/02/15(日) 01:22:01
おやすみ
>>340 だ・か・ら
不定値の定義もよるだろって言ってんだよ
>>342 じゃあ、君は不定値をどう定義をしたんだ?
私は 想定した値と違う場合が「不定値」と見ている だから 作っている人が何を返してほしいかによる。 よって スタックのアドレスが知りたければ 不定値ではないのでは?
想定した値と違うのは単なるバグであって、不定値はそもそも何も想定されていない値だろう。 3行目には同意。
OSの気分次第だろ
OSの気分次第で決められた不定ではない確定した値
仮想アドレスの値なんてプログラマからしてみれば不定だろ? そういうことだ
アドレスの値が不定だったらプログラムなんて動かないだろ。アホか。
>>348 つまり、お前の世界では
malloc(100);
の戻り値も不定であるということだな。
スタックの確保方法自体知らないんじゃね? 空いたところのどことってくるかわかんないとでも考えてるんだろう
だから定義次第っつってんだろ どこかの規定で正確に不定値の定義が定められてんのか?
>>352 だから、お前の不定値の定義では、malloc()の戻り値も不定値なんだろ。
そんな定義がお前以外に通用するとでも思ってるのか?
>>350 libcの実装次第
つまり不定とも捉えることができる
>>350 仮想アドレスが返ってくることは想定できるが
アドレスの値は不定
>>350 は何が返ってくるのか想定できるの?
日本語わかる? 不定値 不定な値 定まってない値 malloc(100) は毎回固定値が返ってくるの?
不定値ってのは単なる日本語じゃなくてプログラム用語だ。 固定値の反義語じゃない。
>>358 C言語 JIS X3010
3.17.2 不定の値 見規定の値又はトラップ表現
少なくともC言語においては、上記のように定義されている。
まともな意見が出た
スマン。誤字った・・・。 見規定 → 未規定
未規定の値なんて聞くとむしろ変数をイメージしてしまうな
未規定ということは仮想アドレスの値自体は不定の値と言えるんじゃない?
これは流石にぐうの音も出まい
未規定の値という言葉もまた曖昧な気がするが
何々? putc("\a"); -> プー
処理系定義(implementation defined) 詳細を実装が選択する。何を選んだかは文書になっていければならない。 未規定(unspecified) 処理系定義に似ているが、文書にする必要がない。
未規定って耳慣れないんだけど、未定義(undefined)と同じ意味?
未規定ってのは、 その未規定な部分に依存したコードを書かなければ正しいコードになるが、 未規定な部分に依存したコードを書くとどんな動きになるか分からないってものだ。 例えば、 foo(a(), b()); の a() と b() の実行順は未規定。 a() と b() の実行順に依存していないコードは正しいコードだが、 a() と b() の実行順に依存したコードの場合、その実行順がどうなるかは保証されない。
>363 ぜんぜん違う &で得たものにせよ、mallocで帰ってきたものにせよ、 Cの正当な手続きで得られたアドレスは、「固定」ではないが、 正当にアクセスできるメモリのアドレスとして「規定」されたもの 不定というのはそれが何か意味のあるものである保証がないことを言う
未定義: 動作が定義されていない(常に動作が保証されない) 未規定: 場合によって動作が保証されない 処理系定義: 動作は保証されるが、処理系ごとに動作が異なる いささか不正確だが(未定義ってのも、別に処理系が動作を定義することを禁止しているわけじゃないしね)、 大まかに言うとこんな感じ。
>>368 処理系定義は、これは処理系ごとに動作が違うので詳細を確認してくださいねということ
未規定というのは、処理系ごとに動作が違うので推奨しませんよということ
未定義というのは、どんなことが起こっても知りませんよということ
処理系定義: implementation-defined 未規定: unspecified 未定義: undefined
>>371 の話にそれば
>>369 の話は未規定じゃなくて処理系定義じゃないか
実行順が右からか、左からかは処理系で定めてねってK&Rにあった気がする
つまり、
ローカル変数を返したらその値は不定値となるわけだ
>>340 が悪い
値自体はローカル変数のアドレスを示す規定された値でしょ。 関数を抜けると無効になるだけで。
> 関数を抜けると無効になるだけで。 それを不定と呼ぶのでは?
>>379 いいえ。
例えば
>>340 のget_local_variable_addressの戻り値を何度出力しても、get_local_variable_address内で宣言されたローカル変数のアドレス以外の値が出力される事はないでしょう。
指している先が無効なだけであって、アドレス値は不定じゃないでしょ。
処理系定義ではあるけどね。
不定=過去に一度も初期化されてない 無効=過去に初期化されたが、現在は利用不可 ってことかな。利用できないという意味では同じだから 熱く議論することでも無い希ガス
宣言されていたローカル関数のアドレス値としては利用できるんだけどね。
これ以上やるなら
>>378 へどうぞ。寝るけど。
コンパイラが値を保障しないって意味なら、不定でも俺は気にしない。
未定義と不定で混乱するのなら分かるけど、なんだよこのレベルの低さ
>>384 レベルの高いお前様の解説を希望しますよ。
不定値のアドレスを使用しても正しい挙動をするかどうか保障できません。
アドレスを%pで表示するのも?
未初期化のポインタなら未定義動作だ なんで未定義動作になってるのかわからんが、いいじゃん見ても
>>386 お前はポインタを怖がり過ぎ。
>>300 は単にポインタ型の変数の値を表示しているだけ。
何も問題なく正しくローカル変数のアドレスが表示される。
PS2キーボードをUSBに変換して使ってるんですけど、\が入力されなくて困ってる・・・ 結構調べたんだが結局直せなかった。スレ違ですまないですけど誰か対象法知ってたらおしえてください。
漢字変換で「えん」って入力して変換すれば半角でも全角でも入力できるよ。
まあそうなんだが、プログラム書いてるとき半角で入力してるからそうするとかなり面倒だよ… 今はクリップボードに格納して対処してるんだがなんとかならないかな〜?
EXCEL VBAでプログラムに興味を持ち、API以外は不自由なく使えるようになったので、C言語に興味を持ちました。 猫でもわかるC、C言語ポインタ完全制覇、Cプログラミング専門課程を読み一通り理解したので今から色々プログラムを組んで練習しようと思っています。 ただ、C言語はできる事が多すぎて初心者なので何からしていいか悩んでいます。 自分では、猫でもわかるシリーズのWindowsアプリの本を読もうかと思うのですが、どうでしょうか? 何か良いアドバイスがありましたらお願いいたします。
何をしたいかをまず決めろ
何のために?
>>390 言語の設定で英語にするといいよ。記号類の刻印が殆ど役に立たなくなるけど。
つーか、どうみてもスレ違いだから二度と帰ってこないでね。
>>390 \のキーを押しても反応無しって事?
他の文字が代わりに入力されてるとかは無いよね
399 :
デフォルトの名無しさん :2009/02/15(日) 17:27:49
猫でもわかるはお勧めでない。 本読んだこと無いが、WEBみる限りいらない
401 :
デフォルトの名無しさん :2009/02/15(日) 17:35:41
アマゾンのこのレビュと同じような理由。 自分は本は見たことはない。 カスタマーレビュー 猫でもわかるWindowsプログラミング 評価が高くない有用性のあるレビュー 初心者にはオススメしません この本はWin32APIの入門書にもかからわず妙に高度なことが多く書いており 逆に初心者に必要な基礎的な部分の説明はていねいされてるとはまったく思えません。 初心者が意味が分からないままコードを写すことに終始する可能性が高いと思います なので初心者には決してオススメしません むしろ入門を終えた人にオススメしたいです
WINAPIの実用テクニックの参考書としては有用だけど Cの入門書としてはとてもおすすめできない
404 :
デフォルトの名無しさん :2009/02/15(日) 17:39:57
WEBみるかぎりC、C++の部分もいらない。おすすめでない。
>>393 Windowsプログラミングをするなら、C++かC#かVBが無難だよ。
406 :
デフォルトの名無しさん :2009/02/15(日) 17:45:11
猫でもわかるは、必要なときサイトをググって調べ物に使うくらいだな。 本もWEBと一緒だったら初めから読みすすめるのは、効率悪い。
407 :
デフォルトの名無しさん :2009/02/15(日) 17:50:04
通常では、TIPS、小技、サンプルというもので、サイト全体が構成されてる。 猫でもわかるね。学習向けとは思えない。
皆さんありがとうございます。
アドバイスを参考に頑張ってみます。
>>405 ありがとうございます。
いずれC++に移行しようと思っています。しかし、まずは基礎となるCを覚えてからと思っています。
Win32より.NETに行こうよ。C++よりC#に行こうよ。
C#やるにしてもこの質問者はC→C++とやった後からでいいと思うよ
何でわざわざ回り道させるんだろうね。まあ趣味ならいいけど。
412 :
デフォルトの名無しさん :2009/02/15(日) 18:42:47
#include <stdio.h> int main( void ) { int i; char *p; char str[16] = "0123456789abcdef"; p = str; for(i = 0; i < (sizeof(str)) ; i++) { printf("%c",p); p++; } return 0; } これを実行すると、結果は「フヘホマミムメモヤユヨラリルレロ」と 表示されてしまいます。何故ですか?
やりたいことはprintf("%c", * p)かな?
414 :
412 :2009/02/15(日) 18:46:58
<<413さん おお! それでうまくいきました。 ありがとうございました。m(_ _)m
415 :
デフォルトの名無しさん :2009/02/15(日) 19:37:08
>>415 ぴったりの時はコンパイラがよきにはからってくれる
>>415 はぁ?どこにバッファがあって、どうやってするんだよ。
419 :
デフォルトの名無しさん :2009/02/15(日) 19:50:02
>>416 の言っている内容自体は正しいけど話が食い違っている可能性があるということね
本当のところどうなのかは
>>415 がバッファオーバーランをどういうつもりで言ったのかによる
423 :
デフォルトの名無しさん :2009/02/15(日) 19:59:48
char str[16] = "0123456789abcdef"; 文字列の最後にnull文字(\0)が入るんだから、正しくは char str[17] = "0123456789abcdef"; こうすべきじゃないの?
>422 >419から察するに意味としては>416の想像したとおりだったと思われる。 一応貼っておくか |11.22 |質問: |char a[3] = "abc"; は正しいのか。何を意味するのか。 |解答: |ANSI Cでは文法的に正しい(たぶんANSI C成立以前のシステムでも |正しく動くものもあるだろう)。ただし本当に稀な状況でだけ役立つ。 |これは大きさが3の配列を宣言し、中身を'a', 'b', 'c'で初期化する。 |通常の終端記号の'\0'は付かない。よってこの配列はC言語の意味での |文字列ではなく、strcpyやprintfの%sなどでは使えない。 |たいていの場合、配列を初期化するときは、初期化子の個数は |コンパイラに数えさせるべきである。(上の初期化子"abc"の場合は |もちろん計算結果は4になる)。
>>423 べき論で言えば、
char str[16] = "0123456789abcdef";
でも
char str[17] = "0123456789abcdef";
でもなく
char str[] = "0123456789abcdef";
こうすべき。
この例で言えば配列要素を一つずつ出力することが目的なんだから べき論で言うなら char array[]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'}; とすべき
428 :
デフォルトの名無しさん :2009/02/15(日) 20:18:04
>>215 だが、俺もまだまだ勉強が足りないな。出直してきます。
そもそもポインタに代入するなら char *p = "略"; for (;*p; p++) 略 でいいだろが
またそうやって初心者に間違った知識を誘導させる
初歩的な質問で恐縮ですが回答お願いいたします。 #include<stdio.h> main() { char a[10]; strcpy(a,"imagine"); printf("%s",a); } ↑のソースコードで何故かstrcpyが未定義の関数扱いされてします。 これは何が原因なのでしょうか?
#include <string.h>
strcpyでヘッダファイル検索しろ
434 :
デフォルトの名無しさん :2009/02/15(日) 20:33:08
>>431 strcpy関数は標準ライブラリstringというヘッダファイルに定義されているので、
ファイルの冒頭に「#include <string.h>」を追加する必要がある。
C言語の標準ライブラリの本がこの前生協にあったからかってこよっと顏
すみません。非常に初歩的な質問ですが visual studio 2008 コマンドプロンプトでcファイルをコンパイルしようとすると LINK : fatal error LINK1104: ファイル 'C:\DOCUME~1\(ユーザー名)'を開くことができません。 と表示されcファイルの保存場所にはobjファイルだけが出来上がってる状態になります。 cファイルの保存場所はまったく別の場所なのにC:\DOCUMENT〜〜を開こうと知るのかもわかりません 問題点をご指摘ください またスレ違いでしたら誘導していただければ助かります
そのcファイルはどこに置いてますか?
8桁の2進数を与えられたときの下2桁を少数として10進数に変換した値を求めなさい。 という問題が出されたのですが、 整数部分を10進数にするのは、簡単なのですが、少数部分の2進数→10進数を どのように求めればよいか、わかりません><; ググっても10進数→2進数の小数点の求め方しか出てこないので困っております・・・ もし、お分かりの方がおられましたら、ご指導お願いします>< もしくは、解説されているHPがあれば教えていただければ光栄です。 スレ違いだったら申し訳ありません><;
>>440 スレ違いどころか鼬害。寧ろ何故ここで聞こうと思ったのか知りたいくらい。
まぁ、整数と見做して変換してから適当に割ればいいだけだけどね。
2進数で下2桁なら4倍して整数にしてそれを10進に変換して最後に4で割ればいい
>>437 どういうコマンド打ったかくらい書けっつーかVSのスレで聞け
>>443 >どういうコマンド打ったか
#include<stdio.h>
int main(void)
{
printf("テスト\n");
return 0;
}
すらコンパイルできませんでした
>VSのスレで聞け
すみませんでした。VSスレで聞いてみます
ありがとうございました
b5 b4 b3 b2 . b1 b0
なら
b5*8 + b4*4 + b3*2 + b2*1 + b1*(1/2) + b0*(1/4)
>>442 でももちろんいい
gdbやDOSのコマンドプロンプト見たいに. 消せないバナー表示がある,標準入出力からの入力ってどうやって実現するの? c:> ← これね backspaceをマスクしてるのかな?
>>447 DOSのコマンドプロンプト見たいな事をやりたいのよ.コマンド入力して結果を表示する流れ.
DOSのプロンプトの場合,左側にC:\>見たいなバナーが表示されているじゃないですか?
そしてこの表示だけは,ユーザがいくらDeleteキー押してもBackspaceを押しても消せない
じゃないですか?
これを実現したい.
batの頭で @echo off のことか?
そういうのはWin32 APIとか各環境で色々用意されている関数群で実現できるはず。
>>448 #include <stdio.h>
int main(void)
{
char buf[100+1];
printf("私をバックスペースで消してみろw");
scanf("%100s", buf);
return 0;
}
for(;;){ printf("C:\>"); fflush(stdout); scanf(); 処理 } こういう事か?
プロンプト消去したいんじゃね?
>>453 いや、自分のCUIプログラムでプロンプトを表示させたいってことじゃね?
455 :
448 :2009/02/15(日) 22:09:57
みなさんどうも. そうだ...こういうのは環境依存なんだなきっと. Linuxでやりたいんだが...
>>455 ncursesとかでググって見たらどうよ?
>>456 なんか牛刀な感じがするんですよね...ncurses使うのは...
やっぱそれしか手はないのかぁ
>>455 DOSの場合はファンクションコールの一行入力を使っている。
>>458 バックスペース押したら消える、ってコードで既にncursesが要るんじゃないか?
あとはターミナルが対応してるならエスケープシーケンス(だっけ?)でも出来るかも。
こっちはあんま遣ったこと無いからよく知らない。
厄介な割にはたいした効果がない。 普通にGUIで作ったら?
telnetで使えないだろ。
telnetなんて危険なものを使うなんてどうかしている。
じゃSSHで 中身云々が問題になるんなら生のtelnetはつかわんだろし
普通X。
sshで使えないだろ。
Linuxでbashライクのが欲しいなら、libreadlineを使えばいいよ。
VT100で使えないだろ。
まずはgnu readlineをすすめるべきだろ
回線切れるからscreen 必須なんだよ ssh -Xとかやってらんねーよ
よそでやれ
476 :
デフォルトの名無しさん :2009/02/16(月) 11:13:14
2次元配列のキャストとかがわかんないです。 ここでつまずく。
>>476 配列を[ ]してみたら、そこはまだ配列だった。というのがCの2次元配列
479 :
デフォルトの名無しさん :2009/02/16(月) 12:58:27
> 配列を指し示すポインタの配列 アホ
>>479 何か不満か?文句はANSIルールブック作った奴に言ってくれ
配列の配列もあるし、普通は配列の先頭を指し示すポインタの配列を使う
>>480 いや、いくらなんでも「配列を指し示すポインタの配列」というのは有り得ない。
484 :
476 :2009/02/16(月) 14:31:59
float balance[10][5]; float *p; p=(float *) balance; でbalance[3][1]にアクセスする場合なんですが *(p+(3*5)+1) なんですが。 キャストすることなんですが、何故キャストするんでしょうか? 2次元っていっても(3*5)これ1次元ですよね? (3*5)って言う場所がbalance[3]なんですか? +1がbalance[1]ですか? 詳しく教えてください キャストする理由など
485 :
476 :2009/02/16(月) 14:33:23
(3*5)っていうのは15で balance[10][5]; これで 12345 12345 12345これをたすと15で[3]の位置ですよね?? キャストの理由なども
このスレ時々のぞいて見ると、教えるほうも初心者で笑える。 char array[SIZE]; //配列 char (*ptr)[SIZE]; //配列を指し示すポインタ char (*ptr[SIZE2])[SIZE]; //配列を指し示すポインタの配列
>>486 では char array[SIZE][SIZE]; は?
>>483 配列の配列と言えば十分。
例えば、484のbalanceなら、メモリ上では10 * 5 == 50個のfloatオブジェクトがびっしり並んで配置されている。
それなのに、ポインタの配列と言うのは違和感を拭えない。
>>484 それは二次元配列を一次元配列に変換してるようなものだ
(別に問題は無いが)
float balance[10][5];
float (*p)[5];
p= balance;
というのがある
>488 ×ポインタの配列 ○配列を指し示すポインタの配列
てゆうか、みんなルールブックとか読まないの?(´・ω・`) そう記述されているから、違和感があるといわれてオレに突っ込まれても困る
そもそも488はポインタの意味が分かってないだろ
>>491 不適切な表現や訳を当てにするのかお前は
>>484 ちゃんとした日本語を話せるようになってから出なおしてきなさい
主語を省くな
>>484 キャストするほかに、p = &balance[0][0];とする方法もあるが、結果的には同じこと。
やりたいことは、489の言うように1次元配列のようにしたいということ。
多次元配列の要素はすべて連続して置かれており、
*(p + 4)で、balance[0][4]にアクセスでき、
*(p + 5)で、balance[1][0]にアクセスできる。
ちょうど、*(p+(i*5)+j)がbalance[i][j]に相当するので、
基の2次元配列を意識してそういう書き方をすることがある。
どちらかというと、逆に1次元配列を多次元配列として扱いたい場合によく使う。
俺は
>>492 がどのくらいわかってるのか興味がある
>483 >481
>>491 JIS X 3010を見たがchar array[SIZE][SIZE]などといったものを
「配列を指し示すポインタの配列」と称している個所は見つけられなかったぞ。
>>477 ざっと流し読んだけどそこの作者は微妙に勘違いしてる節があるので参考にするのはやめたほうがいい
500 :
486 :2009/02/16(月) 15:08:24
よくわかってないのに、わかった振りして教えたりしなきゃいいのにね。 まあ世の中の「Cできます」とかほざく奴の90%くらいはこの程度の理解な訳だが。
>>500 では先生、良く分かる解説をお願いします。
>>501 きみの知ったかがどのレス番号なのか教えてくれれば、間違いを指摘してやってもいいが。
type x[ ][]と宣言されているtype型の(配列)変数xに対し &x[0]がtype* へのポインタ値であると解釈するかどうかは 処理系依存 でおk?
>>503 間違っている。
x[0]はtype型の配列であり、配列へ&演算子を作用させた結果は配列へのポインタであるから、
&x[0]はtype (*)[]でなければならない。
>>503 違う。少なくともANSI以降、type x[m][n]とあったら、
&x[0]はtype [n]へのポインタ型。type (*)[n]と書く。
なんか、恐ろしく低レベルな言い争いをしているような気が…
Cの多次元配列は実装が先立ったこじつけ理論だから、 処理系作る人間でもない限り理解しなくてもいい事だよ。 なんせその処理系作る側の人間ですら判りにくくて使わないからだ。 配列のポインタ云々は関数引数に受け渡す時しか出てくる機会がない。 保守性を考えればそこは素直に構造体でも使うべきだ。
ここまで読みましたが良く分からないので 1次元配列だけ使うことにします><;
>処理系作る人間でもない限り理解しなくてもいい事だよ。 配列の配列を使う以上は理解してないとトラブルのもとだ
お前らそんなにイライラしてストレスでも溜まってるのか?
511 :
476 :2009/02/16(月) 17:53:33
2次元配列を1元配列にするっていうのはわかりましたが。 何故キャストするんですか? p=(float *) balance;
balanceは"float[n]へのポインタ型"だから
513 :
476 :2009/02/16(月) 17:58:28
balanceこれは何も指定してないので、ポインタってことですよね? 配列では名前だけだとポインタなどと書いてあって。 pにbalanceの先頭ポインタを代入して、何故float *という意味深な物でキャストするんですか? balanceはfloatで宣言してあるんですが。 float balance[10]5] 何故またfloat *という物でキャストするんでしょう。 本には全然詳しく書かれて無く 上記の例ではbalanceをfloat *にキャストする必要がありました。配列要素を手作業で指定する都合上、ポインタ演算を floatポインタに基づいて行わなければなりません。しかし、balanceによって生産されるポインタの型はfloatの2次元配列です。 そこでキャストが必要になるわけです。 と書いてありました。
>上記の例ではbalanceをfloat *にキャストする必要がありました。配列要素を手作業で指定する都合上、ポインタ演算を >floatポインタに基づいて行わなければなりません。しかし、balanceによって生産されるポインタの型はfloatの2次元配列です。 >そこでキャストが必要になるわけです。 この部分は忘れろ
balanceだけだと"float[n]へのポインタ型"になるのよ。floatじゃないの つまり、メモリ的にはbalance[0][0]を指すんだけど、balance++とかのポインタ演算した時に balance[1][0]を指してしまうの balance++でbalance[0][1]を指したいなら、キャストするしかない
>>515 そんな説明で初心者にわかるかぼけ
balanceの型はfloat(*)[5]
これをfloat*に代入するから型が合わない
だからキャストしている
これで充分だろ
>>515 はわかりやすいと思うけどな。
これがわからないのならまだ質問できるレベルにもない。
518 :
476 :2009/02/16(月) 18:15:28
難しいですね。 私が知ってるのは int *p int i=10; p=&a; *p=20; など int ar[5]; int *p; p=ar; printf *p printf *(p+2); (*p)++; などデクリメントやインクリメント、1次元配列まで知ってますが。 どうもここでつまずくんですよ float[n]とかでてきても、よくわかりません。 balance[1][0]を目指すってことは[2][0] [3][0]などを目指し右の値を換えれないなどはわかりますが。 balanceはfloat[n]へのポインタ型など用語がむずかしいです 噛み砕いて教えてくれませんか?
519 :
516 :2009/02/16(月) 18:19:54
な、言ったとおりだろ
アセンブラレベルで追えば何してるか理解できるよ
521 :
デフォルトの名無しさん :2009/02/16(月) 18:23:03
質問できるレベル笑()
全ての元凶は
>>477-478 だな
int i[5][5]; と
int* i[5];
を混ぜてるだろ。
ここでは端的な説明しかしないから、一度ポインタの解説本で勉強してみれば?
総合的にみて、C又は、C解説本で1番イイとおもうやつは? (初心者向きかどうかではなく また、『支持高いけど、あれってどうよ?』ってやつは? 理由含めて。 K&R買おうか迷ってる。独習はなくてもいいよな
「C言語ポインタ完全制覇」って本が良いとおもふ・・・。
527 :
515 :2009/02/16(月) 18:52:20
私の説明が悪いのだろうか…w "float[n]へのポインタ型"とは、nこのfloatをまとめたものを指すポインタ 具体的に言うと、balance[0][0]からbalance[0][n-1]までのメモリ領域を指していると考える だから、balance++などをすると次のbalance[0][n]からbalance[0][2n-1]までを指すことになる この領域の先頭はbalance[1][0]に等しく、この領域の最後がbalance[1][n-1]に等しいの。 なんか書いてて、これは理解できないと思い始めてきた この辺は図に書いて説明するとすぐわかるんだけどな どんな本で勉強しているのかな?良かったら教えて欲しいんだけど
独学C
>>517 =515
自画自賛かよ
説明もさっぱりわからん
530 :
476 :2009/02/16(月) 19:22:04
527さん 独習C第3版とやさしいCとC言語体当たり学習徹底入門で勉強しています
そもそもなんでわざわざ配列の配列を配列に直して扱おうとしてるのかわからん
CプログラミングFAQを読むのがたぶん一番確実
>>476 まず、配列についてのもっとも基礎的な知識として、以下のことを記憶すること。
1) 配列とは、その要素となるある特定の型のオブジェクトが、連続したメモリ上に一定の個数並べられたものである。
2) 配列は、3つの例外を除いて、「その先頭の要素を指すポインタ値」に意味が格下げになる。
3つの例外とは、&演算子を作用させたとき(配列全体へのポインタ値が得られる)、sizeofを作用させたとき(配列全体の大きさが得られる)、charの配列を文字列定数で初期化するとき、を指す。
次に、以下のことを理解すること。
A) 1)に言う「要素」は、大きさの明らかなオブジェクトならば何でもよい。つまり、配列であってもよいし、配列の配列であってもよい。
B) 2)の格下げが起こることにより、配列に[]演算子を作用させることができる。[]演算子はポインタに作用する演算子で、たとえばpがポインタでnが整数であるとき、p[n]は*(p+n)と同じ意味になる。
C) 2)により、たとえば「intの配列の配列」が「intへのポインタ値」や「intへのポインタへのポインタ値」に格下げされると考えるのは勘違いである。「配列の配列」は「配列へのポインタ値」に格下げされる。
それでもまだ理解できないことがあれば、論点を整理して質問すること。
>>524 コンピュータの基礎的なアーキテクチャを理解してるなら、K&Rは良い本だ。
独習はどうでもええよ
>>534 自信を持ってアーキテクチャーなら俺に任せてくれって奴がこのスレに何人いることやら・・・
536 :
476 :2009/02/17(火) 00:01:32
3冊読んでp=(float *) balance;の意味みたいな 配列をキャストする内容など書かれてないし キャストする意味が分からないし、ここでの説明も難しいんですが。 (float *)の意味をききたいんですが脱線してるきがするんですが。 すごい噛み砕いて教えてくれるとうれしいです
>>536 > (float *)の意味をききたいんですが脱線してるきがするんですが。
floatを指すポインタにキャストする。
>>536 balance[10][5];とあったとき、
float *p;
p = (float *)balance;
とすると、pを通してあたかも[0]から[49]まである要素数50の配列と見なして扱える。
実体はbalanceの各要素に対応付けられているんだけど。
なんでそこにキャストが要るのかと言うと、本来2次元配列であるものを1次元であるかのように扱うため、
コンパイラは、親切にも警告・エラーを出そうとするため。
しかし、こっちは意図的にやろうとしており、キャストを書くことでその意思をコンパイラに示すことになる。
>>536 知らんがな。
>>484 のコードだけでは特にポインタにキャストしてから
変数を扱うことに意味は無い。
あえて言えば、配列とポインタの関係とポインタの使い方を
学習するためにキャストしているように見える。
配列をポインタにキャストして使う必要があるケースは
実際のコードでは殆ど無い。
と、こういう意味での「意味」では無い?
→がよく分からんが、多分想像していることは合ってるように思う
ポインタだから→の方向間違いだな(´ω`)‥トホー
しかし、実際問題実用的なプログラム作るときに、2次元以上の配列を使う機会ってどれくらいあるんだろう。 縦横固定で問題のないケースって行列演算くらいしか思い付かない。(少なくとも俺は使ったことがない) 構造体で幅と高さ持たせて、1次元配列上の位置を計算で求めるのはよくあるけど。
>>543 多次元配列はCのネックの部分だから、小さなものでない限り
実用では使わないでしょう。
配列群を整理して締まっておける配列 を次々重ねると超多元配列 出現
>>543 行列もFortran形式にしたりするから多次元配列はめったに使わないな
ボードゲームのシミュレートとかでやりそうなくらいか
argv
549 :
デフォルトの名無しさん :2009/02/17(火) 03:05:32
C言語を今から勉強したいんですけど、初心者にお勧めの参考書ってありますか?
>>549 他のコンピュータ言語でプログラムを組めますか?
それともコンピュータ言語は初めてですか?
>>549 もしもプログラミングそのものの初心者でないならK&R一択だが
まあそんなことはないだろうから「どれを使ってもそれほど大した差はない」と言っておく
むしろ絶対に必要だと思うのは、全部を修了したあとでK&RかCFAQを読んでおくこと
c言語はじめるなら、このサイトがかなり無難な域に入ってると思う。 質問掲示板も良質だし。
初心者のためのポイント学習C言語
http://www9.plala.or.jp/sgwr-t/ とりあえず、サイト知識で、プログラム打ってみて、
『ポインタってなんだ?』『〜〜ってなんだ?』という疑問が生まれるくらい上達したら好きな参考書勝ったほうがいいと思う。
触ったことない人が、選ぶのと上記ぐらいで選ぶのでは、雲泥の差がある。
>ということで、今後もscanfもgetsも使いますが、ご了承ください。 ダメだこりゃ。
また教書でのgets議論が再燃するのかな?かな?
>>553 >これには賛成。エピステーメーが常駐していて、しっかりやる気を殺いでくれる。
試しに開いたトピに、
>それだけで理解できるとお思いですか?
といきなり書かれてて笑った。
慇懃無礼で2chより酷いな。
ここの方が自浄作用が働く分ましかもしれない。 %xのトピックもかなり酷いよ。 で、このサイトも%gを取り扱ってくれない。初心者には%fより使い勝手がいいと思うのだけど。 # まぁ、どうせ%.10sなんかもないしね。
>>557 >慇懃無礼で2chよりひどいな。
慇懃無礼ねぇ。。。。くすくす
560 :
549 :2009/02/17(火) 05:18:22
>>549 初心者の人には、書物の善し悪しなどわかりませんので
出来るだけたくさんの本を買いましょう。すでにC言語が世に
知れてから既に20年近い歳月が流れており、この間に
出版されたC言語の文法書、準文法書は膨大な数になります。
絶版になった本はプレミアがついてオークションでは実に
高価になっています。それだけでも買う価値があるのでは
ないでしょうか?
ありません
何か1人変な奴が湧いてるな
自己紹介乙
566 :
476 :2009/02/17(火) 10:28:10
538さんの説明で少しわかりました。 (float *)は2次元を1次元に扱うっていう意味でわかりました 539さんの 配列をポインタにキャストして使う必要があるケースは 実際のコードでは殆ど無い ポインタっていうのはアドレスを格納するものと覚えてるんですが 配列をポインタにキャストするとbalance[10][5]のアドレスが float *p; pのなかに&balance[0]]0] &balance[0][1] &balance[0][2]〜&balance[10][5] って感じで入るんですよね? p=balanceで 名前だけど先頭の要素を表すので balanceとやると全部のアドレスが代入されるって意味ですよね?
まずは1次元配列がわかってから手を出してはどうか
568 :
476 :2009/02/17(火) 10:41:13
1次元配列はわかっています int array[10]; array[0]; array[1]; array[2]; array[3]; array[4]; 〜〜 array[9];
int* p = (int *)array; ここから先は?
570 :
476 :2009/02/17(火) 10:45:53
int* pはint *pと同じで 1次元配列なので(int *)しないです
572 :
476 :2009/02/17(火) 10:54:35
566のは2次元配列だから[10][5]これを1次元になおすと 10*5で[50]の配列になるとおもいます
全部のアドレスが代入って意味わからん
初心者は想像を絶する実装を勝手にイメージしてることがあるから始末に負えない
575 :
デフォルトの名無しさん :2009/02/17(火) 12:27:08
for (j = 0;j < 8;j++) { tt=((0xff&(2^j))>>j); //あるビットを調べてるつもり ttはunsigned char、 if (tt==0) printf("0です"); else if (tt==1) printf("1です"); else printf("0でも1でもない"); } これだと0xff(11111111)だから「1です」が8回表示されると 思うんですが0でも1でもないも出ます。 どこがおかしいんでしょう?
まずはttも表示させてみてはどうか。
578 :
デフォルトの名無しさん :2009/02/17(火) 12:46:29
2^jじゃなくて1<<tだろ。
2^jてのは、2のj乗じゃありません。XOR。
だから
2^0
>>0 = 2
580 :
赤西仁 :2009/02/17(火) 14:44:44
アークザラッドUというタイトルのゲームの、ゲーム画像(歩行画像など)を抽出したいのですが、 かれこれ1年ほど経ちますが、なかなかうまくいきません。 *もちろん抽出した画像は個人範囲内で利用するつもりです。 ◆試してダメだったこと ネット上からダウンロードできる、ありとあらゆる抽出系ツールを試した。 (ちなみに他のゲームはほとんど抽出可能) ◆教わったこと ・アークザラッドUは独自の画像形式を使っているから抽出できない。 ・PS上で表示されてるということは絶対に摘出はできるはず。 ◆抽出は不可能ではないということを知ったとき 2ちゃんねるで質問したところ、 ある方が実際にキャラクターの歩行画像を抽出して 私が立てたスレにアップしてくださいました。 どうか皆さん、お力をお貸しください。
>>581 だまされちゃいけませんよ。
あいつ(
>>580 )は赤西を名乗るルパンだー
14:44:44を奪われたんだよ。
200年考えてもだめだったので、1億年と二千年くらい牢に入れときましょう
533見ても理解できないよ
間違っているものを幾ら理解しろと言われてモナー
586 :
476 :2009/02/17(火) 17:30:59
515さんのを見てたらわかってきたきがするんですが
http://www.e-chishiki.com/jpn/articles/programming_languages/c/arrays/pointers_and_2_dimensional_arrays ここのサイトの配列でちょっとわかってきて
ポインタpにbalanceを代入しないでbalanceのままつかうと
* (balance[2] + 1 )でアクセスできるのをしりました ですが1次元配列みたいに使うと*(*(balance+2))でアクセスできました
だけど p=(float *)balance;とp=&balance[0][0]は同じ事を知りました。
ですが なぜp=balanceではダメなのか balance(配列の名前 先頭の[0][0]を表す)と書いてあり
p=&balance[0][0]とp=balanceは同じなんですが
それとfloat[n]がまだ実感わかずfloat[n]っていうのは*(balance[1]+1)でしょうか?
*(balance[1]+1)はbalanceをpに代入せずそのまま使ったらこんな感じになりました。
たしかにインクリメントしたらbalance[10][5]の[10の方がインクリメントされて右の[5]のほうは+1や+2で指定しないと値を表示できませんでした
もしかするとfloat[n]っていうのはbalance[10][5]でいう balance[10]ってことでいいんでしょうか???
日本語でOK
588 :
476 :2009/02/17(火) 18:43:07
そんなことよりも先ず、小さいものでいいからプログラムを書くことです。
配列は配列。ポインタはポインタ。 両者は似ているようで別物。配列がポインタ演算上連続した 領域に割り当てられるというのは処理系依存な話。 従って配列をポインタと同一視出来るか、あるいはポインタ値への ポインタと同一視出来るかどうかも処理系依存。 大抵のC処理系ではそれが可能だが、決まっているわけではない、 仮に決められているとしても、その規約が将来に渡って守られる 保証すらない。
巨大ファイルを少しづつ処理するのに便利な機能ってない? 読み込みサイズと位置を指定してループさせてるけど冗長な気がする。
>>590 e[f]は*(e+f)と定義されているのだから、一般にそれは有り得ない話だ。
二次元配列balanceを一次元として扱うのが気持ち悪いという主張の下でなら分かるが。
>>591 単純に頭から順番に読み取るだけなら、位置していなんていらないと思うが。
>配列がポインタ演算上連続した領域に割り当てられるというのは処理系依存な話。 超ダウト。配列要素へのアクセスは常にポインタによって行われるのだから ポインタ演算上連続した領域であることは自明。
>>591 具体的に何をやりたいのかがいまいちよくわからんが、
今のOSならファイルアクセスも効率的にやってくれるので
ファイルがでかいかどうかなんか気にする必要はない
開いて読んで閉じるだけ
596 :
デフォルトの名無しさん :2009/02/17(火) 20:08:05
真性アフォの世話乙
ん?ANSIいくつか知らないけど、全くパディング発生しないか?
>>597 発生したらポインタでリニアにアクセスできないだろ、構造体じゃあるまいし
もし
>>598 の言っている意味なら、「配列がポインタ演算上〜」という言い方がおかしい
「多重配列がその要素配列の要素へのポインタ演算上〜」と言わなきゃ意味が通らない
>>599 40年位前だが、現実として奇数番地へのアクセスでエラーになるアーキテクチャはあっただろ。
だが単純なポインタ操作では、コンパイラがよきに計らってくれた気がする。
どちらにしても、将来に渡って保障されるものなど、何もない。
変な使い方をしない限りコンパイラが良きにはからってくれるなら、規格合致だろ。保証の範囲内。 無理なキャストをしたら、そのあとアクセスできなかろうが 処理系定義・未定義の事項に触れているはずだから問題ない。
ここって、新人を2年目の先輩が指導してる感じだね。
さすが、入社5年目で副部長職の
>>602 様は、言うことが違う。
40年って何だよ 24年前にあっただろうがよ
605 :
476 :2009/02/17(火) 22:19:45
#include <stdio.h> int main(void) { int k[4][2]={ {30,40}, {50,60}, {70,80}, {90,100} }; int *p; p=(int *)k; /* p=k[0]か p=&k[0][0]*/これでもできることが判明しました printf("%d\n",*(p+1)); return 0; } たぶんp=k[0];にするとpがk[0]って感じになり p[1]とやると k[0][1]みたいな感じになりました 先ほどキャストをしらべてたら アドレスをあわせるっていうことで kのまま使うとk[0][0] k[1][0] k[2][0]って左の配列だけ繰り上がるので (int *)にすると4バイトずつ繰り上がるのでk[0][0] k[0][1] k[0][2]ってかんじになるんですか? キャストすることによって4バイトずつくりあがる? キャストをしないと左の配列だけがint[n]っていうのは左の配列のことですよね?
「ポインタ」という「アドレスを格納する型」があると思ってるんじゃないだろうか……。 「int *」と「double *」が違う型であるのと同様に「float *」と「float (*)[5]」は違う型である、というのが理解できていない気がする。
void*
608 :
476 :2009/02/17(火) 23:00:21
独習Cにfloat (*)[5]などでてきてないのでさっぱりです float *はfloatの変数を入れられる? float (*)[5];は配列の balance[10][5]の[10]の部分を代入できる? いきなり独習Cでキャストがでてきて意味が分かりませんでした 検索したらbalanceのキャストでつまずいてる人けっこういたので
まず重要なルール 「Tの配列」という型のオブジェクト(変数など)は、「Tへのポインタ」型に変換できる。 float a[5]; aはfloatの配列(要素数5)なので、floatへのポインタ、即ちfloat*型へ変換できる。 float balance[10][5]; balanceは「floatの配列(要素数5)」の配列(要素数10)なので、 「floatの配列(要素数5)」へのポインタ、float (*)[5]型へ変換できる。
610 :
476 :2009/02/17(火) 23:24:54
ほ! float *型はfloat *p;のことで float i;などの 変数のメモリアドレスを格納できる p=&i それで2次元配列はfloat balance[10][5]; float (*p)[5]; p=balanceってことでいいんですか?
まずポインタがよくわかってないのに配列をやると大抵混乱する
613 :
デフォルトの名無しさん :2009/02/17(火) 23:42:01
>>610 2行目と3行目に繋がりを感じないが、まあ間違ってはいない。
615 :
476 :2009/02/17(火) 23:46:28
じゃあどうすれば良いか教えてください みなさんの考えた得とく方法で教えてください キャストの意味などその(*p)の意味などわかるまでの問題を出して教えてください本当おねがいします
>>615 お前のように日本語が怪しい人間にいくら教えても
お前が本当に理解したかどうかこっちが確認できないんだよ
C言語で書かれたオープンソースコードで、これは読んでおいた方が良いよというのはありますでしょうか?
618 :
デフォルトの名無しさん :2009/02/17(火) 23:53:43
linux kernel source
できれば1〜2万行以内のプログラムでお願いします。
>615 問1 ポインタとは何か説明せよ
621 :
デフォルトの名無しさん :2009/02/18(水) 00:07:07
Declaration of pointers and arrays is quite confusing in C. Asterisk(*) is interpreted by the compiler as part of attributes of variables when you're declaring them, whereas it is seen as part of type names when you're casting types. The same rule holds true of arrays. If I were to redesign C, I would change this rule and the operators priority so that you can declare like: int[3] a; // corresponding to int a[3]; of normal C; int* p; //int *p; (int* p is OK in C too, but * is connected to p, not int.) p = a; // you can cast implicitly. (int[4])[3] b; //int b[3][4]; (int[4])* q; //int (*q)[4]; q = b; // you can! (Compare with above) This conversion might help you understand ointers and arrays in C.
おいんたーしたらあかんえ
623 :
476 :2009/02/18(水) 00:15:16
620さん ポインタとは変数などのメモリアドレスを格納するものです intは4バイト charは1バイト floatは4バイト doubleは8バイト 32bitパソコンの場合です インクリメントするとintのポインタだと4メモリアドレスがくりあがります
624 :
デフォルトの名無しさん :2009/02/18(水) 00:18:26
>>623 char型のポインタ変数(char *p)のサイズは何バイトですか?
32bitパソコンならポインタは常に4バイトだわさ
その間違った知識を捨てて来い
627 :
デフォルトの名無しさん :2009/02/18(水) 00:19:36
('A`;;)
629 :
476 :2009/02/18(水) 00:20:59
ポインタは全て4バイトだと書いてありました ちなみに&xでメモリアドレスを習得 *xでそのメモリアドレスにある値を出力します 次の質問お願いします
476は今はどこにひっかかっとるん? キャストすんのは型が違うからゆーのは理解したん?
>ちなみに&xでメモリアドレスを習得 *xでそのメモリアドレスにある値を出力します ちがうよ
>ちなみに&xでメモリアドレスを習得 *xでそのメモリアドレスにある値を出力します ん? じゃあ x は?
どの本にそんな事が書かれてるんだ
連続突っ込みワロタ
>ポインタは全て4バイトだと書いてありました その本は間違っている。 32ビット環境なら大抵は4バイトだが、保障されているわけではない。 ポインタのサイズが必要なときはsizeofを使って取得すること。
636 :
476 :2009/02/18(水) 00:25:28
今わからないのは (*p)[5]と(float *)balanceをやったら balanceはどうなるかなど こういう細かいのが独習CややさしいCや体当たりC言語に書いてないので しょうじきむかついてです
637 :
476 :2009/02/18(水) 00:28:00
いまのは630さんにいました 631さん632さん xは int i=10; int *x; x=&i;これでメモリアドレスをとります printf("%d",*x);でxの値をだします
母国に帰れ。
>printf("%d",*x);でxの値をだします ち が う よ
>>636 そこはまだ君には早いのでまずポインタを学習しなおしなさい
でも最初はポインタ難しいよなー 慣れてくると常識になってくるんだが。 わかる、わかるぞその気もち、476よ!
どうなるかwwwwwwww
643 :
476 :2009/02/18(水) 00:33:00
ポインタについて沢山調べました (*p)[5]や(float *)などがあまりのってなく 他の事ばっかりのててむかつきます 640さん 641さん お願いです教えてください 一次元配列の代入ならわかってます int a[10]: int *p; int p=a &aでもなくていいです a(名前)は先頭のアドレスをあらわします 一次元までわかってるんです どうすれば良いですか本当に?
ポインタを理解できないうちは、 char *A = "hogehoge"; とか平気にやってエラーを出して悩むんだよ。 だが最初は悩んで悩み抜いて理解にたどり着く努力をするしかない。 いずれ自分の財産となる。
>一次元までわかってるんです いいや、絶対にわかってないね その例で&aと書いたら何になるか答えられるか?
621はスルーなんかねぇ
647 :
641 :2009/02/18(水) 00:35:57
>>643 最初の方読んでないので、かいつまんで何がわからないのかダイジェストでまとめてほしい。
本1冊まるまるポインタを解説してる本があるから買えば?
649 :
476 :2009/02/18(水) 00:37:14
&aだとa[0]だと思います もう教えてください どうすれば(*p)[5]と(float *)までたどり着けるか教えてください 脳みそ取り替えたいくらいです 脳みそ取り替えてください本当に
エキスパートCプログラミングとかどうだ?
デバッガの使い方を覚える。 アドレスの概念を理解する。 この辺がうまいことできればすぐだと思うが。
ノ味噌とり替えたら俺がお前でお前が俺で、結局お前が悩むんじゃね?
質問です 1.関数外で定義された変数 例えばint NNN; 2.関数外でstaticで定義された変数 static int MMM; 3.ヘッダでextern宣言され関数外で定義された変数 int LLL; の違いがわかりません。スコープの範囲と、扱っているメモリについて教えてください。
654 :
476 :2009/02/18(水) 00:42:47
641さん よくある本の最初に書いてあるポインタくらいならわかります int x; printf("%p",&x);など 一次元配列のポインタなどわかります ですがある日突然 float balance[10][5]; float *p; p=(float *) balance; *(p+(3+5)+1)という最悪のパターンにであいました 独習Cですんなりいってたんですが165ページという最悪のページでモヤモヤが一気にでしました キャストは前のページにでてきて doubleをint型に変換する簡単なものでした double i=100.2; printf("%d",(int)i);みたいな簡単なキャスト ですがポインタのキャストという説明も無くそんなのがでました (float *)という意味深な物が とまどいました 調べました よくわかりません float[n]とかいわれてもわかりません nっていうのはfloat[1]とかfloat[2]ですか? さっぱりわかりません脳みそとりかえたいくらいです 助けてください
>>654 > nっていうのはfloat[1]とかfloat[2]
そういうこと。1とか2とかって書くのがだるいからnで一括させているだけのこと。
656 :
476 :2009/02/18(水) 00:46:14
わけもなく(float *)とでてきてむかつきます 一次元配列ではキャストしません そのままp=balanceって言う感じです モヤモヤするかぎり夜更かししてしまいます 夜遅くまで悩み続けて寿命がちじまります 助けてください 独習Cとかかって最悪です。やさしいCにも(*p)[5]の意味も書いてありません ポインタのキャストの理由を書かない本です3冊とも どなたかわかりやすくまとめてください
WORD型の変数をBOOL型に型変換することがなぜ可能なのか、誰か教えて下さい。 2以上の値はどこにいったの? オールオアナッシングなの?
658 :
デフォルトの名無しさん :2009/02/18(水) 00:56:46
>>649 ほら間違ってる
もう一度ポインタとただの配列を勉強しなおすまでそのbalanceとやらから目を離せ
660 :
デフォルトの名無しさん :2009/02/18(水) 00:57:33
>>656 この問題分かるか?ポインタがきちんと理解できていれば分かるだろう。
long x;
short y[5] = {1,2,3,4,5};
x = (long) y;
x++;
printf("%d\n",*((int*)x));
このコードを実行した際に表示される数値は何か予想せよ。
(理由とともに。なお、longは8バイト、intは4バイト、shortは2バイトとする)
661 :
476 :2009/02/18(水) 00:57:39
何故皆さんそんなわかるんですか? おかしすぎです なにやってたんですか 私はもう寝ます 明日もまた質問するのでよろしくお願いします この問題が解消されないとむかついてストレスたまります
typedef int BOOL; typedef unsigned short WORD; 別にどこにも行ってない。 BOOLの戻り値で3値が帰ってくる関数も有馬。
>>657 C言語にはいわゆるbool型がないからBOOLは1バイト整数で代用してるだけ。
BOOL flag = 3;
flag++;
if(flag)...
みたいに普通に使えてしまう。文法的には。
ただしWindowsプログラミングにおいては
flag = TRUE;
flag = FALSE;
だけを代入、比較するように使いなさいというお約束がある。
666 :
デフォルトの名無しさん :2009/02/18(水) 01:06:41
多くの処理系ではint(4バイト整数)だけどな。
667 :
641 :2009/02/18(水) 01:17:33
>>476 float balance[10][5];
これは何を表わしているだろうか?
配列は常にリニアなメモリに格納されるので、これは
float型のデータが入る領域が 5つ連続で並んでいる状態 が 10個並んでいる と考えてほしい。
p=(float *) balance;
と
p=balance;
の違いはなにか?
まず、(float *)とキャストしなくても俺の環境では警告は出なかった。
ただし、
p = *balance;
としないとだめだ。なぜか?
まず、キャストなしのbalance、これはbalance[0][0]のアドレスが格納されている領域を示すアドレスをしめす。
つまりポインタのポインタだ。
なので、
p=balance;
とすると、アドレスが格納されている領域を示すアドレス を floatが格納されている領域を示すアドレス に格納しようとしていることになる。
これはまずい。
キャストするのはこのためだ。
キャストすることによって、
(float * )アドレスが格納されている領域を示すアドレス;
の形になり、アドレスの*はそのアドレスの値(つまりこの場合float)を指すことになるので、
アドレスが入っている領域を示すアドレス ではなく floatが入っている領域を示すアドレス を表わせる。
これで、pに代入が可能となる。
間違ってたらごめんだが、たぶん大丈夫だと思う。
本だとエキスパートCプログラミングの259ページあたりを参照にするといいが、まだこの本は早いだろうな。
コンパイラというか、文法には例外がつきもの 厳密に文法に即していたら、現実的にはほとんどのコードが エラーやら警告やらでコンパイル通せないし、そうなると 場合によっては他のコンパイラに逃げられてしまうので、 コンパイラには何かと適当に融通を効かせる実装時規約が入っ てるのが常だと思っていい。(そこの当たりがまた不満で 癪に触るのだが、どうしてもというのあれば使わないという 最善の手段が残されている) すべてを理詰で考えるのは良い態度だが、こと文法に関しては 過去(文法が完全に確立しているとは言い難い時代)との互換性も 絡んでくるので、まともな理屈や規則を見いだすのが困難なケースも また多い。(歴史の因果を引きずっている部分が多々あり) 何がして良くて何がしてはいけないかなんて、 コンパイラを使ってみて、エラーを出してみて、実行時エラーで コケたりする経験を踏んでつかんでいくもので、エラーが出たら 修正し覚えて行くという方法以外にこういった問題の回避方法は 無いんじゃないかと思われ。
はい、ポインタのポインタと二次元配列の混同来ました〜。
>>666 ごめん。超テキトーに言ってしまった。
intだったのね。
>667 お前も勉強しなおせ
>>668 規格というものに意味を認めないのならそんなもの言語でもなんでもない。
個別のコンパイラのスレでも立ててひきこもっていることをオススメする。
>間違ってたらごめんだが、たぶん大丈夫だと思う。 ぜんぜん大丈夫じゃないよ
ポインタのポインタと2次元配列は違うが、 **balanceでもbalance[0][0]にアクセスできるのでこの場合の説明では問題ないと思うが。 ってかもっとだれもが納得できる説明できんのかだれか? 俺にはよくわからんかったが。
675 :
デフォルトの名無しさん :2009/02/18(水) 01:26:05
説明もできないししようともしない奴らのたたきワロタw
>>674 マ板とかム板って説明放棄で実際無知な奴らがいるので説明するのが怖い
俺は無理だ。
678 :
641 :2009/02/18(水) 01:31:34
(;´・ω・)凹むわ
679 :
デフォルトの名無しさん :2009/02/18(水) 01:33:28
まともに回答する姿勢を見せるとこうなるってことだな。 だから476から200以上レスがあるのにまともな回答が無いわけだ。
680 :
デフォルトの名無しさん :2009/02/18(水) 01:34:48
ここまでの説明で理解できなかったら、プログラム向いてないから諦めたほうがいいだろ。
> まず、キャストなしのbalance、これはbalance[0][0]のアドレスが格納されている領域を示すアドレスをしめす。 > つまりポインタのポインタだ。 これがもう、馬鹿らしい程よく見る、大嘘だろ。 4次元配列 int PPPP[1][2][3][4]; と宣言して、PPPPをポインタのポインタの・・・・・・(ry ぬるぽ!
実際ポインタのポインタ扱いでこの場合はアクセスできるよ。 説明のためだ。 他には?
683 :
デフォルトの名無しさん :2009/02/18(水) 01:38:18
|まず、キャストなしのbalance、これはbalance[0][0]のアドレスが格納されている領域を示すアドレスをしめす。 違う。balanceは配列そのものを表す。 ただし、これは一部の例外を除いてすぐにbalanceの最初の要素へのポインタ値に成り下がる。 |つまりポインタのポインタだ。 違う。配列へのポインタ値になる。 |とすると、アドレスが格納されている領域を示すアドレス を floatが格納されている領域を示すアドレス に格納しようとしていることになる。 違う。配列へのポインタ値をfloatへのポインタ変数に代入しようとしている。 |キャストすることによって、 |(float * )アドレスが格納されている領域を示すアドレス; |の形になり、 違う。(float * )配列へのポインタ値; の形になる。 |アドレスの*はそのアドレスの値(つまりこの場合float)を指すことになるので、 意味がわからない。ポインタに*演算子を作用させた結果はその指すオブジェクトへの参照となる。 |アドレスが入っている領域を示すアドレス ではなく floatが入っている領域を示すアドレス を表わせる。 違う。配列へのポインタではなくfloatへのポインタに変換できる、が正しい。
685 :
デフォルトの名無しさん :2009/02/18(水) 01:39:20
>4次元配列 int PPPP[1][2][3][4]; >と宣言して、PPPPをポインタのポインタの・・・・・・(ry お前ノ場合は突っ込み方が既に間違っておるw 理解してないな
686 :
デフォルトの名無しさん :2009/02/18(水) 01:41:42
>>672 「規格の規格」を論じており、そこに一貫性が見いだせない場合が
あるという意味だから。念のため
かいまつんで言えば、
>>684 の説明では
>>476 にはまったく伝わらないだろうなw
ポインタ配列という言葉を使えば良かったかもしれないが、
いずれにしてもエキスパートCは俺もお勧めだと思う。
>>687 お前が一貫性を見出せなかろうと、規格として成立している以上はそれに従うのが当然だよ
690 :
デフォルトの名無しさん :2009/02/18(水) 01:48:17
ここまでの説明で分からないなら、オツムの程度に問題があるのでは? そこまで懇切丁寧に教える必要あるのか?別に万人が理解できなきゃならないもんでもないし。
>>688 奴にはどうせ伝わらないのは最初からわかっている。
だがそれは厳密な説明を理解する言語力に欠けるほうに問題があるのであって
すんなり納得はしてもらえるかもしれないが正しくない説明を是とするのは間違っている。
692 :
デフォルトの名無しさん :2009/02/18(水) 01:51:51
ポインタは厳密な説明を最初から通したほうが分かりやすいと思う。 ポインタで躓く原因の多くは、入門書などで簡略的あるいは便宜上の嘘を教わったために、 その本当の意味を知らないことにより混乱が生じるためだと思う。
693 :
681 :2009/02/18(水) 01:52:06
PPPPは領域の先頭アドレスを返すわな。
でも、
>>667 はPPPPから先頭アドレスの取得をint**** p;に入れるか、
キャストの際の*を演算子と勘違いしてint *p; へ (int ***) p
だかなんだかするんじゃないか?
もう、何するかわからんから略した。
ところで
ポインタのポインタと2次元配列を
「ポインタのポインタでも同じようにアクセスできるよ」
とかなんとかいうなら
「±10000程度の整数計算するのに、doubleもintもあまり変わらないよ」
程度のもんだと思うぞ。(1024を10乗して1024の9乗で割るとバグったりするが)
違いがある、のを、同じように扱える、というだけで同一視はしないほうがいいだろ
こんな掲示板上でド素人を教育できるはずがないんだよ、そもそもね 言ってわからなけりゃわからないほうが悪い わかってもらうために間違ったことを教えるなんて本末転倒だ
695 :
デフォルトの名無しさん :2009/02/18(水) 01:55:09
>>694 ど素人だろうと小学生だろうと、理解力があるやつはポインタなんてすぐに理解できるよ。
これだけ大量の説明で理解できないやつは、Cには向いてないと思う。。。
int x[100]; int *xx=x;//融通を効かせて通してくれるコンパイラが多いが、こういったケースのみ。出来そうで出来ない場合もあるのでこの点でフラストレーションが 発生する。 int *xx=(int*)x;//融通を効かせてこのキャストを許してくれるコンパイラが多い int *xx=(int*) (&x[0]); //これを通さないコンパイラはあってはならない。 int **xx=x; //これを通してしまうコンパイラは壊れてる int **xx=(int**)x;//警告無しで通してしまうコンパイラは腐ってる 同様に int y[100][100] int *yy=y;//融通を効かせて(int*)&y[0][0]と解釈して通してしまうコンパイラの 言う事や出すコードは病気持ちの可能性が高いのでかな〜り心配したほうがいい int **yy=y;//これも通してしまうのは何だかな〜って感じ。 int *yy=(int*)&y[0][0];//これを通さないコンパイラはモグリ int **yy=(int**)&y[0];//これを通さないコンパイラは世間ズレしている。
理解力というか、慣れてないだけ。 誰も最初からすぐにわかったやつはいないだろう。 ここの説明だけで理解できるとも俺は思えない。 苦戦に苦戦を重ねているk分かる時が来るもんだ。
>int *xx=x;//融通を効かせて通してくれるコンパイラが多いが、 それを通さないコンパイラは企画に準拠してないだろ
699 :
デフォルトの名無しさん :2009/02/18(水) 02:00:01
>>697 本人はそこそこポインタやC言語に慣れてるように感じるけど?
ズブの素人というわけでもなかろうて。
あと、そんなに難しいことか?これまでの説明で十分だろう。
まあCの文法にも分かりにくい問題点はあるんだけどさ。
教条主義的なまでに規格の文言に従うのが正しい姿勢ってやつだ。 規格に一貫性がないから従わないとか言ってる奴はただのバカ。
大事なのは規格というものは一度作られるとそれに追加するのはともかく 前のものを削除するのは極めて難しいということ。 後々に矛盾が発生しないかどうかを十分検討できず、慣習化しているという 理由でなし崩し的に規格化されてしまったケースもあり得る。 その点は法律と同じだね。
>int *yy=(int*)&y[0][0];//これを通さないコンパイラはモグリ >int **yy=(int**)&y[0];//これを通さないコンパイラは世間ズレしている。 ためしにgcc3.4でコンパイルしてみたらwarningが出た。
>>699 俺にはなれているようにはあまり感じられない。
なれてるやつは自分でいろいろ試して自己解決するもんだ。
ファイル読み込み高速化についての相談です。 今まで、1KByteくらいのデータをHDD上のファイルから順次fread関数で読み出していました。 データを予めまとめてHDDからRAM上に移して使うほうが高速になる、という情報を得たので、 1000個まとめてHDDから読み出して、そこから順次1KB分を引き出して使う、というやり方に 変えたのですが、1000個分の読み出しで比較すると10数msほど速くなっただけでした。 こんなものなのでしょうか?
>704 一体誰に聞いたかしらないけれど、その「予めまとめてHDDからRAM上に移す」のは 大抵OSが(状況を見て。だからちょっと時間はかかるかもしれない)やってくれる。 だからほとんどの場合速くならない。
1000個って1000ファイルってこと?
OSが何をやっているのかっていうのを把握しないと、 実測結果に納得いかなくなる場合が多いよ。
708 :
デフォルトの名無しさん :2009/02/18(水) 02:12:40
>>704 どういうファイル構造か知らないけど、
>1000個まとめてHDDから読み出して
これが1000回の関数呼び出しをしているなら、
1000回呼んでることには変わりないわけで、大して早くならないだろう。
>>704 ファイルからデータを読み取るとき、ソースコード上のその位置で
直にディスクから読んでいるとは限らない、むしろそうであるほうが今は珍しい
同様に書き出すときもfprintfなどを呼び出した時点で
ディスクに書き込まれているとは限らない
大抵はfclose()した時点でfflush()されている
たぶんだけど、1000ファイル分読み込んでおいて、 なんかのタイミングでデータをメモリから読むってことなんじゃないの? あらかじめメモリに入れておけば後で読むとき速いっていうことかと。
>>704 OSに1kbyteとか1byteだけファイルから読ませる
ということ位難しいことはない。
あのMS−DOSですら、不可能で、ファイルのデータ
の256バイト程度は、勝手にメモリに取り込んでしまう。
もちろんそれは次の命令時に再利用されるが.
しかしそういうことが腹立たしいと感じる貴方の
精神も相当病んでいる。
int *xx=(int*)x;//融通を効かせてこのキャストを許してくれるコンパイラが多い int *xx=(int*) (&x[0]); //これを通さないコンパイラはあってはならない。 int **xx=x; //これを通してしまうコンパイラは壊れてる int **xx=(int**)x;//警告無しで通してしまうコンパイラは腐ってる ↑ こういうのってコンパイラの企画で決まってるの?
713 :
657 :2009/02/18(水) 02:21:25
>>658 負の値ですか・・・考えてませんでした。というよりCで負の値が出てくることを今更知りました。
これは・・・・補数というものを理解できていないということでしょうか・・・?
よく分かりませんが、私の予想では負の数は-1の時だけBOOLで1となり、他は全て0でしょうか?
>>664 >>665 正の数であれば、0かそうでないかによってif(flag)...の判定が分かれるということでしょうか?
だとすれば、「0の時だけ判定がFALSEになる」という考えでOKでしょうか?
>int **yy=(int**)&y[0];//これを通さないコンパイラは世間ズレしている。 キャストしてるからコンパイルはできるだろうけど これは意味あるの?
>>712 2番目はCの規格で決まっている
4番目はコンパイラの好みと設定の問題
1番目と3番目は書いてある内容のほうがまちがってる
716 :
704 :2009/02/18(水) 02:25:17
>>705 読み出すデータはファイル上では連続しているのですが、そういう場合、続きを読むだろうという
推測がし易いですし、OSが気を利かして先の分までRAM上に移しておいてくれたのでしょうか?
すばらしい仕事です。
>>706 いえ、一つのファイル上のデータで、読み出す単位(約1KB)の1000個という意味です。
>>707 たしかにそうですね・・・
ウィンドウのメッセージ処理を意識するようになっただけでもだいぶ理解が深まりましたし。
>>708 fread( buff, sizeof( DWORD ), 1, fp )を何度も繰り返して、最終的に1KB読み出していました。
これが1回の読み込み処理で、この後、読み込んだ1KB分にたいして処理を施します。
それが終われば、再び上記の要領で1KB読み出す、というふうに繰り返します。
これが今までです。
717 :
704 :2009/02/18(水) 02:25:37
>>708 続き
「1000個分読むようにした」というのは、ファイルのデータ構造などの見直しも行い、
fread関数1回で1KB×1000個(1MB)分読むというふうにしました。
fread( buff, sizeof( struct KOUZOUTAI ), 1, fp ) (KOUZOUTAI:1MBくらい)
>>709 そうだったんですか・・・
考え方を改めないといけません(汗)
>>710 ファイル自体は1個だけです。
狙いとしては、おっしゃる通り、HDDへのアクセスを減らし、メモリから読むだけにして高速化
しようとしていました。
>>711 そ、そうだったんですか・・・
てっきり、キレイに指定したバイト分読んでるものだと・・・
勉強になります。
なんだか誰も信用できねぇwwww お前らまともに書いてて誰が正解か怪しいぜ?
>>674 この場合と言うが、どの場合でも、式における*と[]の演算子は交換可能だ。
a[b]は*(a+b)と定義されているシンタックスシュガーなのだから。
コンパイラの仕様まで詳しく知ってないとだめなら そもそもプログラミングできねぇよ。 実際に動くコンパイラ見つけて、GCC4系で動作確認済みとかやればいい話だし。 実際オープンソースとかそういう注釈必ず付くしね。
>>719 この場合問題になっているのは、**pointerでも**arrayでも正しくアクセスできるかどうかではないよ
*pointerと*arrayが違うものであることが問題なんだ
おまえらまだやってたのかw
727 :
719 :2009/02/18(水) 02:36:23
>>724 ああごめん。つい前後のレス読まないで反応してしまった。
#define BUFLEN 1024 char a[BUFLEN]; とあるとき、aに文字列を詰めるときは事前に memset(a, 0, BUFLEN); などとして0クリアしたほうがいいんですか?
>>728 別に普通はやらなくてもいいけと思うけど、やっておいたほうがいいという人もいる
その程度の話
個人的にはやるのであれば、宣言時なら
char a[BUFLEN] = {0};
とか
char a[BUFLEN] = "";
にしといたほうがいいかとは思うけど
しなくていいよ なんでするの? 最後に'\0'を置くの忘れそうだから?
何度も入れなおして使いまわす時はやった方がいいと思う。 一度しか入れないんならいらないだろうけど。
>>728 公共の場所にあるパソコンを触る場合は、キーボードを
ウェットテッィシュで拭いてから使い、使い終わったら
同じように拭いておくのはマナーだが、変数を必要も無
いのに一々ゼロクリアしなければ使いたく無いというの
は潔癖性を超えて精神の病気の兆候かもな。
>>731 何度も入れなおすたびにmemsetするの?
基本的に要らない気がするが、いろんなソース読んでると必ずmemsetしてるのを見かけるときがある。
使う前にクリアするというよりは、 使ったあとに文字列を空にするためにmemsetするんジャマイカと思う。
>潔癖性を超えて精神の病気の兆候かもな。 プログラマ的ジョークなのかもしれないが、こういう表現をすること自体病んでいると思わないか?
>>732 は逆の意味で重要なポイントをついている。
つまり一人でやってるならいいんだけど、
その領域を他のPMがちゃんと扱ってくれるか信用できないときには…
ゼロクリアすると、Cに限っての話かもしれないが、些細かも知れないが
アプリがクラッシュする場合もあり得るバグの検出が遅れる傾向が
あると思われ。必要な場所以外はランダムに近いデータがメモリに
残ってると、変な文字列が出力されるなど、プログラムの問題を
検出しやすい。
ただ最近は、セキュリティの関係から、作業で使用した文字列等の
データはゼロクリアしてからじゃないと、returnできないという
コーディングルールを採択しているケースが多くなってきている
と感じる。(
>>734 も本質的に同じことを述べている)
破棄前のmemsetは最適化で 無視される場合もあるって言ってた。
事前のゼロクリは単にコーダの自身の無さの表れ
>>716 FILE構造体を見てみると内部にバッファがある
バッファ以下のファイル操作ならバッファ分を先に読み込んでその中でファイルポインタを移動する
fread関数を256回呼び出すより1回呼び出すほうが関数呼び出しのオーバーヘッド分早くなるというだけ
>>476 float balance[5][10]
この2次元配列に対してポインタを使ってみよう
1)
balanceと同じ型のポインタを用意すれば
balance[x][y]にアクセスするようにp[x][y]と使えるだろう
float (*p)[10];
p = balance;
2)
それぞれの列(balance[0][0]〜、balance[1][0]〜、)の先頭を指すポインタを用意してみよう
float *p1 = balance[0][0];
float *p2 = balance[1][0];
float *p3 = ・・・
float *p5 = balance[4][0];
これらのポインタをグループ化しちゃえ
float *P[5] = {p1, p2, p3, p4, p5};
あら、P[x][y]でbalance[x][y]の要素にたどりつけるわ
3)
所詮メモリ上では1次元の配列だから、float[50]で攻めてみよう
float *p;
p = (float *)balance;
balance[x][y]の場所は x*10+y だから *(p + (x*10) + y)でなんとかたどり着けたわ
4)
所詮メモリ上では1次元の配列だから、float[50]で攻めてみよう
float *p;
p = &balance[0][0];
balance[x][y]の場所は x*10+y だから *(p + (x*10) + y)でなんとかたどり着けたわ
742 :
704 :2009/02/18(水) 07:57:45
>>740 なるほど。
そんなふうになっていたのですね。
ありがとうございました。
別にFILEの中にバッファがあるわけじゃないけどね。 もし必要なら自分で用意したバッファをFILEに割り当てることもできるから、 バッファサイズを目的に合わせて最適化することも考えられる。 尤も、昔と違ってディスクキャッシュが善きに計らってくれるから大差ないけどw
744 :
476 :2009/02/18(水) 10:37:33
おきた 歯磨きと顔洗う
大学受験終わって時間を持て余してるんだがCをはじめるにあたってこれオヌヌメって本ない? 知人が柴田って人の明解C言語ってのと10日で覚える(ryってのをもってるって言ってたけど近くに大きめな図書館があるから良さそうなのがあれば借りてこようと思う。
>>743 FILEの仕様はコンパイラで違うから自分で用意したバッファを割り当てるとかありえない
747 :
476 :2009/02/18(水) 11:34:40
やさしいCと独習CとC言語体当たり学習はかわないほうがいいです やめたほうがいいですよ (float *)の意味とかのってませんしね ここの人が言うように なんとかCがいいですよ
>>746 setbuf, setvbuf のことを言ってるんじゃないの?
>>747 ありがとうござます
そのなんとかの部分が知りたい^-^;
>>747 (float *)の意味って本に書くほどの内容じゃないだろ
float型のポインタにキャストだろ
751 :
746 :2009/02/18(水) 11:40:31
知らんのに「ありえない」つったのか。
753 :
476 :2009/02/18(水) 11:43:01
>>753 度々どうもです。
リンク先も参照して図書館に言ってきますわ。
ありがとうござました。
755 :
746 :2009/02/18(水) 11:56:26
756 :
476 :2009/02/18(水) 13:07:07
float[n]へのポインタ型っていうのはなんか少し理解できたきがします float balance[10][5]をポインタに通してつかわず balanceのまま使うと *(balance[1])という感じでbalance[1][0]にアクセスできました balanceの型はfloat(*)[5]この意味はもしかすると *(balance[1]+1)だと balance[1][1]にアクセスできるってかんじであってますか? (float *) balanceをするとfloat *(4バイトずつ進む物に変換するので) balanceのままだと balance[0][0] balance[1][0] balance[2][0] balance[3][0]の左の縦の配列だけインクリメント されるので(4x5)20バイトずつ進んでしまうので (float *)で4バイトすすめれば balance[0][1] balance[0][2]っていうかんじですすめるので キャストする理由は 4バイトずつ進められて*(balance+1)の場合+1で4バイトすすむのでbalance[0][1]とかの考えであってますか? なんとなく自分的には4バイトずつ進めさせるためと思ったんですが
757 :
476 :2009/02/18(水) 13:14:03
#include <stdio.h> int main(void) { int k[4][3]={ {30,40,20}, {50,60,10}, {70,80,30}, {90,100,45} }; printf("%p\n",&k[1]); printf("%p\n",&k[2]); printf("%p\n",&k[3]); return 0; } これで確かめました 30(k[0][0])の場所のメモリアドレスが0だとしたら 50(k[1][0]の場所がメモリアドレス12 70(k[2][9])の場所がメモりアドレス24 intは4バイトなので配列が3こあるので 4x3で12バイト 3個の配列の合計が12バイトで 1つが4バイト キャストすると4バイトに扱えるって意味であってますよね? ですが何故キャストしないと 12バイトずつk[1][0] k[2][0]と左の配列だけ増えてあがるんですか? これは仕様なんですか?
ちょっとまて、言ってることがぐちゃぐちゃだ。
悪意なく聞くが、実年齢いくつだ? 別に小中高とかから選択でいい。(任意だが、それだけで回答もしやすい)
文章が上手くかけてないから、回答もしかねてる部分多いから注意しようぜ。
まず、配列のこと忘れよう。 キャストを知ろう。(データ型を覚えて!)
まず、大きな間違いを指摘する。 キャストで (float *) の*をアドレスの演算子と思うのは×
int型 float型 があるように、 int* 型 、 float*型という型が存在してる。
キャストというのは、型の違う(データ構造も違ったり)ものを、強制的に別の型に置き換える処理
キャストの典型例は、 int i = 2; double x = 3.14; がmainで宣言されているとする。
次の演算結果の値と型両方答えよ。
[1] (i * i) [2] (double) i * i [3] (double) i * (int) x
これらが、正確に分かるなら次のステップ
[4] (i * x) [5] i * (double) ( (int) x ) [6] i + (int *) i
キャストと切っても切れないのが、暗黙の型変換。これ、今考えると新出単語?
暗黙の型変換が分からないなら、[1]を質問する前に、そっちを聞かないと話がおかしくなる。
[0] 暗黙の型変換が分からない →
http://www9.plala.or.jp/sgwr-t/c/sec04.html とりあえず、[3]まで回答、質問してみ。
[1] 4 [2] 4.0 [3] 6.28 [4] 6.28 [5] 6.28 [6] i[0] + 2
[1] int [2] double [3] double [4] double [5] double [6] int
訂正 [3] 6
訂正 [5] 6
764 :
476 :2009/02/18(水) 15:33:53
[1]はiとiをかけて4です [2]も4です [3]は6です なぜなら3.14はキャストされて下2桁は切り捨てられます
スレを私物化するなよ
訂正 [6] 処理系依存
767 :
758 :2009/02/18(水) 15:39:57
[0]は知ってたorなんとなく読んだor読んで理解したor詳しい説明まで読んだ [1][2][3] データ型は? ただ、3.14が3に変換されるんじゃなくて、 (+2^1×11.001.....) みたいなのが(00000011)みたいなの(実際はもっと長いが)に変換されてるって分かってる? 計算結果にも型があるんだから、それを答えて。
768 :
476 :2009/02/18(水) 15:41:22
2^1は2^0乗だね
770 :
476 :2009/02/18(水) 15:47:34
[4]6.28です [5]これはややこしいですね さきに(int x)でキャストして下二桁カットされて3になってそれを(double)でキャストしても3なので 2*3で6です [6]これなんですか i=2;を (int *)iってなんですか?むかつきます iを*iにするってことですか? むかつくんですけど!なんですかほんとに
なるほど消防か。 [1]の解答は int型の4 [2]の解答は double型の4.0 上の二つが理解できてないようだが? もんだいにむかつくな。あと、(int *) と アドレス演算子一緒にするなと何度(ry
773 :
476 :2009/02/18(水) 15:56:02
(int *)これ本に書いてありませんでした キャストの部分を何回も見ても(int *)と書いてませんでした どうすれば良いんですか本当に? キャストの場所に(int *)がのってません 教えてください(int *)(float *) (char *)など頭がいかれて爆発しそうです
高校入試のときなんて、この問題集むかつく何様?何の意味があるの?ナニを表現しようと とか思わんかった 【1】以下を因数分解せよ (1) 3x^2 + 15x + 2xy + 10y (2) (3)
ポインタ + 整数 という演算はちょくちょく拝むけど 整数 + ポインタ という演算は見たことないな…
やっぱり、 p=(float *) balance;を教えてても埒が明かないわけだ。 >どうすれば良いんですか本当に? 他の本、他のサイトで勉強してからまたおいで。いくらでも(int *)が載ってるサイトあるよ。 本が悪いなら出版社に苦情だせば?
777 :
476 :2009/02/18(水) 16:26:11
なんとなくわかりました int i = 100; short *psh = (short *)&i; &iっていうのはint *型ってことなんですね? int *型とかいっててよくわかんなかったけど &iはint型かと思ってました
&はアドレスを指す演算子だよ…
779 :
476 :2009/02/18(水) 16:51:13
void CStyleCast() { int i = 100; short *psh = (short *)&i; TRACE( "%X, %X\n", &i, psh ); // 64F530, 64F530 } 『あ、 (short *) っていうのが増えたね、これがキャスト?』 「そう。 &i は int * 型。それを無理矢理 short * 型に見せかけるのが (short *) 。〈変えたい型を小カッコで囲む〉ってだけね
落書きで300レスも進んだのかw
マジレスするわけじゃないが、焼酎の段階でCは早過ぎ
782 :
758 :2009/02/18(水) 17:02:05
だいたい、キャストの仕方(文法)としてはあってるけど、 こういうことなのは理解しといてね。 int main(){ int i[3] = {1,2,3}; short *psh = (short *)&i; printf( "%X, %X\n", &i, psh ); // 64F530, 64F530 for(int j=0;j<3;j++) printf( "%X, %X\n", i[j], *(psh+j) ); // 1 1 , 2 0 , 3 2 return 0 }// int : 4byte , short 2byte
6.3.2.3 An integer may be converted to any pointer type. Except as previously specified, the result is implementation-defined, might not be correctly aligned, might not point to an entity of the referenced type, and might be a trap representation 6.5.6 When an expression that has integer type is added to or subtracted from a pointer, the result has the type of the pointer operand
あ、C++表記してしまった。しかもキャストの話してるときOTZ C言語では、以下のようにしないと、コンパイルできないときがある だいたい、キャストの仕方(文法)としてはあってるけど、 こういうことなのは理解しといてね。 int main(){ int i[3] = {1,2,3}; /*修正*/ int j; short *psh = (short *)&i; printf( "%X, %X\n", &i, psh ); // 12FF78, 12FF78 <コメントアウトも自分の値に /*修正*/ for(j=0;j<3;j++) printf( "%X, %X\n", i[j], *(psh+j) ); // 1 1 , 2 0 , 3 2 return 0 }// int : 4byte , short 2byte
もう何日やってんだよ・・・・・・・・・・・・・・・・・・・・・・・・
786 :
476 :2009/02/18(水) 18:38:32
理解できる人はいいですね 理解しようとして理解できない私はばかにされてばっかです
787 :
赤西仁 :2009/02/18(水) 18:38:56
アークザラッドUというタイトルのゲームの、ゲーム画像(歩行画像など)を抽出したいのですが、 かれこれ1年ほど経ちますが、なかなかうまくいきません。 *もちろん抽出した画像は個人範囲内で利用するつもりです。 ◆試してダメだったこと ネット上からダウンロードできる、ありとあらゆる抽出系ツールを試した。 (ちなみに他のゲームはほとんど抽出可能) ◆教わったこと ・アークザラッドUは独自の画像形式を使っているから抽出できない。 ・PS上で表示されてるということは絶対に摘出はできるはず。 ◆抽出は不可能ではないということを知ったとき 2ちゃんねるで質問したところ、 ある方が実際にキャラクターの歩行画像を抽出して 私が立てたスレにアップしてくださいました。 どうか皆さん、お力をお貸しください。御礼はします!
476はもう諦めて先に進め そのうちわかるかもしれん
何日くらい悩んでるかわかんねぇけど、1週間くらいであきらめんなよ。
プログラミングは通常は何年も経験するうちにいつの間にか身についているっていうくらいのものなんだから。
>>788 が言うように同じところで立ち止まるより先に進んだ方がいい。
後で戻ってくるとすんなり理解できるかもしれないし。
釣りにせよ真性にせよ相手するだけ時間の無駄だ
今までのとこをわかったつもりになって スッ飛ばしてきたツケだな これからも同じ様にスッ飛ばすのがいい
>>476 どんなひねくれかただよ。
これからは色々考えて、勉強した方がいい。今回は
・ 質問が悪い (本に対する愚痴を書くな)
・ 質問の仕方が悪い (日本語が通っているか書き込む前に見直せ)
・ 質問する場所が悪い (ここは2chだぞ)
・ 調べ方が悪い (同じところ参照して、いっぱい調べましたって?)
・ 調べてないお前が悪い (2chよりGoogle使え)
そもそも、プログラムはパソコンの基本操作じゃないんだから、
弱音しか吐かない人にはあまりやる意味がない。
風景画描きなが、喚いてる奴はいない。なのにプログラムには沢山いる。謎だ。
そもそも2chで訊くのが間違いかもな。 まともな答えなんて出てくるわけねぇ。 レベル的にも親切度的にも別のBBSを探した方が早いかもね。
794 :
デフォルトの名無しさん :2009/02/18(水) 19:56:12
> 別のBBS まあ、がんばれやw
795 :
476 :2009/02/18(水) 19:58:13
重要なルールっていうのを初めて知りましたので 「int *」と「double *」が違う型であるのと同様に「float *」と「float (*)[5]」は違う型である、というのが理解できていない気がする。 この意味がやっとわかりました int *はint aのポインタ double * はdouble a;のポインタ float * は float a;のポインタ 使い方は int *p; p=&a それで配列はfloat *は1次元配列のfloat a[10]に対応; 二次元の場合 float (*)[n] float a[10][5]; float (*p)[5]; p=a; それか p=&a[0]; たぶんあってます この考えであってると思います 自信あります 残るはキャストの(float *)を理解すれば解放されます
797 :
デフォルトの名無しさん :2009/02/18(水) 20:03:41
壮絶な476の釣りにまんまとはまるム版の住人。 もともとか田和の集団だから気付かないんだわこれが。
あのさ、
C言語でのポインタの立ち位置 と
Windowsにおけるレジストリの立ち位置 って
だいたい、同じ気がしてきた。
知らなくても、普通の操作はできるけど、なんか細かい設定とかが
知ってないと、身動き取れない、って感じしないっすかね。
>>476 はこのスレで聞くのあきらめたら?
>>795 キャストとは、違う型を「無理矢理」指定した型に変換するためのもの、ってことは理解してるか?
>>799 みたいなやつって、結局こういう突っ込みを入れたいやつなんだろうな。
実は476の存在を心のどこかで歓迎していたのだろう。
>>800 みたいなやつって、結局こういう突っ込みを入れたいやつなんだろうな。
実は799の存在を心のどこかで歓迎していたのだろう。
802 :
デフォルトの名無しさん :2009/02/18(水) 20:21:39
ポインタなんてそもそも本質的には必要ないんだよ。 long型の変数で情報量的には十分だから。 それで*と&の演算子だけあれば、Cでやれることは全てできる。 long ptr = &value; printf("%d",*ptr); このようなことをすればいいだけ。 わざわざポインタという型を用意して安全性を高めているのは、Cのやさしさだよ。
803 :
デフォルトの名無しさん :2009/02/18(水) 20:22:49
>>801 悔しかったのかもしれないが、2番目は流石につまらん
804 :
476 :2009/02/18(水) 20:23:07
799さん キャストは違う方を変換するっていうのは知ってます float i=10.2; printf("%d",(int)i); 10.2の下の桁はint型によりカットされます なぜならintは小数点を扱えないので そのくらいはわかってます。 独習Cの165ページまで理解できたので
独習Cってあまりいい評判効かないけど?
806 :
476 :2009/02/18(水) 20:36:16
評価の場所ではけっこう良い評価はいってたのでつい。 やさしいCはポインタの場所は簡単にまとめてあって理解しやすかったんですけど float (*)[n]型 float *型などと説明が無く ポインタの宣言は float *pとします。という感じでした 特に初めて聞いたのが float (*)[n]型っていうのです。 型っていうのは私が買った本には、int char double float voidが型でしたこの事を型と呼んでいて 今日やっと int *型っていうのが int *p;とわかりました int *へのというのは &p;ってことがわかりました
まだいたんだ
808 :
デフォルトの名無しさん :2009/02/18(水) 20:40:26
入門書なんだから全ての詳細について書いてるわけないじゃん。 それが嫌なら、ちゃんとした洋書(またはその翻訳本)を買いなさい。
掲示板上のやりとりで何かを習得できることは基本的にありえない 習得の手助けになることはあってもね
Cの文法書などは初心者向けを装いながら、実は「わかっている人」を 対象としている本。 教科書を読みたい=Cがわかる人になりたい のか、プログラムを書けるようになりたいのかはっきりしたいところ。
プログラムを描けるようになる本ってのは俺は見たことない。 あれば教えてほしい。
入門は、コンパクトなハンドブックのみを字引として使って 具体的な目標(与えられた問題でも良い)を設定し、自分で コードを書いてみること。これ以外に無いと思う。 途中で言語や数学の問題にぶつかるかもしれないが。
484の時点で間違ってるような?
>>810 文法書から入ると頭でっかちなだけで使えないプログラマになるとは聞くね。
815 :
476 :2009/02/18(水) 21:25:58
やっと理解できました! ありがとうございました! ちなみに皆さんは何でそんな頭がいいんですか? 普通に売ってる参考書などを見てここまで知識を蓄えたのでしょうか? C言語とポインタがわかれば電光掲示板に表示したりする物など作れますか? 自動販売機のデジタル表示など?
理解できたことに驚き
頭がいいとか悪いとか、知識を蓄えているだとか 他人にアヤつけるのは50年早いンだと思ってる 賢明な人はここで質問なんかしないだろうな
電光掲示板が標準出力ならprintfで十分。 あ、文字列ポインタ使ってたwww
いい加減476うぜー
>>805 推薦図書スレ行け。自分で読んで判断するしか無いけどな
Cを学びたいと思っているのですが何かお勧めの本とかありませんか? ご教授よろしくお願いします
なるほど、これがどこぞのスレで、誰かがってる奴がいた 『2chの人が総出でチェックしてくれるデバッガ』という奴か。頭構造までデバッグしてくれるとは性能いいな
>>820 ネットに転がってる入門文書読んで基礎知識を身につけた後
ひたすら他人の書いた良質のソースコードを理解するように努める
>>822 なるほど!そういえばうちの大学の教授も他人の書いた良質なソースコード読めばいいとか言ってました。
そうしてみますありがとうございました。
CをベースにC++をちょっとだけ使うのが通の楽しみ方って聞いたんだけど CのプロはC++のどの機能が便利だと思うわけ?
ソースを読むのが結局一番いいよな。 わからなかったら実際にその部分だけ自分で書いてみて動かして調べる。
>>820 の理解の良さ。 なんだったんだろうね、今までの数百レス
>>824 ベターCとして使うとC++の人たちが笑うので、
一概にいいとは言えない。
>>824 クラス、クラスの継承、演算子のオーバーロード。
これらのC++に機能を使いながらprintf。
これが通。
通はCだけを使ってC++と同じものを実装する。
ガチガチのC++のコードにさりげなくmallocを入れてみる。 これが通。
10進から2進に変換する関数なのですが、これで変換できる仕組みがよく理解できません。 xに入力されている10進数とbitの論理積には、どんな意味があるのでしょうか? void d2b(int x){ int i; int bit = 1; char c[BitSize]; for(i=0;i<BitSize;i++) { if(x & bit) c[i] = '1'; else c[i] = '0'; bit <<= 1; } printf("2進数: "); for(i=BitSize-1;i>=0;i--){ putchar(c[i]); } printf("\n"); }
質問の内容よりも、必要ない配列を用意し、あげくに逆順に格納するひどいコードに萎え
833 :
831 :2009/02/18(水) 22:33:00
>>832 授業で配布されたサンプルの1つなのですが、ビット演算を使った進数変換が理解できません。
xに入力されている数字は実際は0と1で10111101みたいな形になっているから。 だから10111101 & 00000001 = 00000001 10111101 & 00000010 = 00000000 10111101 & 00000100 = 00000100 みたいにしていくと、2進表示にできる
>ひたすら他人の書いた良質のソースコードを理解するように努める コードには悪質性は定義できても、良質性を定義するのは不可能に近い。 だから文学部とかのゼミでやるような、高貴な文学書を熟読するような感じ で読むのだけはやめたほうがいい。 書いた本人が書いた瞬間がもっとも良質で、時間の経過と共に劣化していくw 生モノに近いな
void d2b(int x) { int b; for(b=31;b>=0;b--){ printf("%d",(x>>b)&1); }
837 :
デフォルトの名無しさん :2009/02/18(水) 22:40:13
>>831 まずxを表示しないその限り進数は無意味だよ。
で、x=13(10進)を2進で表現するとx=1101(2進)
これはそれぞれ、x=1*10+3*1(10進)と、x=1*8+1*4+0*2+1*1(2進)
で、bitはループが進むごとに1,2,4,8,…(10進)、これを2進で表現すると1,10,100,1000,…(2進)となっていく、
即ち、一つの桁だけが1となっている数である。
これとxの論理積求めて、0であればその桁は0、0以外であればその桁は1ということになる。
それを各桁ごとに配列に入れて、最後にまとめて表示すればxの2進表現となる。
>xに入力されている数字は実際は0と1で10111101みたいな形になっている ここがよく分かりません。入力した値が、いつの間に0と1で表現できる形になっているのでしょうか。
最初から
>>836 もうちょい良くなる。
void d2b(int x)
{
unsigned int bitmask = 1 << (sizeof(int)*8 - 1); //1byte==8bits
for(; bitmask; bitmask >>= 1){
putchar((x & bitmask) ? '1' : '0');
}
}
841 :
476 :2009/02/18(水) 22:50:58
abc~zまで表示するプログラムをポインタで作ったんですが #include <stdio.h> int main(void) { char u[50],*p; int i; p=u; for(i=0; i<50; i++) p[i]='a'+i; for(i=0; i<50; i++){ printf("%c",p[i]); if(p[i]=='z')break; } printf("\n"); return 0; } if(p[i]=='z')break;を使わないで 配列にabc~zを入れるところでzまで入力をしたいんですが break;をつかわないとz以上の{|}~などと表示されてしまい for(i=0; i<50; i++) p[i]='a'+i;の部分を for(i=0; p[i]!='z'; i++) p[i]='a'+i; とやってもSegmentation faultと出てしまいます どうすればいいでしょう?
良くなる という表現の裏に潜む意味 「あやつのコードは悪い」 その悪いコードを理解したい(せざるを得ない?)人の立場を 理解しないのもCプログラマの特徴 bitが2のべき数の時( bit=1,2,4,8,16,32...) 整数(x & bit)は0またはbitに等しく bit=2^mの時(m=0,1,2,3...) (x & bit)が0であるか否かはxを2進数であらわした時のmビット目が0か1であるかに 対応する。 以降詳しくは数学板で ここで聞いても無駄
入力した値は、プログラム内(少なくともビット演算部分)では2進数になっているということでしょうか?
844 :
デフォルトの名無しさん :2009/02/18(水) 23:02:09
>>843 進数は表示するときの表示方法でしかない。
表示しなければ進数なんて無い。
>>843 プログラム内というより、コンピュータは基本的に全部2進だよ
メモリとかでも電気があるか無いかで01
CDだと光が反射するかしないかで01
HDDだと磁化されているかされてないかで01
2進数=binary digit=BIT=ビット
なるほど! 根本的な部分が分かってなかったようです。 10進数との論理積に疑問を感じていたんですが、納得できました。 ありがとうございます。
ここじゃ理解出来なかったということは了解
850 :
デフォルトの名無しさん :2009/02/18(水) 23:11:18
>>845 それは嘘。
多値で記録しているものもある。
NAND型フラッシュなら1素子で0から15まで記録するものがある。
板違いで申し訳ないのですがTCP/IPの事で聞きたいのですが良いですか?
アリガトウゴザイマス。
>>841 常にゴミデータと比較することになるから永遠にzと比較できない
>>850 量子コンピュータは無限の値で表わしてるようなもんだしな
>>850 だから01しか記録できないとは書いてないだろ?w
わざと曖昧に書いているのわかれ
まあモチツケおまいら いちいち細かいところに突っ込むのがおまいらの悪いところだ。 正確じゃないとだめだというのは気持ちはわかるが、友達一生できないぞ。
>>841 まずi=0の時とi=1の時にどんなループになっているか考えるんだ
そうすれば自ずとわかるんじゃね?
C言語の問題集にあった配列要素のシャッフルについての質問です。
http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/8911.c この8911.cの61,62行目の
j = rand() % (i + 1);
swap(int, a[i], a[j]);
という2行を swap(int, a[i], a[rand() % (i + 1)]); という1行に変更すると
生成される数字列がおかしくなってしまいます(具体的には数字が重複してしまいます)。
(例 8 3 5 4 4 9 5 1)
#define swap(type, x, y) do { type t = x; x = y; y = t; } while (0)
の部分が何か変な動作をしているからなのでしょうが、
数字列がおかしくなる原因がいまいちよくわかりません。
どなたか回答よろしくお願いします。
入門だからこそ、正しい話をするんじゃないか
>入門だからこそ、正しい話をするんじゃないか それはどうかと思うな。 はじめは噛み砕いた説明で概要をつかませて、その後にちゃんとした情報で修正していった方が速いと思う。 その後に〜を進まなかったときにえらいことになる可能性があるが。
>>863 そういう入門書は沢山あるよね
すべて糞本なんだけど
>>856 無限の値で表わしてるわけじゃないよ
o 関数の入力の値は固定
o 関数内部の初期状態は、確率的に取り得るだけの状態が存在する
o 観測する[1]と関数内部の状態が収束して出力が固定される
てなわけで、無限の値はどこにも出てこない
[1] おおざっぱに言うと入力を与えるとか
866 :
デフォルトの名無しさん :2009/02/18(水) 23:42:00
>>857 「基本的に全部」と書いてあるだろ。全然曖昧じゃない。明らかな嘘。
>確率的に取り得るだけの状態 これが実際には無限じゃなかったっけ?
>>867 結果として、無限の値が発生するわけじゃないっしょ?
870 :
デフォルトの名無しさん :2009/02/18(水) 23:50:18
>>867 量子ビット1つで2状態、n個で2^n状態、を重ね合わせる。
有限個の量子ビットで取りうる状態は、有限。無限ではない。
>>869 そんなの
>>845 に訊け。
>>862 置き換えてみたらわかりました。
swap(int, a[i], a[rand() % (i + 1)]); が置き換わった
do {
int t = a[i];
a[i] = a[rand() % (i + 1)];
a[rand() % (i + 1)] = t;
} while (0);
について考えると、
3行目の a[i] = a[rand() % (i + 1)]; の rand() % (i + 1) と
4行目の a[rand() % (i + 1)] = t の rand() % (i + 1) の値が異なるからですね。
つまり、
a[i] = a[rand() % (i + 1)];
a[rand() % (i + 1)] = t;
では、値が交換されることにならないので、
値が重複してしまうことになる。
つまり
>>845 のいう基本と基本以外の分類がわかっていないのに嘘と断定したわけだな
出力が常に固定された有限個の値しかとらないのであればそうだね。
基本的に全部=全部じゃねーだろ
お前らそういう重箱の隅突っついたような意味のない議論しててよく楽しめるなw
だってここはおっさんしゃべり場だもの
もはや「日本語でおk」で片付く話
878 :
デフォルトの名無しさん :2009/02/18(水) 23:56:36
>>872 フラッシュメモリーのような一般的に普及しているデバイスが「基本的」とやらに含まれていないことがそもそも嘘だ。
(・∀・)ニヤニヤ
基本的に がこれからはやる予感
これからはすべての事柄を対象に入れないとえらい目に合うと自覚する
>>845 であった・・・
>>845 >CDだと光が反射するかしないかで01
これウソだろw
A:基本的に2月はまだ寒いよな B:ハア?オーストラリアじゃ暑くて火事が起こってんだぜ?アフォ? A:いや、東京の話だよw 今このレベル
>>845 >HDDだと磁化されているかされてないかで01
これもウソだww
酷いww
>>878 845の言う基本的か否かを一般的に普及しているかどうかという問題にすりかえようとしていることがそもそも間違い
>>883 反射率の変化点が1、それ以外0
>>885 磁化されているかではなく、磁性体の方向だろうな
888 :
デフォルトの名無しさん :2009/02/19(木) 00:11:07
>>886 一般的に普及しているものを含まないなんて、全然一般的じゃないだろ。
即ち、「コンピュータは基本的に全部2進」と言うのは嘘。
>>845 ○ >
>>843 嘘 > プログラム内というより、コンピュータは基本的に全部2進だよ
嘘 > メモリとかでも電気があるか無いかで01
嘘 > CDだと光が反射するかしないかで01
嘘 > HDDだと磁化されているかされてないかで01
アンカー以外全部ウソだろwwww
一般的に普及=基本的ではないな x86系のCPUなんてその最たるものだと思うが
フラッシュメモリを計算機の話をしているときに持ち出すことには異論が出るだろうな。ここ以外の正常な場所では。
N極S極といえばいいじゃない
>>888 それは君の考える基準なだけ(たとえ他にも居たとしても)であって
845の示した基準が不明なわけだから断定するのが間違い
Cの話をしようぜ
基本的にセブンイレブンのおでんは旨い。 もちろんそうじゃないっていう人がいるのはわかるぜ。だけどここは流石に突っ込まないだろお前らでも?
おまえら重箱の隅好きだよな
俺はおでん全般が苦手だ。
だから
>>896 は嘘つきだ。
正しい話をすれば横道にそれないのに わかりやすくどころか混乱させる事しかしない 馬鹿なの?
たんなる揚げ足取りだろ クラスに1人はいたわ
クラスで言えないからここで発散してる可能性を探るべきだ。
>>888 メディアに載ってる状態は 1/0 ではない場合も多々あるが、基本的アーキテ
クチャとして, 1/0 を扱う方向で設計されているものがほとんどであることは
事実だわな.
だからと言って、
>>845 の例は全く間違いであることは確なんだが.
>>899 誰もがわかっているのに無理やりそらしてるのはお前らじゃね?
ワイドショーのマスコミみたいに。
906 :
デフォルトの名無しさん :2009/02/19(木) 00:20:48
>>904 他人の揚げ足取りでメシウマする連中がいるスレなんだろう。
基本的にセブンイレブンのおでんは汚い。 もちろんそうじゃないっていう人がいるのはわかるぜ。だけどここは流石に突っ込まないだろお前らでも?
909 :
赤西仁 :2009/02/19(木) 00:22:29
アークザラッドUというタイトルのゲームの、ゲーム画像(歩行画像など)を抽出したいのですが、 かれこれ1年ほど経ちますが、なかなかうまくいきません。 *もちろん抽出した画像は個人範囲内で利用するつもりです。 ◆試してダメだったこと ネット上からダウンロードできる、ありとあらゆる抽出系ツールを試した。 (ちなみに他のゲームはほとんど抽出可能) ◆教わったこと ・アークザラッドUは独自の画像形式を使っているから抽出できない。 ・PS上で表示されてるということは絶対に摘出はできるはず。 ◆抽出は不可能ではないということを知ったとき 2ちゃんねるで質問したところ、 ある方が実際にキャラクターの歩行画像を抽出して 私が立てたスレにアップしてくださいました。 どうか皆さん、お力をお貸しください。
入門者にとっては、わかっているとはかぎらないよね ごちゃごちゃ横道にそれずに正しい事を話せばいいのに
>>908 汚いかどうか考えたことないので突っ込み以前の問題です。
912 :
476 :2009/02/19(木) 00:24:30
841の私の質問にこたえてください
>>912 常に初期化する前のp[i]と比較している。
p[i] = 'a' + i した後にiをインクリメントしているから、p[i]がさっき代入したものと比較できていない。常にゴミデータが入っているp[i]を使っている。
これで十分でないか?
914 :
デフォルトの名無しさん :2009/02/19(木) 00:29:17
>>841 for(i=0; i<50; i++) {
p[i]='a'+i;
if(p[i] == 'z') break;
}
>p[i]がさっき代入したものと比較できていない。 さっき代入を行ったときのp[i]とは違うものになっているので、p[i]の中身が・・・・ ってことね。
ちゃんとiが9529止まったぜ!
917 :
476 :2009/02/19(木) 00:35:47
ほー ゴミデータとかレベル高いですね やっぱりif(p[i]=='z')break;使うしか無いんですね 回答ありがとうございました
919 :
デフォルトの名無しさん :2009/02/19(木) 00:38:44
i = -1; i = -1; do{ ++i; p[i]='a'+i; }while(p[i]!='z');
#include <stdio.h> int main(void) { char u[50],*p; char c; p=u; for(c='a'; c < 'z'+1; c++) p[i]=c; p[i] = '\0'; for(i=0; p[i] != '\0'; i++) printf("%c",p[i]); printf("\n"); return 0; }
>ゴミデータとかレベル高いですね センスあるボケですね
ちよ、ポインタを使うんだ! p = u; for(*p='a'; *p!='z'; ++p) *(p+1) = *p+1; p = u; for(printf("%c", *p); *p!= 'z'; ++p) printf("%c", *(p+1));
なんで、この頃ゴミみたいな討論を続けたがるのさ?
925 :
476 :2009/02/19(木) 00:52:56
C言語楽しいです ドラゴンレーダーとか人造人間って作れるんですか? ドクターゲロや則巻センベエになるには電子工作とかしなきゃだめですか? ドラゴンレーダーとか作れるんでしょうか?ドラゴンボールの位置とか
>この頃 ダウト
>ドラゴンレーダーとか作れるんでしょうか?ドラゴンボールの位置とか まずドラゴンボールを持って来い。話はそれからだ。 (元ネタは一休さんです)
ゴミみたいな話をしたがるのは今に始まったことじゃない。 マ板ム版は昔からだ。 2chでも釣り堀として愛好されてるくらいだし。
476に一つだけ、ナマエを付けてやろう。 ヨンナム
韓国系ですね
>>921 >for(c='a'; c < 'z'+1; c++)
> p[i]=c;
おかしいだろ、これ
a-zが連続であることを当てにするのはやめなさい
934 :
赤西仁 :2009/02/19(木) 01:41:42
アークザラッドUというタイトルのゲームの、ゲーム画像(歩行画像など)を抽出したいのですが、 かれこれ1年ほど経ちますが、なかなかうまくいきません。 *もちろん抽出した画像は個人範囲内で利用するつもりです。 ◆試してダメだったこと ネット上からダウンロードできる、ありとあらゆる抽出系ツールを試した。 (ちなみに他のゲームはほとんど抽出可能) ◆教わったこと ・アークザラッドUは独自の画像形式を使っているから抽出できない。 ・PS上で表示されてるということは絶対に摘出はできるはず。 ◆抽出は不可能ではないということを知ったとき 2ちゃんねるで質問したところ、 ある方が実際にキャラクターの歩行画像を抽出して 私が立てたスレにアップしてくださいました。 どうか皆さん、お力をお貸しください。
>>934 あと、1レス見たらアク禁にしてもいいか?
936 :
赤西仁 :2009/02/19(木) 02:42:14
アークザラッドUというタイトルのゲームの、ゲーム画像(歩行画像など)を抽出したいのですが、 かれこれ1年ほど経ちますが、なかなかうまくいきません。 *もちろん抽出した画像は個人範囲内で利用するつもりです。 ◆試してダメだったこと ネット上からダウンロードできる、ありとあらゆる抽出系ツールを試した。 (ちなみに他のゲームはほとんど抽出可能) ◆教わったこと ・アークザラッドUは独自の画像形式を使っているから抽出できない。 ・PS上で表示されてるということは絶対に摘出はできるはず。 ◆抽出は不可能ではないということを知ったとき 2ちゃんねるで質問したところ、 ある方が実際にキャラクターの歩行画像を抽出して 私が立てたスレにアップしてくださいました。 どうか皆さん、お力をお貸しください。
938 :
デフォルトの名無しさん :2009/02/19(木) 04:22:54
#include<stdio.h> #include<string.h> void main(void) { int max_sincho=0,sincho=0,i; char namae[20],max_namae[20]; for(i=0;i<=5;i++){ printf("名前と身長を入力\n"); scanf("%s,%d",&namae,&sincho); if(sincho>max_sincho){ strcpy(max_namae,namae); max_sincho=sincho; } } printf("%s,%d",max_namae,max_sincho); } 最終結果がおかしくでるんですが、、 受け渡しがうまく行ってない?? 初歩的ですいません、ご回答お願いします。
>>938 × scanf("%s,%d",&namae,&sincho);
○ scanf("%s %d",&namae,&sincho);
半角スペース区切りで名前と慎重を入力
&namaeの&がいらない。 namaeそれ自体がアドレスだから
941 :
デフォルトの名無しさん :2009/02/19(木) 04:40:15
> 939 ありがとうございます!!結果正常にでました。 ところで、なぜコンマで区切るとエラるんですか??
942 :
デフォルトの名無しさん :2009/02/19(木) 04:40:55
>940 ありがとうございます!! 配列自体がアドレスってこと忘れてましたw
>>941 %sはカンマ区切りを分離しないから。つまり、「foo,bar」と入力するとnamaeにfoo,barがコピーされてsinchoが入力待ちになる。
どうしてもカンマ区切りにしたいなら、%d,%sで済ませるか%[^,],%dとする必要がある。
どの場合もscanf()を使う限り、フォーマットを間違って入力するとフォローできなくなるので要注意。
>>940 別に&namaeでも通るだろ
(char*)(&name[0])とか
&namae[0]のほうがベターだが
慣習的にnamaeが一次元配列の場合、namaeでも
通用するというのが正しく
nameの前に&はいらないというのは
言い過ぎ
簡潔最小表現の盲目的礼賛=Cプログラマーの趣味
というプロパガンダを流そうとしていることミエミエ
配列名は先頭要素へのポインタに成り下がるが、配列に&をつけても要素へのポインタにはならない。 同値性のみを云々するなら兎も角、意味論的には& namaeは間違い。 そういう意味では& namae[0]は正しいが、その型がchar *なのは自明なので(char *)とキャストするのは愚の骨頂。 プロパガンダ云々と言った電波を垂れ流す前に勉強するべきだ屑。
#include <stdio.h> int main(void){ char x[1024]; x++; return 0; } このプログラムがコンパイルとおりません。コンパイラ壊れてるんですね?
>>946 コンパイラの名前と出力されたエラーメッセージを書きなさい。
配列は動かせない。 char x[1024], *p = x; p++; とかやっとけ
949 :
746 :2009/02/19(木) 07:32:45
>>949 そりゃそうだ。それはそうとして、この程度の知識はあったのねw
ポインタといのはint main関数以外使わないなら、出番は ないのでしょうか?
>>951 malloc を使うときに必要
コマンドライン引数を使うときに必要
>>946 int x[1024];
でxは配列名であると同時に、x[0]へのintポインタ定数
ポインタ変数ではないので、++演算子を使うことが出来ない。
より正確を期するとxをx[0]へのintポインタ定数と見なして
もらえるのは慣習上の特認(この特認を認めなければソースコードが
*や&や()だらけの読めた代物ではなくなってしまう)
954 :
746 :2009/02/19(木) 11:27:56
>>950 昔同じ事してたからね
ポインタと配列の違いを理解してなかった
今考えれば当たり前のことだけど
ポインタ の 配列 配列 の ポインタ
混乱の真犯人はキャスト演算子
957 :
ヨンナム :2009/02/19(木) 13:10:38
#include <stdio.h> #include <ctype.h> int main(void) { char str[80],*p; gets(str); p=str; while(*p) *p++=toupper(*p); printf("%s\n",str); return 0; } これなんですが、printf("%s\n",str);ここをポインタで表示したいのですが *pとやってもpとやっても表示できません どうすればいいんですか?おしえてください
ポインタで表示の意味がわからん。 %pのこと?
ああ、pを使ってということか。 p はp++でインクリメントしてstrの末尾の\0を指してるんだから そのままじゃ何も出ないだろうよ。
960 :
476 :2009/02/19(木) 13:21:14
ポインタの中身で表示したいんです printf("%s\n",str); をprintf("%s\n",p); とやったんですが空白が表示されるだけです もしかして*pの位置が最後になってるからですか? インクリメントをしたせいで本来pですが読み込んだ分のインデックスがaiueoだとしたらp[5]からはじまるので pがp[5]になってしまい 表示されるときp[5]からなのでp[5]以上は何も入ってないから空白が表示されるんでしょうか?教えてください
961 :
476 :2009/02/19(木) 13:24:21
考えてた事同じですね! やはりインクリメントで読み込んだ分の最後の行になり*pの最後が\0になってしまうから インクリメントのせいでpのインデックスがstr[0]から読み込んだ分のstr[5]から始まってしまうってことですね! ありがとうございます理解しました
962 :
476 :2009/02/19(木) 13:32:13
インデックスを戻すには p=str; printf("%s",p);でできました p=strでstrの先頭にもどせば&str[0]なのでそこから表示できました 自分って頭良いと思います
その調子でがんがれ
964 :
476 :2009/02/19(木) 13:38:02
なんとかポインタのキャストなので難しい事をしたので 次へ進むとすんなりいけます 次は構造体とかなんか難しそうなので、まだ構造体へいってなく文字列とポインタなので ポインタをクリアすればもう完ぺきだとおもいます。 早くファイル操作などやってみたいです ファイルを保存したり インデックスではp[5-5]などと調整しましたができなく。 p=str;でインデクスを戻す方法をあみだしました この掲示板の人たちはとても親切でありがたいです この掲示板がなかったらポインタでつまづいてましたありがとうござじます
ポインタより日本語を勉強しろよ…
>>829 テンプレート無しの単継承ならそれっぽくできそうだけど…
多重継承やテンプレートはどうやれば良いか皆目検討がつかん
本質的には言語が優れているわけじゃなくて コンパイラが高機能になりましたよってことだからナー
いい加減うぜー
iphoneでソフト作りたいんだがC言語でいいの?
Objective Cで
どうもです
>>966 多重継承は単純に継承先が継承元をメンバとして保持し、
テンプレートはマクロで実現するんだ。
*HENSU[] という形式の変数を、 他の関数にそのまま渡すにはどうしたらいいんでしょうか? 具体的には以下のようなものを作ろうとしているのですが、 何分勉強不足でして、思うようにいきません。 ご教授いただけたら幸いです。 #include <stdio.h> void Enumerate(int, char *[]); int main(int argc, char *argv[]) { Enumerate(argc, *argv); return 0; } void Enumerate(int num, char *name[]) { int i; for (i = 0; i < num; i++) { printf("%s\n", *name[i]); } }
>>973 したいことがよくわからんが、そのソースを動くようにするには
Enumerate(argc, argv); にして
printf("%s\n", name[i]); でいい。
#include <stdio.h> void Enumerate(int, char *[]); int main(int argc, char *argv[]){ Enumerate(argc, argv); return 0; } void Enumerate(int num, char *name[]){ int i; for (i = 0; i < num; i++) { printf("%s\n", name[i]); } }
>>974-975 ありがとうございます。これでうまくいきました。
* を外せばよかったんですね。盲点でした。
プロが一人でキャラクタベースのローグライク作るとしたら何日ぐらいでできる?あまり凝った仕様じゃなくてシンプルなルールのやつで
一日だろ
仕様はどこまで決まってるの? マップは作成工数に入れる?
ローグ懐かしいな 暇が出来たら作ってみたいな
ぶっちゃけスーファミのシレンを丸パクしたらどれぐらいかかるのかな、と
ぜんぜんシンプルじゃねーじゃねーかw
985 :
476 :2009/02/19(木) 21:20:46
問題です 1.int a; &aは何へのポインタでしょう? 2.int a[5]; aは何へのポインタでしょう? &a[0]は何へのポインタでしょう 3.int a[10][5]; aは何へのポインタでしょう? a[1]は何へのポインタでしょう? これができなければだめです
しまった。2の後半の&a[0]を&aと見間違えたorz そこもintへのポインタ、int*な。
C言語というより、コマンドプロンプトについてなのですが コマンドプロンプトで入力するとき、全角入力はできないのでしょうか?
Alt+全角 ほかから張り付けという手もある。 次からWindows板行け。
>>989 了解です(`・ω・´)ゞ
ありがとうございました
問題です
1.int a; &aは、ポインタでしょうか?
>>476 がんばってくれ。
↓参考
#include<stdio.h>
int main(){
printf( "476を応援 %d \(^O^)/%sTEL\n"+0XA,0x1dc,'-'/'-'+"POW\bWAT\b");
return 0;
}
992 :
デフォルトの名無しさん :2009/02/19(木) 22:45:25
ポインタでa[5][5]; のa[0][1];のアドレスを得たいんですが &a[0][1]では無く ポインタ演算子でやるにはどうしたらいいんでしょうか? いろいろ試したあげく (a+0)+0などとやってみて 他には(a+0)+(a+1);とやってみましたがダメでした どうすればいいでしょう?
a[0] + 1
このスレ見てて思ったんだが、「このデータの型をコンパイラはこう解釈した」ということを表示する、簡単な手段/ツールってないのかな。 デバッガで何とかなる?
慣習法には依存しないほうがいいな
struct {} A = n; とかやると〜はstruct{} Aに変換できないみたいなエラーを吐いてくれるものもある。
1000ゲット
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。