0〜Nの間の数値の内、3の倍数と3のつく数字の時だけ”アホ”と表示したいのですが 「3のつく数字の時」 を高速に判定するにはどうするのがベストですか
>>4 全部の数字に対してアホと表示することをどうして考えないのでしょうか?
仕様レベルから見直して下さい。
>>4 事前に「N以下で3のつく数字」のテーブルを作っておき、
対象の数字がそのテーブルにあるかチェックする。
>>4 #include <stdio.h>
main(){
int n;
printf( ">>" );
scanf( "%d", &n );
while( n%10!=3 && n>10 ){ n/=10; }
if( n%10==3 ){
printf("3のつく数字です。");
}
}
>>4 > 「3のつく数字の時」
> を高速に判定するにはどうするのがベストですか
sprintf関数で文字列にして、strchr関数で'3'を見つける。
>>4 #include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>
int BuffSize(int n)
{
int num = n;
int size=0;
while(num){ num /= 10; size++; };
return ++size;
}
int main()
{
int i,n,nabeatu=0;
char *nstr;
printf("%dまでの数値を入力\n",INT_MAX);
scanf("%d",&n);
nstr = malloc(sizeof(char)*(BuffSize(n)));
for(i = 1; i < n; i++){
sprintf(nstr,"%d",i);
if(i % 3 == 0 || strchr(nstr,'3')){
printf("%s%c\n",nstr,'!');
nabeatu++;
}else
printf("%s\n",nstr);
}
printf("ナベアツ数%d回\n",nabeatu);
free(nstr);
return 0;
}
パスワードのプログラムでキーボードから入力された文字数が9文字以上ならやり直し 8文字以下なら同意済みのpass{9}にコピーであらかじめ設置済みのパスワードと比較して 一致ならok、不一致ならやり直しってプログラム作りたいんだけど作れない 誰か親切な方教えてください
宿題なら宿題スレへ。 そうじゃないなら、どこがどうわからないのかをもっと具体的に。
>>4 高速にということになれば絶対的な解は存在しない。
常に処理系依存であり、実測によって確認する必要がある。
一般的な考え方は、コンピュータ上での整数は2進数であり、
10進数としての見かけを扱うなら10進数(の規則)に変換する必要があるということである
(たとえばsprintfと%d指定子を使って文字列を作り出すことによって。
ただし、文字列にすることは常にバッファの確保の問題を内包しているし、
sprintfのような強力な関数を呼ぶことは多くの場面で大きなコストとなることは覚えておくこと)。
単に10進数の各桁の数字を順に取り出したいなら、%演算子で10の剰余(最小の桁の数字)を得た後で
/=演算子で1/10にすることを繰り返す昔ながらのアルゴリズムが最も汎用的な解で、ほとんどの処理系で十分に高速である。
しかし、いずれにせよ後で標準出力等に数字を文字列にして出力しようとしているなら、
あらかじめsprintfで文字列を作って(恐らくはポインタを操作して)1文字ずつ解析したほうが速い可能性は高い。
>>10 まず、以下の単語の意味を適切な日本語で説明すること。
・同意済みの
・pass{9}
・設置済みの
>>10 > 入力された文字数が9文字以上ならやり直し
これ不要だと思うが?
>>10 #include <stdio.h>
#include <string.h>
int comp(char copy[],char pass[])
{ return strcmp(copy,pass); }
int main()
{
char buff[100] = {'\0'};
char copy[9] = {'\0'};
char pass[] = "password";
char *temp;
int len,i,r;
while(1){
do{
puts("passを8文字以下で入力");
fgets(buff,sizeof(buff),stdin);
if(temp = strrchr(buff,'\n'))
*temp = '\0';
if(9 <= strlen(buff))
puts("9文字以上になってます。");
}while(9 <= strlen(buff));
for(i = 0; buff[i]; i++)
copy[i] = buff[i];
copy[i] = '\0';
r = comp(copy, pass);
if(r==0){ puts("認証成功"); break;
}else if(r != 0){ puts("認証失敗"); }
}
return 0;
}
>>4 #include <stdio.h>
#define N 10000
int main(int argc,char **argv){
int i,ii,j,k,times=0;
for(i=1;i<=N;i++){
if(i % 3==0){times++;continue;}
ii=i;j=1;
while(j*10<=ii)j*=10;
do{
if(ii/j==3){times+=j;break;}
else{ii-=(ii/j)*j;j/=10;}
}while(j>=1);
}
for(i=1;i<=times;i++)
printf(
(i%61==0)
?"やってみたお前が一番阿呆¥n"
:(i%47==0)
?"なんとやらの一つ覚えのなんとやらテーブル参照¥n"
:(i%19==0)
?"あほんだらの下からスキャン¥n"
:"こんな問題だした
>>4 はアホ¥n");
}
18 :
16 :2008/05/20(火) 02:05:56
ゴメソ バグってた. 各自で直してくれ
19 :
16 :2008/05/20(火) 02:26:44
受けた仕事は最後迄というセオリーに沿って修正したの貼っとく
#include <stdio.h>
#define N 10000
int main(int argc,char **argv){
int i=1,ii,j,k,times=N/3;
while(i<=N){
if(i % 3==0){i++;continue;}
ii=i;j=1;
while(j*10<=ii)j*=10;
do{
if(ii/j==3){times+=j-1;i+=j;break;
}else{ii-=(ii/j)*j;j/=10;}
}while(j>=1);
i++;
}
for(i=1;i<=times;i++)
printf(
(i%61==0)
?"やってみたお前が一番阿呆¥n"
:(i%47==0)
?"なんとやらの一つ覚えのなんとやらテーブル参照¥n"
:(i%19==0)
?"あほんだらの下からスキャン¥n"
:"こんな問題だした
>>4 はアホ¥n");
}
ヘッダファイルが沢山インクルードされているソースだといちいち使われている変数の型をヘッダファイルに確認しなきゃいけないんですがそれが煩わしいです なにかソースを読むときのコツとか心構えがあれば教えてください
このサイトのどこを読めばいいんでしょう?
コードリーディングって言うんですね、VBのデバッグツールは変数の内容をポップアップで表示できますがそれと似た感じで、ソースコードにある変数名からその型や構造体の詳細を表示できるリーディングツールとかがあるんでしょうか? っていうかもう朝だw
>>10 #include <stdio.h>
#include <string.h>
#define TRUE 1
int main( void );
char pass[] = "hogehoge";
int main(){
char s[100];
while( TRUE ){
printf( "pass>>" );
scanf( "%s", s );
if( strcmp( s, pass )==0){ break; }
}
return 0;
}
26 :
デフォルトの名無しさん :2008/05/20(火) 08:15:22
fgetsの入力バッファ(stdin)をクリアはどうすれば良い? 言語:C OS:Win コンパイラ:Borland bcc55
rewind(stdin)
>>20 まっとうなライブラリなら提供する変数やシンボルについて詳細な説明を文書にしてあるはずである。
標準ライブラリの規格や、開発環境が独自に用意したものなら付属のマニュアルを読むこと。
もし不親切なライブラリや出所の怪しいライブラリを使うはめになったら、まずは開発環境のコード支援機能を活用すること。
どうしてもヘッダファイルの中身を直接読まなければならないなら、grepツールを使うことが多くの場合で助けになる。
一方で、変数の型は必ずしも確認する必要があるわけではない。
特にtypedefや#defineによってわざわざ元の型を隠そうとしている場合には、むしろ元の型が何であるか考えないことが、
ライブラリ作成者が意図した使い方のはずである(もちろん、これもタコなライブラリに関しては当てはまらない)。
>19 正しいアルゴリズムを書けないのに 自分は頭がいいんだと勘違いして 他人を嘲ることほど恥ずかしいことはない
4==16 としか思えないのだが...
正しいアルゴリズムを書けて頭も良く人を嘲ることがでいる
>>32 さんに
>>19 のコードのどこを修正したら正しく動作するか
やってもらいましょうw
他の板なら 4=16 と書かれるであろうところを ちゃんと 4==16 と書くところにこの板の格調の高さを感じる
もしかして
>>4 =
>>16 ってことか?
4と16の比較でもしてるのかと思った
>>32 頭が悪いからこそ普段からバカにされてるストレスの発散として他人を嘲る
でも、頭が悪いから嘲ろうとしても逆にバカにされ余計ストレスをためる
の悪循環にはまってるから何言ってもムダだよ
>>34 不可能である。
>19は3の倍数と3のつく数字の数を数えようとしている(それすら間違っているが)。
対して、>4が要求しているのは、任意のある数字に3がつくかどうかを効率よく知る方法である。
アルゴリズムの修正とは手段を訂正することであって目的を訂正することではない。
目的を訂正するならそれはアルゴリズムの完全な書き直しである。
>>38 貴方はなぜそんなにムキになってるんですか?w
おまえら・・・一体ナニヤツ?
あいかわらず一定確率で初心者に優しくないなおまいらw てか質問者そっちのけw
そもそも掲示板という環境は初心者に優しくない リアルタイムに顔つきあわせてやるのが最善なんだから
質問者が結論出してしめないからこうなるw
スキルの開きがすごいからな
タイムラグのある文字だけのコミュニケーションで的確に意思を疎通させるには 双方の日本語力と論理的思考力が不可欠だってだけだよ どちらかでも欠ければどんな質問もまともに回答されるとは保証できない
VisualStudio2005 でデバッグ実行すると普通に実行できて、デバッグなしで実行すると途中でエラーが発生しましたって出るんですけど。。。 何でですかね。。。?
>>46 コンパイラの警告レベルを上げて、出てきたメッセージを詳細に分析しましょう。
操作方法を詳しく知りたいならVisualStudioのスレへ行きましょう。
プログラムの内容についての相談ならソースを張りましょう。
>>45 46みたいなアホを見ると質問者の方に問題がある場合が多いと思うぜ
>>46 よくある原因は大きく分けて3つある。
1)初期化されていない変数を誤って使用している場所があって、
メモリのいたずらでたまたまデバッグ実行するときだけ適切な値が入っている。
そのような場所がないかを探すこと(目視で、あるいはコンパイラの警告を読むことで)。
どうしてもわからないならエラーが起きた地点から処理を逆行して調べる
(とんでもない距離を遡る必要があるかもしれない)。
2)正しく確保していないメモリに書き込んでいるか、
確保したメモリの大きさを踏み越えてしまっていて、
やはりメモリのいたずらでたまたまデバッグのときだけ問題がないようになっている。
配列やポインタの周辺を徹底的に調べること。特に添字の範囲が適切であるかどうか。
3)デバッグ時とそうでないときでmainの実行時引数や環境変数
(一番ありそうなのはカレントディレクトリのパス)が異なっていて、
それを正しく処理しないコードを書いている(特にファイルを操作する場面で)。
そのような処理がないかを洗い出す。
問題が起きたときは常にエラーや警告をを注意深く読むこと。解決のヒントはたいていそこにある。
また、他人に相談するときはそれらを正確に説明すること。どんな名プログラマも君の頭の中に直接アクセスすることはできない。
正確にどこでどんなエラーで落ちたのかを調べる。 特に、ソースのどこで起きたのかをデバッガなしで特定するノウハウは今後役に立つ
>>4 あいつってそれしかできないのかと思ったら他にも楽しいネタ持ってて好感度あっぷした俺
int ohoho(long kazu)
{
int sanda; // 3の数
long keisan;
if((kazu % 3) == 0)
printf("3の倍数だぜっ¥n");
sanda = 0;
for(keisan = kazu; keisan > 0; keisan /= 10)
if(sanda = ((keisan % 10) == 3))
break;
if(sanda)
printf("3があるっちぅねん¥n");
}
>>4 は"アホ"と表示させたいことに気づいてやってください。
53 :
デフォルトの名無しさん :2008/05/20(火) 19:42:25
下のプログラムはピラミッドなのですが、それを変数は3つのままで*9個を基準に下に作りたいのです。 要するにこれの逆を作るにはどうすればいいでしょうか? #include <stdio.h> void main(void) { int dan,j,k; for (dan=1; dan<=9; dan=dan+2){ for(j=1; j<=9-dan; j=j+2){ printf(" "); } for(k=1; k<=dan*2-1; k=k+2){ printf("*"); } printf("\n"); } }
>>53 宿題の丸投げならスレあるぞ。
逆つーんなら
for (dan=1; dan<=9; dan=dan+2){
を
for (dan=9; dan>=1; dan=dan-2){
にするとか
>53 質問とは関係ないが、mainはintを返すと宣言しなければいけない いくつかの古い入門書や間違ってる入門書もあるので注意だ
56 :
デフォルトの名無しさん :2008/05/20(火) 21:29:39
質問です。 入力された米国ドルを英国ポンドに換算するconvert()という関数を作成し その関数を使って換算後の金額を表示するプログラムを作成してください (為替レートは1ポンドを2ドルと仮定します)。 という問題があるんですが convert()という関数だけ作ってもらえませんかね? まだはじめたばかりの初心者なんですが、この関数の作り方がわからなくて;;
>>56 int convert(int usDallerAmount);
質問です。
javaとjavaScriptぐらいしか触ったことの無い俺に
ポインタの有用性の分かるプログラムを教えてください。
何でも出来るから便利とはよく聞くんですが、
実際どういうときにどういう使い方が出来るから便利なのかさっぱり思いつきません。
ポインタが有効的に利用されているプログラムのソースなどありましたら教えてください。
double convert(double dollar) { return dollar/2.0; }
>>52 ってかさ、数値が 3 の倍数であること。あるいは 3 が現れることを判定するのが肝でそこを考えるのがあれだしょ?
で、そういう関数ができたら後はそれで「4はそのアルゴリズムが想像できないマジアホですっ」て出すとかはお好きにどうぞってことじゃないかなぁ・・とマジ書き
>>57 javaの参照はポインタみたいなもんだろ。
>>57 Cにおいてはポインタは、有用であるというより、むしろ必須であるというほうが正確だ。
さらに突っ込んで言えば、およそどんなコンピューターシステムでも
メモリアドレスの概念を用いて複雑なデータ処理を行うのであり、
Cは他の高級な言語ではプログラマの目から「隠されている」メモリアドレスの処理を
プログラマが明示的に操作することが出来る機能としてポインタを実装しているに過ぎない。
ポインタの有用性を考える必要はない。ポインタが実際のところなんであるかを理解すれば、
いくらでも有効に活用することができるはずであるし、もし理解しないとしたら、
きっと君はCで何かを行うことはほとんどまったくできないだろう。
>>57 メモリマップドI/Oのシステムだと、ハードウェアのレジスタがメモリアドレスに割り当てられているから、
ポインタが無いと絶対にアクセスできない。
また、DMA転送の場合には、ハードに対してメモリアドレスを指定するから、
やっぱりポインタが必要となる。
なので、Cでデバイスドライバを作るとき、ほとんどの場合必須。
次のフローチャートをC言語で記述し、実効せよ 文字応答 l 文字入力 l 文字出力 l 終了 <実行例> A (←入力) 入力文字:A (←出力) を作りたいんだが #include <stdio.h> void main(void) { char moji; char ("#c",&moji); if(moji=="A") { ptrintf("あたり\n"); } rewind(stdin); getchar(); } 見難いですが エラーが3件でますどなたか分かりませんか? int,,char,,floot ってのがあまり把握できないんですが int= 文字 %d char=名前 %c floot=計算式 %f で使用すればいいですよね?
#cじゃなくて%c
あとscanfじゃないかな
エラーメッセージを読んでください スペルミスくらい確認してください ptrintf
パソコン2台で移し間違えもありました>< scanfにしたらエラーが2件に減りました scanfの宣言を確認してください intはconst char [2]" と間接操作のレベルが異なります const char *型からint型の変更ができません
rewind(stdin)は基本的に有り得ない。 "A"じゃなくて'A'。 コンパイラの出力を眺めても分からなさそうなのはこれくらいかな。
>>68 できました!ありがとうございます><
これだけ解くのに2時間かかった。。。
とりあえずあせらずゆっくり教科書を読むんだ
"A"と'A'の違いがわかれば一人前だな。
>>71 "A" の方が照れてる感じです!
じゃなくて、一人前のレベルが低すぎるよ
\nってどんな意味があるの? "" ←のいる時といらないときの状況が分からないんだけど説明できる人います?
"A" = 文字列 'A' = 文字 = 数値 \nは改行コード
>>74 ''って数値だけだったのか
ありがとうございました分かりましたw
"A"は文字列というか、 {'A', '\0' } というchar型配列をメモリに確保して、その先頭のアドレスを"A"に置き換えている "A" = 配列の先頭へのアドレス と少なくとも俺は思っているんだが合ってるんだか全く分からん 'A' == 0x41
>>76 その文字列を代入した「変数」がアドレスを表す。"A"自体は文字列リテラルとしか言いようが無い。
"A" 文字列リテラル。文字列。末尾に\0を持つ。 'A' 文字リテラル。単なる小さな整数。 ひとつの文字と一対一対応するがある値がどの文字と対応するかは環境依存。 言語仕様上、'a'の次が'b'である保障もなし。 ただし、数字は連続する。たとえば'1'の次はつねに'2'。
なるほど、ひょうかひょうか
関数ポインタが使いこなせるようになれば一人前だな
関数ポインタを引数に取るAPIとかざらにあるから、使ってなくはないはずなんだが 使いこなしてると言われると自信ないなあ どんなんなんだ
関数ポインタを使って好きなときに好きなように処理を入れ替えれるなら 使いこなせてるって言うんじゃない?知らないけど
全然分かりませんん!チンプンカンプンです!
俺的メモ。 一人前=それなりのモジュール設計ができ、デバッグもでき、 ライブラリを探してきて一人で組み込めるレベル。 他人に頼らずに他人に迷惑かけずにそこそこの仕事ができるレベル。 DQでいうとベホイミとルーラを覚えたくらいだな。
ifとwhileしか使えないオレはメラが使えるくらいか
if for do while などは、幅広い言語で共通して使えるものだから むしろ敵に素手で攻撃するようなものだ
89 :
デフォルトの名無しさん :2008/05/22(木) 14:55:45
すみませぬ。 LUNAXにプログラムにおいて 20という数字をターミナルに入力したら、 それを読み取り、30という数字を表示する プログラムの作り方がわからない為、教えて頂けませんか??
HelloWorldは書いたかい?
>>89 scanf("%d", &n);
printf("30\n%d\n%d\n%d\n%d\n", n*3/2, n+10, n*2-10, n*n-370);
処で、LUNAXってなんだ?
次世代型の月OS
LUNA SEA , X-JAPAN
すいません、ループする度に、一文字ずつ読み込んでいくという、関数の作り方教えてもらえませんか?
>>95 void function(){for (;;) getchar();}
・関数を作る ・関数の中にループ処理を書く ・ループの中に一文字読み込む処理を書く 以上
>>95 の質問に付け足しです。
数値を文字に変換するという問題を出されたんですが、ループする度に数字を一つずつ読み込んでいくというのの、関数の書き方を教えてください。
・関数を作る ・関数の中にループ処理を書く ・ループの中に数字を一文字読み込む処理を書く 以上
>>95 君にとっての全くの他人が君のその書き込みによって
君が望んでいることを100%理解することができる確信があるか。
あるなら誰も止めはしないが、おそらく望む答えが返ってくる確率は極めて低い。
一番安全に入力させる方法ってなんなの?
103 :
デフォルトの名無しさん :2008/05/22(木) 21:43:27
質問です。変数の型について調べているのですが、 float型とdouble型について、まずFLT_MINとDBL_MINで最小値を表示させたところ、 floatの最小値:1.175494e-38 doubleの最小値:2.225074e-308 と出ました。次に、 float i,j=1.0; int k=0; for(;;k++){ j = j*0.5; if(j == 0) break; i=j; } こんなようなプログラムを書いて、最小値を調べようとしました。(double型は上のfloatをdoubleに置き換えて調べました。) そうしたら、floatでは 1.401298e-45 という値が、doubleでは 4.940656e-324 という値が出てきました。上に書いたマクロ定義で調べた値と違うのですが、なぜなんでしょうか? アンダーフローすると0になるというように聞いたので0になったらループを抜けるというようにしたのですが・・・ 何かわかる方おられましたら教えていただけないでしょうか、よろしくお願いします。
>>103 その出力値は非正規化数で表せる最小値。
FLT_MINやDBL_MINの値は正規化数で表せる最小値。
正規化数は1.xxxx * 2のn乗という形で表されるが、
非正規化数は0.00xx * 2の(指数の最小値)乗という形で、
正規化数よりさらに小さな値を表す。
その代わり見てのとおり精度が犠牲になっている。
どんな場合でも、浮動小数点数の値が別のある値と==であるとか あるいは<=や>=であることを期待してループの終了条件とかに使ってはいけない 浮動小数点数はあくまで実数のシミュレーションで、 本当に細かい部分の値がどうなっているかはたいてい予測しがたいから
アンダーフローって0になるとは限らなかったと思うが
107 :
103 :2008/05/22(木) 22:23:56
みなさんレスありがとうございます。 「(指数の最小値)乗」ということは、floatの場合0.00xx * 2の-38乗という形を直したものが1.401298e-45ということでしょうか? ==を使って終了条件がつくれないとなると、ループを使ってアンダーフローまで繰り返すという方法自体が無理なのかもしれないですね。 アンダーフローが0になるというのはネットで検索してて見つけたのですが・・・
IEEEの浮動小数点数は段階的にアンダーフローして最終的にはゼロになる 最初のアンダーフローの時点で例外を吐いて実行を止めるかどうかは処理系定義 だったっけ どのみちそういう非正規化領域の値の演算が役に立つとも思われんけど
mathematicaみたいに広い範囲の数値を計算するにはどうすればいいの?
多倍長のやつをじっそうするとかそういうライブラリ使うかしろ
>>107 「アンダーフローが0になる」というのは、そういう処理系が多い、ってだけの話。
処理系によって扱いが違うはずだから、まずはその処理系のマニュアルを読んだほうが良いかと。
>>108 アンダーフロー例外で割り込み発生させるかどうか
CPUに設定できるのもあるぜ
そこまでいくとハードの話になるが
>>113 やや古い(というかむしろ事実上標準の)規格では
途中での宣言は禁止だからだな
Sound *snd;をmain関数内の先頭に移動させてみたら?
{ Sound *snd; if((snd = Read_Wave(argv[1])) == NULL){ exit(1); } if(Write_Wave(argv[2], snd)){ exit(1); } Free_Sound(snd); } って囲えば?
116 :
116 :2008/05/23(金) 02:49:01
>>116 analyze_graph() →analyze_depth()
→analyze_breadth()
じゃないの?
そういうことではない?
118 :
116 :2008/05/23(金) 07:01:41
>>117 え?すいませんもう少し詳しく教えてもいただけないでしょうか?
Visual C++ 2005を使っているのですが <windows.h>が動きません。 どこをどうしたらいいでしょうか?(スレチかな?)
PlatformSDKとか、WindowsSDKが入っていないか、 インストール先が変更されてインクルードパスが通っていないとか まずHDD内のどこかに、windows.hがあることを確認してみよう あるならあるで、設定の問題と。ばかばかしいが、話はそれからだ
2008なら最初から入ってるよ>Windows SDK (Express Editionでも)
char fname[256]; printf("入力ファイル>"); scanf( "%s", fname ); これで入力したファイル名が存在しないならエラーを表示するプログラムってどうかくんですか?
FILE *fp; char fname[256]; printf("入力ファイル>"); scanf("%s",fname); if ((fp = fopen(fname, "r")) == NULL) { printf("ファイルを開くのに失敗しました\n"); exit(1); }
どうも
125 :
デフォルトの名無しさん :2008/05/23(金) 14:00:40
最適二分木問題っていうのはどのようなものなんでしょうか?
>>125 最適二分木という言葉はちょっと聞いたいたことがない
たぶん平衡二分木を作る問題のこと
平衡二分木が何かについて知らないならまず数学板へ行くこと
127 :
デフォルトの名無しさん :2008/05/23(金) 15:01:00
128 :
デフォルトの名無しさん :2008/05/23(金) 15:59:58
int (*a)[10]; という宣言は何を表しているんですか? いまいちイメージがつかめないので使用例なども教えてください
>>128 (*a)はint型の長さ10の配列を意味し
(*a)[3]はその4番目の変数を表す。
つまりaは(○○○○)へのポインタということになる
○○○○の部分は自分で考えてね。
int a[10]; は「 a は 要素数が 10 の int の配列である」と読む。 同じように、int (*a)[10]; は「 *a は 要素数が 10 の int の配列である」と読む。 *aが配列であるなら、つまりaは配列へのポインタである。 *aにカッコをつけるのは、*演算子より[]演算子の優先順位が高いから。 もし int *a[10]; と書いたらこれは int *(a[10]); と解釈されて、 「 a[10] は int へのポインタである」となる。
>>128 int (*a)[10]; a is pointer to array(10) of int
ちなみに
int *a[10]; a is array(10) of pointer to int
関数ポインタについて何ですが ヘッダファイルで extern foo[](); を宣言して その実体を.cファイルに記述するのですが このfoo[]()は外部に公開したくないので staticな関数にしようとするとエラーになってしまうのですが そういう物なのでしょうか?
133 :
デフォルトの名無しさん :2008/05/23(金) 19:03:37
void aretottekoi() { 処理 return ; } 何故return ;をするんですか?
習性、なんとなく常にreturnを最後に入れたいから 確かに無しで問題ない、あってもなにも変わらない
>>132 externつけて宣言した変数の実体をstaticつけて定義してるのか?
>>135 宣言を
extern static foo[]();
としたら怒られるし
実体の方にstatic宣言しても効果はないし・・・
ヘッダの先頭でstatic つけて宣言するだけでいいんじゃね
まちがえた.cのほうにstaticつけてへっだに何も書かなきゃいいんじゃねーの?
>>137 ヘッダでstaticのみ付けると
[]の数を具体的に示せとエラーが出て
ヘッダ内で実体を書くと
多重定義でエラーが出ます・・・
公開したくない外部ってどこのこと? externって「外部の」って意味の単語なんだけど。
dllってどうやって作るんですか?
というか extern foo[](); なんて宣言できたか?
いろいろ省略してるんだろおもってスルーしてたが
たぶん extern (*foo[])() の間違いだろう 関数の配列なんて存在しないから
公開したくないのになぜextern宣言する
なにを公開したくてなにを公開したくないのか整理しなおせ
148 :
デフォルトの名無しさん :2008/05/23(金) 19:45:25
16bitで signed のデータが、バイト単位で入ってきます。 これが unsigned char に格納されています。 マイコンへの組み込みの場合 これを signed int のデータに格納するには どのように書くのが一般的でしょうか? intは、16bitです。 unsigned char High_Byte_Data; unsigned char Low_Byte_Data; int a; a = (int)(((unsigned int)High_Byte_Data << 8) + (unsigned int)Low_Byte_Data);
C言語の本を買おうと思うのですが、入門書の次に買うようないい本ないでしょうか。
>>148 キャストはぜんぜん必要ないと思うぞ。
a = (High_Byte_Data << 8) + Low_Byte_Data;
ないとまずいのは右シフトだね!
あとchar型の演算はint型で行われるってやつ この二つであってる?
signed char でハマるのも良い思い出。
>>118 「連結成分分解」がわからないけど、
analyze_graph() からanalyze_depth()とanalyze_breadth()を呼び出して、
そこでやってるんじゃないかと推測。
ヘッダって別に.hじゃなくても.cでよくね? なんでソースコードと区別すんだ? って思ったんだけど、なんか理由あるの?
mylib.h mylib.c って対に作ることが多くないか? mylib_pub.c mylib_imp.c なら結局同じことだし
>>155 Cのプロジェクトの構成概念上、へっだとソースは別のものであり、
ゆえに先人はこれを名前で区別することを望み、そのために.cと.Hを使うことを選び、
そしてそれはよい慣例となったからである。そしてこの慣例を無視するべき理由は、
少なくとも多くの人を納得させるであろうものは、きっと存在しない。
>>155 ヒント:make のデフォルトサフィックスルール
そりゃ後付でそうなってるだけだろw
ヘッダファイルをコンパイルしても無意味だし、
ヘッダをコンパイルしてコードが生成されたら
それはそのヘッダが悪い。
.hを.cにしてもいいが、無駄なコンパイル作業が
増えるだけなのでコンパイルすべき.cとは区別すべき。
そんなこともわからない
>>159 はいっぺんリビルドされるべき。
後付けっていうか、make以前から
>>160 みたくしてただろうってことでは
小規模なプログラムなら、.cも.hも適当でいけるが、
.cと.hに分離することで、何かとうまく運ぶというか
運用上の利便性があると
162 :
デフォルトの名無しさん :2008/05/24(土) 11:23:14
要素数がnの二分木を力ずく法っていうのを使って全パターン作りたいんですけど どういうふうにやったらいいんでしょうか
>>162 名前からして総当りすればいいんじゃねw
164 :
デフォルトの名無しさん :2008/05/24(土) 11:59:22
○3 図1 / \ ○2 ○5 / / \ ○1 ○4 ○6 上図みたいに左の要素は自身より小さくて右は大きいとして(添え字は要素の大きさ) ビット列の表現で作りたいんですが ○1 図2 \ ○2 \ ○3 \ ○4 \ ○5 下にいくなら1、上にいくなら0とかすると 図2なら11111みたいに でもこの方法だと図1が作れないので他にいい方法がないでしょうか
任意の数字n個をテキストファイルに出力したいんですが 1 2 ・ ・ 100 のように ファイルオープンなどの使い方がよくわかりません。 1〜10までの数字を順番にテキストファイルに出力するプログラムを書いて簡単な説明をしていただけませんか?
int main() { int n, i; FILE *fp; scanf("%d", &n); if (fp = fopen("hoge.txt", "w") == 0) return 1; for (i = 1; i <= n ; ++i) { fprintf(fp, "%d\n", i); } fclose(fp); return 0; } fopenで開いて返り値をとって、そこのfprintfでどんどん書き込む そんだけ
#include <stdio.h> main(){ int i,n; FILE *fp; fp=fopen("test.txt","w"); for(i=0;i<=100000;i++){ n=i; fprintf( fp, "%d\n",n ); } fclose(fp); } をつくって、10000までの数字は順番に出力できたのですが50000から正常に出力できません 50000の場合30000越えたあたりから数字が急にマイナスのあたいになってしまって 100000だと実行後にフリーズしてしまいます。 なにがおかしいのでしょうか?
int
16bitの環境で勉強っすか。
なんかいい方法ないですか?
longを使うとか。
172 :
148 :2008/05/24(土) 13:55:28
>>150 >>151 ご回答ありがとう御座います。
unsigned char の値が、どのように int に格納されるのかよく分かりません。
特に負の値の場合なのですが、例を挙げて解説されているサイトをご存知ないでしょうか?
High_Byte_Data = 0x8B
Low_Byte_Data = 0xCD
longつかっても何も変わりませんでした
174 :
デフォルトの名無しさん :2008/05/24(土) 13:56:23
1、2、3、4、5の並び替えの120通りを配列につめこむプログラムを教えてください
#include <stdio.h> main(){ long i,n; FILE *fp; fp=fopen("test.txt","w"); for(i=0;i<=50000;i++){ n=i; fprintf( fp, "%d\n",n ); } fclose(fp); } 今50000になってるとこを変えてやってるんですけど30000までしか正しく出力できません
なんていうか・・入門系の本なんでも良いから1冊やるべきだと思う
いや、
>>176 のどこにミスがあるか教えてください
>>176 50000L にするのと %ld じゃね?
181 :
側近中の側近 ◆0351148456 :2008/05/24(土) 15:14:53
>>164 (っ´▽`)っ
二分木だよね?
二分木の表現方法はいろいろある。
以下は節点・小・大の順に並べる方法。
図1:321_546 →0011001000010000010101000110
図2:1_2_3_4_5 →000100000010000000110000010000000101
読み方は、
節点(3)
→小さいほうの枝(2)
→大きいほうの枝(5)
→小さいほうの枝(2)の小さいほうの枝(1)
→小さいほうの枝(2)の大きいほうの枝(_)
→大きいほうの枝(5)の小さいほうの枝(4)
→大きいほうの枝(5)の大きいほうの枝(6)
_は空を意味する。要素の大きさは2進法で表示する。
上記の場合、要素のサイズは4バイト。つまり、最大が1111(2)=15。
空(_)を0000で表示する。
0は空で予約されているため、要素の最小値は0001(2)=1
182 :
側近中の側近 ◆0351148456 :2008/05/24(土) 15:17:53
(っ´▽`)っ 他にも葉→節→根の順に並べる方法もある。 図1:1_24653 図2:5_4_3_2_1
183 :
デフォルトの名無しさん :2008/05/24(土) 15:30:00
184 :
デフォルトの名無しさん :2008/05/24(土) 17:53:28
1〜10までの自然数の和を求めるプログラムをfor文を用いて作成 #inclede <stdio.h> void main(void) { int sum; int i; sum = 0; for(i=1;i<=10;i++){ sum = sum + i; } printf("sum = %d\n",sum) } これでレポートだしたら自然数の和になってないから駄目だといわれた。 なんでだろ
incledeがまずいんじゃね?
0から始まってないからだろ
って、ああ問題が1〜10なのかスマン
void main(void) がまずいんじゃね?
189 :
デフォルトの名無しさん :2008/05/24(土) 18:09:38
>>184 のやってることは0+1+2+…+10の総和を求めてるから
"自然数"の和になってないからでは。
sum = 1;
for(i=2;i<=10;i++){
sum = sum + i;
}
たしかにsumの初期値の0は自然数じゃない・・・ しかしへりくつのような気も・・・
>>189 自然数とだけ言った場合0を含むのか含まないのかは分かりません
192 :
側近中の側近 ◆0351148456 :2008/05/24(土) 18:17:26
(っ´▽`)っ n(n+1)/2を使えってことでしょうな
for文使えと書いてあるのにか
194 :
側近中の側近 ◆0351148456 :2008/05/24(土) 18:19:24
(っ´▽`)っ #include <stdio.h> int main(void) { int n = 10; int sum; sum = n * (n + 1) / 2; printf("sum = %d\n", sum); return 0; }
"sum=%d¥n"× "1+2+3+4+5+6+7+8+9+10=%d¥n"◎ こういうことってありがちじゃない?
197 :
側近中の側近 ◆0351148456 :2008/05/24(土) 18:23:47
>>195 #include<stdio.h>
int main( void ){
int i, sum = 1;
printf("%d",sum);
for(i=2;i<=10;++i){
sum += i;
printf("+%d",i);
}
printf("=%d\n",sum);
}
こういうことか?w
199 :
側近中の側近 ◆0351148456 :2008/05/24(土) 18:34:41
(っ´▽`)っ こういうことかな?カナ?けいいちくん♥ #include <stdio.h> int main(void) { int i; int n = 10; int sum = 0; char formula[128] = ""; for(i = 1; i <= n ; i++){ sum += i; if(i == 1){ strcat(formula, "1"); } else{ sprintf(formula, "%s+%d", formula, i); } printf("%s=%d\n", formula, sum); } return 0; }
なんでループに入れてムダな分岐増やしたがるアホはいなくならないんだろう
201 :
側近中の側近 ◆0351148456 :2008/05/24(土) 19:04:39
>>200 (っ´▽`)っ こうしろと?
sum += i;
strcat(formula, "1");
printf("%s=%d\n", formula, sum);
for(i = 2; i <= n ; i++){
sum += i;
sprintf(formula, "%s+%d", formula, i);
printf("%s=%d\n", formula, sum);
}
202 :
側近中の側近 ◆0351148456 :2008/05/24(土) 19:07:32
(っ´▽`)っ こうかな? #include <stdio.h> int main(void) { int i; int n = 10; int sum = 0; char formula[128] = ""; for(i = 1; i <= n ; i++){ sum += i; sprintf(formula, "%d+", formula, i); printf("%s\b=%d\n", formula, sum); } return 0; }
ビットフラグについて簡単なコードを用いて教えて下さい。
#define BIT(k) (1<<(k)) フラグを立てる a|=BIT(k) フラグを下げる a&=~BIT(k) フラグ検査 a&BIT(K)
205 :
側近中の側近 ◆0351148456 :2008/05/24(土) 19:27:21
>>203 (っ´▽`)っ
int main(void)
{
int x = 0;
if(処理1を行なう条件が真){
x |= 1
}
if(処理2を行なう条件が真){
x |= 2
}
if(処理3を行なう条件が真){
x |= 4
}
if(処理4を行なう条件が真){
x |= 8
}
if(x & 1){
処理1
}
if(x & 2){
処理2
}
if(x & 4){
処理3
}
if(x & 8){
処理4
}
return 0;
}
206 :
側近中の側近 ◆0351148456 :2008/05/24(土) 19:31:22
1〜10までの数を10個被らないで表示させたいんですけどプログラム書いてもらえませんか? 乱数使ってやってみたんですけど数字が被ってしまいます
つ shuffle
>>207 配列に1〜10の数値を入れておいて、乱数でシャフルすればいいよ。
10! > RAND_MAXだと完全にランダムにならないから要注意だぞ
なに?それ
それを言い出したら、ランダム自体が完全には無理。
ちょっとよくわからないです 乱数で出力する際に同じ値が出力されてたらやり直すとかでできないですか?
>>213 やればいいじゃないか、
10個ぐらいならその方式で問題ないだろ
具体的にプログラム書いてもらえませんか?お願いします
>>215 わかりました、ちょっとまっててください
今Linuxでプログラムを作ってて、ビープ音を鳴らすようなプログラムを 作ってるんですが、エスケープシーケンスで周波数を変更するというのが 仮想コンソールではできないようなので、起動時に何らかの方法でビープ音を 鳴らすかどうか選択させるようにしようと考えてます。 その場合、どのようにして鳴らす・鳴らさないを切り替えればいいのでしょうか? 毎回if文で振り分ける事もできるのですが、短時間にかなりの回数ビープ音を 鳴らすルーチンが呼ばれるので、処理軽減の目的でできれば使いたくないんです。 なにかいい方法はありますでしょうか?よろしくお願いします。 長文失礼しました。
>>213 そんなやり方じゃ、出力のたびに確認が増えるだろ。
>>217 >その場合、どのようにして鳴らす・鳴らさないを切り替えればいいのでしょうか?
>毎回if文で振り分ける事もできるのですが、短時間にかなりの回数ビープ音を
>鳴らすルーチンが呼ばれるので、処理軽減の目的でできれば使いたくないんです。
>なにかいい方法はありますでしょうか?
ここを分かるようにいってくれ。
>>217 その程度のことなら毎回ifでも問題なさそうな気がする。
ビープ鳴らすコストでifのコストなんてかき消されると思う。
本当に毎回ifでだめか試してみろ。
Cの入門書が終わったレベルから読める物理シミュレーションの参考書でいいものがあったら教えてください
>>220 いや、実際できます。4ms毎に呼んでいて、1秒で250回呼ばれることになるので
できるだけ処理を軽くしたいと思いまして。(ビープ音源による擬似和音でして。)
将来なにかアプリケーションとかを作った際にビープ音に限らず役に立つように
思ったので、他に方法あるかなーと思いまして。
なので他の方法をもしよろしければよろしくお願いします。
>>217 関数ポインタを使う方法。
int (*p) (int num); /* 関数ポインタpを宣言 */
/* beep音発生処理 */
int beep(引数){処理}
/* 何もしない */
int no_op(){ return 0;}
/* 起動時処理 */
if(条件){p = beep;}
else {p = no_op;}
(*p)(引数); <---プログラム中にたくさん
>>223 そんな方法があったとは知りませんでした。
それを使ってみます!
>>224 おお!わざわざありがとうございます!
じっくり読んでみます。
>>207 #include <stdio.h>
#include <stdlib.h>
#define N 10
#define SEED 31415926
int main()
{
static int a[N];
int i, n;
srand(SEED);
for (i = 0; i < N; i++)
a[i] = i;
for (i = N ; i > 0; --i) {
n = (int)((double)rand() / (RAND_MAX - 1) * i);
printf("%d ", a[n]);
a[n] = a[i - 1];
}
putchar('\n');
return 0;
}
N-BASIC の時代にすでにあったようです。手元にはとある雑誌の1981年12月号があります。
関係ないですが、全角空白(&h80, &h41)はいやなんですが、どうすればいいんでしょうか?
>>226 どこかのアップローダーにアップロードをするしかないかな
インデント部分だけ全角空白ならまだいいんじゃない? 全置換→再インデントができる環境ならなんでもないんだけど、 スペースすべてが全角空白だと苦しむ人もいるだろうね
txtに書いてどっかにうpれ
>>225 関数のポインタは、ifの分岐に比べて速くなるとは限らないよ。
むしろ遅くなるかも。
>>226 毎回違う結果を出したいなら、以下を追加。
#include <time.h>
srand((unsigned)time(NULL));
>>222 ビープ鳴らす処理がほかと独立しているなら、
そのためのスレッドを作るようにするってのはどうだ。
鳴らさないときは、そもそもスレッドを作らないようにする。
個人的には、全体的に軽くしたいのなら、
他にもっと重い処理がないか、そしてそれを改善できないかを考えるほうがいいと思う。
1秒に250回のビープくらい、大したことなさそうな気がしてならない。
>>229 thanks! うまくいきました。次回からはそうします。
236 :
側近中の側近 ◆0351148456 :2008/05/25(日) 07:37:11
237 :
側近中の側近 ◆0351148456 :2008/05/25(日) 07:38:56
(っ´▽`)っ if文があるからといって遅いとは限らない if文がないからといって速いとは限らない やはり計測ですよ計測☆ 計測してやはり遅ければ対応を取ろう。 速ければ問題なし☆
238 :
側近中の側近 ◆0351148456 :2008/05/25(日) 07:41:36
(っ´▽`)っ むしろ可読性、保守性を優先すべきです。
239 :
側近中の側近 ◆0351148456 :2008/05/25(日) 07:45:49
(っ´▽`)っ っていうか、1秒間に250回ビープ音鳴らすなんてどんなシステムなんだよ。 if文全部消して実行したとしても、音源の出力待ちが多発するんじゃないのか?
>>234 それもそうですね。なんか変なとこにばっかりこだわってた
かもしれないです。
>>239 いや、昔のPC98であったようなビープ音で擬似和音を作って
曲を鳴らしたいと思いまして。例えば440Hzと220Hzを高速で
切り替えると和音っぽく聞こえるみたいな。一応ビープ出力を
すると発音中のを上書きして発音するような感じなんで問題は
ないかと。ただ前なぜか実験中、一撃で電源落ちましたが。
>>172 unsigned char→int の場合は符号拡張される。
負の値の場合だと、例えば
0xCD → 0xFFFFFFCD
になる。
242 :
241 :2008/05/25(日) 08:55:57
>>241 >
>>172 >
> unsigned char→int の場合は符号拡張される。
> 負の値の場合だと、例えば
> 0xCD → 0xFFFFFFCD
> になる。
ごめん、何言ってんだ、俺。
0xCD → 0xCDは変わらないが、10進表現されるときに負の値になる。
>>241 はぁ?
なんで、unsigned charが負に拡張されるんだよ。
#include <stdio.h> int main(void) { unsigned char a=0xFF; signed char b=-1; signed int c; c=a; printf("%d %d %u %u %X %X \n",c,a,c,a,c,a); c=a; printf("%d %d %u %u %X %X \n",c,b,c,b,c,b); return 0; }
>>244 2回目の、c=a; は c=b; のつもりかな?
#include <stdio.h> int main(void) { unsigned char a=-1; signed char b=-1; signed int c; c=a; printf("%d %d %u %u %X %X \n",c,a,c,a,c,a); c=b; printf("%d %d %u %u %X %X \n",c,b,c,b,c,b); return 0; }
http://www.geocities.jp/ky_webid/cpp/language/038.html ここに書かれてあるようにcとc++を同時に使うには、はじめに何を宣言したらいいですか?
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include "math.h"
#include "time.h"
#include "sift.h"
#include "imgfeatures.h"
#include "kdtree.h"
#include "utils.h"
#include "xform.h"
#include "cv.h"
#include "highgui.h"
#include <cv.h>
#include <cxcore.h>
#include <highgui.h>
こんな宣言したらエラーがでたんですが…
>>248 エラーの内容は?""で囲んだファイル名のヘッダはちゃんと存在しているのか?
コンパイルしようとしたソースファイルは?
250 :
248 :2008/05/25(日) 12:49:44
1>c:\program files\microsoft visual studio 8\vc\include\cstdio(25) : error C2143: 構文エラー : '{' が ':' の前にありません。 というエラーがでます。 そして、<studio.h>を消すと、 <stdlib.h>でエラーがでます。ほんとにお手上げです。 ソースファイルには問題はありません。
.c に入れてるんじゃねーの?
>>250 > ソースファイルには問題はありません。
へぇ
>>250 だからヘッダというより構文の方にだな・・・エラーが出てるじゃないかw
C++はスレ違い。やるならあっちで。
255 :
251 :2008/05/25(日) 13:15:50
スレ違いマルチに優しいなおまいら
どこに行ったんだろう
ん?あいつなら今も生きているさ・・・おまいらの心の中に。
259 :
241 :2008/05/25(日) 16:08:50
>>242 すまん、完全にボケてる…orz
吊ってくる
配列へのポインタを格納するのに以下の2つの方法があるけど、ど ちらが一般的でしょ? 1. p = &arg[0]; 2. p = arg; 1の方法は冗長に思えて嫌なのだけど、配列であることを明示する 為には有効なのかな? それともただの好み?
配列変数に配列を明示する名前をつけた上で1.かな。
配列を明示する名前ってたとえばどんなの?
*arrayとか。
じゃあ良い例を。
配列のアドレスは&argだろ!
>>260 お好みでいいし、どちらかに固定するべきものでもない。
演算子だと思ったのか。ワイルドカードとして見て欲しかった。
>>260 どっちでもいいけど、前者だと配列それ自体より配列の要素へのポインタってイメージが強いな。
>>265 つか、配列に array とか名前つけるのがいい例だと思ってるの?
>>260 そもそも配列へのポインタであることを意識する必要があるのかと。
argが配列かポインタかによって、その後のpの扱いに違いがあるのだろうか。
>>271 配列ならpをインクリメントする可能性があるだろうな。
>>272 配列じゃなくてもインクリメントするだろw
結局のところアクセスできる範囲と型とを
意識しないといけないからどっちも扱いは変わんないよ。
迷うならコメント。ひとことでいいから
つうか配列ならインデクサで書けよ
C言語を始めたばかりの初心者ですが、問題集の問題がよく分からないので 教えて貰えませんか? 開発環境はVisual Studio 2005です。 問題↓ 西暦年を入力して、その年が閏年か平成かを判定する関数を作成する。 閏年は、西暦年が 4の倍数であり、かつ100の倍数でない。 400の倍数である。 <実行例> 西暦年:1990 平成です ------------ 西暦年:1996 閏年です どうすればいいのでしょう?^^;
平成はねーよw
1989をくわしく というか書いたのそのまま入れてけばできるよ
平成天皇は不老不死という前提でいいんだろうか・・・
#include <stdio.h> main() { int year; scanf("%d", &n); printf("西暦年:%d\n"); if (year >= 1989) printf("平成です\n"); if (year % 4 == 0 && year % 100 != 0 && year % 400 == 0) printf("閏年です\n"); }
285 :
276 :2008/05/25(日) 20:53:24
すいません、平成じゃなくて「平年」でした^^;
>>281 >if (year % 4 == 0 && year % 100 != 0 && year % 400 == 0)
ひどすぎる
wikipediaあたりからコピペすりゃいいのに
まだ早い
最適化すると if(0)
>>280 if (1989 <= year && year < 2008)
printf("平成です\n");
else if (2008 <= year && year < 2018)
printf("恐らく平成です\n");
else if (2018 <= year && year < 2038)
printf("ひょっとしたら平成かもしれませn\n");
else if (2038 <= year && year < 2048)
printf("平成ではないと思います\n");
else if (2058 <= year)
printf("平成ではないのはほぼ確実です\n");
292 :
276 :2008/05/25(日) 21:30:55
すいません、解決しました。 どうもありがとうございました。
元号なんて不経済だよ
if (year > 1900 && year < 2100) { printf("%s年です\n", year % 4 == 0 ? "閏" : "平"); } else { fprintf(stderr, "そんな過去や未来、気にしてもしょうがないじゃないですか。\n"); }
296 :
デフォルトの名無しさん :2008/05/26(月) 01:26:44
#include<stdio.h> void main(void) { char id1,id2,id3; printf("2桁の数字を入力してください"); scanf("%d",&id1,&id2,&id3); printf("16進数にすると%02xです。\n",id1); printf("3文字の略語アルファベットを入力して下さい:"); scanf("%d,"&id1); printf("逆順にすると%dです\n",id1,id2,id3); } 実行結果 2桁の文字を入力してください。 16進数にすると026です。 3文字の略語(アルファベット)を入力してください:EOF 逆順に生じするとFOEです。 エラー1 c:\users\nhsxxxxx\documents\cl11\525\525\a.cpp(7) : warning C4996: 'scanf': This function or variable may be unsafe. Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. c:\program files\microsoft visual studio 8\vc\include\stdio.h(295) : 'scanf' の宣言を確認してください。 c:\users\nhsxxxxx\documents\cl11\525\525\a.cpp(11) : error C2296: '&' : 無効です。左オペランドには型 'const char [4]' が指定されています。
scanf("%d,"&id1); ↓ scanf("%d",&id1);
298 :
デフォルトの名無しさん :2008/05/26(月) 01:32:40
>>297 デバックなしで開始はできましたが
最後の逆順に表示するとFOEです。というところにエラーがでます
printf("3文字の略語アルファベットを入力して下さい:");
scanf("%d,",&id1);
printf("逆順にすると%dです\n",id1,id2,id3);
}
scanfに何を入れたらいいか。。どなたかお願いします><
printf("2桁の数字を入力してください"); scanf("%d", &id1); printf("16進数にすると%02xです。\n",id1); printf("3文字の略語アルファベットを入力して下さい:"); scanf("%c%c%c", &id3, &id2, &id3); printf("逆順にすると%dです\n",id1,id2,id3);
scanfの戻り値をチェックしないすべてのコードに災いあれ
すまん適当に書いたら全然見当違いだった
どんな教科書を読めば296みたいなコードを書くようになるんだろう
その書き方はよくないのかい?
教科書なんかだと盲目的にintを使いそうなもんだけどな どんな意図でcharを使ってるんだろうか
なんだこいつ。 -- printf("3文字の略語アルファベットを入力して下さい:"); scanf("%d,"&id1); printf("逆順にすると%dです\n",id1,id2,id3); -- 3文字の略語(アルファベット)を入力してください:EOF 逆順に生じするとFOEです。 -- コピペもできないのか?
306 :
デフォルトの名無しさん :2008/05/26(月) 20:44:41
1,2,3,4,5の順列を考えて 二次元配列に入れるプログラムをどなたか教えてください 1,2,3,4,5〜5,4,3,2,1の120通りを a[120][5]のような配列に入れるプログラムです、お願いします
>>306 さぁ宿題スレにいくんだ
もしくは自力でもうちょっとがんばれ
>>306 エレガントではないけど、
まず、5*5*5*5*5=3125の重複順列を作って
その中から、重複しているものをはずせば
309 :
デフォルトの名無しさん :2008/05/26(月) 21:13:51
doxygenってなんて読むの? なんて読んでる?
310 :
デフォルトの名無しさん :2008/05/26(月) 21:14:09
今日からCを学び始めましたが char* argv[] という記述の意味がよくわかりません。 char型のデータを保持する配列変数argv[]の 先頭アドレスを保持するポインタ変数*argvを宣言する、 という意味ですか?
char ** argv と同じこと
>今日からCを学び始めましたが >char* argv[] 速すぎだろ
char *argv[] のことか?
>>311 要素数が空の配列宣言子 [] は、関数の引数リストに現れた場合、(最初の一回のみ)ポインタ宣言子に変換される。
よってこの場合 int main(int argc, char *argv[]) は int main(int argc, char **argv) と同じである。
char **argv の意味するところがわからなくて困っているなら、君はきっとまだやるべきでないページを開いているだろう。
もし本の先頭から順に読んでいってそのようなはめになっているのなら、今すぐその本を窓から投げ捨てることをお勧めする。
1.関数の引数リスト以外ではどこに現れますか? 2.int main(int argc, char *argv[])と int main(int argc, char *argv[1])と int main(int argc, char *argv[10000000])の 違いはなんでしょうか?
317 :
デフォルトの名無しさん :2008/05/26(月) 21:45:34
すみません。ポインタとインクリメント演算子の関係についてですが、 *p++; とした場合、++(後置インクリメント演算子)の方が優先順位が高いので先にp++が実行され、 その後 *pで値参照がされるという解釈でよろしいですか? また、++*pとした場合、前置インクリメント演算子(++)と間接演算子(*)の優先順位は同じなので また、両方の演算子の結合性が右であるため、先に*pが評価されその後++が評価されると考えればいいんでしょうか? よろしくお願いします m(_ _)m
>>117 ちがう・・というより、試してみなよそのくらい。
前置きの++と後置きの++は 同じ演算子では無く、 動作自体が違う。
321 :
317 :2008/05/26(月) 21:57:35
(;´д`)ちがうの・・・
>>318 試してるんですが、結果が思うようにいく(いかないじゃない)ので。。
>>319 ありがとうございました。
違うということなので、違うと覚えておいて、勉強を進めていきます。
趣味でやってるので、今わから無くてもいいので。。いずれ、わかればいいです。。
どうもありがとうございました。
322 :
317 :2008/05/26(月) 22:00:25
>>320 どうもありがとうございます。動作が違うんですね。あ!わかった!
ひとつの式としてみるんですね!
前置インクリメントの場合はひとつの式が評価される前にインクリして
後置インクリメントの場合はひとつの式が評価された後にインクリするんですね。
あー、ややこしい。。どうもありがとうございました。
>>306 #include<stdio.h>
#include<string.h>
int array_remove(int array[], int array_size, int index){
int ret;
ret=array[index];
memmove(&array[index], &array[index+1], sizeof(int)*(array_size-1-index));
return ret;
}
void foo(int result[5], int value){
int i, seed[5]={1,2,3,4,5}, div[5]={24,6,2,1,1};
for(i=0;i<5;i++){
result[i]=array_remove(seed, 5, value/div[i]);
value%=div[i];
}
}
int main(void){
int a[120][5], i, j;
for(i=0;i<120;i++) foo(a[i], i);
for(i=0;i<120;i++){
for(j=0;j<5;j++) printf("%d", a[i][j]);
printf("\n");
}
return 0;
}
>>317 *p++は(*p)++でなく*(p++)。これが++(後置インクリメント演算子)の方が優先順位が高いの意味。
後置インクリメントはステートメントの式の評価が終了してから行われる。
例として*p++=1;のステートメントは*p=1;p=p+1;として実行される。
>>316 1.外部配列のextern宣言
2.同じ
>>315 がどういうつもりで書いたか知らないけど、1個目の[]の中身は常に無視される
いいえ、「インクリ」しません。
327 :
319 :2008/05/26(月) 22:08:49
まず、*と++の優先順位は同じ、結合は右から左。なので、 *p++は*(p++)となり、まずp++が計算され、その結果(「その後」ではない)に*が作用する。この++はpの値を変化させる事に注意。 ++*pは、++(*p)としか解釈しようがなく、まず++pが計算され、その結果(「その後」ではない)に++が作用する。この++は*pの値を変化させる事に注意。 いずれの場合も、次のシークエンスポイントまでにpまたは*pの値が1増えるが、それがいつ起こるかはわからない。 -- 自然科学ではないのだから、「試してみてどうこう」などというのはもってのほか。規格書にあたるべし。
328 :
317 :2008/05/26(月) 22:09:42
>>324 ありがとうございます。自分としてはそのつもりで書いたんですが。。
ん〜、ややこしいので、またいずれわかるくらいの気持ちでいきます。
本当にありがとうございました。
329 :
317 :2008/05/26(月) 22:14:04
>>327 どうもありがとうございます。前置の場合は、優先順位じゃなく
それしか解釈のしようがないからなんですね。その辺は、おしえてもらって
よくわかりました。
後置の場合は、おおよそ僕の書き方がわるかったのかもしれませんが
一応
>>317 の文で理解してるつもりです。皆さんがおっしゃりたいことを
書いたつもりなので。
>>322 でややこしくなって、間違った事をかいてしまいましたが。
この問題についてよくわかりました。皆さんどうもありがとうございました。
こんなとこで言い訳しなくても
>>327 *p++は*p,p++でインクリメントは後だし、++*pで++pが計算されることなんてないんだが。
文字コード確認したいんですけど main() { unsigned char i; for(i=0; i<256; i++){ printf("%d=%c¥n",i,i); } } 無限ループします なんで?
お前ら、アホの集団みたいだね
335 :
333 :2008/05/26(月) 23:12:59
>>332 iが256になるから。
そんなことくらい自分で気付けよ、まったく。。。
アンサインド・チャーは256を作り出せないだから
337 :
333 :2008/05/26(月) 23:20:31
>>336 アンサインドキャラだろw
>>335 自分で変な書き方していたと思うので書き換える。
iがオーバーフローするから。
338 :
332 :2008/05/26(月) 23:23:05
for(i=0; i<=255; i++) でも駄目ですか?
やってみればわかることをなぜわざわざ聞く
書き方が悪かったです
>>338 これで駄目な理由が判りません
for(i=0; ++i;;)
>>340 unsigned char の範囲は 0 〜 255 です。
条件が偽になりません
unsigned char c=0; do{ }while(i++<255);
>>327 随分「試してみなよ」に反応してるが試して答えを見つけよと極論してるのではない。
言語仕様で決まってること、あいまいなことの学習はせなあかんよ。
それとは別に試すというのは *p++ = 5; だけでなく *(p++) や (*p)++ を体感するということでもある。*(p+1) であったり p[1] はどうなのかと・・・。
これから初めていくのに、正しい答えを後から理解するという回り道をすることがけして悪いとは思わない。
>>346 i <= 255 の間ずっとループまわせって意味だろ
つまり無限ループ
348 :
344 :2008/05/26(月) 23:56:08
いっけねついiって書いちゃった c++ね
>>332 i を unsigned char と宣言しているからである。
大抵の処理系で unsigned char は 0 〜 255 で、i<256 が偽になることはない。
正しく動くようにするには、int で宣言する。文字とはある小さな整数値であって、型 char のことではない。
そのライフはunsignedですか?
>>351 これ以上減らそうったってそうはいかないぜ
符号なしでも0は表現できます ><;
unsignedなlifeにlife-=damageしてゲームオーバーにならないバグ
355 :
332 :2008/05/27(火) 00:17:08
unsigned charで255の次は0だから255まで表示させるんだったら
for文ではなく
>>344 のように書かないといけないってことですね
お世話になりました
unsignedなlifeが1の時に2ダメージ食らうとアンデットになりますか?
まぁ、255 FF が最大だから、その値に一致したらオワルとか っつか、素直に符号ありのintにしチャイナと
そろそろgotoの出番か?
ユウキは逮捕されて、実刑判決がでましたよ?え?後藤のことじゃない?
いや、do-whileでもなんとかなるはず
ループ展開すればいいんじゃね?
>ループ展開すればいいんじゃね? コンパイラでもやらねーよ
>>306 ,308
亀レスだが、重複なしチェックを書いてみた。
int uniq_check(int x){
int i=0, sum1=1, sum2=1, a[]={0,2,3,5,7,11,0,0,0,0};
while(x>0){
sum1 *= a[x % 10];
sum2 *= a[i+1];
x /= 10;
i++;
}
return (sum1==sum2);
}
>>306 #include<stdio.h>
int main() {
int a[120][5], i, l, r, t;
for(i=0; i<5; i++) a[0][i]=1+i;
for(i=1; i<120; i++) {
for(l=0; l<5; l++) a[i][l]=a[i-1][l];
for(l=3; a[i][l]>=a[i][l+1]; l--);
for(r=4; a[i][l] > a[i][r]; r--);
t=a[i][l], a[i][l]=a[i][r], a[i][r]=t;
for(l++, r=4; l<r; r--, l++)
t=a[i][l], a[i][l]=a[i][r], a[i][r]=t;
}
for(i=0; i<120; i++) {
for(l=0; l<5; l++) printf("%d ", a[i][l]);
printf("\n");
}
return 0;
}
int
いんとじゃなくていんてだよ
サイキック #include <stdio.h> int check(int a[], int n, int col) { while(0<col--) if(a[col]==n) return 0; return 1; } void set(int a[][5], int n, int col) { static int row; static int tmp[5]; int i; if(0<=col) tmp[col++]=n; else row=col=0; if(col==5) { for(i=0; i<5; i++) a[row][i]=tmp[i]; row++; } else for(i=1; i<=5; i++) if(check(tmp, i, col)) set(a, i, col); } int main(int argc,char *argv[]) { int a[120][5], i; set(a, 0, -1); for(i=0; i<120; i++) printf("%3d %d %d %d %d %d\n", i, a[i][0], a[i][1], a[i][2], a[i][3], a[i][4]); return 0; }
>>368 うはwwwこんなコード書いたら先輩になぐられるなwww
>>369 慌てるな、殴られたら殴り返せ、目には目を、歯には歯を。
左の頬を打たれたら右の頬を差し出せ
そやそや、ケツを蹴られたら相手の前をケリ返せ! Kick in the nuts だぜ?
標準入力から文字(英小文字のみ)を読み込んだ後、 各アルファベットの出現回数を数えて表示する。但し出現回数0は省略する。 というプログラムを作ることになりました。 1文字づつ読み込み、それぞれを配列に入力、 配列を1文字づつアスキー番号と照らし合わせ、合致したら係数配列に1を追加 最後に、係数配列が0で無ければ表示 といった感じで考えているのですが、どうもうまくいきません。 模範解答は文字列を入力したらctrl + dを入力すると、結果が表示されますが、 私のでは文字列入力後にctrl + dを押しても何も起こりません。 どこに問題があるのかご教示下さい。
#include <stdio.h> int main(void) { char input[40],alpha[26],j=0; int i,l,k=0,count[26]; for(i=0; i<40; i++) { input[i] = get char(); } printf("\n"); for(i=0; i<=25; i++) { j=i+97; alpha[i]=j; } for(i=0; i<=40; i++) { for(; k<=25; k++) { if(input[i]==alpha[k]) { count[k]++; break; } } } for(i=0; i<=25; i++) { if(count[i] != 0) { printf("%c = %d\n",alpha[i],count[i]); } } return 0; }
突っ込みどころ多すぎ。 ctrl + d で終わるようにするには、getchar()の戻り値を EOF と比べてごらん。
>>375 模範解答はctrl+dを押すことと、出力結果のみで、
プログラム自体は書かれておりません。
1週間悩んでも分からなくて、こちらで質問した次第です。
>>373 UNIXを前提としている問題をWindowsで解こうとしてるとか?
>>377 とりあえず、EOFで入力を終了するようにすることと、
count[26] = {0}; とでもして0に初期化すれば
一応出るとは思う。
あ、あと k のforループで k = 0 追加な。何で省略したの?
>>372 相手にnutsが無いんですけど、どうしたらいいですか?
>>373 少なくとも以下のことについて考え直さなければならない。
・入力を最大40文字に限定する必要性
特に指定がない限り、入力されただけの文字を処理できるほうがよりよい解答である。
大抵の人は getchar() の戻り値がEOFになるまで1文字ずつ処理する、というコードを書くだろう。
標準入力に EOF を打ち込むには、UNIXでは ctrl+d を、Windowsでは ctrl+z を使う。
getchar() の戻り値は int で、EOF は char に収まらない可能性があることに注意すること。
戻り値を格納する変数を char で宣言していたら、無限ループに陥るかもしれない。
・配列を3つ用意する必要性
上記のように1文字ずつ処理を行うなら、入力をバッファする配列は必要なくなる。
1文字読んで、その文字がなんであるかを調べ、対応するカウンタを1増やせばよい。
英子文字の文字コードを格納する配列も必要ない。詳しくは下で述べる。
・文字セットを限定する意味
文字セットをASCIIに限定すると、当然ながらASCIIでない環境では正しく動かない。
もちろん一般的にはASCIIを使用している環境が大多数であるから、その自覚があって、
本当に汎用な移植性を考慮しないならば、ASCIIであると決めてかかってもかまわない。
問題は、そう決めてかかったとして、つまり英小文字が97から始まる一連の数値であるとして、
配列にその値を格納する必要があるかどうかである。'a' から 'z' までの値が一連であるとわかっているなら、
ある文字の 'a' から数えた番号を得るのは、単にその文字から 'a' を引けばよい。
つまり、ある文字 c に対応するカウンタを1増やすなら、count[c-'a']++; と書けばすむ。
また一方で、文字セットをASCIIに限定しないコードを書くならば、恐らくは switch 文を使って
26通りの分岐判定を行わなければならない。どの道、それを格納する配列は必要ない。
・カウンタの宣言の仕方
static と宣言したり関数の外で宣言した以外の変数の初期値はゴミである。
ゴミを演算に使ったら結果もゴミとなる(場合によってはクラッシュするかもしれない)。
変数の中身を使うときは、明示的に値が与えられたことを確認しなければならない。
この場合、各文字のカウンタは最初は0であってほしいのだから、int count[26]={0}; と宣言する。
383 :
デフォルトの名無しさん :2008/05/27(火) 13:48:04
display()とprintf()の違いをおしえてください。 調べてもよく分かりません。
まずdisplay()とやらがどこで出てきたのかから説明してもらおうか。
385 :
デフォルトの名無しさん :2008/05/27(火) 14:05:56
すみません。 勘違いでした。
>>382 補足
実際には入力された文字が本当に英小文字であるか確認する必要がある
(でないと予想外の入力があったときに配列の境界を踏み越えてしまって大騒ぎになる)。
これも、文字セットをASCIIであると限定するなら if('a'<=c && c<='z') と書けば済むし、
限定しないならやはり switch 文等での振り分けが必要になる。
387 :
デフォルトの名無しさん :2008/05/27(火) 15:14:38
今、C言語の問題をやってますが難しくて分かりません。 どのようにやったら良いでしょうか? //------------------------------------------------------ // C言語基礎 問題 // 3人の学生の英数国理社のテストの点数データが // それぞれ配列にある // 学生それぞれの平均点と科目別に平均点を出せ //------------------------------------------------------ #include <stdio.h> #include <stdlib.h> void main(void) { // 英 数 国 理 社 static int seito1[]={41,93,64,88,33}; static int seito2[]={84,31,78,53,57}; static int seito3[]={54,34,59,46,58}; }
宿題は宿題スレへ
すみませんorz
390 :
デフォルトの名無しさん :2008/05/27(火) 15:34:17
小数点以下を切り上げる関数を作ろうと思ったのですが どのように作ればよいでしょうか?
つ[ceil()]
dosスレで聞いたのですが答えが得られなかったので、このスレでご存知の方はいませんでしょうか? 実質的にstdinの話なのでCと深く関係してるんですが… dos, windowsプラットフォームで、 OS標準のコマンドのみで、バイナリ・ファイルをstdinから読み込みたいです。 852 名前: デフォルトの名無しさん 投稿日: 2008/05/27(火) 07:17:24 cat <in.txt >out.txt みたいなことできるdosのコマンドありませんか? (winは全バージョン可能) typeだとstdinからは無理っぽいんですが… copy con out.txt とかひねくれたの思いついたんですけど、これはstdinじゃないです。 困ってるのでよろしくお願いします。 857 名前: デフォルトの名無しさん 投稿日: 2008/05/27(火) 14:41:43 やりたい事は、標準入力からファイルデータ(特にバイナリ)を入力するので、 もしそのコマンドなら、 findstr /v "^$" <a.exe > b.exe とかです。が、失敗します。 858 名前: デフォルトの名無しさん 投稿日: 2008/05/27(火) 14:47:53 テキストファイルのときは、 more <a.txt>b.txt で出来ますが(実質copy /a a.txt b.txtと同じだけど意味が違う) バイナリファイルだとこのコマンドでは出来ません。 若しくは玄人向けのdosコマンドレファレンスのサイトご存知ないでしょうか。 861 名前: デフォルトの名無しさん [sage] 投稿日: 2008/05/27(火) 15:27:42 技術力が高いスレで聞いてもいいんですけど。じゃ質問を少し変えると、 標準入力(リダイレクト < )を使ってテキスト・バイナリ・ファイルを作ることはで来ますか? できれば、後はパイプでできるんで・・・ 標準入力の内容をそのままのデータで、ローカル・ディスク上のファイルにすることは出来ますか?と同じです。
>>392 Cでなくても標準入出力を扱えるツールは作れます。
勿論、Cでもできますが。
catとか作るのは簡単なんですが、そうするとそのPC(OS)標準じゃないですよね。 stdinからのデータをディスク上のファイルにしてくれるシェルコマンド・システムコール・ API関数とか予め用意されてるものです。 実質リダイレクトなんですけど、Cならsystem(char*)です。 ご存知ないですか?
どのOSのどのバージョン?
dos, win, プラットフォームで、全バージョン可能 今手元になくて試してないですが、そういえばunix(bsd,linux)のcatはバイナリ通るんですか? やりたい事は、バイナリで、cat <in.file>out.fileらしき事です。特にstdin受け付けるコマンド。 winですが、cygwinとかも入ってるし自作も出来るんですけど・・・
>>396 ここはCでプログラムを組むのに梃子摺る入門者向けのスレです。
DOS標準コマンドがどうだとか、シェルスクリプトがどうだとか言うのはスレ違いです。
思った回答が得られなくて焦っているのかも知れませんが、やっていることは嵐と同じレベルなので程ほどに。
398 :
373 :2008/05/27(火) 17:03:07
皆様から頂いたアドバイスを参考にプログラムを修正したところ、無事動作致しました。 何も考えずにそうした部分でも、様々な必要性など、考えもしなかったことばかりで、 まさに目から鱗という状態、大変勉強になりました。 ありがとうございました。
>>397 せっかく数行も書いてるようですけど、そういう時は適切なスレに誘導する事が出来るのが紳士的というものですよ。
>>399 だってDOSプログラミングスレとのマルチだし、この板以外は知らないもーん。
今日授業でint型の関数calc()で計算するプログラムを作ったんですが、関数にすると何が便利になるんですか?
402 :
デフォルトの名無しさん :2008/05/27(火) 17:56:30
ほしゅしやすい 変数が重複しない
>>401 例えば標準関数のprintf()が関数じゃなかったら不便だろ。
>>400 この場合はマルチって言わないよ。
Cと少し遠いのは確かだけど。
ストリームも絡んでるし、入門C程度じゃ答えられる奴はそうはいないだろう。
>catとか作るのは簡単なんですが、そうするとそのPC(OS)標準じゃないですよね。 って言ってるから、作るのは問題じゃなくて、OS標準のコマンドかどうかが問題なわけだろう。 少し遠いどころか、C言語の入門と全然関係ない。
>>401 例えば同じような計算を何度もしたいときに便利
int sum(int n) {
int i, t = 0;
for (i = 1; i <= n; i++) {
t += i;
}
return t;
}
int main() {
printf("1〜10の合計=%d\n", sum(10));
printf("1〜100の合計=%d\n", sum(100));
printf("1〜1000の合計=%d\n", sum(1000));
return 0;
}
> OS標準のコマンドのみで、バイナリ・ファイルをstdinから読み込みたい その時点で少なくともここよりdosだろ。
>>394 DOSはリダイレクトがないってことなんかな。
dir > filelist.txt とかできないってこと?
>>409 リダイレクトはあるよ。
catに相当するコマンドが無いってだけ。
CP/M からもってきたtype というビルトインコマンドがあったからcat相当のものが無いんだろうね。
catの本来の機能である、複数ファイルを連結する機能がほしいのではなく、 標準入力を受け取り、それを標準出力に出せればいいの? type hoge | more > foo 何がしたいのか理解できてない><
413 :
デフォルトの名無しさん :2008/05/27(火) 18:36:28
#include<stdio.h> void mat_add(const int ma[2][3],const int mb[2][3],int mc[2][3]) { int i,j; for(i = 0; i < 2; i++) for(i = 0; j < 3; j++) mc[i][j] = ma[i][j] + mb[i][j]; } int main(void) { int i,j; int ma[2][3] = { {1, 2, 3}, {4, 5, 6} }; int mb[2][3] = { {6, 3, 4}, {5, 1, 2} }; int mc[2][3]; mat_add(ma,mb,mc); for(i = 0; i < 2; i++){ for(j = 0; j < 3; j++) printf("%3d",mc[i][j]); putchar('\n'); } return(0); } 行列の和を計算するプログラムを作ったのですが、コンパイルして実行すると 何も表示されません。どの部分に不具合があるのでしょうか?
for(i = 0; i < 2; i++) for(i = 0; j < 3; j++)
>>413 多分間違ってる
>for(i = 0; j < 3; j++)
パッと見だけど、 for(i = 0; j < 3; j++) ここは j = 0 じゃない?
君たち、何を言ってるんだね for(i = 0; j < 3; j++) ここだろ。常考
mat_add の2重ループ、内側は for(j = 0; j < 3; j++) じゃない?
なんつー初歩的なミスを… 皆さんありがとうございました!
>>412 質問内容はこのスレのレベルを超えてるから、分からなくて当然じゃん
422 :
413 :2008/05/27(火) 19:37:13
すみません。また手詰まりになりました… 行列の積を計算するプログラムなのですが実行すると数値がおかしなことになります。 #include<stdio.h> void mul(const int ma[2][3],const int mb[3][2],int mc[2][2]) { int i,j,k; for(i = 0; i < 2; i++){ for(j = 0; j < 2; j++){ mc[i][j] = 0; for(k = 0; k < 3;k++){ mc[i][j] += ma[i][k] * mb[k][j]; } } } }
423 :
413 :2008/05/27(火) 19:37:41
int main(void) { int i,j; int ma[2][3],mb[3][3],mc[2][2]; for(i = 0; i < 2; i++){ for(j = 0; j < 3; j++){ printf("ma[%d][%d]:",i+1,j+1); scanf("%d",&ma[i][j]); } } for(i = 0; i < 3; i++){ for(j = 0; j < 2; j++){ printf("mb[%d][%d]:",i+1,j+1); scanf("%d",&mb[i][j]); } } mul(ma,mb,mc); for(i = 0; i < 2; i++){ for(j = 0; j < 2; j++){ printf("%3d",mc[i][j]); } putchar('\n'); } return(0); }
内積とかちゃんと理解してるのか?
425 :
413 :2008/05/27(火) 20:11:56
失礼、自己解決しました。mb[3][3]が間違ってますね…
行列のクラス作ればいいんじゃね?
>>426 クラスってなに?まあ、おまえには聞いてないがなww
429 :
デフォルトの名無しさん :2008/05/27(火) 22:02:41
#include <stdio.h>とか#include <stdlib.h>とか、 一行にまとめてかけないの?俺って、ソースがナガイの嫌いで簡潔にかきたいんだよね。 どの本見ても書いてないからさ〜。 あと、while文の中に?と:の三項演算子使いたいんだけど、 あれって、while(a?b:c)とすると変数cに偽である0を入れたら ループしなくなるのかな?教えてエロい人。
やってみた?
入力された文字列から数字文字列を削除する関数を作りたいんだけど ↓を作ってみて実行してもうまくいかない。どこがいけないのか教えていただきたい void del_digit(char str[]) { int i=0,j=0; unsigned len=0; while(str[len]) len++; while(str[i]!=0){ if(str[i]>='0' && str[i]<='9'){ for(j=i;j<=len+1;j++){ str[j]=str[j+1]; } i++; } else i++; } }
2重のwhileはなにゆえ?ってかforでよくないか? for-if-forでいけそうだけど、あんま考えずに書いてるんでずれてたらごめぽ。
>>429 一行の #include 指令で複数のヘッダを直接取り込むことはできない。
どうしても #include を書き連ねるのに堪えられないというのなら、
使う可能性のあるヘッダを全て #include したヘッダを作成すればよい。
以後は全てにおいてそのヘッダ一個を #includeすれば済む。
?: 演算子の意味を本当に理解しているか。
理解していないならもう一度教科書を読み直すこと。
void delDigit(char * str) { unsigned dest = 0; for (unsigned src = 0; str[src]; ++src, ++dest) { while (str[src] >= '0' && str[src] <= '9') ++src; str[dest] = str[src]; } str[dest] = '\0'; }
435 :
434 :2008/05/27(火) 22:26:00
for(j=i;j<len;j++) だろ
>>431 void del_digit(char str[])
{
int i, j;
for(i=j=0;str[i];i++) if(!isdigit(str[i])) str[j++]=str[i];
str[j]='\0';
}
438 :
431 :2008/05/27(火) 22:28:54
>>432 自分の傾向としてどうもfor文が得意でない
のでそれ以外で書こうとしてしまいがちです・・・
とりあえずfor-if-forの線で考えてみます
>>435 やっぱり難しく考えすぎですか・・・
ほぼ初心者なので書いてくださった
>>434 のあっさりした
プログラムが難しく感じてしまいます。
439 :
431 :2008/05/27(火) 22:33:24
いろいろとレスしてくださったかたがたありがとうございます 参考にして修正したいと思います
void DeleteDigit(char * szBase) { char* szString = szBase; do { while ('0' <= *szBase && *szBase <= '9') szBase++; } while (*szString++ = *szBase++); }
こんばんは x/=16ってどういう意味ですか?
x=x/16
C言語 複合代入演算子 でググれ
445 :
デフォルトの名無しさん :2008/05/27(火) 23:06:03
プログラムは難しいだろ。バグは絶対無くならないからね。 それに、ポインタもやらなければいけないからCはとても敷居が高いよ。
#include <stdio.h> int main(void) { int a; scanf("&d",&a); if(a-10)printf("入力値は10じゃない"); } 10 と入力しても「入力値は10じゃない」と出てしまいます。 どこが間違っていますか。
>>447 > scanf("&d",&a);
scanf("%d",&a);
451 :
447 :2008/05/27(火) 23:41:55
452 :
デフォルトの名無しさん :2008/05/27(火) 23:47:05
case 1: 'A': ans = a*b; じゃなくて case 'A':ans = a*b; じゃないか?
rewind(stdin); っている?
case 1: 'A': ans = a*b; ↓ case 'A':ans = a*b; 同じようにBも case 'B': あと最後のdefaultは何の条件にも当てはまらなかった時だから default: printf(〜〜)
>>452 switchのラベルがおかしい。
switch( hoge ){
case 'A':
//処理
break;
case 'B':
//処理
break;
default:
//処理
break;
×float A,B ○float a,b; にもつっこんであげようぜ ってかエラー出るならエラーメッセージ貼れ
小数部2桁は 「%2f」じゃなくて「%.2f」じゃなかったっけか
459 :
デフォルトの名無しさん :2008/05/28(水) 00:01:29
http://www.uploda.org/uporg1447967.jpg c:\users\nhsxxxxx\documents\cl11\5 26\5 26\分岐.cpp(16) : error C2059: 構文エラー : ':'
c:\users\nhsxxxxx\documents\cl11\5 26\5 26\分岐.cpp(20) : error C2059: 構文エラー : ':'
c:\users\nhsxxxxx\documents\cl11\5 26\5 26\分岐.cpp(24) : error C2065: 'default' : 定義されていない識別子です。
c:\users\nhsxxxxx\documents\cl11\5 26\5 26\分岐.cpp(24) : error C2143: 構文エラー : ';' が '定数' の前にありません。
c:\users\nhsxxxxx\documents\cl11\5 26\5 26\分岐.cpp(25) : error C2146: 構文エラー : ';' が、識別子 'printf' の前に必要です。
c:\users\nhsxxxxx\documents\cl11\5 26\5 26\分岐.cpp(26) : warning C4060: switch ステートメントに 'case' または 'default' ラベルがありません。
問題これ
http://www.uploda.org/uporg1447937.jpg
とりあえず case 文付近を、言われたとおりに直そう
http://www2.uploda.org/uporg1447998.jpg エラー2まで減りましたw
c:\users\nhsxxxxx\documents\cl11\5 26\5 26\分岐.cpp(9) : warning C4996: 'scanf': This function or variable may be unsafe. Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
c:\program files\microsoft visual studio 8\vc\include\stdio.h(295) : 'scanf' の宣言を確認してください。
c:\users\nhsxxxxx\documents\cl11\5 26\5 26\分岐.cpp(11) : warning C4996: 'scanf': This function or variable may be unsafe. Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
c:\program files\microsoft visual studio 8\vc\include\stdio.h(295) : 'scanf' の宣言を確認してください。
c:\users\nhsxxxxx\documents\cl11\5 26\5 26\分岐.cpp(16) : error C2146: 構文エラー : ':' が、識別子 'ans' の前に必要です。
c:\users\nhsxxxxx\documents\cl11\5 26\5 26\分岐.cpp(16) : warning C4244: '=' : 'float' から 'int' への変換です。データが失われる可能性があります。
c:\users\nhsxxxxx\documents\cl11\5 26\5 26\分岐.cpp(20) : error C2146: 構文エラー : ':' が、識別子 'ans' の前に必要です。
c:\users\nhsxxxxx\documents\cl11\5 26\5 26\分岐.cpp(20) : warning C4244: '=' : 'float' から 'int' への変換です。データが失われる可能性があります。
ビルドログは "file://c:\Users\nhsxxxxx\Documents\CL11\5 26\5 26\Debug\BuildLog.htm" に保存されました。
5 26 - エラー 2、警告 4
なんでansがint型なの? 特別な意図があるの?
コンパイラが親切に >構文エラー : ':' が、識別子 'ans' の前に必要です。 まで言ってるのにガン無視とか…コンパイラが可愛そうすぎです
エラーは0になりました しかし、デバックなしで開始するとすべてエラー吹く、全部演算記号エラー! >>構文エラー : ':' が、識別子 'ans' の前に必要です。 int:ansにすればいいの?エラー3でました int、float,charが間違ってますか?
週末、土日を二日くらい潰して、入門書で勉強してみな。 このくらいなら、それくらいで取り返せるよ。
467 :
デフォルトの名無しさん :2008/05/28(水) 00:20:42
符号なし変数の最上位ビットを符号ビットをみなして、符号付き変数へ変換したいと思います。 このような場合、以下のようなコードでよいのでしょうか? unsigned int a = 0xFABC; int b; b = (int)a; (キャストは、わかりやすくするために書いただけです)
>>452 実行例1の、と,はひどい入力ですね。
何かのテストケースかw
>>465 掛け算とdefaultだけ
switch (kigo) {
case 'A':
ans = a * b;
printf("%.2f×%.2f=%.2f", a, b, ans);
break;
default:
printf("Error");
}
あとは入門書読み返せ
季語www
>>467 負の数の内部表現に2の補数を用いているならOK、そうでない環境ならOUT。
内部表現の仕様はC言語の規格の範疇ではない。
int 型:使用するコンピュータがもっとも効率よく処理できる大きさ (2バイトか4バイト)を割り当てるため、表現できる数値の範囲はコンピュターによって異なります って参考書に書いてあるけど、これはどういう意味なの?
だいたい書いてあるとおりの意味だよ。正確ではないけど。
2バイトつまり16ビットならなら2^16の分だけ数を表現出来る つまり-32768〜32767の65536個 4バイトならさらに(ry
int は 「-2147483647〜2147483647」 まで数値入れられるパソコンが多いけど、 「-32768〜32767」 までしか数値入らないパソコンもあるよ、って事 要するに -32768〜32767 より大きい数字を使うかもしれない整数値には long int 使っとけってこった
今時のWindowsやUnixなら、intはみんな4バイト。 鈴木くんちが2バイトで、田中くんとこが3バイトってわけじゃないから大丈夫。
if(x>y ll s>t) x= s+t; else y=s-t; swich(x>y ll s>t) { case ; s=x+t; break; defalut; y=s-t; } 上と下両方あるんだが どっちも同じなの?全く違うの? 教えてくだしあ
>>477 意味が分からん
せめてコンパイル通るソース書いてくれ
上と下両方ある、の意味が分からんが とりあえず下のコードは論外
そのままで通らないのはおいといて、いいように直してVCにつっこんだらC4145がでた ツッコミもひるむほどの打ち間違いか、なんかの釣りか…。
真偽値をswitchするとか初めてみたw
switchって場合によってはif elseif elseより高速なんだっけ? 何れに知れも下はない。
>>477 ifと同じ動作をするswitchは
swich(x>y ll s>t)
{
case 0: y=s-t; break;
default: s=x+t;
}
swich(x>y ll s>t){ case 1: x=s+t; break; default: y=s-t; } 順番的にこっちの方がわかりやすいんじゃね?
swich(笑)
>>485 この場合なら問題ないけど、真の値が1だと決め付けるのはいただけない。
いや、1って規格で決まってるだろ
>>487 だから「この場合は問題ない」って書いてあるじゃない。
void *p = ...;
switch (p) {
case 1: ...
default: ...
}
どうでもいい流れだな
>>482 caseに割り振られる整数値が綺麗に整列していれば、
コンパイラが効率のいい処理ジャンプを書いてくれるかもしれない
書いてくれないとしても、たぶんif elseif elseと同じものになって
より遅いということはきっとない
>>493 普通のANSIで決まってる
比較演算は0か1を返すって
ああ、あと論理演算も然り
あ、比較演算の結果の話か 勘違いスマソ。
それはね、もう項目と数値の幅を予め決めておいて フフンッ その範囲内でなら整うようにすりゃ良いんだよ パンダこの野郎 けど、 \t (タブ)と言った制御文字も使うといいお 政権交代しろやっ
左揃えなら書式指定で %-4d みたいな
>>497 printf("%d人目 %-10d%-10d%-10d\n", 1, 12, 34, 46);
printf("平均 %-10.2f%-10.2f%-10.2f\n", 52.67, 41.00, 93.67);
タブもいいかもね
タブと%-d(f)だね -が左揃え
double dataPTS[10][dim]; double queryPT[dim]; こう宣言すると error C2057: 定数式が必要です。 error C2466: サイズが 0 の配列を割り当てまたは宣言しようとしました。 error C2087: 'dataPTS' : 添字がありません。 こんなエラーが出てくれます。 後から代入しようとしたんですが、できませんでした。 わざわざ宣言の時点で値を入れてやらないといけないんでしょうか。
503 :
デフォルトの名無しさん :2008/05/28(水) 17:11:37
そういう規則です。C++STLをつかえば vector<double> queryPT[(dim); と書けます。
>>502 できない
動的に配列のサイズを決めたいならmallocするしかない
#define しないとだめなんでしたね。うっかりしてました。 あと、 typedef double ANNcoord; // coordinate data type typedef double ANNdist; // distance data type typedef ANNcoord* ANNpoint; // a point typedef ANNpoint* ANNpointArray; // an array of points ANNpointArray dataPts; // data points *int datapts ANNpoint queryPt; // query point *double querypts と宣言したんですが、ANNpoint
#define しないとだめなんでしたね。うっかりしてました。 あと、 typedef double ANNcoord; // coordinate data type typedef double ANNdist; // distance data type typedef ANNcoord* ANNpoint; // a point typedef ANNpoint* ANNpointArray; // an array of points ANNpointArray dataPts; // data points *int datapts ANNpoint queryPt; // query point *double querypts と宣言されているんですが、結局は double** ANNpointArrayと一緒になりますよね。 んで、 ANNpointを操作するときは、 for(a){ for(b){ ANNpoint[a][b] } } とかやっても大丈夫ですか?
大丈夫じゃない ANNpointは変数ではなくdoubleへのポインタ型でしかない 仮にANNpoint型の変数のことを言ってるとしても多次元参照するにはキャストが必要
多次元参照するためのキャストってどんなんがあります?
509 :
506 :2008/05/28(水) 17:54:28
すいません、いったん席離れます。明日帰ってきます。
510 :
497 :2008/05/28(水) 17:57:01
ありがとうございます タブ\tと%-d(f)を効果的に活用します
>>509 まさか仕事で分からないことを職場から聞きつつ華麗な定時退社か?
こんなアホなtypedefの連鎖かます職場じゃ先輩に聞いてもアレだろうな・・・
513 :
デフォルトの名無しさん :2008/05/28(水) 19:58:56
int array[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0}, i=0; while(array[i]?++i:0) while文のカッコ内の解釈としては、array[i]が0じゃないときは ++iが実行されて、array[i]が0のときは偽だから3項演算子の最後の0が式の値となり 結果的にwhileカッコ内が偽になるからループを抜けるという解釈でよろしいでしょうか? よろしく。
よろしゅうございますよ でも普通はforを使う
515 :
513 :2008/05/28(水) 20:03:39
>>514 ありがとうございます。普通はforを使うんですか!これからは、forを使いたいとおもいます。
どうもありがとうございました!
こんなコード書くなんて俺ってカッコイイーと勘違いした典型ですね 実際にはループの度にarray[i]の評価とiまたは0の評価で 計2回の評価を必要とするので効率が悪いですはい
私は基本的に typedef は使いません。 typedef のメリットをまったく感じません。 typedef でなにがわかりやすくなったのでしょうか。 (a + b + c)(d + e + f) を計算するのに A = a + b, B = d + e とおいて、とかするのですか? 信じられません。
節子、それtypedefちゃう
意味がわからないなら使わなくていいんじゃね 開発の規模がある程度大きくなったらわかるよ
>>517 ・d + e + f を関数化したほうが分かりやすい事がある。
・関数化するよりマクロのほうが速度的に速い。
この二つだけで十分じゃないか。
ええと、typedefのはなしだよな?
typedefか 構造体・共用体と、関数ポインタにしか使わんな
メモリの関係で float と double を入れ替えなきゃならない可能性があるときは typedef してる
525 :
デフォルトの名無しさん :2008/05/29(木) 00:13:19
私の会社に来たソフトハウスの人(30代)が 書いていたヘッダをこっそり見ていたら、↓みたいな感じでした。 char c_AVal[10]; char c_BVal[20]; char c_CVal[ 1]; char c_DVal[18]; char c_EVal[ 2]; char c_FVal[ 1]; 1バイトの変数も char c_CVal[ 1]; のように宣言するのは見たことがないのですが、 これは普通の宣言でしょうか? char c_CVal;と同じでしょうか? 知り合いの話では、Cのコーディング経験は実は数か月らしいとのことで、 少し心配しています。標準ライブラリの使い方も怪しかったものですから。
1よりもサイズが増える可能性があるなら別にいいんじゃね? あとは使い方次第
527 :
デフォルトの名無しさん :2008/05/29(木) 00:36:35
if文の中で演算子を使えますか? たとえば+-*/の計算。 除算かつ、割る数(b)が0の場合、別な処理をしたい。 ------------------------------------ 変数a,bに整数を入力させる。 変数eにはgetchar で演算子が入る switch文で演算子「+,-,*,/」を判別。 bが0 かつ 演算子が「/」の場合。 if(b=0 && e=/) このように考えましたが、if文の中で「/」を使う事が出来ないようです。 根本的な間違いでしょうか。
if(b==0 && e=='/')
変数eに入ってるのは演算子じゃなくて、 '/' のASCII文字コードです 文字コードはただの数値なので普通に e == '/' (ASCIIコードで '/' は10進数の47なので e == 47 でもいいです)で比較しましょう
横入りすみません、windowsAPIの勉強してるのですが、 例えばMessageboxを使ったソースなどは、borlandコンパイラでは コンパイル出来ないのでしょうか? ------------------------------------------------------------- #include <windows.h> int WINAPI WinMain(HINSTSNCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow) { MessageBox(NULL,"Kitty on your lap","メッセージです",MB_OK); return 0; } ---------------------------------------------------------------------- 上記のようなソースをborlandでコンパイルしようとすると、 「エラー E2147 winapi.cpp 3: 引数宣言は 'HINSTSNCE' で始められない」 のようなエラーが発生します。 どうしてでしょうか?
エラーの位置をよく見ること MessageBoxじゃなくWinMainで起きてる そしてスペルをよく確認せよ
>>525 ん、それは構造体のメンバだったりしませんか?
そしてchar配列をその構造体にキャストして放り込んだりしていませんか?
534 :
532 :2008/05/29(木) 01:54:09
途中でした。 もしそうであれば、そのような定義にすることでメンバが違うことによる コードの差というものが少なくなり、凡ミスを防ぎやすくなる場合があります。 個人的には好きではありませんが、そういう記法を採用している現場を いくつか見ました。
535 :
デフォルトの名無しさん :2008/05/29(木) 15:24:37
C言語で逆ポーランド記法で書いた数式を入力すると,その計算結果を出力するプログラムを作りたいんですけど、わからないので誰か教えてください。お願いします!
入力の仕方、データの格納、計算、出力方法、どれがわからんの 自分で書いたコード載せてごらん。
宿題かレポートネタの予感 ぐぐってみたか 2ちゃんに頼るにせよ、なんとなくでもなんか知っておかないと
スタックはわかるんだろうか
俺?わからないよおれは
>>535 どんな問題に立ち向かうときも、本当に必要とされるのは、まず問題を理解し、そして適切な大きさのタスクに分解し、
それら一つ一つを適切に解決する方法を 自 分 で 見出す能力であり、それがプログラミングの本質である。
我々は君が進むべき道を迷っていたら恐らく正しいであろう道を指し示すことはあるし、
明らかに危険な道に踏み込もうとしていたら強く引きとめもするだろう。
だが目的地にたどり着くのはあくまでも君自身が足を動かしたことに因らなければならない。
そうでなければそもそも君がプログラミングを行う(あるいは学ぶ)ことにならないからである。
while if(数値) プッシュ if(演算子) 2個ポップ 演算結果をプッシュ end 良くわからないけどこんな感じじゃね?
public static void Main(string[] args) { foreach(string arg in args) { System.Console.WriteLine(arg); } } ってな感じのが書きたいのですが、 コマンドライン引数が取れません。 というか、stringの使い方がわかりません。 出来る人には簡単すぎることなのかもしれませんが、 どうか教えてください。
スレタイを300回くらい読み直せ
>>543 C言語では、stringはどうやって使うんですか?
使えません
>>545 じゃあ文字列の操作ってできないんですか?
できます
まずC言語の本を買って読んでください
これはきっと俺をJava嫌いにするための工作だな
C#じゃないのか
なんだC#か
>>535 UNIX プログラミング環境という(蝶オススメ)本にCで書いた電卓プログラムがのっている。
553 :
デフォルトの名無しさん :2008/05/29(木) 23:49:43
>>536 #include <stdio.h>
#include <stdlib.h>
#define LIMIT 3 /* スタックに入る数の最大値 */
#define OVERFLOW -1
#define UNDERFLOW -2
int StackArray[LIMIT];
int top; /* スタックの先頭を指す */
int push(int x); /* 関数のプロトタイプ宣言 */
int pop(void); /* 関数のプロトタイプ宣言 */
int main(void)
{
int order, x, y;
top = 0;
while(1)
{
printf("\n現在のデータ数:%d\n", top);
printf("(1) push (2) pop (3) finish: ");
scanf("%d", &order);
switch(order)
{
554 :
デフォルトの名無しさん :2008/05/29(木) 23:50:42
>>553 の続きです。
case 1:
printf("input data: ");
scanf("%d", &x);
if (push(x) == OVERFLOW)
puts("stack overflow");
break;
case 2:
y=pop();
if(y==UNDERFROW)
puts("My stack is already empty.");
else
break;
case 3:
default:
puts("please input 1, 2 or 3");
break;
}
}
}
555 :
デフォルトの名無しさん :2008/05/29(木) 23:51:11
>>554 の続きです。
int push(int x)
{
if (top < LIMIT)
{
StackArray[top] = x;
top = top + 1;
return 0;
}
else
return OVERFLOW;
}
int pop(void)
{
}
ここから先がわかりません。
演算は+、−、×の3種類のみ、数は1,2・・・9の9種類のみ、入力には空白なし、文字は半角英数入力文字列を配列に格納する、各文字のAscil Codeを入れる
この条件を満たすプログラムを作りたいんです。
んーとりあえずスタックの操作が出来るためのテストプログラムってことでいいのかな? popなんだから値を一個取り出せばいいんだけど…できない?
557 :
デフォルトの名無しさん :2008/05/30(金) 00:39:48
おまえらみたいに賢くなるには どんな本を読めばいいのか教えてくれ!
まずはpop()を書いてcase 2:とcase 3:を完全にし動作するのを確かめる。以外にやることないだろう。
スタックに値があれば取り出して指示変数topを1減らし取り出した値をreturnする pushが書けたんだから要領はわかるだろ
561 :
530 :2008/05/30(金) 01:07:00
>>531 さん
---------------------------------------------------------
HINSTANCEはインスタンスハンドルと呼ばれる情報で、アプリケーション
そのものを表すユニークな値を表しています。この値はWindowsAPIの一部
の関数を利用する為に必要な情報となります。
---------------------------------------------------------
しかし、
---------------------------------------------------------
このパラメータは16ビットWindows時代に使われていたもので、Win32API
では利用する事はありません。
----------------------------------------------------------
OSがXPだった為、必要ないパラメータだったようです。
ただ、HINSTANCEを削除してコンパイルしても、
やっぱりWinMainでエラー出ました。
もうちょっと考えてみます。ありがとうございました。
>>561 HINSTSNCE
を256回読み直せ
不要だからって即削除するとはさすがだw
>>561 不要なのはhPrevInstanceの方だけだぞ
何故ほぼコピペなのにコンパイルエラー出すのか、そっちの方が不思議でならない
>>561 hPrevInstanceは利用されていないだけでWinMainの引数として存在していないといけない。
前回エラーになったのはhInstanceの型名のtypoだ
初心者って絶対エラーメッセージ読まないよね
読んでも多分難しくて分からないだろうという理由(思い込み)で 読むことを放棄してるんだと思う。
挙句の果てにスペルミスということをやっと理解した暁には 凡ミスでしたお騒がせしましたとか言うんだぜ。
>>564 初心者の半分はコピペを知らずに手打ちしてエラーを出す
残りの半分は安易にコピペしてエラーを出す
>>568 理解したときにはこのスレのことなんか忘れてるんじゃね?w
で、またわからなくなったときに思い出して質問しにくるんだと思う
ったく・・・ここは質問スレじゃねえんだよ!
Cコンパイラって、初心者にいわせれば、自分の都合に基づいてエラー出すから、 それが打ち間違いであれ、打ち間違いとかそういうエラーとは限らないってこと HINSTANCEは、H+INSTANCEな。そもそもこれに気づかないと、打ち間違いばかりになる
だれか俺にHINSTSNCEの読み方を教えてくれ
まさしく ぐぐれ だな おろかな質問の履歴がでてくるよ
コピペだけじゃ絶対身に付かないよ。 変数や関数は何かの略称なので、それぞれの原型の意味を覚えたほうがいい。 HINSTANCE = HANDLE INSTANCE
>>574 冗談だぜw
エイチインストスンセ
とか言ってほしかった…
HINSTSNCE に一致する日本語のページ 1 件中 1 - 1 件目 (0.06 秒) C言語なら俺に聞け(入門篇) Part 28 pc11.2ch.net/test/read.cgi/tech/1211198816/530
ウケそうになかったので即レスしなかったが、全言語で3件 重複除く もうちょいありそうな気がしたがなあ さすがに、ぐぐるコードでは0件だった サジェッションが出てくるかとおもったが、なかったな typoネタのちょい雑談として。
C言語脱初心者を目指してるものです。
>>559 にあったK&Rを読もうと思ったのですが、
日本語訳と原著どちらを読んだほうがいいでしょうか?
日本語訳は異常に評判が悪いんですが、かといって自分は
そこまで英語が得意というわけでもないので困ってしまいまして。
>日本語訳は異常に評判が悪いんですが 別にわるかないよ。 普通に読んで普通に理解できるレベル。
誤記誤植が最初の増刷で直ってるのに、 いまだにあるかのように言ってる奴がいるだけ。
>>579 K&Rは語調が固く、読みにくい。また活字も見にくい。
C言語のバイブルと呼ばれてはいるが、それは
裏を返せば古くて取っつきにくいということ。
もっと読みやすい本を探した方がいい。
C言語初心者というかプログラミング初心者が読んでもちんぷんかんぷんだろうな ただ深く理解するためには必須に近いと思う
N88-BASICしか知らないときにK&R読んだけど、普通に覚えられたよ。 活字をよみつけてないとか、そういうレベルの人以外はK&Rでもいいよ。
C言語作った本人が関数ポインタの文法の変態っぷりにキレててワロタ記憶がある
586 :
デフォルトの名無しさん :2008/05/31(土) 14:15:20
質問です。 /* listは1つのサイズが30byteの構造体 */ struct list *p; p = (struct list *)malloc(sizeof(struct list)*10); の後にp[0]〜p[9]の各メンバに値を代入して p++; printf("%d", p->age); ってやると実行時エラーが出ます。何故でしょう?(WindowsXP-gcc-メモリ2GB) mallocってスタック領域に連続した番地に確保されるものですよね? ちなみにp++;を削除してprintf("%d", (p+1)->age); としてやると正常に実行されました。
587 :
デフォルトの名無しさん :2008/05/31(土) 14:16:16
↑30byteじゃなくて40byteです
588 :
デフォルトの名無しさん :2008/05/31(土) 14:19:17
p++; はポインタ演算で構造体のサイズ40byte分次のメモリ番地(この場合&p[1])を指と思ったのですが・・・
>>586 それよりmallocで確保した領域を管理するポインター進めるのって気持ち悪くない?
もうひとつインデックスを管理するint indexcount とか用意して
(p + indexcount)->age
とかで参照しないと
後でfreeできないような・・・
p->ageを初期化してないのに読むなよ。
>>590 つ >の後にp[0]〜p[9]の各メンバに値を代入して
>>586 問題はそこにはないんじゃなかろうか?
問題が再現する最小のコードを張ってみてください
実行時エラーってmallocで確保した領域のアドレスを指してポインター を進めちゃっててfreeでエラーとかでないの?
>>586 freeするときにpを元の位置に戻してないとか
595 :
デフォルトの名無しさん :2008/05/31(土) 14:41:55
596 :
デフォルトの名無しさん :2008/05/31(土) 14:47:49
これだと構造体のサイズは20です。
2分探索木って配列で取るものなのかな・・・ コストはかかるけどノードを毎回1個確保していったほうがよくね?
598 :
デフォルトの名無しさん :2008/05/31(土) 14:50:57
あ、 //問題点1:46,47行目 はreturn p;の前にp++;しちゃってるので駄目ですね・・・ でも、問題点2のほうは・・・よく分からないです。
(node *)NULL (node *)malloc(sizeof(node)*(6+1)) 問題とは関係ないけど、こういうキャストいらんだろ。
>>595 >//問題点1:46,47行目はエラー
p++; をコメント解除したら、returnするpの位置が変わるような気がするんだけど?
>//問題点2:26行目をPrint_Tree(p);にして、55行目でPrint_Tree関数の最初にx++;をしても同じエラー
Print_TreeがPrint_Treeの中から再帰的に呼ばれてることを忘れてる
601 :
デフォルトの名無しさん :2008/05/31(土) 14:52:28
>>597 そうなんですか・・
普段は必要な時に毎回1個ずつ取っていくスタイルなのですが
今回は練習のためにもこうしてみました。
ちょっと意図がつかみきれないというか、要求されてる仕様を ちゃんと理解して無い気がする・・・・
>>595 なんか読んでたら混乱してきたけど、構造的におかしいだろ。
いろんなところで変数ずらそうとするから変なことになってる。
>>601 NULL は0だけど、
NULLにインクリメントしたら0+20でNULLじゃなくなる
だから
55行目の if (x != (node *)NULL) {
を通過してしまってエラーになる
605 :
デフォルトの名無しさん :2008/05/31(土) 14:54:20
>>600 ありがとうございます。
そういえばそうでした。再帰だということを忘れていました。
606 :
デフォルトの名無しさん :2008/05/31(土) 14:56:15
>>602-604 すいません。たしかにその通りです。
30分くらい考えたのに気づきませんでした。
mallocは連続した領域に確保されないこともあるんだよね?
callocやreallocじゃない
ボインなおっぱいにポイン(し)た なんつって
>>607 そんなわけない
指定したサイズが確保できなければポインターがNULLになって返ってくる。
>>607 動的配列つくれねぇじゃんよ
断片化の心配はなさそうだけど
第一断片化してる領域を渡されても関数の戻りは確保した領域の先頭アドレスだけで、 断片になってる領域の先頭アドレスだけ渡されても残りの情報はどうやって得ると思ってるんだ・・・
不連続な3つの領域を確保してくれたんなら、ポインタ3個返してもらわないとな
>>586 元の状態がこうであるかのように見えるが、
for(i=0;i<10;i++) {p[i].age=i;} p++; printf("%d", p->age);
実際はこうであったのではないかしら。
for(i=0;i<10;i++) {p->age=i;p++;} printf("%d", p->age);
それをこうしたら動いた、と。
for(i=0;i<10;i++) {p[i].age=i;} printf("%d", (p+1)->age);
「正常に実行された」というのは「落ちなかった」というだけなのでは。
ってなんかリロードしたらレスがてんこ盛りで俺浦島太郎。
>>616 それ以前にmallocした領域を管理してるポインターのアドレスを更新する
というのがかなりやばい。
>>618 プログラム終了時にfreeされるからいいよ派なんじゃないの?
この構造なら parent を辿っていけば元の p[1] になるから計算可能
VC言語で僕のちんぽをかちんこちんにするプログラム作ってください><;
たいていのエロゲはC/C++で作られてますよ
つーか昔作ったコアを変えてないとかそんな程度だろ。 基本の開発ツールはVC++6あたりのままってとこかな?
スタックに、じゃなくてヒープに。 スタックに確保して、freeをサボるような書き方したいなら、allocaとかか
CはJAVAより速いって本当? どのくらい
JavaVMをC/C++で実装しちゃう位
Javaって乱暴なたとえだとエミュレーターのようなものだからな・・・
仮想マシンだから、別に何かのハードをエミュレートするってわけじゃないお
Web系業務系でJavaが優勢なのはなんで?
>>631 確かCなんかで書かれたCGIだと負荷が大きいけど
サーブレットだと負荷が小さいとかだったような
またご冗談を
635 :
デフォルトの名無しさん :2008/05/31(土) 17:13:36
#include <stdio.h> int main(void) { int a[] = {10, 11, 12, 0}, *p = a; for(;*p++;) printf("%d ", *p); return 0; } C独習者で色々実験中です。 int a[] = {10, 11, 12, 0}, *p=a; for(;*p++;) printf("%d ", *p); とします。*p++の部分で1番最初のループの前にp++でインクリメントされるので 10は表示されないのはわかっていたんですが、一番最後のループでp++されてから*で参照され 0がループの終了条件になりprintf文での0は表示されないとおもったんですが、表示されてしまいます。 要するに結果が 11, 12, 0 と表示されます。 これってなんででしょうか?私の予想では 11, 12 しか表示されないと思ったのですが。
636 :
側近中の側近 ◆0351148456 :2008/05/31(土) 17:19:31
>>635 (っ´▽`)っ
ループ終了判定の後にインクリメントしてるからでしょうな。
>>635 ひとつずつ追ってけば簡単
最初 *p == 10
for(;*p++;) のとき *p++ == 10
printf("%d ", *p); のとき *p == 11
for(;*p++;) のとき *p++ == 11
printf("%d ", *p); のとき *p == 12
for(;*p++;) のとき *p++ == 12
printf("%d ", *p); のとき *p == 0
for(;*p++;) のとき *p++ == 0
638 :
側近中の側近 ◆0351148456 :2008/05/31(土) 17:21:38
(っ´▽`)っ for(;*p++;) printf("%d ", *p); は、 for(;*p;){ p = p + 1; printf("%d ", *p); } と等価じゃないのかな?カナ?
>>631 ボトルネックがIOだから、言語の速さはあまり関係ない。
Javaとかスクリプト系言語は、メモリに常駐してうごく仕組みがよういされているけど、
CでベタにCGIを書くと、ページが表示されるたびに、プロセスを生成しなくちゃならないので
あまり速くならない。
2chはCで書かれてるけど、スクリプト系のようにメモリに常駐するしくみが用意されていて、
そのあたりはクリアさている。
640 :
側近中の側近 ◆0351148456 :2008/05/31(土) 17:23:10
(っ´▽`)っ おそらく、 for(;*(++p);) printf("%d ", *p); とすれば、 10, 11, 12 と出力されるんでしょうな。
641 :
側近中の側近 ◆0351148456 :2008/05/31(土) 17:24:03
(っ´▽`)っ
いや、
>>640 は違うな
11, 12
になるでしょ。
642 :
側近中の側近 ◆0351148456 :2008/05/31(土) 17:24:55
(っ´▽`)っ まあ、どっちにしろ、forの継続判定に++を使うのは 紛らわしいのでやめたほうがいいってことだね☆
>>615 Linked Listみたいになってりゃ良いんじゃね?
644 :
635 :2008/05/31(土) 17:40:39
みなさん、どうもご丁寧なレスありがとうございます。
なんか、C言語は深いですね。。私は、p++が先にされてその後*p参照されてそれが終了条件になるとおもっていました。
要するに*(p++)が終了条件になると思っていました。
なぜかというと独習Cに*p++;という一文は参照先の値をインクリメントするんじゃなく
ポインタ変数をインクリメントするという解説があったからです。
まだまだ未熟なようですが、この一件に関しましてはなんとなく理解できました。
>>637 さん、側近中の側近さん。お二方には、とても丁寧な解説をいただいて
とても感謝いたしております。
ほんとうにどうもありがとうございました。
>>644 >要するに*(p++)が終了条件になると思っていました。
そのとおり
>なぜかというと独習Cに*p++;という一文は参照先の値をインクリメントするんじゃなく
>ポインタ変数をインクリメントするという解説があったからです。
それも正しい
前置インクリメントと後置インクリメントの違い (++p と p++ の違い) を勉強しなおすといいよ
安西先生・・・linkedlistにランダムアクセスしたいです
>>646 要素の追加・削除がない間だけ
struct hoge **table
を作ってアクセスするんだwww
648 :
デフォルトの名無しさん :2008/05/31(土) 18:46:51
#include<stdio.h> int main(void) { int a; while (a<11){ printf("%d",a); a++; } printf("\n"); } これで12345678910と出力されますが 12345 678910 のように5行目まで出力した時点で 一度改行するにはどうすればいいんでしょうか? どなたか教えてください。お願いします。
>>648 while (a<11){
printf("%d",a);
if (a == 5) printf("\n");
a++;
}
*p++ は、 間接演算子よりインクリメント演算子の方が優先順位高いという事を知らなくて、アドレスの中身が+1される、と考えてしまう、という罠と インクリメント演算子の方が優先順位高いから、アドレスが+1された後でアドレスが参照される、と考えてしまう罠が混在する二重の罠
651 :
648 :2008/05/31(土) 19:08:24
>>649 さん
if使えばよかったんですね。
教えていただきありがとうございました。
652 :
635 :2008/05/31(土) 19:10:17
>>645 そういうことでしたか。。ここのforの条件判定の部分まで
後置インクリメントの式の評価が終わってから、インクリメントされるというのが
適用されるのですね。
普通の文では、一文が評価されてから、インクリメントされるというのは
理解していたんですが、、この条件判定の部分までそうだとはちょっとわからなかったです。
でもようやく理解できました。ありがとうございました。
653 :
635 :2008/05/31(土) 19:15:06
>>650 どうもっす。頭こんがらがってきます。。ここが一番難しいようなことを
本に書いてあるので、がんばりまっす。先に構造体とかやったので、あとは
ここだけなので。。
ありがとうございます。
俺は下手に学校や会社で教わった奴より、独学で覚えたやつの方が信頼している がんばれよ
>>644 後置インクリメントの勉強でなければ
for (p = a; ;*p; p++) printf("%d ", *p);
が自然なコード。
独習Cで色々実験中って書いてあるから勉強中なんだろう 何故while文じゃなくてfor文?とは思ったが
657 :
デフォルトの名無しさん :2008/05/31(土) 21:44:36
1〜9の範囲の整数を入力するプログラムを教えてください
>>657 1.文字列を入力する。
2.入力した文字列が数字であるかどうかチェックする。数字でなければアウト。
3.入力した数字文字列が1〜9であるかどうかチェックする。この範囲の数字でなければアウト。
こういう手順で。
どのあたりがわからないのでしょうか?
659 :
デフォルトの名無しさん :2008/05/31(土) 22:03:15
テス
660 :
デフォルトの名無しさん :2008/05/31(土) 22:05:12
for文の再設定式でi++と++iってどこが違うんですか?
ふつーの使い方してる分には何も違わない。 for(i=0; i<10; foo(i++)) for(i=0; i<10; foo(++i)) みたいに書いたとき意味合いが変わってくるってだけ。forだからどうこうは関係ない。
663 :
デフォルトの名無しさん :2008/05/31(土) 22:16:19
>>661-662 ありがとうございます
if(i<=10){
printf("i=%d",i);
i++;
}
質問ばかりで申し訳ないんですが、この場合i++は、
どういう働きをしているんでしょうか。
増えているのはわかるのですが、いつ評価されているんでしょうか?
あたまだいじょうぶか
#include <stdio.h> main() { int a,b,wa; printf("キーボードから数字を二つ入力して下さい\n"); scanf("%d, &a"); scanf("%d, &b"); wa = a + b; printf("入力した数字 %d と %d の和を計算すると\n",a,b); printf("%d になります。",wa); } 実行して、数字入力してエンターを押すとエラーになってプログラムが終了してしまいます。 なぜでしょうか?
666 :
側近中の側近 ◆0351148456 :2008/05/31(土) 22:21:19
>>663 (っ´▽`)っ
これと同じ。
if(i<=10){
printf("i=%d",i);
i = i + 1;
}
667 :
側近中の側近 ◆0351148456 :2008/05/31(土) 22:22:19
>>665 (っ´▽`)っ ぷぎゃー☆
scanf("%d, &a");
scanf("%d, &b");
でなく
scanf("%d", &a);
scanf("%d", &b);
だよ。二重引用符に位置が違う。
>>665 scanf("%d, &a"); <−コレ
scanf("%d", &a); こうすればおkかな?
>>663 例えば
int n;
int i = 0;
n = array[i++];
となっている場合、
array[i++]は、array[i] → i = i + 1 の順に実行されるから、
n == array[0]
になる
array[i++] を array[++i]に変えた場合、
array[++i]は、i = i + 1 → array[i] の順に実行されるから、
n == array[1]
になる
「array[i++]は、array[i] → i = i + 1 の順に実行される」
「array[++i]は、i = i + 1 → array[i] の順に実行される」
↑この違い。
670 :
側近中の側近 ◆0351148456 :2008/05/31(土) 22:28:18
(っ´▽`)っ アドバイスだけど、 i++や++iは単独で使用するのがお勧め。 つまり、j=i++;やj=++i;のような、 ++の位置によって結果が変わるような使い方はやめたほうがよい。 というのは、わかりづらいし、バグを誘発させるから。 i++;j=i; j=i;i++; に変えても動きは同じだし、こっちのほうが断然わかりやすい。 ちなみにsizeof(i++)は、多くのコンパイラでiがインクリメントされません。
>ちなみにsizeof(i++)は、多くのコンパイラでiがインクリメントされません。 というか未定義だろ
673 :
側近中の側近 ◆0351148456 :2008/05/31(土) 22:58:28
>>672 (っ´▽`)っ
ようわからんけど、
3年ぐらい前にこのスレで話題に上がったような気がする・・・。
sizeof演算子は型、変数名、または定数に作用して 型のサイズ、変数のサイズ、または定数の型のサイズを返す i++はiの値(変数)を返すからsizeofを適用することはできない(もしやったら未定義) じゃないの
>i++はiの値(変数)を返すからsizeofを適用することはできない(もしやったら未定義) それだと構文エラーにならないとおかしい気もするが
>>674 そうすると
int *p;
sizeof(*p) は未定義?
sizeofを単項式に作用させた場合、式を評価するかしないか(演算子を適用するか無視するか)は処理系定義なんじゃなかったっけ
>>644 あなたの理解は間違えていない。
だが、状態を理解できていないだけだね。
while(*p) printf("%d ", *p++);
こうすればよかった。
評価しないって決まってたはず
いったいどれが正しいんだよ!!!
バイナリデータから4bitを32bit毎に取り出したいんですけど、どうしたらいいのかまったくわかりません だれか教えてください
sizeof演算子は型または単項式に作用し、その型または項をなす変数ないし定数が持つ型のサイズをバイト単位で返す。 このとき単項式の値は評価されず、副作用を生じることもない。
>>681 unsigned charの配列を使えば?
>>681 たとえば下位4ビットを取り出したい場合は
unsigned long *p=(long *)buffer; /* longが32ビットとして */
for(i=0;i<len;i++){
n=p[i] & 0x0000000F;
/* 何かの処理 */
}
のようにする
686 :
側近中の側近 ◆0351148456 :2008/05/31(土) 23:53:27
(っ´▽`)っ 3年前の結論は sizeofはプリコンパイル時に処理されるから、 i++であろうが、++iであろうが、iであろうが、 その変数のサイズに置き換えられる とな。
そもそもsizeofはコンパイル時に計算するんだし、処理を中に入れる必要性が謎すぎるw
>>686 処理されないと定義されているのにそういう議論になったということは、
処理するしないではなく、なぜ処理されないのかについて議論していたのかな。
そりゃあ嘘だ ほとんどのコンパイラではコンパイル時に解決して定数になる場合が多いというだけで そう処理しろと規格で決まってるわけじゃない(C99の可変長配列の問題もあるし)
C89では副作用を生じないと規定されている
これ以上は規格スレでやったほうがいいと思う
692 :
側近中の側近 ◆0351148456 :2008/05/31(土) 23:58:43
(っ´▽`)っ というか、当時を覚えている古参はいないのかな?
>>686 マクロじゃないから当たり前といえばそうなんだけど、
プリコンパイル済みファイルを除いてもまだ残っていたよ。
コンパイル時に算出するのかな、、、と思ったけどそうでもない意見が
出てきたw
>>689 kwsk
>>685 ありがとうございます。
この時のnはどの型でもいいのでしょうか?
というのも、4bitを32bit毎に取り出し、そのままバイナリとして出力したいと考えているからです。
お手数ですがよろしくおねがいします。
#include <stdio.h> void foo(unsigned size) { char sz[size]; printf("sizeof(size) is dynamically changes:%u", sizeof(size)); } int main() { foo(1); foo(10); foo(100); return 0; }
失礼。 - printf("sizeof(size) is dynamically changes:%u", sizeof(size)); + printf("sizeof(size) is dynamically changes:%u¥n", sizeof(sz));
>>693 その通りの意味だ
規格では「sizeof演算子はオペランドのサイズを返す」とだけ規定してある
そしてC89ではオペランドのサイズはコンパイル時に常に解決可能だったから
多くのCコンパイラはそれをコンパイル時またはプリコンパイル時に定数に置き換えるという実装を選んだ
そんだけ
C99では配列の要素数に変数を使って宣言することが許された
そのような配列に対してsizeofを作用させるならもちろん実行時に解決するしかない
>>694 整数型ならなんでもいい
なぜなら最も小さいcharでも確実に4ビット以上あるから
ただし、たぶんunsignedであったほうが面倒が少ない
699 :
側近中の側近 ◆0351148456 :2008/06/01(日) 00:09:50
(っ´▽`)っ 古参出てこいや☆
>>697 へええ。C99よく知らなかったので勉強になりました。トン
701 :
694 :2008/06/01(日) 00:18:53
>>698 ありがとうございます。
例えばunsigned charなら8bitですよね。
この配列に4bitのデータを入れると残り4bitには何が入るのでしょうか?
できれば余分なデータは入れたくないなと思っています。必要な4bitのみを出力した時はどうすればいいのでしょうか?
よろしくおねがいします
703 :
694 :2008/06/01(日) 00:22:28
すいません 出力したいです
704 :
635 :2008/06/01(日) 00:25:50
>>654 がんばります。ありがとうございました。Cは自分で色々と勉強できるし、工夫するのが楽しい言語ですね。
色々やってみるとおもしろいです。
>>655 なるほど。たしかに、賢いやり方に見えます。Cは書き方ひとつでわかりやすい良いソースがかけるので楽しいですね。
ここで、質問すると本当に的確な答えがでてきて、とても参考になります。本当にありがとうございます。
>>678 なるほど、そういうやり方が正しいやり方なんですね。たしかに、ソースもスマートで
わかりやすいですね。Cは色々な書き方ができて面白いですね。参考になります。
色々と教えていただき、本当に皆さんありがとうございました。感謝しきれないくらいです。
しかし、直後、プロバイダ規制を喰らい、代理レスでのお礼しかできませんので、
これ以降返事をいただいても、お礼がかけませんので(;^_^
本当にありがとうございました。しかし、commufaは規制ばかりだ。。
>>703 言っている事がいまいちよくわからんが
4bitのみ出力なんて無理だから、
32bitを2つ取り出して
char c = 0;
c = ((p[i] & 0xF) << 4) | (p[i + 1] & 0xF);
みたいな感じでやればいいのではなかろうか
>>701 この場合の4bitのデータというのは4bitで表現できるunsignedなデータだから、
その表現のために使う下位4bit以外にはすべて0が入る
下位4bitのみを出力したいならそれ以外のbitを無視すればいい
どのように無視するかはどのように出力するかに依存する
4つのビットを取り出したいのか 任意の4ビットを整数(符号つきなのかそうでないのか)として取り出したいのか はっきりしろ
>>648 亀レスだが以下のように、 int a=0; で初期化した方が安全。
#include<stdio.h>
int main(void)
{
int a=0;
while (a<11){
printf("%d",a);
if (a == 5) printf("\n");
a++;
}
printf("\n");
}
gccならコンパイルオプションで gcc -Wall test.c とすればワーニングが出る。
むしろ変数は初期化して当たり前だな
コンパイルオプションでワーニングを出せばすぐ判ったろうにって内容の 質問も結構有るみたいだけど、初心者には敷居が高いのかな?
warningの内容の意味がわからないんだろう 初期化されていない変数が使用されています、の初期化って何?みたいな
職業プログラマでも当たり前のように初期化しない奴がいるから困る 同じプロジェクトではやりたくないな Javaなんかは、その辺を気にして作られたんだろうけど 「NullPointerExceptionって何><」とか、普通に言うアホもいるしな
713 :
694 :2008/06/01(日) 01:56:22
>>704 なるほど。それで行けそうな気がします。
ありがとうございます
>>706 8bitで出力させて上位の4bitを無視するようにしてやればいいということですよね?
それは考えていませんでした。ありがとうございます
>>707 4つのビットを取り出したいという意味でした。
わかりづらくて申し訳ありません。
おまじないとして初期化してたおかげでたまたま動くのようなのもなぁ・・・・
その意見も分かるが、たとえ1つでも中身が想定できない変数があるってのもな
初期化してない変数をそのまま使うなんて論外
初期化するしないにしても、普通はそのあとに値を入れると想定してるはずってことだろ
宣言を先頭でするみたいな変なルールがない限りあんまり無いかな。
警告以前に未定義動作だろうが
>>720 ブロックの先頭以外での宣言ってC99以外なら規格外ですよね。
それを変なルールと表現する時代になったの?
>>672 そういうコンパイラの定義とかを知りたい場合はどこで情報を入手したらいいんですか?
そもそもフリーのコンパイラに日本語マニュアル?なんて存在すんですか?
とりあえず、ANSI C言語辞典、K&R両方そろえてから考えましょうか
>>722 40近いおっさんプログラマが、それを普通に知らずに、
コーディング規約をC89に設定したプロジェクトで、変数を先頭以外で宣言してたわw
gccなんだが、makefile的にコンパイル通ってたんだよな
まだ若手の俺でも知ってるのに、結構認知度低いのか?C++ばっかやってた人間には見えないし
>>712 みたいなプログラミング作法って職場毎にマニュアルで規定されているんですか?
Cの場合 BCCでは宣言は最初にしないとエラー UNIXやCygwinでは先頭でなくてもエラー出ない
先頭で宣言しないとエラーってなんかCOBOLとかあの時代 の言語がそうだなw 最近のは途中でもOKだけど・・・ でも途中にあるのって気持ち悪くないかな・・・
>>728 windowsでcやるのが面倒ならゲーム端末なんかの
ハックネタを参考にソッチでやってみれば?
俺はC++やJavaで開発してるときは、できるだけその変数を初めて使う直前で宣言するようにしてる 気持ち悪いという意見も分からんでもないが、 たとえば、ローカルでしか使わない変数をグローバルには置かないだろ?置くやつもいそうだが・・・ まー、直前で宣言する理由は、それと似たようなもんだ
>>732 あーそういう意味じゃなくて・・・
そりゃローカル変数までグローバルのように定義してたら逆に
うざくてしかたない。
言いたかったのはグローバル変数を途中の関数と関数の間に
おけるおけないのは無し
void hogeA()
{
}
int hogehoge;
void hogeB()
{
hogehoge = 0;
}
>おけるおけないのは無し 置ける置けないの話 MS-IME・・・簡便してくれorz
IME以前に人に物事を伝える能力に疑問があるだろw
736 :
デフォルトの名無しさん :2008/06/01(日) 02:43:42
>>658 プログラムについてまだよくわからないので、途中まで教えてください
ソースファイル全体レベルだと、一番上に密集させてるなー そもそも変数の場所を探すのが大変になる MFCだと、theAppが半端な場所に勝手に作られていた気もするがw デバッグしてるときなら、__func__が使えない環境の場合、#undefで定義することはあるかな
658のどこがわからないのか具体的に。
さっさとソース書けよって意味ではなかろうか
>>733 え?
void hogeA()
{
int i;
printf("hello");
int j;
}
こういう話だよね?
>>726 こういう当たり前レベルのことすらできないおっさんが混ざってて
かつgccな環境なら -pedantic-errors をFLAGSに突っ込みましょう
そんでもって、あれ?あれ?コンパイルできなくなったよ!?とか
慌てふためく姿を肴に酒の一杯でも飲みましょう
gcc拡張を使ってるんだという自覚があれば、コーディング規約で
どうにかしましょ。
サンプルよこせということで?
ブロックの先頭に書いた上でtagsとかを活用するのがよさげ。 なぜかユーザの多い秀丸にもタグジャンプ機能ついた気がする。 関数内で宣言が遠いよ、とぼやく前に関数をコンパクトにすることを 考えないとね。どんだけでかい関数作っちゃってるんですか?
>>742 関数はコンパクトでもどうしても機能的にそのソース内に
おさめないとまずそうな関数がいっぱいあると同じく
宣言遠いよになりますよね・・・
細かくブロックわけすればいいじゃん。
途中まででいいということですので半分くらい。。。 #include<stdio.h> int main(void) { int input;
>>743 グローバル変数のことかしら。
であれば、それがグローバルであるべきかどうかを考えてみては?
>>744 kwsk
それかそういうのを解説してるサイトアドレスプリーズ
>>745 それは・・・・新手のいじめですかw
>>746 いやあまりグローバルは使って無いけど
構造体の定義とかそのソース内でしか使わないのを
あらたに定義するときは関数が増えると
遠く感じますね〜
そういえばみなさんは関数を定義する際プロトタイプ宣言する派ですか? それとも関数自身が使われる関数の上に書いておしまい派ですか?
変数の宣言かぁ オブジェクト指向ではこれらの問題点を解決してるんですよね・・
>>749 上に書く
変数宣言を最初にやりたがる人は旅行のときにちゃんと計画を立てるのが好きな人
後からでも宣言するのは行き当たりばったりな旅行でもOKな人と勝手に思った
>>750 cでもその辺を意識して作ればいい。
クラスのように動的に構築はしないけど
コンストラクタのような機能の関数で、グローバル変数の初期化
デストラクタのような機能の関数で、mallocした領域の開放とか
ctorとdtorでやってることの関連性がないような。
>>753 そりゃそもそも概念が違うし
あくまでオブジェクト指向のいい面を意識しながらってこと
755 :
745 :2008/06/01(日) 03:28:10
>>747 int a;
a=0;
{
int b; /* ブロックの先頭なのでおk */
}
ってこと。
あと、いじめじゃなくておおまじめですw
>>748 ソースファイルが
構造体を使わない関数群
構造体定義
構造体を使う関数群(これがたとえば1000行)
というレイアウトの場合に、ファイル終端あたりから構造体の定義を
参照するときはやっぱり遠いですよね。
そのとき、ファイルの先頭を見に行くのか、ヘッダを見に行くのか、
ファイルの中のどこかで定義されているのを探しに行くのか
どれがよさげに思います?
個人的には他人のソースを見る機会が多いので、どこにあっても
問題ないようにタグジャンプしまくりますけど。
>>750 確かに、他言語で解決済みの問題って、旧言語ではバッドノウハウに
なってる可能性が有るな。 自戒をこめて。
757 :
530 :2008/06/01(日) 04:44:37
>>all すんませんでした。HINSTSNCE←全然気づきませんでした。 また質問来るからその時はよろしく・・お願いします。
758 :
530 :2008/06/01(日) 04:59:32
HINSTSNCE⇒HINSTANCEに修正したのに、 --------------------------------------------------------- Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland winapi.cpp: 警告 W8057 winapi.cpp 8: パラメータ 'hInstance' は一度も使用されない(関数 __ all WinMain(HINSTANCE__ *,HINSTANCE__ *,char *,int) ) 警告 W8057 winapi.cpp 8: パラメータ 'hPrevInstance' は一度も使用されない(関数 stdcall WinMain(HINSTANCE__ *,HINSTANCE__ *,char *,int) ) 警告 W8057 winapi.cpp 8: パラメータ 'lpCmdLine' は一度も使用されない(関数 __ all WinMain(HINSTANCE__ *,HINSTANCE__ *,char *,int) ) 警告 W8057 winapi.cpp 8: パラメータ 'nCmdShow' は一度も使用されない(関数 __s ll WinMain(HINSTANCE__ *,HINSTANCE__ *,char *,int) ) Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland Error: 外部シンボル '_main' が未解決(C:\BORLAND\BCC55\LIB\C0X32.OBJ が参照) -------------------------------------------------------------------- というエラーが出ます。main()関数がないから? LINKがどうとか、エラーを調べたけどよくわからないです。
コンソールアプリケーションとして扱われてるんじゃなかろうか borlandコンパイラどうなってるのか知らないし、 統合開発環境が無いと作れない人なんで解決法の提示が出来ないが…
自分でやって出来なければ、APIから今時入ろうだなんて ちょっと無謀だって気もしなくもない。 (だからといってJavaや.NETを勧めるわけでもないが...) 今時APIを学びたいなんて酔狂な人はDelphiだろなやっぱり 幾分近い道は。 APIを使ったプログラミングなんて本来(超)ベテラン向け(だった) ということは覚えておいたほうがいい。
>>758 参考にしてるホームページよく見ろよ
WinAPIの最初の項目に書いてあるだろ
762 :
530 :2008/06/01(日) 05:31:52
>>759 ,760,761さん
朝早くから本当にありがとうございます!
コンパイルできたよー!
コンパイルする時に、ずっとbcc32 `FileName`でコンパイル通してました。
bcc32 -W `FileName`←オプションの-Wが必要だったんですね!
これで少し本を読みすすめられます。
763 :
デフォルトの名無しさん :2008/06/01(日) 09:02:14
>>738 #include<stdio.h>
int main (void)
{
int i,n;
からわかりません
764 :
648 :2008/06/01(日) 12:06:29
すいませんまた教えてもらいたいんですけど 648に書き込んだプログラムを元にキーボードから50以下の数値を入力して その数値から順番に出力し51になると終了するプログラムにしたいんですが どうすればいいでしょうか?とりあえずscanfをつかうこと分かりますが、うまくつかえません どなたか解説お願いします。ループの初期問題ですが苦戦してます。 実行例 20 ←入力 21 ←1回目出力 22 ←2回目出力 ・ ・ 50 ←n回目出力
>>764 for(i=n+1;i<=50;i++) printf("%d\n", i);
これで分かるですか?
>>763 >>658 1.char *str; gets(str);
2.これいるか?
3.if('0' <= a && a <= '9')
>>764 int main (void)
{
int i,n;
printf("数値を入力してください...")
scanf(%d, &n);
while(n < 51){
printf("%d\n",n);
n++;
}
return 0;
}
767 :
648 :2008/06/01(日) 13:13:35
>>765 さん
>>766 さん
回答ありがとうございます。
for文を使うとそうなるんですね。正直C言語苦手なので
習った所を教科書でもう一度確認してみます。
苦手とかいうレベルじゃねーぞw
>>762 エントリポイントとかの勉強をするのは今がいいかも!
初心者すぎて申し訳ないのですが int sum = 0, v; これはどういう意味なんでしょうか? intの中には文字は入らないと聞いたのですが
0はintだろ。
int sum = 0; int v; こう読めなかったんじゃない
>>770 同じ意味で分けて書くと
int sum = 0;
int v;
こう。
>>770 int sum = 0, v;
と
int sum, v;
sum = 0;
は同じです。
宣言と同時に初期化をしているだけです。
カンマ演算子を知らない奴は多いだろうな
なんでいきなりカンマ演算子がでてくるんだ。
>>774 ですがそんな言葉があること自体しらなかった。
なんかC言語が廃れる理由ってマニアックなんですよね。
C言語に精通した人から見ると記述が少なくなって言いとかあるんでしょうけど
どうもわざわざ敷居をあげてる気がする。
残念ながら、ほとんどのC-likeな言語で同様の記述ができます。
>>771-774 ありがとうございます。分かりました。
はじめはsumの中に0とvが入っているんだと思ってました。
一応つっこんどくと変数宣言や関数の引数リストのカンマはカンマ区切りであってカンマ演算子ではない
>>778 それは知ってるけど、宣言と同時に初期化って気持ち悪いんだよな・・・
俺は1stepでも、変数に未知の値が入っている方が気持ち悪い
変数が自動で初期化されない言語で、明示的に初期化する方法がないほうが気持ち悪いわ
>>782 配列の初期化は宣言と同時じゃないとできないし。。。
>>777 いつの間にC言語が廃れたのか知りませんが、低級言語なので
時折面倒な事があるのは確かですね。
けれど、他の高級言語のような、「中で何をやっているのかわからない」
という漠然とした不安感はないですよ。
787 :
側近中の側近 ◆0351148456 :2008/06/01(日) 16:07:07
(っ´▽`)っ カンマ演算子は気をつけてね☆ int i, j = 0; で0が設定されるのはjだけ。iは設定されない。 int* i, j; では、iはint*型、jはint型。
宣言時以外の=は初期化じゃなくて代入だろ…
Cが低級言語とな
>>789 最近は中級言語なんて呼ばれることもあるらしいから、
そのうち本当に低級言語になったりしてな
C言語が低級言語になったらアセンブラは何になるんだろうな
792 :
側近中の側近 ◆0351148456 :2008/06/01(日) 16:14:41
(っ´▽`)っ 変数はなるべく、宣言、設定、参照、廃棄の期間(変数の寿命)が 短くなるようにするほうが好ましい。 長くなればなるほど、初期化漏れ、廃棄漏れが多くなるからね。 使う直前で設定する。使ったらすぐに廃棄する。
ヒエログリフ
ここでおさらい 1) Cは高級言語(人間に理解しやすい文法を持つ言語という意味)である 2) Cは低レベル言語(低い=ハードウェアに近い階層をいじくることができる言語という意味)である
>>794 低レベル言語といわず低レベルレイヤー言語とかのうほうが
説得力増すかな?
他のより高級な言語との対比で使ってしまったことをお詫びしまする。
アセンブリ言語も理解はしやすいよ。
Cで開発できるならできればアセンブラは避けたいな〜
でもアセンブラとCの速度差は、身をもって味わったな・・・ Cと他の高級言語の差も
>>800 そりゃ違うでしょ・・・
アセンブラ(マシン語)になってくると1命令が使うクロックとか
意識して書けるけど、Cの場合はコンパイラが最適化してくれる
とは言ってもやはり効率は若干落ちる。
まあその分開発速度はCが上なんだろうけど。
他の高級言語とCの比もそうでCの欠点を補う形で
あれこれ仕組みをいれちゃったので安全なプログラミングは
できるけどその代わり速度は犠牲になったり云々・・・
まあしかし、それなりにCPUに詳しくないと、Cより速くはならない。
アセンブラなんて基本情報の為にちょっと勉強しただけで触った事は無いな
804 :
デフォルトの名無しさん :2008/06/01(日) 17:52:18
ポインタ変数ってアドレスを格納できる変数のことですか?
一般的にはそうじゃないか? ポインタという言葉をアドレスの指定以外にも用いることあるが
806 :
デフォルトの名無しさん :2008/06/01(日) 17:58:00
では配列名がポインタの役割をしているとはどういう意味ですか?
アドレス以外で使ったっけ?
int hairetu[20]; のとき hairetu は &hairetu[0] と一緒
811 :
810 :2008/06/01(日) 18:06:12
Cスレだった忘れてくれ
>>806 配列であろうが変数はすべてメモリのどこかに確保されるので
アドレスを持つことになります。
それはまちがい
>>814 どれが間違い?
関数の一時な変数がコンパイルされると実はメモリ上に確保されずに
レジスタでまかなわれてるとかいう話?
とりあえずはアドレスの話なのでそんな細かいのはいいんだよ
816 :
デフォルトの名無しさん :2008/06/01(日) 18:18:33
確かに少しあいまいです
質問の意図するところは
>>809 でした
>>809 の場合で何でhairetu は &hairetu[0] と一緒になるのかがいまひとつわかりません
registerストレージクラスの変数のアドレスを取得するのは違法だとかそんな話だろ。
818 :
デフォルトの名無しさん :2008/06/01(日) 18:23:24
配列名は入れ物であってこれがなぜアドレスを示すのかが謎です それなら&なんてはじめから存在する必要が無いようにも思えます
>>816 それは例がintだからわかにくいかもしれないのでcharの配列で考えてみなよ
>>816 そういう決まりだからじゃないのか?
hairetuはhairetu[20]の先頭アドレス
だから先頭の配列であるhairetu[0]のアドレスと同じ
入れ物の置き場所がアドレス []の反対が&
連続レススマン
>>818 Cは数値を渡すのが基本だからアドレスっていう数値を渡すためにポインタが出てくるんじゃないかな。
>>816 a[b] と *(a + b) は一緒
&*a と a は一緒
a + 0 と a は一緒
であるから
&hairetu[0] == &*(hairetu + 0) == (hairetu + 0) == hairetu
>>806 どこで聞いた話か知らないがその言葉は正しくない
正確には、「一部の例外を除き、配列名はその先頭要素へのポインタ値に成り下がる」だ
一部の例外というのは、sizeof演算子を適用するとき、&演算子を適用するとき、配列の宣言と同時に初期化するとき、のこと
でもこれがイメージできないのはちとつらいな・・・
826 :
デフォルトの名無しさん :2008/06/01(日) 18:35:38
>>819-825 アリガトゴザイマス
イメージはできたのですがどうも&が存在してる理由がピンときません
初めて&が出てきたので後々に&演算子を適用するという場合に&がナイト不都合が生じるということでおkですか
配列以外に使う。
>>826 &がなかったら、配列以外の変数のポインタが取れないじゃん?
&(hairetu[0])の方がわかりやすいんじゃない?
>>826 えーと関数とかにデータを渡す際、int1つ程度であれば値渡しでいいですけど
intを20個とか渡すとなるとコピーするコストがかかるので配列の先頭アドレス
を渡せばアドレスのバイト数(これは実行環境で変動)で済むので
変数のアドレスを求めたりします
配列は大抵ポインタで渡すから 配列名書いただけでポインタ取れるようにしてる。
832 :
デフォルトの名無しさん :2008/06/01(日) 18:46:31
ようやく謎が解けました… こんどこそ大丈夫です アリガトゴザイマシタm(_ _)u
833 :
側近中の側近 ◆0351148456 :2008/06/01(日) 18:54:02
(っ´▽`)っ 要チェックや! int func(int *i) { printf("%d\n", sizeof(i)); return 0; } int main(void) { int i[20]; printf("%d\n", sizeof(i)); func(i); return 0; }
これは重要だな。
835 :
側近中の側近 ◆0351148456 :2008/06/01(日) 18:58:59
(っ´▽`)っ
>>833 は、
配列は引数で渡されるとポインタに格下げになる
というルールの例だよ。
sizeof(array)/sizeof(array[0])は良く使う
837 :
側近中の側近 ◆0351148456 :2008/06/01(日) 19:00:30
(っ´▽`)っ だから、配列を引数に渡したい場合には、 配列のサイズも一緒に渡さなければならないってこと☆ こういう感じに。 int func(int *i, int length) { printf("%d\n", sizeof(i) * length); return 0; }
型がなんであれ、ポインタの実態はアドレスだから 32ビット環境じゃ2^32でアドレスが管理されているから 32bitすなわち4バイトであるのは既知なること。
>>833 int func(int i[])の方がわかりやすいような
>>835 違う違う、配列の先頭のアドレスをポインタで引き渡しているんであって
格下げでも何でもないって
>>840 に一票
ちなみに文字列定数を定義するならchar*じゃなくてchar[]だな
842 :
側近中の側近 ◆0351148456 :2008/06/01(日) 19:03:47
>>840 (っ´▽`)っ
じゃあ、なぜsizeof(i)が配列全体のサイズじゃないのさ?
アドレスのサイズになるよね。
843 :
側近中の側近 ◆0351148456 :2008/06/01(日) 19:04:38
(っ´▽`)っ じゃあ、格下げというか、配列とみなさなくなるって言えばいいのかな?カナ?
sizeofは関数じゃないの?
845 :
側近中の側近 ◆0351148456 :2008/06/01(日) 19:05:42
(っ´▽`)っ いや、普通にi[10]とかアクセスできるから、 配列とはみなしてるんだろうなぁ☆ 単にsizeofの問題か。
847 :
側近中の側近 ◆0351148456 :2008/06/01(日) 19:07:37
(っ´▽`)っ まあ、とにかく、sizeofを配列に対して使う時には、 それがローカル変数なのか、引数なのか確認を忘れないこと☆
すみません、質問があります。 ファイルから読み込んだ文字列を一行ずつ配列に保管したいのですが、 自分がやると最終行だけが配列の全体に保管されてしまいます。 何がおきているのでしょうか。 data.txtは5行の適当なファイルを想定しています。 #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX 100 int main(){ FILE *fp; char c[100]; int i; char *a[5]; fp=fopen("data.txt","r"); if(fp==0){ printf("Error."); exit(1); } for(i=0;fgets(c,MAX,fp)!=NULL;i++){ printf("%d:%s",i,c); a[i]=c; } for(i=0;i<5;i++) printf("%s\n",a[i]); fclose(fp); return 0;
849 :
側近中の側近 ◆0351148456 :2008/06/01(日) 19:09:54
(っ´▽`)っ
>>837 は間違ってるな・・・微妙に。
sizeof(i) * lengthはアドレスのサイズ×配列のサイズだから、
何も意味しないよね・・・
アドレスはint型だろうから、偶然配列全体のサイズになるだろうけど。
32bitCPUでintが16bitってことはあったぞ ポインタが何bitだったかは覚えてないけど
hairetu[3] *(hairetu + 3) *(3 + hairetu) 3[hairetu] とできますよ。
まちがえてかいてしまた。 int main(void) { int hairetu[5] = {1,2,3,4,5}; printf("%d\n", hairetu[2]); printf("%d\n", *(hairetu + 2)); printf("%d\n", *(2 + hairetu)); printf("%d\n", 2[hairetu]); return 0; } これでも実行してね、といいたかったのです。
c[] = {読み込んだデータ} a[0] = c[]の先頭アドレス a[1] = c[]の先頭アドレス a[2] = c[]の先頭アドレス a[3] = c[]の先頭アドレス a[4] = c[]の先頭アドレス
855 :
側近中の側近 ◆0351148456 :2008/06/01(日) 19:18:36
>>848 (っ´▽`)っ
これこそアドレスだよアドレス☆
a[i]=c;
は、a[i]にcのアドレスを設定している。
行が読み込まれるとcは上書きされる。fgets(c,MAX,fp)でね。
a[i]に設定されたアドレスは変わらず、上書きされたcを指している。
だから、a[i]が最終行の文字列を指すわけ。
解決策は、a[i]=c;ではなく、strcpy(a[i], c)とすべき。
あと、char *a[5]をchar a[5][100]に変えてね。
静的領域を書き換えちゃダメだよ☆
858 :
側近中の側近 ◆0351148456 :2008/06/01(日) 19:19:27
>>853 その配列の表記は、知らない人多いから使いたくないな
>>842 だから char *i でも double *i でも
ポインタの 実態 は アドレス だから、環境にもよるが
扱えるメモリによって違うが、アドレスの番地を記憶している
識別子であることには変わりはないっす
>>859 使う使わないじゃなくて、等価であることを知ることで理解が進めばと思ったです。
2[hairetu]なんて書いてたらグーでパンチする。
けど、*(hairetu + 2)は別にいいでしょ。これが同じということを知ってほしい。
>>842 配列を引数に渡す事ができないということを言わないと。
854補足 つまりcのデータは毎回上書きされるので 最後に読んだデータになる。 解決方法としてはc[][]とバッファを2元配列にでもするか a[i] = malloc(strlen(c) + 1); memcpy(a[i],c,strlen(c)); と動的に領域を確保するとか。
*(2 + hairetu) これも気持ち悪いな
思想的には間違ってないが、そんなコード描いてるやついたら、俺はキレるw
足し算引き算の順番くらい好きにやらせてくれよ
絶対アドレス00000002から、なんかのテーブルでもあるのかなという感じw
ごめん その手のコードが分からない人が不具合誘発して、その尻拭いをするのはコリゴリなんだ・・・
>>866 そうでもないぜ・・・
>>864 のような記述ってBASICで作ってるお遊びプログラムの延長で
組んでるように見えるし、こういう書き方するのに限ってバグ大量に入れてるし
定数は右に書くもんだと思ってる
>>845 ひどい勘違い
[]演算子は配列に適用されるものでなくポインタに適用されるもの
配列名に対して[]が使えるのは、そのとき配列名がポインタに格下げされているから
格下げも何も、ポインタを要求する所に使ったら ポインタ型に暗黙にキャストされるだけだろ。
ポインタ型にキャスート(笑)
定数は==の左に書くものだと思ってる
警告ぐらいちゃんと嫁
C/C++はアセンブラのなれの果て。とかいまだに思ってる自分があって、 乏しいMASM経験から、定数は右のほうに置くくせがあるのかな…と自己分析してみた
警告を平気な顔で残してソース管理してるやつは、ほんとムカつくなー
うん、西暦10000年問題とかまったく考えてなさそう
>>875 それを見るたびに、ああ、これを書いた人は不安だったのかなって思ってる
881 :
側近中の側近 ◆0351148456 :2008/06/01(日) 20:22:34
>>875 (っ´▽`)っ
それって、if(k = 0){...}を防止するための措置だよね?
if(0 = k){...}はコンパイルエラーになるから。
>873 それはヌルポインタ定数0のことだ
>>881 けど最近のコンパイラは前者でも警告を出すよねって話
出ないコンパイラやmakefileもあるから、侮れないな あとtrue=1やfalse=0という前提で書かれているソースもひっかかる
>>877 なれの果てだねえ。
↑ポインタに格下げとか言う表現がちょっとびっくり
どうやってもアセンブラレベルだとポインタ持ってるからint が32bitだと
配列の先頭を指してるポインタに[n]*4するだけやん。
格下げも何も・・・
格下げという表現の時点で無理やりアセンブラに一枚オブラートかぶせただけって感じがする。
>>874 ?
a[b] は *(a + b) と等価で、
配列への整数の足し算は定義されてないから
ポインタに暗黙にキャストされるという話だろ?
>>887 意味不明でキャストの意味を間違っているから黙っていた方が良いお
無知を晒すのは痛々しいお ^ω^
等価っていうのは合ってるけどなw
ポインタはポインタ。ポインタ型はないが変数の型を指定して ポインタを宣言しないと、int型の変数をchar型のポインタを用いて 間接演算子を用いても適切に扱えんぞな
>885 ポインタとアドレスの区別がついてないならもう一度勉強しなおすことをお勧めする >873 違う 具体例を出すと、たとえば配列aに対して if(a) と書くと条件が真となる しかしもしここでaがポインタでないなら(ポインタを要求する文脈ではないからそうなるはずだが)この条件は不定になってしまう なぜなら、「配列の中身」や「配列のアドレス」でなく、配列名が指すべきものつまり「 配 列 そ の も の 」が いかなる値を持つべきかは規定されていないからだ 配列は配列そのものを指すが、先の例外を除いて、先頭要素へのポインタに成り下がる だから if(a) は正しく真と判定され、また一方でsizeof(a) はa全体のサイズを返し、&a は「配列へのポインタ」を返す
よくわからん
訂正 ×「配列の中身」 ○「配列の要素」
>>891 873は833の例に対して引数がint*なんだから配列渡そうが、
ポインタ渡そうが違いはないってこと言いたいんじゃないか?
なぜそこで833が出てくる アンカーつけてないなら普通直前の872の話だろ で872は845につながっている ここで問題になっているのは845の「[]は配列に作用する演算子だ」という勘違い
レス番つけるなら >> つけてくれ。追うのがめどい。。
しかもここID付かないから余計面倒w
格下げなんて俺用語使ってるからダメなんだよ。 配列-ポインタ変換と言おうぜ。
おまいら、知ってっか?2038年問題を。っていっても、すでに対策済みだがなw
ポインタはポインタ、配列とは無関係。これまた、ややこしいな・・・ すでにポインタの実態は、配列とポインタに対して sizeof で結論は出ていたはずだろ? ポインタはどう足掻いても、例え動的確保をしようが、アドレスの番地に過ぎないんだよ。 割り当てが 2^32 の範囲ないであれば、8bitで1byteなら4バイト 配列は宣言した変数*要素数だって結論は出ただろ?四の五の言わずに ポインタはポインタ、実態はアドレス
>>891 配列を条件式として使ったらどうなるか定義されてないからポインタに変換されて、
後はそのポインタが条件式として使われる(0=偽/非0=真)だけだろ。
ポインタに格下げの意味が分からん。ぶっちゃけ、配列のアドレスを渡そうが コードはその配列の要素を無視して無関係な場所をポインタに 指定することも可能だが?
お前の言ってる意味の方が分からん
>>901 違う。
コンパイラには定義されていない構文をそのまま通してやる義理などない。それは未定義だ。
配列がポインタへ格下げされると定義されているからこそ、if(a) は正しくコンパイルされる。
>>903 理解力の無いバカなら余計に話しするなよクズが
うわっ、識別子の意味も分かってないバカがポインタ型とかぬかしてんぞw 以後放置よろw なんだよポインタ型ってw 出るとこに出たら笑われんぞw
if(配列)なんて現実的でない例にどんな意味があるんだろう
>>904 言ってる事は正しいんだが、それって 「格下げ」 なのか?
配列よりポインタの方が格下なのか?
>>906 ポインタ型 (pointer type) は規格にも載ってる用語だが・・・。
ポインタ型を知らないとなw
ポインタにはアドレスを渡してんだよ。例え配列でなくても int a; を &a でアドレスを渡すことがあろう。 ポインタで宣言された識別子は、その指定された型応じて使える 実態はアドレスに過ぎない識別子。
っつーか、メモリのアドレスも知らなさそうな素人がコードを書いているんじゃね? 自分、大学の実験でも内面的なものを扱ったが、それくらい知っておけ
「アドレス」 の実体は別に規定されてないけどね。
>>908 確かに「格下げ」とか「成り下がる」とかは正式な用語ではない。
しかし、多くの場面で実際に使われている。
特にCプログラミングFAQにおいて使われていることから、
準公式な用語として認識しているプログラマが少なからずいる。
もって回った表現で言えば「縮退したデータ型に暗黙に変換される」となる
(なお、これは「キャスト」のことではない、念のため)。
ここで言う「縮退した」とは、「配列全体」(という概念)を意味する配列の名前が
「配列の先頭要素へのポインタ」になることを言う。
規格スレ行け
変換をキャストと言う事も正式用語でなくともよく聞くけどな。
>>914 それって暗黙なのか?
少なくともソース書いてる本人は意識してるはずだぞ
そりゃ暗黙だろう。
>>914 別に格は下がってないけど?配列の場合、先頭のアドレスを
単独の場合はとりわけ & アドレス演算子でポインタにアドレスを渡しているんだが?
しかし、変数の型に応じたポインタを宣言しないと、適切に指定したアドレスの
変数が使えんぞ。
>911 >920 日本語でおk
void はカエレ
質問です。 switch文を使って、数字以外のものを決めることはできないのでしょうか。 (例えば、プラスやマイナス)↓ switch(na){ case 0: case 1: ma = +; break; case 2: case 3: ma = -; break; }
無理です
>>925 1. 数値を記号と対応させる(列挙子を使うと良い)
2. 文字や文字列を使用する
3. 関数ポインタを利用する
状況次第で 1〜3 のどれかを使う。
>>924 voidじゃないよ。
>>925 もう一体何がしたいのか分からないよ><
もう少しやりたいことを具体的に書いてみようー
>>925 できない。
そもそも switch だろうがなんだろうが、「正負を格納するデータ型」は存在しない以上、それを記録することもできない。
整数型の変数に 1 か -1 を格納して、必要なら他の数との演算に使うこと。
数式のグラフを表示をしたいときはどうすればいいの?
naはintか何かで プラスマイナスっていうのは記号で付いてこないでOK? それとも文字列でくるのを判断したいのか?
グラフを表示したいだけなら Excel とか gnuplot とか使っとけ
グラフィカルユーザーインターフェースによる
>>932 naはintです。naとプラスマイマスを一緒に文字列でだしたいです。
代数に-100から100までを代入して図が動くプログラムを書いて来いと言われたんだ
>>914 格下使うって(私の周りでまぁ使わん)雰囲気、通じるけどぉ。
そもそも
int a[50];
同じスコープ内で a[n] でなく *(a+n) と記述してしまうプログラマーはセンスないと思わないっすか?
記述可能な事とはまた違うでしょ。
union
{
int iValue;
char cVal[sizeof(int)];
} k;
void *vp = (void*)&k;
int *ip = (int*)vp;
char *cp = (char*)vp;
ネタ
どうしてもswichで処理したければ 最初にifでnaが0以上か0未満か 調べて0未満なら*-1しておけば swichを両方で使える。 あと正だったのか負だったのかは 覚えておかないとあれだけどな
そういえば、どっかで配列の表現使わずにポインタで 書いた方がはやいってのを見たんだが、それってどうなの?
>938 だからそのグラフを ど こ に 出力するのかによるって言ってるだろ
ごめんなさい、間違っていました・・・。 naで決めたプラスマイナスと英数字を一緒に表示させたいのです orz
>>941 昔の話、今時のコンパイラなら最適化してくれる
>>943 naの型とどういうルールで中のデータが決まるの?
>>941 そういう場合もある。
ただし、君は以下のことを見直すべきである。
[]演算子は「配列の表現」ではない。常にポインタに対して適用される。「添字を用いた参照」ガ正しい。
すみません、やはり宿題を片付けますスレに行ってきます。 ありがとうございました。
>>943 char c;
case 0: c='+'; break;
case 1: c='-'; break;
質問主は名前欄に最初の発言のレス番号入れろよ ここIDつかねーんだから
>950 丸神正頼乙
次スレって誰が立てるんだっけ?
>>950 にお願いしたら。
あと重複を避けたいので宣言してからでよろ
957 :
950 :2008/06/01(日) 22:59:26
俺かよ ちょっと待て
958 :
950 :2008/06/01(日) 23:01:53
じゃあ俺が
960 :
956 :2008/06/01(日) 23:05:31
乙
急に静かになった
スレ立てはえーよw ギリギリまでたてないことがほとんどだし、1000まで行ってからたつこともよくあんのに。
質問です voidポインタから値を参照する時、意図した型のものかどうかを判定するにはどうしたらいいでしょうか?
>>964 判定も何もvoidポインタでもらってきても
いずれ何らかの形でキャストしなおさない?
ということは判定も何もプログラム組む時点で
わかってるはずなんだけど・・・
元がどんな型だったのかを void ポインタから知る事は出来ない。
967 :
965 :2008/06/02(月) 02:24:11
hogeという構造体の定義があって hoge *wp = malloc(sizeof(hoge)); これはキャストを明示してないけどね。
明示してないだけで暗黙にキャストが発生してる
まあとにかくvoid *というのは大きさが無いポインタ、 位置だけを知っているポインタという意味だから、 大きさが無い=中身が無いわけで、 当然void *から値は参照できない おわかり?
970 :
964 :2008/06/02(月) 02:40:54
用語を知らないのでよくわからない書き方になってすみません 例えばvoidポインタから構造体aとしてキャストして構造体内の値を参照する、というプログラムで 何らかの原因で構造体bのポインタが入っていた場合に キャストする前にaかbかを判定する方法があるのだろうか、と思って質問してみたんです voidポインタから直に型を判別する方法は無いので、その点注意してプログラムを組む、ということでいいでしょうか? あと、voidポインタ使用時に、これには気をつけろ!なんていう点があったら教えてもらいたいです
ない。 キャストは全面的にプログラマの責任で行わなければいけない。
>あと、voidポインタ使用時に、これには気をつけろ!なんていう点があったら教えてもらいたいです 第一に、できるだけvoidポインタなんか使わずに済ませることを考える 第二に、それでも使わざるを得ないなら必ず何のポインタから変換したのかを確実に把握できるようにする あとは普通のポインタと同じ
>>970 > voidポインタから直に型を判別する方法は無いので、その点注意してプログラムを組む、ということでいいでしょうか?
それでいいよー。
a、b、どちらも指す可能性があるポインタを使うと便利な場面はあるので
きちんと把握して操作することを心がけましょー
>>970 もし、void *が指しているオブジェクトが構造体で、
しかも来る可能性のある構造体がなんなのかわかっていて、
かつその構造体の定義に手を入れることができるなら、
先頭要素に共通のフラグを埋め込むことで
(たぶん、まずint *にキャストして値を調べることで)判別できる
でもそんなことやるくらいなら素直にもうひとつ変数を用意して
そこに型の情報を示す値を入れてvoid *と一緒にやりとりしたほうがいい
>>964 その程度のレベルでvoidポインタを扱うのは早すぎるんじゃないか?
考え方としては、void*とセットで型に関する情報を伝播させればいい ただしCはそれ手動な。やりようはいろいろだが、自前だ
Javaでいうところのinstanceofが欲しいのだろうが、あれはすべてのクラスの親にObjectが存在して ガーベジコレクションを使ってるからこそ実現してることだしな MFCなんかだと、方法はなくはないが、そういう余計な処理がないからこそ、Cが高速であるとも言える まー、原始的に伝えるしかないわな enum {type_int, type_float};みたいなのを引数で渡すのが無難だろう
>>970 void*のまま使おうと考えずに、mallocしたらすぐ適当なstructにキャストしよう。
その上で型を判断しよう。
例:
typedef struct
{
int typeID;
}Base;
typedef struct
{
Base typo;
int piyoko;
}fuga;
うめ しないと誰も使わない感じだね・・・
ではこちらで。 「配列がポインタに成り下がる」という言葉を理解するためには、配列が「二級オブジェクト」であるということを理解する必要がある。 二級オブジェクトであるとは、メモリ上に場所を持つけれど、それ自体は意味のある値を何一つ持たないということである。 比較のために、こちらは一級オブジェクトである構造体の話をしよう。構造体は、代入することもできるし、そのまま関数に渡すこともできる。 これは、その構造体型の値というものが、他のどんな整数やポインタ値とも比較も演算も変換もできないけれど、概念上存在するからである。 対して、配列はそのような値を持つということが規定されていない(できるできないの話ではない。持たないと決まっているということである)。 だから配列名は配列全体を意味し、よって sizeof を作用させれば配列全体のサイズが、& を作用させれば配列全体へのポインタが得られるけれど、 決して配列に代入したり、関数にそのまま渡すことはできない。代入する、あるいは引数にコピーされるべき値というものがなければいけないからだ。 しかしこれだけでは、配列の要素にアクセスするために、& 演算子で得られた値を更にキャストするという迂遠な手続きが必要となってしまう。 そこで規格は、上に挙げた配列全体を考える場合を除いて、「配列の名前はその先頭要素へのポインタ値に暗黙に変換される」ことにした。 これによって、現在よく知られている配列を扱うさまざまなスタイルが正当性を持つこととなり、容易に配列の要素にアクセスできる仕組みが確立され、 そしてこの動作は俗に「成り下がる」とか「意味が格下げになる」と呼ばれるようになった。 再度念を押しておくが、これは「キャスト」ではない。キャストとはある型の値を(可能なら)別の型に変換することである。 配列にはそもそも値がない。ないものをキャストで変換することは不可能である。 「成り下がる」とか「格下げ」という言葉が嫌いなら使わなければよい。だが、以下のようには決して考えてはいけない。 ・配列はその先頭要素を指す定数ポインタである ・なにかの値を関数に直接渡すことが出来ないときは、代わりに自動的にポインタを渡すものである
参考になるが、入門じゃないなコレw 仕事おわったら読み直してみよう
その辺りはC++でテンプレートを弄っていれば判り易いんだけどね。 ロートルは、構造体でさえ代入不可だと思い込んでいたりするから困る。
Cでは”配列型”という概念は無いYO それどころか、実は”配列”という概念すらないYO int a[234];と宣言すると、int型の234個の連続無名変数ブロックと その先頭の読み出し専用ポインタ変数(事実上の定数)aが宣言されたことと等価になるYO コードブロック内の[]はすべてポインタ値に対する演算子で、表現a[2];*(a+2);2[a];はすべて等価で、 同じ無名int変数を指すんだYO
typedef int type_a[234]; でtype_aは配列型になったYOと喜ぶのは間違い。 type_a x; とすると、 コンパイラが、int x[234];が指定されたものだとして、 自動展開してくれるんだと思ったほうがいい Cのtypedefは、ある種のマクロだと思うべき。 int a[]={1,2,3,4,5,6,7} だってある種のマクロ表現。コンパイラがコンパイルエラーにならないように適当に解釈して 数字を補ってくれるサービスのようなもの int func( int a[] );も同じだが、ちょっと異質。これはサービスじゃなくて、ダブルスタンダート。 int func( int *a );の別表現。 すべてのint型配列を総称する型があるんだと誤解させかねないint func( int a[] );のような 書式は、初学者向けのサンプルコードでは使わないで欲しいと思うにゃ。
>>983 その解釈において、sizeof(a)がどうなるのか説明してみてください。
>>983 それならどのようなものを配列と呼ぶの?
struct で括れば満足?
読み手のレベルを意識しないオナニーレスが続いてるな
初心者に対して正しくない言葉を教えるのはよくないよねって ことでこうなってるんじゃないかなー
まあスレウメとあわせていいのでは? 新規質問は新スレでやってるようですし
>>985 sizeofも一種の組み込みマクロサービス
sizeof の引き数は、変数や型ではなく、識別子 (数値やリテラルを与えるのは無効)
どんな値になるのかは、コンパイラがそのコンテクストで決定できる。
多くの処理系では、識別子aが例え読み出し専用のポインタであっても、
int a[100];のような宣言書式で定義されていれば、sizeof(a)をsizeof(int)*100として
返してくれているみたい。
sizeof演算子を使うと、宣言に修正を入れた場合でも、コード修正は少なくてすむので
多用されがちであるが、やはりどのような値を返すのかは、チェックしたほうが良い
(コンパイラを神様と思わない。使用者が期待する値を返さない場合もあるかも)
質問です 構造体定義をした際、コンパイラが勝手にサイズ調整のための 余分なエリアを入れないようにするにはどうすれば良いでしょうか?
>>991 >sizeof の引き数は、変数や型ではなく、識別子 (数値やリテラルを与えるのは無効)
sizeof("Hello") って出来なかったっけ?
>>993 sizeof(0)もできるね。
まぁ、
>(コンパイラを神様と思わない。使用者が期待する値を返さない場合もあるかも)
こんなこと書いちゃう>991に期待しちゃダメってことだね。
sizeof(main)=1と出ました このコンパイラはバカじゃないかと思いました。(某gcc)
997 :
gcc :2008/06/02(月) 17:51:58
>>995 関数のサイズを取得しようなんて馬鹿に言われたくないね。
>>995 何のサイズを取得したんだと小一時間(ry
999 :
992 :2008/06/02(月) 17:52:58
>>996 これまたコンパイラ依存ですか・・orz
BMPファイルを出力するプログラムにヘッダなどを
必要な構造体を持たせてるんですがCygwin(gcc?)
でコンパイルするとずれるんですよね・・・
cはやっぱり規格に不備があるよね。
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。