C言語なら俺に聞け(入門篇) Part 28

このエントリーをはてなブックマークに追加
1未定義の名無しさん
言語の入門者向け解説スレです。
・C++言語はスレ違いです。
・分からない事をなるべく詳しく書いて下さい。
・ソースコードを晒すと答えやすくなるかもしれません。
・開発環境や動作環境も晒すと答えが早いかもしれません。
・質問者は最初にその質問をした時のレス番号を名前欄に書いて下さい。

前スレ
C言語なら俺に聞け(入門篇) Part 27
http://pc11.2ch.net/test/read.cgi/tech/1209429897/
過去スレ
http://makimo.to:8000/cgi-bin/search/search.cgi?q=%82b%8C%BE%8C%EA%82%C8%82%E7%89%B4%82%C9%95%B7%82%AF&andor=AND&sf=0&H=&view=table&D=tech&shw=5000

教えて欲しいのではなく宿題を丸投げしたいならこちらへ
C/C++の宿題を片付けます 107代目
http://pc11.2ch.net/test/read.cgi/tech/1211006255/
2未定義の名無しさん:2008/05/19(月) 21:07:23
3未定義の名無しさん:2008/05/19(月) 21:07:45
4デフォルトの名無しさん:2008/05/19(月) 21:43:15
0〜Nの間の数値の内、3の倍数と3のつく数字の時だけ”アホ”と表示したいのですが

「3のつく数字の時」
を高速に判定するにはどうするのがベストですか
5デフォルトの名無しさん:2008/05/19(月) 22:12:08
>>4
全部の数字に対してアホと表示することをどうして考えないのでしょうか?
仕様レベルから見直して下さい。
6デフォルトの名無しさん:2008/05/19(月) 22:12:44
>>4
事前に「N以下で3のつく数字」のテーブルを作っておき、
対象の数字がそのテーブルにあるかチェックする。
7デフォルトの名無しさん:2008/05/19(月) 22:27:08
>>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のつく数字です。");
}
}
8デフォルトの名無しさん:2008/05/19(月) 22:29:02
>>4
> 「3のつく数字の時」
> を高速に判定するにはどうするのがベストですか
sprintf関数で文字列にして、strchr関数で'3'を見つける。
9デフォルトの名無しさん:2008/05/19(月) 22:30:53
>>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;
}
10デフォルトの名無しさん:2008/05/19(月) 23:42:50
パスワードのプログラムでキーボードから入力された文字数が9文字以上ならやり直し
8文字以下なら同意済みのpass{9}にコピーであらかじめ設置済みのパスワードと比較して
一致ならok、不一致ならやり直しってプログラム作りたいんだけど作れない

誰か親切な方教えてください
11デフォルトの名無しさん:2008/05/19(月) 23:47:58
宿題なら宿題スレへ。
そうじゃないなら、どこがどうわからないのかをもっと具体的に。
12デフォルトの名無しさん:2008/05/19(月) 23:48:05
>>4
高速にということになれば絶対的な解は存在しない。
常に処理系依存であり、実測によって確認する必要がある。

一般的な考え方は、コンピュータ上での整数は2進数であり、
10進数としての見かけを扱うなら10進数(の規則)に変換する必要があるということである
(たとえばsprintfと%d指定子を使って文字列を作り出すことによって。
ただし、文字列にすることは常にバッファの確保の問題を内包しているし、
sprintfのような強力な関数を呼ぶことは多くの場面で大きなコストとなることは覚えておくこと)。

単に10進数の各桁の数字を順に取り出したいなら、%演算子で10の剰余(最小の桁の数字)を得た後で
/=演算子で1/10にすることを繰り返す昔ながらのアルゴリズムが最も汎用的な解で、ほとんどの処理系で十分に高速である。
しかし、いずれにせよ後で標準出力等に数字を文字列にして出力しようとしているなら、
あらかじめsprintfで文字列を作って(恐らくはポインタを操作して)1文字ずつ解析したほうが速い可能性は高い。
13デフォルトの名無しさん:2008/05/20(火) 00:05:37
>>10
まず、以下の単語の意味を適切な日本語で説明すること。
・同意済みの
・pass{9}
・設置済みの
14デフォルトの名無しさん:2008/05/20(火) 01:15:45
>>10
> 入力された文字数が9文字以上ならやり直し
これ不要だと思うが?
15デフォルトの名無しさん:2008/05/20(火) 01:19:44
>>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;
}
16デフォルトの名無しさん:2008/05/20(火) 01:57:06
>>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");
}
17デフォルトの名無しさん:2008/05/20(火) 01:57:38
>>14
同意 あからさまに不必要情報
1816:2008/05/20(火) 02:05:56
ゴメソ
バグってた.
各自で直してくれ
1916: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");
}
20デフォルトの名無しさん:2008/05/20(火) 03:55:12
ヘッダファイルが沢山インクルードされているソースだといちいち使われている変数の型をヘッダファイルに確認しなきゃいけないんですがそれが煩わしいです
なにかソースを読むときのコツとか心構えがあれば教えてください
21デフォルトの名無しさん:2008/05/20(火) 04:03:38
22デフォルトの名無しさん:2008/05/20(火) 04:42:32
このサイトのどこを読めばいいんでしょう?
23デフォルトの名無しさん:2008/05/20(火) 04:46:24
>>22
最初から読めよ
24デフォルトの名無しさん:2008/05/20(火) 06:23:41
コードリーディングって言うんですね、VBのデバッグツールは変数の内容をポップアップで表示できますがそれと似た感じで、ソースコードにある変数名からその型や構造体の詳細を表示できるリーディングツールとかがあるんでしょうか?

っていうかもう朝だw
25デフォルトの名無しさん:2008/05/20(火) 07:51:51
>>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
27デフォルトの名無しさん:2008/05/20(火) 08:36:49
>>26
空読み。
28デフォルトの名無しさん:2008/05/20(火) 08:47:29
rewind(stdin)
29デフォルトの名無しさん:2008/05/20(火) 09:12:59
>>28
それって動作未定義じゃなかったっけ?
30デフォルトの名無しさん:2008/05/20(火) 09:14:38
>>20
まっとうなライブラリなら提供する変数やシンボルについて詳細な説明を文書にしてあるはずである。
標準ライブラリの規格や、開発環境が独自に用意したものなら付属のマニュアルを読むこと。

もし不親切なライブラリや出所の怪しいライブラリを使うはめになったら、まずは開発環境のコード支援機能を活用すること。
どうしてもヘッダファイルの中身を直接読まなければならないなら、grepツールを使うことが多くの場合で助けになる。

一方で、変数の型は必ずしも確認する必要があるわけではない。
特にtypedefや#defineによってわざわざ元の型を隠そうとしている場合には、むしろ元の型が何であるか考えないことが、
ライブラリ作成者が意図した使い方のはずである(もちろん、これもタコなライブラリに関しては当てはまらない)。
31デフォルトの名無しさん:2008/05/20(火) 09:37:20
>>27
dクス
解決しますた
32デフォルトの名無しさん:2008/05/20(火) 10:05:26
>19
正しいアルゴリズムを書けないのに
自分は頭がいいんだと勘違いして
他人を嘲ることほど恥ずかしいことはない
33デフォルトの名無しさん:2008/05/20(火) 10:21:55
4==16
としか思えないのだが...
34デフォルトの名無しさん:2008/05/20(火) 10:28:32
正しいアルゴリズムを書けて頭も良く人を嘲ることがでいる>>32
さんに>>19のコードのどこを修正したら正しく動作するか
やってもらいましょうw
35デフォルトの名無しさん:2008/05/20(火) 10:39:30
他の板なら 4=16 と書かれるであろうところを
ちゃんと 4==16 と書くところにこの板の格調の高さを感じる
36デフォルトの名無しさん:2008/05/20(火) 10:47:04
もしかして>>4=>>16ってことか?
4と16の比較でもしてるのかと思った
37デフォルトの名無しさん:2008/05/20(火) 10:59:51
>>32
頭が悪いからこそ普段からバカにされてるストレスの発散として他人を嘲る
でも、頭が悪いから嘲ろうとしても逆にバカにされ余計ストレスをためる
の悪循環にはまってるから何言ってもムダだよ
38デフォルトの名無しさん:2008/05/20(火) 11:09:11
>>34
不可能である。
>19は3の倍数と3のつく数字の数を数えようとしている(それすら間違っているが)。
対して、>4が要求しているのは、任意のある数字に3がつくかどうかを効率よく知る方法である。
アルゴリズムの修正とは手段を訂正することであって目的を訂正することではない。
目的を訂正するならそれはアルゴリズムの完全な書き直しである。
39デフォルトの名無しさん:2008/05/20(火) 11:51:38
>>38
貴方はなぜそんなにムキになってるんですか?w
40デフォルトの名無しさん:2008/05/20(火) 12:07:36
おまえら・・・一体ナニヤツ?
41デフォルトの名無しさん:2008/05/20(火) 15:33:27
あいかわらず一定確率で初心者に優しくないなおまいらw てか質問者そっちのけw
42デフォルトの名無しさん:2008/05/20(火) 15:47:39
そもそも掲示板という環境は初心者に優しくない
リアルタイムに顔つきあわせてやるのが最善なんだから
43デフォルトの名無しさん:2008/05/20(火) 16:03:59
質問者が結論出してしめないからこうなるw
44デフォルトの名無しさん:2008/05/20(火) 16:05:56
スキルの開きがすごいからな
45デフォルトの名無しさん:2008/05/20(火) 16:17:19
タイムラグのある文字だけのコミュニケーションで的確に意思を疎通させるには
双方の日本語力と論理的思考力が不可欠だってだけだよ
どちらかでも欠ければどんな質問もまともに回答されるとは保証できない
46デフォルトの名無しさん:2008/05/20(火) 16:26:02
VisualStudio2005 でデバッグ実行すると普通に実行できて、デバッグなしで実行すると途中でエラーが発生しましたって出るんですけど。。。
何でですかね。。。?
47デフォルトの名無しさん:2008/05/20(火) 16:34:00
>>46
コンパイラの警告レベルを上げて、出てきたメッセージを詳細に分析しましょう。
操作方法を詳しく知りたいならVisualStudioのスレへ行きましょう。
プログラムの内容についての相談ならソースを張りましょう。
48デフォルトの名無しさん:2008/05/20(火) 16:37:38
>>45
46みたいなアホを見ると質問者の方に問題がある場合が多いと思うぜ
49デフォルトの名無しさん:2008/05/20(火) 17:22:28
>>46
よくある原因は大きく分けて3つある。

1)初期化されていない変数を誤って使用している場所があって、
メモリのいたずらでたまたまデバッグ実行するときだけ適切な値が入っている。
そのような場所がないかを探すこと(目視で、あるいはコンパイラの警告を読むことで)。
どうしてもわからないならエラーが起きた地点から処理を逆行して調べる
(とんでもない距離を遡る必要があるかもしれない)。

2)正しく確保していないメモリに書き込んでいるか、
確保したメモリの大きさを踏み越えてしまっていて、
やはりメモリのいたずらでたまたまデバッグのときだけ問題がないようになっている。
配列やポインタの周辺を徹底的に調べること。特に添字の範囲が適切であるかどうか。

3)デバッグ時とそうでないときでmainの実行時引数や環境変数
(一番ありそうなのはカレントディレクトリのパス)が異なっていて、
それを正しく処理しないコードを書いている(特にファイルを操作する場面で)。
そのような処理がないかを洗い出す。


問題が起きたときは常にエラーや警告をを注意深く読むこと。解決のヒントはたいていそこにある。
また、他人に相談するときはそれらを正確に説明すること。どんな名プログラマも君の頭の中に直接アクセスすることはできない。
50デフォルトの名無しさん:2008/05/20(火) 17:43:30
正確にどこでどんなエラーで落ちたのかを調べる。
特に、ソースのどこで起きたのかをデバッガなしで特定するノウハウは今後役に立つ
51デフォルトの名無しさん:2008/05/20(火) 18:48:04
>>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");
}
52デフォルトの名無しさん:2008/05/20(火) 19:19:41
>>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");
}
}
54デフォルトの名無しさん:2008/05/20(火) 20:05:19
>>53
宿題の丸投げならスレあるぞ。
逆つーんなら
for (dan=1; dan<=9; dan=dan+2){

for (dan=9; dan>=1; dan=dan-2){
にするとか
55デフォルトの名無しさん:2008/05/20(火) 20:43:38
>53
質問とは関係ないが、mainはintを返すと宣言しなければいけない
いくつかの古い入門書や間違ってる入門書もあるので注意だ
56デフォルトの名無しさん:2008/05/20(火) 21:29:39
質問です。
入力された米国ドルを英国ポンドに換算するconvert()という関数を作成し
その関数を使って換算後の金額を表示するプログラムを作成してください
(為替レートは1ポンドを2ドルと仮定します)。
という問題があるんですが
convert()という関数だけ作ってもらえませんかね?
まだはじめたばかりの初心者なんですが、この関数の作り方がわからなくて;;

57デフォルトの名無しさん:2008/05/20(火) 21:58:02
>>56
int convert(int usDallerAmount);

質問です。
javaとjavaScriptぐらいしか触ったことの無い俺に
ポインタの有用性の分かるプログラムを教えてください。

何でも出来るから便利とはよく聞くんですが、
実際どういうときにどういう使い方が出来るから便利なのかさっぱり思いつきません。
ポインタが有効的に利用されているプログラムのソースなどありましたら教えてください。
58デフォルトの名無しさん:2008/05/20(火) 22:00:17
double convert(double dollar)
{
  return dollar/2.0;
}
59デフォルトの名無しさん:2008/05/20(火) 22:07:38
>>52
ってかさ、数値が 3 の倍数であること。あるいは 3 が現れることを判定するのが肝でそこを考えるのがあれだしょ?
で、そういう関数ができたら後はそれで「4はそのアルゴリズムが想像できないマジアホですっ」て出すとかはお好きにどうぞってことじゃないかなぁ・・とマジ書き
60デフォルトの名無しさん:2008/05/20(火) 22:07:58
>>57
javaの参照はポインタみたいなもんだろ。
61デフォルトの名無しさん:2008/05/20(火) 22:11:00
>>57
Cにおいてはポインタは、有用であるというより、むしろ必須であるというほうが正確だ。
さらに突っ込んで言えば、およそどんなコンピューターシステムでも
メモリアドレスの概念を用いて複雑なデータ処理を行うのであり、
Cは他の高級な言語ではプログラマの目から「隠されている」メモリアドレスの処理を
プログラマが明示的に操作することが出来る機能としてポインタを実装しているに過ぎない。

ポインタの有用性を考える必要はない。ポインタが実際のところなんであるかを理解すれば、
いくらでも有効に活用することができるはずであるし、もし理解しないとしたら、
きっと君はCで何かを行うことはほとんどまったくできないだろう。
62デフォルトの名無しさん:2008/05/20(火) 22:58:38
>>57

メモリマップドI/Oのシステムだと、ハードウェアのレジスタがメモリアドレスに割り当てられているから、
ポインタが無いと絶対にアクセスできない。
また、DMA転送の場合には、ハードに対してメモリアドレスを指定するから、
やっぱりポインタが必要となる。

なので、Cでデバイスドライバを作るとき、ほとんどの場合必須。
63デフォルトの名無しさん:2008/05/20(火) 23:41:28
次のフローチャートを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 で使用すればいいですよね?
64デフォルトの名無しさん:2008/05/20(火) 23:43:01
#cじゃなくて%c
65デフォルトの名無しさん:2008/05/20(火) 23:43:51
あとscanfじゃないかな
66デフォルトの名無しさん:2008/05/20(火) 23:44:33
エラーメッセージを読んでください
スペルミスくらい確認してください
ptrintf
67デフォルトの名無しさん:2008/05/20(火) 23:48:00
パソコン2台で移し間違えもありました><
scanfにしたらエラーが2件に減りました

scanfの宣言を確認してください

intはconst char [2]" と間接操作のレベルが異なります

const char *型からint型の変更ができません
68デフォルトの名無しさん:2008/05/20(火) 23:50:02
rewind(stdin)は基本的に有り得ない。
"A"じゃなくて'A'。

コンパイラの出力を眺めても分からなさそうなのはこれくらいかな。
69デフォルトの名無しさん:2008/05/20(火) 23:51:36
>>68
できました!ありがとうございます><
これだけ解くのに2時間かかった。。。
70デフォルトの名無しさん:2008/05/21(水) 00:15:34
とりあえずあせらずゆっくり教科書を読むんだ
71デフォルトの名無しさん:2008/05/21(水) 00:31:56
"A"と'A'の違いがわかれば一人前だな。
72デフォルトの名無しさん:2008/05/21(水) 00:41:49
>>71
"A" の方が照れてる感じです!
じゃなくて、一人前のレベルが低すぎるよ
73デフォルトの名無しさん:2008/05/21(水) 00:41:50
\nってどんな意味があるの?
"" ←のいる時といらないときの状況が分からないんだけど説明できる人います?
74デフォルトの名無しさん:2008/05/21(水) 00:44:29
"A" = 文字列
'A' = 文字 = 数値

\nは改行コード
75デフォルトの名無しさん:2008/05/21(水) 00:47:16
>>74
''って数値だけだったのか
ありがとうございました分かりましたw
76デフォルトの名無しさん:2008/05/21(水) 00:51:09
"A"は文字列というか、
{'A', '\0' } というchar型配列をメモリに確保して、その先頭のアドレスを"A"に置き換えている

 "A" = 配列の先頭へのアドレス

と少なくとも俺は思っているんだが合ってるんだか全く分からん

'A' == 0x41
77デフォルトの名無しさん:2008/05/21(水) 01:11:42
>>76
その文字列を代入した「変数」がアドレスを表す。"A"自体は文字列リテラルとしか言いようが無い。
78デフォルトの名無しさん:2008/05/21(水) 01:16:00
"A" 文字列リテラル。文字列。末尾に\0を持つ。
'A' 文字リテラル。単なる小さな整数。
ひとつの文字と一対一対応するがある値がどの文字と対応するかは環境依存。
言語仕様上、'a'の次が'b'である保障もなし。
ただし、数字は連続する。たとえば'1'の次はつねに'2'。
79デフォルトの名無しさん:2008/05/21(水) 01:17:57
>>77
変数じゃなくて評価した式の値ね
80デフォルトの名無しさん:2008/05/21(水) 01:21:05
なるほど、ひょうかひょうか
81デフォルトの名無しさん:2008/05/21(水) 01:22:34
関数ポインタが使いこなせるようになれば一人前だな
82デフォルトの名無しさん:2008/05/21(水) 01:34:11
>>81
lambdaを実装するんだ!!
83デフォルトの名無しさん:2008/05/21(水) 02:53:59
関数ポインタを引数に取るAPIとかざらにあるから、使ってなくはないはずなんだが
使いこなしてると言われると自信ないなあ どんなんなんだ
84デフォルトの名無しさん:2008/05/21(水) 02:59:12
関数ポインタを使って好きなときに好きなように処理を入れ替えれるなら
使いこなせてるって言うんじゃない?知らないけど
85デフォルトの名無しさん:2008/05/21(水) 08:16:32
全然分かりませんん!チンプンカンプンです!
86デフォルトの名無しさん:2008/05/21(水) 08:24:33
俺的メモ。

一人前=それなりのモジュール設計ができ、デバッグもでき、
ライブラリを探してきて一人で組み込めるレベル。
他人に頼らずに他人に迷惑かけずにそこそこの仕事ができるレベル。
DQでいうとベホイミとルーラを覚えたくらいだな。
87デフォルトの名無しさん:2008/05/21(水) 09:26:33
ifとwhileしか使えないオレはメラが使えるくらいか
88デフォルトの名無しさん:2008/05/21(水) 09:30:13
if for do while などは、幅広い言語で共通して使えるものだから
むしろ敵に素手で攻撃するようなものだ
89デフォルトの名無しさん:2008/05/22(木) 14:55:45
すみませぬ。

LUNAXにプログラムにおいて
20という数字をターミナルに入力したら、
それを読み取り、30という数字を表示する
プログラムの作り方がわからない為、教えて頂けませんか??
90デフォルトの名無しさん:2008/05/22(木) 14:59:52
HelloWorldは書いたかい?
91デフォルトの名無しさん:2008/05/22(木) 15:00:32
>>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);
92デフォルトの名無しさん:2008/05/22(木) 16:47:38
処で、LUNAXってなんだ?
93デフォルトの名無しさん:2008/05/22(木) 17:02:21
次世代型の月OS
94デフォルトの名無しさん:2008/05/22(木) 18:17:01
LUNA SEA , X-JAPAN
95デフォルトの名無しさん:2008/05/22(木) 19:30:41
すいません、ループする度に、一文字ずつ読み込んでいくという、関数の作り方教えてもらえませんか?
96デフォルトの名無しさん:2008/05/22(木) 19:38:29
>>95
void function(){for (;;) getchar();}
97デフォルトの名無しさん:2008/05/22(木) 19:56:44
・関数を作る
・関数の中にループ処理を書く
・ループの中に一文字読み込む処理を書く

以上
98デフォルトの名無しさん:2008/05/22(木) 19:58:59
>>95の質問に付け足しです。
数値を文字に変換するという問題を出されたんですが、ループする度に数字を一つずつ読み込んでいくというのの、関数の書き方を教えてください。
99デフォルトの名無しさん:2008/05/22(木) 20:00:38
>>98
もう宿題スレいけよ
100デフォルトの名無しさん:2008/05/22(木) 20:02:40
・関数を作る
・関数の中にループ処理を書く
・ループの中に数字を一文字読み込む処理を書く

以上
101デフォルトの名無しさん:2008/05/22(木) 20:04:51
>>95
君にとっての全くの他人が君のその書き込みによって
君が望んでいることを100%理解することができる確信があるか。
あるなら誰も止めはしないが、おそらく望む答えが返ってくる確率は極めて低い。
102デフォルトの名無しさん:2008/05/22(木) 21:41:05
一番安全に入力させる方法ってなんなの?
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になったらループを抜けるというようにしたのですが・・・
何かわかる方おられましたら教えていただけないでしょうか、よろしくお願いします。
104デフォルトの名無しさん:2008/05/22(木) 21:51:22
>>103
その出力値は非正規化数で表せる最小値。
FLT_MINやDBL_MINの値は正規化数で表せる最小値。

正規化数は1.xxxx * 2のn乗という形で表されるが、
非正規化数は0.00xx * 2の(指数の最小値)乗という形で、
正規化数よりさらに小さな値を表す。
その代わり見てのとおり精度が犠牲になっている。
105デフォルトの名無しさん:2008/05/22(木) 21:57:44
どんな場合でも、浮動小数点数の値が別のある値と==であるとか
あるいは<=や>=であることを期待してループの終了条件とかに使ってはいけない
浮動小数点数はあくまで実数のシミュレーションで、
本当に細かい部分の値がどうなっているかはたいてい予測しがたいから
106デフォルトの名無しさん:2008/05/22(木) 22:10:06
アンダーフローって0になるとは限らなかったと思うが
107103:2008/05/22(木) 22:23:56
みなさんレスありがとうございます。

「(指数の最小値)乗」ということは、floatの場合0.00xx * 2の-38乗という形を直したものが1.401298e-45ということでしょうか?
==を使って終了条件がつくれないとなると、ループを使ってアンダーフローまで繰り返すという方法自体が無理なのかもしれないですね。
アンダーフローが0になるというのはネットで検索してて見つけたのですが・・・

108デフォルトの名無しさん:2008/05/22(木) 22:58:01
IEEEの浮動小数点数は段階的にアンダーフローして最終的にはゼロになる
最初のアンダーフローの時点で例外を吐いて実行を止めるかどうかは処理系定義

だったっけ

どのみちそういう非正規化領域の値の演算が役に立つとも思われんけど
109デフォルトの名無しさん:2008/05/22(木) 23:01:42
mathematicaみたいに広い範囲の数値を計算するにはどうすればいいの?
110デフォルトの名無しさん:2008/05/22(木) 23:03:08
多倍長のやつをじっそうするとかそういうライブラリ使うかしろ
111デフォルトの名無しさん:2008/05/22(木) 23:04:42
>>107

「アンダーフローが0になる」というのは、そういう処理系が多い、ってだけの話。
処理系によって扱いが違うはずだから、まずはその処理系のマニュアルを読んだほうが良いかと。
112デフォルトの名無しさん:2008/05/23(金) 00:30:27
>>108
アンダーフロー例外で割り込み発生させるかどうか
CPUに設定できるのもあるぜ
そこまでいくとハードの話になるが
113デフォルトの名無しさん:2008/05/23(金) 00:40:50
http://hooktail.org/computer/index.php?Wave%A5%D5%A5%A1%A5%A4%A5%EB%A4%F2%C6%FE%BD%D0%CE%CF%A4%B7%A4%C6%A4%DF%A4%EB

このサイトのをBCC Developerでコンパイルしたいんですが、
コンパイルが通りません。

main.cのSound *snd;が宣言できない位置だっておこられます・・・

114デフォルトの名無しさん:2008/05/23(金) 00:43:04
>>113
やや古い(というかむしろ事実上標準の)規格では
途中での宣言は禁止だからだな

Sound *snd;をmain関数内の先頭に移動させてみたら?
115デフォルトの名無しさん:2008/05/23(金) 01:36:15
{

Sound *snd;

if((snd = Read_Wave(argv[1])) == NULL){
exit(1);
}

if(Write_Wave(argv[2], snd)){
exit(1);
}

Free_Sound(snd);
}
って囲えば?
116116:2008/05/23(金) 02:49:01
ttp://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/6651.txt
このプログラムで連結成分分解をしていると書いてあるのですが、どこで
やっているのかがわからないので教えていただけないでしょうか?
ttp://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/6652.txt
出力はこのようになり、分かれているのが連結成分分解です。
どうぞよろしくお願いします。
117デフォルトの名無しさん:2008/05/23(金) 06:44:43
>>116

analyze_graph() →analyze_depth()
              →analyze_breadth()

じゃないの?
そういうことではない?


118116:2008/05/23(金) 07:01:41
>>117
え?すいませんもう少し詳しく教えてもいただけないでしょうか?
119デフォルトの名無しさん:2008/05/23(金) 09:04:35
Visual C++ 2005を使っているのですが
<windows.h>が動きません。
どこをどうしたらいいでしょうか?(スレチかな?)
120デフォルトの名無しさん:2008/05/23(金) 09:42:41
PlatformSDKとか、WindowsSDKが入っていないか、
インストール先が変更されてインクルードパスが通っていないとか

まずHDD内のどこかに、windows.hがあることを確認してみよう
あるならあるで、設定の問題と。ばかばかしいが、話はそれからだ
121デフォルトの名無しさん:2008/05/23(金) 10:05:41
2008なら最初から入ってるよ>Windows SDK
(Express Editionでも)
122デフォルトの名無しさん:2008/05/23(金) 13:28:20
char fname[256];
printf("入力ファイル>");
scanf( "%s", fname );

これで入力したファイル名が存在しないならエラーを表示するプログラムってどうかくんですか?
123デフォルトの名無しさん:2008/05/23(金) 13:39:21
FILE *fp;
char fname[256];

printf("入力ファイル>");
scanf("%s",fname);

if ((fp = fopen(fname, "r")) == NULL) {
printf("ファイルを開くのに失敗しました\n");
exit(1);
}
124デフォルトの名無しさん:2008/05/23(金) 13:44:24
どうも
125デフォルトの名無しさん:2008/05/23(金) 14:00:40
最適二分木問題っていうのはどのようなものなんでしょうか?
126デフォルトの名無しさん:2008/05/23(金) 14:59:22
>>125
最適二分木という言葉はちょっと聞いたいたことがない
たぶん平衡二分木を作る問題のこと

平衡二分木が何かについて知らないならまず数学板へ行くこと
127デフォルトの名無しさん:2008/05/23(金) 15:01:00
>>126
そうなんですか
ありがとうございます
128デフォルトの名無しさん:2008/05/23(金) 15:59:58
int (*a)[10];
という宣言は何を表しているんですか?
いまいちイメージがつかめないので使用例なども教えてください
129デフォルトの名無しさん:2008/05/23(金) 16:04:53
>>128
(*a)はint型の長さ10の配列を意味し
(*a)[3]はその4番目の変数を表す。

つまりaは(○○○○)へのポインタということになる

○○○○の部分は自分で考えてね。
130デフォルトの名無しさん:2008/05/23(金) 16:25:28
int a[10]; は「 a は 要素数が 10 の int の配列である」と読む。
同じように、int (*a)[10]; は「 *a は 要素数が 10 の int の配列である」と読む。
*aが配列であるなら、つまりaは配列へのポインタである。

*aにカッコをつけるのは、*演算子より[]演算子の優先順位が高いから。
もし int *a[10]; と書いたらこれは int *(a[10]); と解釈されて、
「 a[10] は int へのポインタである」となる。
131デフォルトの名無しさん:2008/05/23(金) 16:29:31
>>128
int (*a)[10]; a is pointer to array(10) of int

ちなみに
int *a[10];  a is array(10) of pointer to int
132デフォルトの名無しさん:2008/05/23(金) 18:53:25
関数ポインタについて何ですが
ヘッダファイルで
extern foo[]();
を宣言して
その実体を.cファイルに記述するのですが

このfoo[]()は外部に公開したくないので
staticな関数にしようとするとエラーになってしまうのですが
そういう物なのでしょうか?

133デフォルトの名無しさん:2008/05/23(金) 19:03:37
void aretottekoi()
{
処理
return ;
}
何故return ;をするんですか?
134デフォルトの名無しさん:2008/05/23(金) 19:05:36
習性、なんとなく常にreturnを最後に入れたいから

確かに無しで問題ない、あってもなにも変わらない
135デフォルトの名無しさん:2008/05/23(金) 19:06:25
>>132
externつけて宣言した変数の実体をstaticつけて定義してるのか?
136デフォルトの名無しさん:2008/05/23(金) 19:08:16
>>135
宣言を
extern static foo[]();
としたら怒られるし
実体の方にstatic宣言しても効果はないし・・・
137デフォルトの名無しさん:2008/05/23(金) 19:14:50
ヘッダの先頭でstatic つけて宣言するだけでいいんじゃね
138デフォルトの名無しさん:2008/05/23(金) 19:16:38
まちがえた.cのほうにstaticつけてへっだに何も書かなきゃいいんじゃねーの?
139デフォルトの名無しさん:2008/05/23(金) 19:17:23
>>137
ヘッダでstaticのみ付けると
[]の数を具体的に示せとエラーが出て
ヘッダ内で実体を書くと
多重定義でエラーが出ます・・・
140デフォルトの名無しさん:2008/05/23(金) 19:20:33
公開したくない外部ってどこのこと?
externって「外部の」って意味の単語なんだけど。
141デフォルトの名無しさん:2008/05/23(金) 19:34:22
dllってどうやって作るんですか?
142デフォルトの名無しさん:2008/05/23(金) 19:35:06
というか
extern foo[]();
なんて宣言できたか?
143デフォルトの名無しさん:2008/05/23(金) 19:35:31
>>141
コンパイラのマニュアルを読むこと
144デフォルトの名無しさん:2008/05/23(金) 19:37:30
いろいろ省略してるんだろおもってスルーしてたが
145デフォルトの名無しさん:2008/05/23(金) 19:37:46
たぶん extern (*foo[])() の間違いだろう
関数の配列なんて存在しないから
146デフォルトの名無しさん:2008/05/23(金) 19:38:57
公開したくないのになぜextern宣言する
147デフォルトの名無しさん:2008/05/23(金) 19:41:06
なにを公開したくてなにを公開したくないのか整理しなおせ
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);
149デフォルトの名無しさん:2008/05/23(金) 21:14:55
C言語の本を買おうと思うのですが、入門書の次に買うようないい本ないでしょうか。
150デフォルトの名無しさん:2008/05/23(金) 22:51:56
>>148
キャストはぜんぜん必要ないと思うぞ。

a = (High_Byte_Data << 8) + Low_Byte_Data;
151デフォルトの名無しさん:2008/05/23(金) 23:31:47
ないとまずいのは右シフトだね!
152デフォルトの名無しさん:2008/05/23(金) 23:33:15
あとchar型の演算はint型で行われるってやつ

この二つであってる?
153デフォルトの名無しさん:2008/05/24(土) 00:05:18
signed char でハマるのも良い思い出。
154デフォルトの名無しさん:2008/05/24(土) 01:35:15
>>118

「連結成分分解」がわからないけど、
analyze_graph() からanalyze_depth()とanalyze_breadth()を呼び出して、
そこでやってるんじゃないかと推測。
155デフォルトの名無しさん:2008/05/24(土) 02:22:55
ヘッダって別に.hじゃなくても.cでよくね?
なんでソースコードと区別すんだ?
って思ったんだけど、なんか理由あるの?
156デフォルトの名無しさん:2008/05/24(土) 02:35:19
mylib.h
mylib.c
って対に作ることが多くないか?
mylib_pub.c
mylib_imp.c
なら結局同じことだし
157デフォルトの名無しさん:2008/05/24(土) 03:38:11
>>155
Cのプロジェクトの構成概念上、へっだとソースは別のものであり、
ゆえに先人はこれを名前で区別することを望み、そのために.cと.Hを使うことを選び、
そしてそれはよい慣例となったからである。そしてこの慣例を無視するべき理由は、
少なくとも多くの人を納得させるであろうものは、きっと存在しない。
158デフォルトの名無しさん:2008/05/24(土) 08:22:04
>>155
ヒント:make のデフォルトサフィックスルール
159デフォルトの名無しさん:2008/05/24(土) 08:39:17
そりゃ後付でそうなってるだけだろw
160デフォルトの名無しさん:2008/05/24(土) 10:36:18
ヘッダファイルをコンパイルしても無意味だし、
ヘッダをコンパイルしてコードが生成されたら
それはそのヘッダが悪い。

.hを.cにしてもいいが、無駄なコンパイル作業が
増えるだけなのでコンパイルすべき.cとは区別すべき。

そんなこともわからない>>159はいっぺんリビルドされるべき。
161デフォルトの名無しさん:2008/05/24(土) 10:40:40
後付けっていうか、make以前から>>160みたくしてただろうってことでは

小規模なプログラムなら、.cも.hも適当でいけるが、
.cと.hに分離することで、何かとうまく運ぶというか
運用上の利便性があると
162デフォルトの名無しさん:2008/05/24(土) 11:23:14
要素数がnの二分木を力ずく法っていうのを使って全パターン作りたいんですけど
どういうふうにやったらいいんでしょうか
163デフォルトの名無しさん:2008/05/24(土) 11:23:54
>>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が作れないので他にいい方法がないでしょうか
165デフォルトの名無しさん:2008/05/24(土) 12:29:30
任意の数字n個をテキストファイルに出力したいんですが
1
2


100

のように

ファイルオープンなどの使い方がよくわかりません。

1〜10までの数字を順番にテキストファイルに出力するプログラムを書いて簡単な説明をしていただけませんか?
166デフォルトの名無しさん:2008/05/24(土) 12:44:46
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でどんどん書き込む
そんだけ
167デフォルトの名無しさん:2008/05/24(土) 13:34:56
#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だと実行後にフリーズしてしまいます。
なにがおかしいのでしょうか?
168デフォルトの名無しさん:2008/05/24(土) 13:37:21
int
169デフォルトの名無しさん:2008/05/24(土) 13:50:05
16bitの環境で勉強っすか。
170デフォルトの名無しさん:2008/05/24(土) 13:51:36
なんかいい方法ないですか?
171デフォルトの名無しさん:2008/05/24(土) 13:54:08
longを使うとか。
172148:2008/05/24(土) 13:55:28
>>150
>>151
ご回答ありがとう御座います。
unsigned char の値が、どのように int に格納されるのかよく分かりません。
特に負の値の場合なのですが、例を挙げて解説されているサイトをご存知ないでしょうか?

High_Byte_Data = 0x8B
Low_Byte_Data = 0xCD
173デフォルトの名無しさん:2008/05/24(土) 13:55:32
longつかっても何も変わりませんでした
174デフォルトの名無しさん:2008/05/24(土) 13:56:23
1、2、3、4、5の並び替えの120通りを配列につめこむプログラムを教えてください
175デフォルトの名無しさん:2008/05/24(土) 13:59:04
>>173
fprintfは%ldにした?
176デフォルトの名無しさん:2008/05/24(土) 14:01:15
#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までしか正しく出力できません
177デフォルトの名無しさん:2008/05/24(土) 14:16:20
なんていうか・・入門系の本なんでも良いから1冊やるべきだと思う
178デフォルトの名無しさん:2008/05/24(土) 14:20:17
いや、>>176のどこにミスがあるか教えてください
179デフォルトの名無しさん:2008/05/24(土) 14:21:35
>>178
だから %d を%ld にした?
180デフォルトの名無しさん:2008/05/24(土) 14:43:06
>>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
>>181
ありがとうございます!
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)
}

これでレポートだしたら自然数の和になってないから駄目だといわれた。
なんでだろ
185デフォルトの名無しさん:2008/05/24(土) 17:55:23
incledeがまずいんじゃね?
186デフォルトの名無しさん:2008/05/24(土) 17:56:54
0から始まってないからだろ
187デフォルトの名無しさん:2008/05/24(土) 17:57:17
って、ああ問題が1〜10なのかスマン
188デフォルトの名無しさん:2008/05/24(土) 17:59:08
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;
}

190デフォルトの名無しさん:2008/05/24(土) 18:12:39
たしかにsumの初期値の0は自然数じゃない・・・
しかしへりくつのような気も・・・
191デフォルトの名無しさん:2008/05/24(土) 18:14:08
>>189
自然数とだけ言った場合0を含むのか含まないのかは分かりません
192側近中の側近 ◆0351148456 :2008/05/24(土) 18:17:26
(っ´▽`)っ
n(n+1)/2を使えってことでしょうな
193デフォルトの名無しさん:2008/05/24(土) 18:18:46
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;
}
195デフォルトの名無しさん:2008/05/24(土) 18:19:33
"sum=%d¥n"×
"1+2+3+4+5+6+7+8+9+10=%d¥n"◎
こういうことってありがちじゃない?
196デフォルトの名無しさん:2008/05/24(土) 18:23:09
>>194
forがないじゃん。
197側近中の側近 ◆0351148456 :2008/05/24(土) 18:23:47
>>196
(っ´▽`)っ きにすんな☆
198デフォルトの名無しさん:2008/05/24(土) 18:24:14
>>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;
}
200デフォルトの名無しさん:2008/05/24(土) 18:59:45
なんでループに入れてムダな分岐増やしたがるアホはいなくならないんだろう
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;
}
203デフォルトの名無しさん:2008/05/24(土) 19:12:08
ビットフラグについて簡単なコードを用いて教えて下さい。
204デフォルトの名無しさん:2008/05/24(土) 19:26:31
#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
>>204
(っ´▽`)っ GJ!
207デフォルトの名無しさん:2008/05/24(土) 21:38:34
1〜10までの数を10個被らないで表示させたいんですけどプログラム書いてもらえませんか?
乱数使ってやってみたんですけど数字が被ってしまいます
208デフォルトの名無しさん:2008/05/24(土) 21:43:31
つ shuffle
209デフォルトの名無しさん:2008/05/24(土) 21:44:22
>>207
配列に1〜10の数値を入れておいて、乱数でシャフルすればいいよ。
210デフォルトの名無しさん:2008/05/24(土) 22:00:30
10! > RAND_MAXだと完全にランダムにならないから要注意だぞ
211デフォルトの名無しさん:2008/05/24(土) 22:01:38
なに?それ
212デフォルトの名無しさん:2008/05/24(土) 22:25:14
それを言い出したら、ランダム自体が完全には無理。
213デフォルトの名無しさん:2008/05/24(土) 22:46:33
ちょっとよくわからないです
乱数で出力する際に同じ値が出力されてたらやり直すとかでできないですか?
214デフォルトの名無しさん:2008/05/24(土) 22:47:26
>>213
やればいいじゃないか、
10個ぐらいならその方式で問題ないだろ
215デフォルトの名無しさん:2008/05/24(土) 22:54:12
具体的にプログラム書いてもらえませんか?お願いします
216デフォルトの名無しさん:2008/05/24(土) 22:57:23
>>215
わかりました、ちょっとまっててください
217デフォルトの名無しさん:2008/05/24(土) 22:57:49
今Linuxでプログラムを作ってて、ビープ音を鳴らすようなプログラムを
作ってるんですが、エスケープシーケンスで周波数を変更するというのが
仮想コンソールではできないようなので、起動時に何らかの方法でビープ音を
鳴らすかどうか選択させるようにしようと考えてます。
その場合、どのようにして鳴らす・鳴らさないを切り替えればいいのでしょうか?
毎回if文で振り分ける事もできるのですが、短時間にかなりの回数ビープ音を
鳴らすルーチンが呼ばれるので、処理軽減の目的でできれば使いたくないんです。

なにかいい方法はありますでしょうか?よろしくお願いします。
長文失礼しました。
218デフォルトの名無しさん:2008/05/24(土) 23:08:27
>>213
そんなやり方じゃ、出力のたびに確認が増えるだろ。
219デフォルトの名無しさん:2008/05/24(土) 23:10:28
>>217
>その場合、どのようにして鳴らす・鳴らさないを切り替えればいいのでしょうか?
>毎回if文で振り分ける事もできるのですが、短時間にかなりの回数ビープ音を
>鳴らすルーチンが呼ばれるので、処理軽減の目的でできれば使いたくないんです。

>なにかいい方法はありますでしょうか?

ここを分かるようにいってくれ。
220デフォルトの名無しさん:2008/05/24(土) 23:15:58
>>217
その程度のことなら毎回ifでも問題なさそうな気がする。
ビープ鳴らすコストでifのコストなんてかき消されると思う。
本当に毎回ifでだめか試してみろ。
221デフォルトの名無しさん:2008/05/24(土) 23:26:40
Cの入門書が終わったレベルから読める物理シミュレーションの参考書でいいものがあったら教えてください
222デフォルトの名無しさん:2008/05/24(土) 23:27:32
>>220
いや、実際できます。4ms毎に呼んでいて、1秒で250回呼ばれることになるので
できるだけ処理を軽くしたいと思いまして。(ビープ音源による擬似和音でして。)
将来なにかアプリケーションとかを作った際にビープ音に限らず役に立つように
思ったので、他に方法あるかなーと思いまして。
なので他の方法をもしよろしければよろしくお願いします。
223デフォルトの名無しさん:2008/05/24(土) 23:29:18
>>217
関数ポインタを使う方法。

int (*p) (int num); /* 関数ポインタpを宣言 */

/* beep音発生処理 */
int beep(引数){処理}

/* 何もしない */
int no_op(){ return 0;}

/* 起動時処理 */
if(条件){p = beep;}
else {p = no_op;}

(*p)(引数); <---プログラム中にたくさん
224デフォルトの名無しさん:2008/05/24(土) 23:29:43
>>217
ググっても中々見つからないのでうp
参考になると思う

元ファイル名は beep2-1.2a.tar.gz
http://ccfa.info/cgi-bin/up/src/up19467.gz

※GPLです!
225デフォルトの名無しさん:2008/05/24(土) 23:44:19
>>223
そんな方法があったとは知りませんでした。
それを使ってみます!

>>224
おお!わざわざありがとうございます!
じっくり読んでみます。
226デフォルトの名無しさん:2008/05/24(土) 23:46:38
>>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)はいやなんですが、どうすればいいんでしょうか?
227デフォルトの名無しさん:2008/05/24(土) 23:59:32
>>226
どこかのアップローダーにアップロードをするしかないかな
228デフォルトの名無しさん:2008/05/25(日) 00:01:04
インデント部分だけ全角空白ならまだいいんじゃない?

全置換→再インデントができる環境ならなんでもないんだけど、
スペースすべてが全角空白だと苦しむ人もいるだろうね
229デフォルトの名無しさん:2008/05/25(日) 00:01:15
>>226
&nbsp;使うとか?
230デフォルトの名無しさん:2008/05/25(日) 00:02:55
txtに書いてどっかにうpれ
231デフォルトの名無しさん:2008/05/25(日) 00:10:23
>>225
関数のポインタは、ifの分岐に比べて速くなるとは限らないよ。
232デフォルトの名無しさん:2008/05/25(日) 00:13:02
むしろ遅くなるかも。
233デフォルトの名無しさん:2008/05/25(日) 00:14:17
>>226
毎回違う結果を出したいなら、以下を追加。
#include <time.h>
srand((unsigned)time(NULL));

234デフォルトの名無しさん:2008/05/25(日) 00:18:02
>>222
ビープ鳴らす処理がほかと独立しているなら、
そのためのスレッドを作るようにするってのはどうだ。
鳴らさないときは、そもそもスレッドを作らないようにする。

個人的には、全体的に軽くしたいのなら、
他にもっと重い処理がないか、そしてそれを改善できないかを考えるほうがいいと思う。
1秒に250回のビープくらい、大したことなさそうな気がしてならない。
235デフォルトの名無しさん:2008/05/25(日) 00:37:15
>>229
thanks! うまくいきました。次回からはそうします。
236側近中の側近 ◆0351148456 :2008/05/25(日) 07:37:11
>>223
(っ´▽`)っ GJ!
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文全部消して実行したとしても、音源の出力待ちが多発するんじゃないのか?
240デフォルトの名無しさん:2008/05/25(日) 08:14:15
>>234
それもそうですね。なんか変なとこにばっかりこだわってた
かもしれないです。

>>239
いや、昔のPC98であったようなビープ音で擬似和音を作って
曲を鳴らしたいと思いまして。例えば440Hzと220Hzを高速で
切り替えると和音っぽく聞こえるみたいな。一応ビープ出力を
すると発音中のを上書きして発音するような感じなんで問題は
ないかと。ただ前なぜか実験中、一撃で電源落ちましたが。
241デフォルトの名無しさん:2008/05/25(日) 08:50:57
>>172

unsigned char→int の場合は符号拡張される。
負の値の場合だと、例えば
 0xCD → 0xFFFFFFCD
になる。
242241:2008/05/25(日) 08:55:57
>>241
> >>172
>
> unsigned char→int の場合は符号拡張される。
> 負の値の場合だと、例えば
>  0xCD → 0xFFFFFFCD
> になる。

ごめん、何言ってんだ、俺。
 0xCD → 0xCDは変わらないが、10進表現されるときに負の値になる。

243デフォルトの名無しさん:2008/05/25(日) 08:58:59
>>241

はぁ?

なんで、unsigned charが負に拡張されるんだよ。
244デフォルトの名無しさん:2008/05/25(日) 09:13:24
#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;
}
245デフォルトの名無しさん:2008/05/25(日) 09:22:46
>>244
2回目の、c=a; は c=b; のつもりかな?
246デフォルトの名無しさん:2008/05/25(日) 09:37:09
#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;
}
247デフォルトの名無しさん:2008/05/25(日) 10:41:26
勝手に貼ってみた
http://codepad.org/7lTj9jOg
248デフォルトの名無しさん:2008/05/25(日) 12:40:00
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>

こんな宣言したらエラーがでたんですが…
249デフォルトの名無しさん:2008/05/25(日) 12:42:23
>>248
エラーの内容は?""で囲んだファイル名のヘッダはちゃんと存在しているのか?
コンパイルしようとしたソースファイルは?
250248:2008/05/25(日) 12:49:44
1>c:\program files\microsoft visual studio 8\vc\include\cstdio(25) : error C2143: 構文エラー : '{' が ':' の前にありません。

というエラーがでます。

そして、<studio.h>を消すと、 <stdlib.h>でエラーがでます。ほんとにお手上げです。

ソースファイルには問題はありません。
251デフォルトの名無しさん:2008/05/25(日) 12:53:47
.c に入れてるんじゃねーの?
252デフォルトの名無しさん:2008/05/25(日) 13:05:28
>>250
> ソースファイルには問題はありません。
へぇ
253デフォルトの名無しさん:2008/05/25(日) 13:07:59
>>250
だからヘッダというより構文の方にだな・・・エラーが出てるじゃないかw
254デフォルトの名無しさん:2008/05/25(日) 13:08:36
C++はスレ違い。やるならあっちで。
255251:2008/05/25(日) 13:15:50
>>253
ヘッダに書き込めばいいんでしょうか?
>>254
移動します。
256デフォルトの名無しさん:2008/05/25(日) 13:18:13
スレ違いマルチに優しいなおまいら
257デフォルトの名無しさん:2008/05/25(日) 14:44:40
どこに行ったんだろう
258デフォルトの名無しさん:2008/05/25(日) 14:56:00
ん?あいつなら今も生きているさ・・・おまいらの心の中に。
259241:2008/05/25(日) 16:08:50
>>242

すまん、完全にボケてる…orz
吊ってくる

260デフォルトの名無しさん:2008/05/25(日) 17:49:42
配列へのポインタを格納するのに以下の2つの方法があるけど、ど
ちらが一般的でしょ?

1. p = &arg[0];
2. p = arg;

1の方法は冗長に思えて嫌なのだけど、配列であることを明示する
為には有効なのかな? それともただの好み?
261デフォルトの名無しさん:2008/05/25(日) 18:01:56
配列変数に配列を明示する名前をつけた上で1.かな。
262デフォルトの名無しさん:2008/05/25(日) 18:03:32
配列を明示する名前ってたとえばどんなの?
263デフォルトの名無しさん:2008/05/25(日) 18:05:21
*arrayとか。
264デフォルトの名無しさん:2008/05/25(日) 18:10:05
>>263
そりゃダメだろ。
265デフォルトの名無しさん:2008/05/25(日) 18:10:30
じゃあ良い例を。
266デフォルトの名無しさん:2008/05/25(日) 18:12:55
配列のアドレスは&argだろ!
267デフォルトの名無しさん:2008/05/25(日) 18:14:27
>>260
お好みでいいし、どちらかに固定するべきものでもない。
268デフォルトの名無しさん:2008/05/25(日) 18:14:41
演算子だと思ったのか。ワイルドカードとして見て欲しかった。
269デフォルトの名無しさん:2008/05/25(日) 18:18:30
>>260
どっちでもいいけど、前者だと配列それ自体より配列の要素へのポインタってイメージが強いな。
270デフォルトの名無しさん:2008/05/25(日) 18:21:24
>>265
つか、配列に array とか名前つけるのがいい例だと思ってるの?
271デフォルトの名無しさん:2008/05/25(日) 18:22:29
>>260
そもそも配列へのポインタであることを意識する必要があるのかと。
argが配列かポインタかによって、その後のpの扱いに違いがあるのだろうか。
272デフォルトの名無しさん:2008/05/25(日) 18:26:08
>>271
配列ならpをインクリメントする可能性があるだろうな。
273デフォルトの名無しさん:2008/05/25(日) 18:30:38
>>272
配列じゃなくてもインクリメントするだろw

結局のところアクセスできる範囲と型とを
意識しないといけないからどっちも扱いは変わんないよ。
274デフォルトの名無しさん:2008/05/25(日) 19:45:54
迷うならコメント。ひとことでいいから
275デフォルトの名無しさん:2008/05/25(日) 19:51:18
つうか配列ならインデクサで書けよ
276デフォルトの名無しさん:2008/05/25(日) 20:26:45
C言語を始めたばかりの初心者ですが、問題集の問題がよく分からないので
教えて貰えませんか?
開発環境はVisual Studio 2005です。

問題↓

西暦年を入力して、その年が閏年か平成かを判定する関数を作成する。
閏年は、西暦年が
4の倍数であり、かつ100の倍数でない。
400の倍数である。

<実行例>
西暦年:1990
平成です
------------
西暦年:1996
閏年です



どうすればいいのでしょう?^^;
277デフォルトの名無しさん:2008/05/25(日) 20:28:22
>>276
宿題スレにいって答えもらう
278デフォルトの名無しさん:2008/05/25(日) 20:30:01
平成はねーよw
279デフォルトの名無しさん:2008/05/25(日) 20:38:52
1989をくわしく

というか書いたのそのまま入れてけばできるよ
280デフォルトの名無しさん:2008/05/25(日) 20:41:51
平成天皇は不老不死という前提でいいんだろうか・・・
281デフォルトの名無しさん:2008/05/25(日) 20:46:52
#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");
}
282デフォルトの名無しさん:2008/05/25(日) 20:48:10
>>280は不敬罪で逮捕
283デフォルトの名無しさん:2008/05/25(日) 20:50:04
>>281
ねーよw
284デフォルトの名無しさん:2008/05/25(日) 20:52:33
>>281
西暦表示のところが間違ってたな。
285276:2008/05/25(日) 20:53:24
すいません、平成じゃなくて「平年」でした^^;
286デフォルトの名無しさん:2008/05/25(日) 21:00:45
>>281
>if (year % 4 == 0 && year % 100 != 0 && year % 400 == 0)
ひどすぎる
287デフォルトの名無しさん:2008/05/25(日) 21:06:26
wikipediaあたりからコピペすりゃいいのに
288デフォルトの名無しさん:2008/05/25(日) 21:06:43
まだ早い
289デフォルトの名無しさん:2008/05/25(日) 21:07:45
最適化すると if(0)
290デフォルトの名無しさん:2008/05/25(日) 21:07:47
>>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");
291デフォルトの名無しさん:2008/05/25(日) 21:26:11
>>290
不敬罪な
292276:2008/05/25(日) 21:30:55
すいません、解決しました。
どうもありがとうございました。
293デフォルトの名無しさん:2008/05/25(日) 21:47:39
元号なんて不経済だよ
294デフォルトの名無しさん:2008/05/25(日) 22:33:01
>>293
審議中(AARy)
295デフォルトの名無しさん:2008/05/25(日) 23:05:37
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]' が指定されています。
297デフォルトの名無しさん:2008/05/26(月) 01:28:05
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に何を入れたらいいか。。どなたかお願いします><

299デフォルトの名無しさん:2008/05/26(月) 01:37:58
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);
300デフォルトの名無しさん:2008/05/26(月) 01:39:45
scanfの戻り値をチェックしないすべてのコードに災いあれ
301デフォルトの名無しさん:2008/05/26(月) 01:40:45
すまん適当に書いたら全然見当違いだった
302デフォルトの名無しさん:2008/05/26(月) 02:23:27
どんな教科書を読めば296みたいなコードを書くようになるんだろう
303デフォルトの名無しさん:2008/05/26(月) 02:48:03
その書き方はよくないのかい?
304デフォルトの名無しさん:2008/05/26(月) 02:52:47
教科書なんかだと盲目的にintを使いそうなもんだけどな
どんな意図でcharを使ってるんだろうか
305デフォルトの名無しさん:2008/05/26(月) 06:19:29
なんだこいつ。
--
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]のような配列に入れるプログラムです、お願いします
307デフォルトの名無しさん:2008/05/26(月) 20:59:19
>>306
さぁ宿題スレにいくんだ

もしくは自力でもうちょっとがんばれ
308デフォルトの名無しさん:2008/05/26(月) 21:07:57
>>306
エレガントではないけど、
まず、5*5*5*5*5=3125の重複順列を作って
その中から、重複しているものをはずせば
309デフォルトの名無しさん:2008/05/26(月) 21:13:51
doxygenってなんて読むの?
なんて読んでる?
310デフォルトの名無しさん:2008/05/26(月) 21:14:09
>>308
ちょっとやってみます
311デフォルトの名無しさん:2008/05/26(月) 21:17:11
今日からCを学び始めましたが
char* argv[]
という記述の意味がよくわかりません。
char型のデータを保持する配列変数argv[]の
先頭アドレスを保持するポインタ変数*argvを宣言する、
という意味ですか?
312デフォルトの名無しさん:2008/05/26(月) 21:19:21
char ** argv と同じこと
313デフォルトの名無しさん:2008/05/26(月) 21:28:14
>今日からCを学び始めましたが
>char* argv[]
速すぎだろ
314デフォルトの名無しさん:2008/05/26(月) 21:33:47
char *argv[]
のことか?
315デフォルトの名無しさん:2008/05/26(月) 21:34:56
>>311
要素数が空の配列宣言子 [] は、関数の引数リストに現れた場合、(最初の一回のみ)ポインタ宣言子に変換される。
よってこの場合 int main(int argc, char *argv[]) は int main(int argc, char **argv) と同じである。

char **argv の意味するところがわからなくて困っているなら、君はきっとまだやるべきでないページを開いているだろう。
もし本の先頭から順に読んでいってそのようなはめになっているのなら、今すぐその本を窓から投げ捨てることをお勧めする。
316デフォルトの名無しさん:2008/05/26(月) 21:44:24
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

318デフォルトの名無しさん:2008/05/26(月) 21:50:03
>>117
ちがう・・というより、試してみなよそのくらい。
319デフォルトの名無しさん:2008/05/26(月) 21:51:08
>>318
試すような事なのか?

>>317
違う。
320デフォルトの名無しさん:2008/05/26(月) 21:56:29
前置きの++と後置きの++は
同じ演算子では無く、
動作自体が違う。
321317:2008/05/26(月) 21:57:35
(;´д`)ちがうの・・・

>>318試してるんですが、結果が思うようにいく(いかないじゃない)ので。。

>>319 ありがとうございました。
違うということなので、違うと覚えておいて、勉強を進めていきます。
趣味でやってるので、今わから無くてもいいので。。いずれ、わかればいいです。。

どうもありがとうございました。
322317:2008/05/26(月) 22:00:25
>>320 どうもありがとうございます。動作が違うんですね。あ!わかった!

ひとつの式としてみるんですね!
前置インクリメントの場合はひとつの式が評価される前にインクリして
後置インクリメントの場合はひとつの式が評価された後にインクリするんですね。

あー、ややこしい。。どうもありがとうございました。
323デフォルトの名無しさん:2008/05/26(月) 22:02:27
>>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;
}
324デフォルトの名無しさん:2008/05/26(月) 22:02:32
>>317
*p++は(*p)++でなく*(p++)。これが++(後置インクリメント演算子)の方が優先順位が高いの意味。
後置インクリメントはステートメントの式の評価が終了してから行われる。

例として*p++=1;のステートメントは*p=1;p=p+1;として実行される。
325デフォルトの名無しさん:2008/05/26(月) 22:05:18
>>316
1.外部配列のextern宣言
2.同じ
>>315がどういうつもりで書いたか知らないけど、1個目の[]の中身は常に無視される
326デフォルトの名無しさん:2008/05/26(月) 22:08:12
いいえ、「インクリ」しません。
327319:2008/05/26(月) 22:08:49
まず、*と++の優先順位は同じ、結合は右から左。なので、
*p++は*(p++)となり、まずp++が計算され、その結果(「その後」ではない)に*が作用する。この++はpの値を変化させる事に注意。
++*pは、++(*p)としか解釈しようがなく、まず++pが計算され、その結果(「その後」ではない)に++が作用する。この++は*pの値を変化させる事に注意。
いずれの場合も、次のシークエンスポイントまでにpまたは*pの値が1増えるが、それがいつ起こるかはわからない。
--
自然科学ではないのだから、「試してみてどうこう」などというのはもってのほか。規格書にあたるべし。
328317:2008/05/26(月) 22:09:42
>>324
ありがとうございます。自分としてはそのつもりで書いたんですが。。
ん〜、ややこしいので、またいずれわかるくらいの気持ちでいきます。

本当にありがとうございました。
329317:2008/05/26(月) 22:14:04
>>327
どうもありがとうございます。前置の場合は、優先順位じゃなく
それしか解釈のしようがないからなんですね。その辺は、おしえてもらって
よくわかりました。

後置の場合は、おおよそ僕の書き方がわるかったのかもしれませんが
一応>>317の文で理解してるつもりです。皆さんがおっしゃりたいことを
書いたつもりなので。>>322でややこしくなって、間違った事をかいてしまいましたが。

この問題についてよくわかりました。皆さんどうもありがとうございました。
330デフォルトの名無しさん:2008/05/26(月) 22:34:12
こんなとこで言い訳しなくても
331デフォルトの名無しさん:2008/05/26(月) 22:43:11
>>327
*p++は*p,p++でインクリメントは後だし、++*pで++pが計算されることなんてないんだが。
332デフォルトの名無しさん:2008/05/26(月) 23:05:18
文字コード確認したいんですけど
main()
{
unsigned char i;
for(i=0; i<256; i++){
printf("%d=%c¥n",i,i);
}
}
無限ループします
なんで?
333デフォルトの名無しさん:2008/05/26(月) 23:07:07
お前ら、アホの集団みたいだね
334デフォルトの名無しさん:2008/05/26(月) 23:12:45
>>332
255 の次は 0
335333:2008/05/26(月) 23:12:59
>>332
iが256になるから。
そんなことくらい自分で気付けよ、まったく。。。
336デフォルトの名無しさん:2008/05/26(月) 23:16:28
アンサインド・チャーは256を作り出せないだから
337333:2008/05/26(月) 23:20:31
>>336
アンサインドキャラだろw

>>335
自分で変な書き方していたと思うので書き換える。
iがオーバーフローするから。
338332:2008/05/26(月) 23:23:05
for(i=0; i<=255; i++)
でも駄目ですか?
339デフォルトの名無しさん:2008/05/26(月) 23:30:15
やってみればわかることをなぜわざわざ聞く
340デフォルトの名無しさん:2008/05/26(月) 23:33:33
書き方が悪かったです
>>338これで駄目な理由が判りません
341デフォルトの名無しさん:2008/05/26(月) 23:34:18
for(i=0; ++i;;)
342デフォルトの名無しさん:2008/05/26(月) 23:41:36
>>340
unsigned char の範囲は 0 〜 255 です。
条件が偽になりません
343デフォルトの名無しさん:2008/05/26(月) 23:42:29
>>338
警告でてない?
344デフォルトの名無しさん:2008/05/26(月) 23:46:32
unsigned char c=0;
do{


}while(i++<255);
345デフォルトの名無しさん:2008/05/26(月) 23:47:42
>>327
随分「試してみなよ」に反応してるが試して答えを見つけよと極論してるのではない。
言語仕様で決まってること、あいまいなことの学習はせなあかんよ。
それとは別に試すというのは *p++ = 5; だけでなく *(p++) や (*p)++ を体感するということでもある。*(p+1) であったり p[1] はどうなのかと・・・。

これから初めていくのに、正しい答えを後から理解するという回り道をすることがけして悪いとは思わない。
346デフォルトの名無しさん:2008/05/26(月) 23:49:32
>>342
これ>>338って
0〜255じゃないの?
347デフォルトの名無しさん:2008/05/26(月) 23:54:28
>>346
i <= 255 の間ずっとループまわせって意味だろ
つまり無限ループ
348344:2008/05/26(月) 23:56:08
いっけねついiって書いちゃった
c++ね
349デフォルトの名無しさん:2008/05/27(火) 00:01:56
>>332
i を unsigned char と宣言しているからである。
大抵の処理系で unsigned char は 0 〜 255 で、i<256 が偽になることはない。
正しく動くようにするには、int で宣言する。文字とはある小さな整数値であって、型 char のことではない。
350デフォルトの名無しさん:2008/05/27(火) 00:05:22
もうやめてー!>>332のライフは0よ!!
351デフォルトの名無しさん:2008/05/27(火) 00:09:20
そのライフはunsignedですか?
352デフォルトの名無しさん:2008/05/27(火) 00:11:37
>>351
これ以上減らそうったってそうはいかないぜ
353デフォルトの名無しさん:2008/05/27(火) 00:11:56
符号なしでも0は表現できます ><;
354デフォルトの名無しさん:2008/05/27(火) 00:15:07
unsignedなlifeにlife-=damageしてゲームオーバーにならないバグ
355332:2008/05/27(火) 00:17:08
unsigned charで255の次は0だから255まで表示させるんだったら
for文ではなく>>344のように書かないといけないってことですね
お世話になりました
356デフォルトの名無しさん:2008/05/27(火) 00:17:55
unsignedなlifeが1の時に2ダメージ食らうとアンデットになりますか?
357デフォルトの名無しさん:2008/05/27(火) 00:22:56
まぁ、255 FF が最大だから、その値に一致したらオワルとか
っつか、素直に符号ありのintにしチャイナと
358デフォルトの名無しさん:2008/05/27(火) 00:25:22
そろそろgotoの出番か?
359デフォルトの名無しさん:2008/05/27(火) 00:25:55
ユウキは逮捕されて、実刑判決がでましたよ?え?後藤のことじゃない?
360デフォルトの名無しさん:2008/05/27(火) 00:26:02
いや、do-whileでもなんとかなるはず
361デフォルトの名無しさん:2008/05/27(火) 00:28:39
ループ展開すればいいんじゃね?
362デフォルトの名無しさん:2008/05/27(火) 00:58:24
>ループ展開すればいいんじゃね?
コンパイラでもやらねーよ
363デフォルトの名無しさん:2008/05/27(火) 01:01:40
>>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);
}
364デフォルトの名無しさん:2008/05/27(火) 01:15:47
>>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;
}
365デフォルトの名無しさん:2008/05/27(火) 01:24:28
int
366デフォルトの名無しさん:2008/05/27(火) 01:27:09
いんとじゃなくていんてだよ
367デフォルトの名無しさん:2008/05/27(火) 01:38:17
>>366
いいえ、イントゥッです。
368デフォルトの名無しさん:2008/05/27(火) 02:52:59
サイキック

#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;
}
369デフォルトの名無しさん:2008/05/27(火) 08:06:25
>>368
うはwwwこんなコード書いたら先輩になぐられるなwww
370デフォルトの名無しさん:2008/05/27(火) 09:46:32
>>369
慌てるな、殴られたら殴り返せ、目には目を、歯には歯を。
371デフォルトの名無しさん:2008/05/27(火) 10:07:50
左の頬を打たれたら右の頬を差し出せ
372デフォルトの名無しさん:2008/05/27(火) 10:43:12
そやそや、ケツを蹴られたら相手の前をケリ返せ!
Kick in the nuts だぜ?
373デフォルトの名無しさん:2008/05/27(火) 11:02:14
標準入力から文字(英小文字のみ)を読み込んだ後、
各アルファベットの出現回数を数えて表示する。但し出現回数0は省略する。
というプログラムを作ることになりました。

1文字づつ読み込み、それぞれを配列に入力、
配列を1文字づつアスキー番号と照らし合わせ、合致したら係数配列に1を追加
最後に、係数配列が0で無ければ表示
といった感じで考えているのですが、どうもうまくいきません。

模範解答は文字列を入力したらctrl + dを入力すると、結果が表示されますが、
私のでは文字列入力後にctrl + dを押しても何も起こりません。

どこに問題があるのかご教示下さい。

374デフォルトの名無しさん:2008/05/27(火) 11:02:34
#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;
}
375デフォルトの名無しさん:2008/05/27(火) 11:05:53
>>373
その模範解答を見てみれば?
376デフォルトの名無しさん:2008/05/27(火) 11:10:00
突っ込みどころ多すぎ。
ctrl + d で終わるようにするには、getchar()の戻り値を EOF と比べてごらん。
377デフォルトの名無しさん:2008/05/27(火) 11:11:01
>>375
模範解答はctrl+dを押すことと、出力結果のみで、
プログラム自体は書かれておりません。
1週間悩んでも分からなくて、こちらで質問した次第です。
378デフォルトの名無しさん:2008/05/27(火) 11:22:03
>>373
UNIXを前提としている問題をWindowsで解こうとしてるとか?
379デフォルトの名無しさん:2008/05/27(火) 11:22:52
>>377
とりあえず、EOFで入力を終了するようにすることと、
count[26] = {0}; とでもして0に初期化すれば
一応出るとは思う。
380デフォルトの名無しさん:2008/05/27(火) 11:23:36
あ、あと k のforループで k = 0 追加な。何で省略したの?
381デフォルトの名無しさん:2008/05/27(火) 13:43:19
>>372
相手にnutsが無いんですけど、どうしたらいいですか?
382デフォルトの名無しさん:2008/05/27(火) 13:46:23
>>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()の違いをおしえてください。
調べてもよく分かりません。
384デフォルトの名無しさん:2008/05/27(火) 13:53:41
まずdisplay()とやらがどこで出てきたのかから説明してもらおうか。
385デフォルトの名無しさん:2008/05/27(火) 14:05:56
すみません。
勘違いでした。
386デフォルトの名無しさん:2008/05/27(火) 14:31:44
>>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};
}
388デフォルトの名無しさん:2008/05/27(火) 15:17:43
宿題は宿題スレへ
389デフォルトの名無しさん:2008/05/27(火) 15:25:45
すみませんorz
390デフォルトの名無しさん:2008/05/27(火) 15:34:17
小数点以下を切り上げる関数を作ろうと思ったのですが
どのように作ればよいでしょうか?
391デフォルトの名無しさん:2008/05/27(火) 15:40:52
つ[ceil()]
392デフォルトの名無しさん:2008/05/27(火) 15:43:10
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 
技術力が高いスレで聞いてもいいんですけど。じゃ質問を少し変えると、 
標準入力(リダイレクト < )を使ってテキスト・バイナリ・ファイルを作ることはで来ますか? 
できれば、後はパイプでできるんで・・・ 
標準入力の内容をそのままのデータで、ローカル・ディスク上のファイルにすることは出来ますか?と同じです。 
393デフォルトの名無しさん:2008/05/27(火) 15:45:46
>>392
Cでなくても標準入出力を扱えるツールは作れます。
勿論、Cでもできますが。
394デフォルトの名無しさん:2008/05/27(火) 16:22:20
catとか作るのは簡単なんですが、そうするとそのPC(OS)標準じゃないですよね。

stdinからのデータをディスク上のファイルにしてくれるシェルコマンド・システムコール・
API関数とか予め用意されてるものです。
実質リダイレクトなんですけど、Cならsystem(char*)です。
ご存知ないですか?
395デフォルトの名無しさん:2008/05/27(火) 16:27:13
どのOSのどのバージョン?
396デフォルトの名無しさん:2008/05/27(火) 16:35:07
dos, win, プラットフォームで、全バージョン可能

今手元になくて試してないですが、そういえばunix(bsd,linux)のcatはバイナリ通るんですか?
やりたい事は、バイナリで、cat <in.file>out.fileらしき事です。特にstdin受け付けるコマンド。
winですが、cygwinとかも入ってるし自作も出来るんですけど・・・
397デフォルトの名無しさん:2008/05/27(火) 16:43:10
>>396
ここはCでプログラムを組むのに梃子摺る入門者向けのスレです。
DOS標準コマンドがどうだとか、シェルスクリプトがどうだとか言うのはスレ違いです。
思った回答が得られなくて焦っているのかも知れませんが、やっていることは嵐と同じレベルなので程ほどに。
398373:2008/05/27(火) 17:03:07
皆様から頂いたアドバイスを参考にプログラムを修正したところ、無事動作致しました。
何も考えずにそうした部分でも、様々な必要性など、考えもしなかったことばかりで、
まさに目から鱗という状態、大変勉強になりました。
ありがとうございました。
399デフォルトの名無しさん:2008/05/27(火) 17:25:16
>>397
せっかく数行も書いてるようですけど、そういう時は適切なスレに誘導する事が出来るのが紳士的というものですよ。
400デフォルトの名無しさん:2008/05/27(火) 17:51:20
>>399
だってDOSプログラミングスレとのマルチだし、この板以外は知らないもーん。
401デフォルトの名無しさん:2008/05/27(火) 17:55:04
 今日授業でint型の関数calc()で計算するプログラムを作ったんですが、関数にすると何が便利になるんですか?
402デフォルトの名無しさん:2008/05/27(火) 17:56:30
ほしゅしやすい
変数が重複しない
403デフォルトの名無しさん:2008/05/27(火) 17:57:15
>>401
例えば標準関数のprintf()が関数じゃなかったら不便だろ。
404デフォルトの名無しさん:2008/05/27(火) 17:59:22
>>400
この場合はマルチって言わないよ。
Cと少し遠いのは確かだけど。
ストリームも絡んでるし、入門C程度じゃ答えられる奴はそうはいないだろう。
405デフォルトの名無しさん:2008/05/27(火) 18:04:08
>catとか作るのは簡単なんですが、そうするとそのPC(OS)標準じゃないですよね。 

って言ってるから、作るのは問題じゃなくて、OS標準のコマンドかどうかが問題なわけだろう。
少し遠いどころか、C言語の入門と全然関係ない。
406デフォルトの名無しさん:2008/05/27(火) 18:05:40
>>404
>>394を読む限りC言語は関係ない
407デフォルトの名無しさん:2008/05/27(火) 18:14:06
>>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;
}
408デフォルトの名無しさん:2008/05/27(火) 18:26:10
> OS標準のコマンドのみで、バイナリ・ファイルをstdinから読み込みたい
その時点で少なくともここよりdosだろ。
409デフォルトの名無しさん:2008/05/27(火) 18:27:51
>>394
DOSはリダイレクトがないってことなんかな。
dir > filelist.txt とかできないってこと?
410デフォルトの名無しさん:2008/05/27(火) 18:28:59
>>409
リダイレクトはあるよ。
catに相当するコマンドが無いってだけ。
411デフォルトの名無しさん:2008/05/27(火) 18:31:17
CP/M からもってきたtype というビルトインコマンドがあったからcat相当のものが無いんだろうね。
412デフォルトの名無しさん:2008/05/27(火) 18:35:14
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);
}

行列の和を計算するプログラムを作ったのですが、コンパイルして実行すると
何も表示されません。どの部分に不具合があるのでしょうか?
414デフォルトの名無しさん:2008/05/27(火) 18:38:22
for(i = 0; i < 2; i++) 
for(i = 0; j < 3; j++) 
415デフォルトの名無しさん:2008/05/27(火) 18:38:35
>>413
多分間違ってる
>for(i = 0; j < 3; j++)
416デフォルトの名無しさん:2008/05/27(火) 18:39:03
パッと見だけど、
for(i = 0; j < 3; j++)

ここは j = 0 じゃない?
417デフォルトの名無しさん:2008/05/27(火) 18:39:40
君たち、何を言ってるんだね

for(i = 0; j < 3; j++) 
ここだろ。常考
418デフォルトの名無しさん:2008/05/27(火) 18:39:56
mat_add の2重ループ、内側は
for(j = 0; j < 3; j++)
じゃない?
419デフォルトの名無しさん:2008/05/27(火) 18:40:43
ちょw
>>413人気すぎwww
420デフォルトの名無しさん:2008/05/27(火) 18:41:14
なんつー初歩的なミスを…

皆さんありがとうございました!
421デフォルトの名無しさん:2008/05/27(火) 19:16:10
>>412
質問内容はこのスレのレベルを超えてるから、分からなくて当然じゃん
422413: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];
}
}
}

}
423413: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);
}
424デフォルトの名無しさん:2008/05/27(火) 19:42:34
内積とかちゃんと理解してるのか?
425413:2008/05/27(火) 20:11:56
失礼、自己解決しました。mb[3][3]が間違ってますね…
426デフォルトの名無しさん:2008/05/27(火) 20:16:59
行列のクラス作ればいいんじゃね?
427デフォルトの名無しさん:2008/05/27(火) 20:34:56
>>426
クラスってなに?まあ、おまえには聞いてないがなww
428デフォルトの名無しさん:2008/05/27(火) 21:47:02
>>427
あれだよ、学校で部屋分かれるやつ。
429デフォルトの名無しさん:2008/05/27(火) 22:02:41
#include <stdio.h>とか#include <stdlib.h>とか、
一行にまとめてかけないの?俺って、ソースがナガイの嫌いで簡潔にかきたいんだよね。

どの本見ても書いてないからさ〜。

あと、while文の中に?と:の三項演算子使いたいんだけど、
あれって、while(a?b:c)とすると変数cに偽である0を入れたら
ループしなくなるのかな?教えてエロい人。
430デフォルトの名無しさん:2008/05/27(火) 22:10:26
やってみた?
431デフォルトの名無しさん:2008/05/27(火) 22:13:14
入力された文字列から数字文字列を削除する関数を作りたいんだけど
↓を作ってみて実行してもうまくいかない。どこがいけないのか教えていただきたい

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++;
}
}
432デフォルトの名無しさん:2008/05/27(火) 22:19:45
2重のwhileはなにゆえ?ってかforでよくないか?
for-if-forでいけそうだけど、あんま考えずに書いてるんでずれてたらごめぽ。
433デフォルトの名無しさん:2008/05/27(火) 22:24:07
>>429
一行の #include 指令で複数のヘッダを直接取り込むことはできない。
どうしても #include を書き連ねるのに堪えられないというのなら、
使う可能性のあるヘッダを全て #include したヘッダを作成すればよい。
以後は全てにおいてそのヘッダ一個を #includeすれば済む。

?: 演算子の意味を本当に理解しているか。
理解していないならもう一度教科書を読み直すこと。
434デフォルトの名無しさん:2008/05/27(火) 22:24:25
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';
}
435434:2008/05/27(火) 22:26:00
>>431
難しく考えすぎじゃない?
436デフォルトの名無しさん:2008/05/27(火) 22:27:52
for(j=i;j<len;j++) だろ
437デフォルトの名無しさん:2008/05/27(火) 22:28:37
>>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';
}
438431:2008/05/27(火) 22:28:54
>>432
自分の傾向としてどうもfor文が得意でない
のでそれ以外で書こうとしてしまいがちです・・・

とりあえずfor-if-forの線で考えてみます

>>435
やっぱり難しく考えすぎですか・・・
ほぼ初心者なので書いてくださった>>434のあっさりした
プログラムが難しく感じてしまいます。
439431:2008/05/27(火) 22:33:24
いろいろとレスしてくださったかたがたありがとうございます
参考にして修正したいと思います
440デフォルトの名無しさん:2008/05/27(火) 22:40:05
void DeleteDigit(char * szBase)
{
char* szString = szBase;
do {
while ('0' <= *szBase && *szBase <= '9')
szBase++;
} while (*szString++ = *szBase++);
}
441デフォルトの名無しさん:2008/05/27(火) 22:48:20
こんばんは

x/=16ってどういう意味ですか?
442デフォルトの名無しさん:2008/05/27(火) 22:49:26
x=x/16
443デフォルトの名無しさん:2008/05/27(火) 22:49:50
C言語 複合代入演算子
でググれ
444デフォルトの名無しさん:2008/05/27(火) 22:53:36
>>442
>>443
解決しました
ありがとう
445デフォルトの名無しさん:2008/05/27(火) 23:06:03
プログラムは難しいだろ。バグは絶対無くならないからね。
それに、ポインタもやらなければいけないからCはとても敷居が高いよ。
446デフォルトの名無しさん:2008/05/27(火) 23:16:37
>>445
初心者乙
447デフォルトの名無しさん:2008/05/27(火) 23:38:27
#include <stdio.h>
int main(void)
{
int a;
scanf("&d",&a);
if(a-10)printf("入力値は10じゃない");
}


10 と入力しても「入力値は10じゃない」と出てしまいます。
どこが間違っていますか。
448デフォルトの名無しさん:2008/05/27(火) 23:40:12
>>447
&d
449デフォルトの名無しさん:2008/05/27(火) 23:40:37
>>447
> scanf("&d",&a); 

scanf("%d",&a); 
450デフォルトの名無しさん:2008/05/27(火) 23:40:41
>>446
玄人乙
451447:2008/05/27(火) 23:41:55
>>448-449
凡ミスしてしまいました

ありがとうございました
452デフォルトの名無しさん:2008/05/27(火) 23:47:05
参考書広げても何がどう悪いのかよくわからない;w;
プリントを手帳にそのまま移しました
どなたか、どこがいけないのか教えていただけませんか?
学校では半数以上の人がこの問題を解いていて、本当に全くついていけないTT
http://www.uploda.org/uporg1447937.jpg
453デフォルトの名無しさん:2008/05/27(火) 23:53:46
case 1: 'A': ans = a*b;
じゃなくて
case 'A':ans = a*b;

じゃないか?
454デフォルトの名無しさん:2008/05/27(火) 23:54:44
rewind(stdin); っている?
455デフォルトの名無しさん:2008/05/27(火) 23:56:02
case 1: 'A': ans = a*b;
 ↓
case 'A':ans = a*b;

同じようにBも
case 'B':

あと最後のdefaultは何の条件にも当てはまらなかった時だから
default:
printf(〜〜)
456デフォルトの名無しさん:2008/05/27(火) 23:56:39
>>452
switchのラベルがおかしい。
switch( hoge ){
case 'A':
//処理
break;
case 'B':
//処理
break;
default:
//処理
break;
457デフォルトの名無しさん:2008/05/27(火) 23:58:03
×float A,B
○float a,b;

にもつっこんであげようぜ
ってかエラー出るならエラーメッセージ貼れ
458デフォルトの名無しさん:2008/05/28(水) 00:01:01
小数部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
460デフォルトの名無しさん:2008/05/28(水) 00:03:20
とりあえず case 文付近を、言われたとおりに直そう
461デフォルトの名無しさん:2008/05/28(水) 00:11:29
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
462デフォルトの名無しさん:2008/05/28(水) 00:13:56
>>461
'A'とか'B'のあとにコロンがない。 >>455 参照
463デフォルトの名無しさん:2008/05/28(水) 00:14:25
なんでansがint型なの?
特別な意図があるの?
464デフォルトの名無しさん:2008/05/28(水) 00:15:22
コンパイラが親切に
>構文エラー : ':' が、識別子 'ans' の前に必要です。
まで言ってるのにガン無視とか…コンパイラが可愛そうすぎです
465デフォルトの名無しさん:2008/05/28(水) 00:19:44
エラーは0になりました
しかし、デバックなしで開始するとすべてエラー吹く、全部演算記号エラー!
>>構文エラー : ':' が、識別子 'ans' の前に必要です。
int:ansにすればいいの?エラー3でました

int、float,charが間違ってますか?
466デフォルトの名無しさん:2008/05/28(水) 00:20:07
週末、土日を二日くらい潰して、入門書で勉強してみな。
このくらいなら、それくらいで取り返せるよ。
467デフォルトの名無しさん:2008/05/28(水) 00:20:42
符号なし変数の最上位ビットを符号ビットをみなして、符号付き変数へ変換したいと思います。
このような場合、以下のようなコードでよいのでしょうか?

unsigned int a = 0xFABC;
int b;

b = (int)a;

(キャストは、わかりやすくするために書いただけです)
468デフォルトの名無しさん:2008/05/28(水) 00:23:13
>>452
実行例1の、と,はひどい入力ですね。
何かのテストケースかw
469デフォルトの名無しさん:2008/05/28(水) 00:24:51
>>465
掛け算とdefaultだけ
switch (kigo) {
  case 'A':
    ans = a * b;
    printf("%.2f×%.2f=%.2f", a, b, ans);
    break;
  default:
    printf("Error");
}

あとは入門書読み返せ
470デフォルトの名無しさん:2008/05/28(水) 00:27:20
季語www
471デフォルトの名無しさん:2008/05/28(水) 00:36:14
>>467
負の数の内部表現に2の補数を用いているならOK、そうでない環境ならOUT。
内部表現の仕様はC言語の規格の範疇ではない。
472デフォルトの名無しさん:2008/05/28(水) 00:41:44
int 型:使用するコンピュータがもっとも効率よく処理できる大きさ
(2バイトか4バイト)を割り当てるため、表現できる数値の範囲はコンピュターによって異なります
って参考書に書いてあるけど、これはどういう意味なの?
473デフォルトの名無しさん:2008/05/28(水) 00:44:32
だいたい書いてあるとおりの意味だよ。正確ではないけど。
474デフォルトの名無しさん:2008/05/28(水) 00:45:48
2バイトつまり16ビットならなら2^16の分だけ数を表現出来る
つまり-32768〜32767の65536個
4バイトならさらに(ry
475デフォルトの名無しさん:2008/05/28(水) 00:52:53
int は 「-2147483647〜2147483647」 まで数値入れられるパソコンが多いけど、
「-32768〜32767」 までしか数値入らないパソコンもあるよ、って事

要するに -32768〜32767 より大きい数字を使うかもしれない整数値には long int 使っとけってこった
476デフォルトの名無しさん:2008/05/28(水) 00:56:03
今時のWindowsやUnixなら、intはみんな4バイト。
鈴木くんちが2バイトで、田中くんとこが3バイトってわけじゃないから大丈夫。
477デフォルトの名無しさん:2008/05/28(水) 01:11:52

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;
}

上と下両方あるんだが
どっちも同じなの?全く違うの?
教えてくだしあ
478デフォルトの名無しさん:2008/05/28(水) 01:17:05
>>477
意味が分からん
せめてコンパイル通るソース書いてくれ
479デフォルトの名無しさん:2008/05/28(水) 01:17:15
上と下両方ある、の意味が分からんが
とりあえず下のコードは論外
480デフォルトの名無しさん:2008/05/28(水) 01:21:08
そのままで通らないのはおいといて、いいように直してVCにつっこんだらC4145がでた
ツッコミもひるむほどの打ち間違いか、なんかの釣りか…。
481デフォルトの名無しさん:2008/05/28(水) 01:41:22
真偽値をswitchするとか初めてみたw
482デフォルトの名無しさん:2008/05/28(水) 09:34:40
switchって場合によってはif elseif elseより高速なんだっけ?
何れに知れも下はない。
483デフォルトの名無しさん:2008/05/28(水) 09:41:22
>>477
ifと同じ動作をするswitchは

swich(x>y ll s>t)
{
  case 0: y=s-t; break;
  default: s=x+t;
}
484デフォルトの名無しさん:2008/05/28(水) 09:42:51
>>483
お前は肝心なことを忘れてる
485デフォルトの名無しさん:2008/05/28(水) 10:11:51
swich(x>y ll s>t){
 case 1: x=s+t; break;
 default: y=s-t;
}
順番的にこっちの方がわかりやすいんじゃね?
486デフォルトの名無しさん:2008/05/28(水) 10:28:27
swich(笑)

>>485
この場合なら問題ないけど、真の値が1だと決め付けるのはいただけない。
487デフォルトの名無しさん:2008/05/28(水) 10:59:49
いや、1って規格で決まってるだろ
488デフォルトの名無しさん:2008/05/28(水) 11:05:39
>>487
だから「この場合は問題ない」って書いてあるじゃない。

void *p = ...;
switch (p) {
case 1: ...
default: ...
}

489デフォルトの名無しさん:2008/05/28(水) 11:06:13
>>488
!!
490デフォルトの名無しさん:2008/05/28(水) 11:15:31
どうでもいい流れだな
491デフォルトの名無しさん:2008/05/28(水) 11:16:45
>>488
!=0
492デフォルトの名無しさん:2008/05/28(水) 13:50:17
>>482
caseに割り振られる整数値が綺麗に整列していれば、
コンパイラが効率のいい処理ジャンプを書いてくれるかもしれない
書いてくれないとしても、たぶんif elseif elseと同じものになって
より遅いということはきっとない
493デフォルトの名無しさん:2008/05/28(水) 15:06:49
>>487
まじで!?C99ってやつ?
494デフォルトの名無しさん:2008/05/28(水) 15:13:54
>>493
普通のANSIで決まってる
比較演算は0か1を返すって
495デフォルトの名無しさん:2008/05/28(水) 15:15:21
ああ、あと論理演算も然り
496デフォルトの名無しさん:2008/05/28(水) 15:17:01
あ、比較演算の結果の話か
勘違いスマソ。
497デフォルトの名無しさん:2008/05/28(水) 16:56:50
http://imepita.jp/20080528/600650の下半分みたいに
こんな風にきれいに並ばって表示されるようにしてねフフンこの教科書には載ってないけどねフフンって言われた。
四則演算やら小数の位の指定は分かった。でも整った表示は普通にやっても出来ないとか言われて不安だ・・ボスケテ
498デフォルトの名無しさん:2008/05/28(水) 17:02:36
それはね、もう項目と数値の幅を予め決めておいて フフンッ
その範囲内でなら整うようにすりゃ良いんだよ パンダこの野郎
けど、 \t (タブ)と言った制御文字も使うといいお 政権交代しろやっ
499デフォルトの名無しさん:2008/05/28(水) 17:03:55
左揃えなら書式指定で %-4d みたいな
500デフォルトの名無しさん:2008/05/28(水) 17:04:21
>>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);

タブもいいかもね
501デフォルトの名無しさん:2008/05/28(水) 17:09:47
タブと%-d(f)だね
-が左揃え
502デフォルトの名無しさん:2008/05/28(水) 17:09:52
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);
と書けます。
504デフォルトの名無しさん:2008/05/28(水) 17:13:24
>>502
できない
動的に配列のサイズを決めたいならmallocするしかない
505デフォルトの名無しさん:2008/05/28(水) 17:24:46
#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
506デフォルトの名無しさん:2008/05/28(水) 17:26:47
#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]
}
}
とかやっても大丈夫ですか?
507デフォルトの名無しさん:2008/05/28(水) 17:37:16
大丈夫じゃない
ANNpointは変数ではなくdoubleへのポインタ型でしかない
仮にANNpoint型の変数のことを言ってるとしても多次元参照するにはキャストが必要
508デフォルトの名無しさん:2008/05/28(水) 17:49:54
多次元参照するためのキャストってどんなんがあります?
509506:2008/05/28(水) 17:54:28
すいません、いったん席離れます。明日帰ってきます。

510497:2008/05/28(水) 17:57:01
ありがとうございます
タブ\tと%-d(f)を効果的に活用します
511デフォルトの名無しさん:2008/05/28(水) 18:56:17
>>509
まさか仕事で分からないことを職場から聞きつつ華麗な定時退社か?
512デフォルトの名無しさん:2008/05/28(水) 19:36:32
こんなアホな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カッコ内が偽になるからループを抜けるという解釈でよろしいでしょうか?

よろしく。
514デフォルトの名無しさん:2008/05/28(水) 20:00:30
よろしゅうございますよ

でも普通はforを使う
515513:2008/05/28(水) 20:03:39
>>514
ありがとうございます。普通はforを使うんですか!これからは、forを使いたいとおもいます。

どうもありがとうございました!
516デフォルトの名無しさん:2008/05/28(水) 20:05:06
こんなコード書くなんて俺ってカッコイイーと勘違いした典型ですね
実際にはループの度にarray[i]の評価とiまたは0の評価で
計2回の評価を必要とするので効率が悪いですはい
517デフォルトの名無しさん:2008/05/28(水) 21:33:48
私は基本的に typedef は使いません。
typedef のメリットをまったく感じません。
typedef でなにがわかりやすくなったのでしょうか。

(a + b + c)(d + e + f) を計算するのに A = a + b, B = d + e とおいて、とかするのですか?
信じられません。
518デフォルトの名無しさん:2008/05/28(水) 21:42:17
節子、それtypedefちゃう
519デフォルトの名無しさん:2008/05/28(水) 21:43:23
意味がわからないなら使わなくていいんじゃね
開発の規模がある程度大きくなったらわかるよ
520デフォルトの名無しさん:2008/05/28(水) 21:46:18
>>517
・d + e + f を関数化したほうが分かりやすい事がある。
・関数化するよりマクロのほうが速度的に速い。
この二つだけで十分じゃないか。
521デフォルトの名無しさん:2008/05/28(水) 21:50:27
ええと、typedefのはなしだよな?
522デフォルトの名無しさん:2008/05/28(水) 22:02:49
typedefか
構造体・共用体と、関数ポインタにしか使わんな
523デフォルトの名無しさん:2008/05/29(木) 00:10:53
メモリの関係で float と double を入れ替えなきゃならない可能性があるときは typedef してる
524デフォルトの名無しさん:2008/05/29(木) 00:12:40
>>522
列挙型も忘れないで!
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のコーディング経験は実は数か月らしいとのことで、
少し心配しています。標準ライブラリの使い方も怪しかったものですから。
526デフォルトの名無しさん:2008/05/29(木) 00:22:19
1よりもサイズが増える可能性があるなら別にいいんじゃね?
あとは使い方次第
527デフォルトの名無しさん:2008/05/29(木) 00:36:35
if文の中で演算子を使えますか?
たとえば+-*/の計算。
除算かつ、割る数(b)が0の場合、別な処理をしたい。
------------------------------------
変数a,bに整数を入力させる。

変数eにはgetchar で演算子が入る

switch文で演算子「+,-,*,/」を判別。

bが0 かつ 演算子が「/」の場合。
if(b=0 && e=/)

このように考えましたが、if文の中で「/」を使う事が出来ないようです。
根本的な間違いでしょうか。




528デフォルトの名無しさん:2008/05/29(木) 00:38:56
if(b==0 && e=='/')
529デフォルトの名無しさん:2008/05/29(木) 01:00:01
変数eに入ってるのは演算子じゃなくて、 '/' のASCII文字コードです

文字コードはただの数値なので普通に e == '/' (ASCIIコードで '/' は10進数の47なので e == 47 でもいいです)で比較しましょう
530デフォルトの名無しさん:2008/05/29(木) 01:29:27
横入りすみません、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' で始められない」
のようなエラーが発生します。
どうしてでしょうか?
531デフォルトの名無しさん:2008/05/29(木) 01:41:25
エラーの位置をよく見ること
MessageBoxじゃなくWinMainで起きてる
そしてスペルをよく確認せよ
532デフォルトの名無しさん:2008/05/29(木) 01:48:24
>>525
ん、それは構造体のメンバだったりしませんか?
そしてchar配列をその構造体にキャストして放り込んだりしていませんか?
533デフォルトの名無しさん:2008/05/29(木) 01:53:30
>>528
>>529

ありがとうございます。無事に解決することができました
534532:2008/05/29(木) 01:54:09
途中でした。
もしそうであれば、そのような定義にすることでメンバが違うことによる
コードの差というものが少なくなり、凡ミスを防ぎやすくなる場合があります。
個人的には好きではありませんが、そういう記法を採用している現場を
いくつか見ました。
535デフォルトの名無しさん:2008/05/29(木) 15:24:37
C言語で逆ポーランド記法で書いた数式を入力すると,その計算結果を出力するプログラムを作りたいんですけど、わからないので誰か教えてください。お願いします!
536デフォルトの名無しさん:2008/05/29(木) 15:29:18
入力の仕方、データの格納、計算、出力方法、どれがわからんの
自分で書いたコード載せてごらん。
537デフォルトの名無しさん:2008/05/29(木) 15:32:35
宿題かレポートネタの予感
ぐぐってみたか 2ちゃんに頼るにせよ、なんとなくでもなんか知っておかないと
538デフォルトの名無しさん:2008/05/29(木) 15:35:09
スタックはわかるんだろうか
539デフォルトの名無しさん:2008/05/29(木) 16:24:13
俺?わからないよおれは
540デフォルトの名無しさん:2008/05/29(木) 16:57:43
>>535
どんな問題に立ち向かうときも、本当に必要とされるのは、まず問題を理解し、そして適切な大きさのタスクに分解し、
それら一つ一つを適切に解決する方法を 自 分 で 見出す能力であり、それがプログラミングの本質である。
我々は君が進むべき道を迷っていたら恐らく正しいであろう道を指し示すことはあるし、
明らかに危険な道に踏み込もうとしていたら強く引きとめもするだろう。
だが目的地にたどり着くのはあくまでも君自身が足を動かしたことに因らなければならない。
そうでなければそもそも君がプログラミングを行う(あるいは学ぶ)ことにならないからである。
541デフォルトの名無しさん:2008/05/29(木) 18:01:03
while
 if(数値) プッシュ
 if(演算子) 2個ポップ 演算結果をプッシュ
end

良くわからないけどこんな感じじゃね?
542デフォルトの名無しさん:2008/05/29(木) 19:25:16
public static void Main(string[] args)
{
 foreach(string arg in args)
 {
  System.Console.WriteLine(arg);
 }
}
ってな感じのが書きたいのですが、
コマンドライン引数が取れません。
というか、stringの使い方がわかりません。

出来る人には簡単すぎることなのかもしれませんが、
どうか教えてください。
543デフォルトの名無しさん:2008/05/29(木) 19:26:34
スレタイを300回くらい読み直せ
544デフォルトの名無しさん:2008/05/29(木) 19:46:32
>>543
C言語では、stringはどうやって使うんですか?
545デフォルトの名無しさん:2008/05/29(木) 19:59:41
使えません
546デフォルトの名無しさん:2008/05/29(木) 20:08:25
>>545
じゃあ文字列の操作ってできないんですか?
547デフォルトの名無しさん:2008/05/29(木) 20:09:08
できます
548デフォルトの名無しさん:2008/05/29(木) 20:09:38
まずC言語の本を買って読んでください
549デフォルトの名無しさん:2008/05/29(木) 20:11:01
これはきっと俺をJava嫌いにするための工作だな
550デフォルトの名無しさん:2008/05/29(木) 20:12:11
C#じゃないのか
551デフォルトの名無しさん:2008/05/29(木) 20:17:56
なんだC#か
552デフォルトの名無しさん:2008/05/29(木) 21:03:16
>>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を入れる
この条件を満たすプログラムを作りたいんです。
556デフォルトの名無しさん:2008/05/30(金) 00:36:37
んーとりあえずスタックの操作が出来るためのテストプログラムってことでいいのかな?
popなんだから値を一個取り出せばいいんだけど…できない?
557デフォルトの名無しさん:2008/05/30(金) 00:39:48
おまえらみたいに賢くなるには
どんな本を読めばいいのか教えてくれ!
558デフォルトの名無しさん:2008/05/30(金) 00:40:02
まずはpop()を書いてcase 2:とcase 3:を完全にし動作するのを確かめる。以外にやることないだろう。
559デフォルトの名無しさん:2008/05/30(金) 00:41:05
>>557
K&R
CFAQ
560デフォルトの名無しさん:2008/05/30(金) 00:43:57
スタックに値があれば取り出して指示変数topを1減らし取り出した値をreturnする
pushが書けたんだから要領はわかるだろ
561530:2008/05/30(金) 01:07:00
>>531さん

---------------------------------------------------------
HINSTANCEはインスタンスハンドルと呼ばれる情報で、アプリケーション
そのものを表すユニークな値を表しています。この値はWindowsAPIの一部
の関数を利用する為に必要な情報となります。
---------------------------------------------------------

しかし、

---------------------------------------------------------
このパラメータは16ビットWindows時代に使われていたもので、Win32API
では利用する事はありません。
----------------------------------------------------------
OSがXPだった為、必要ないパラメータだったようです。
ただ、HINSTANCEを削除してコンパイルしても、
やっぱりWinMainでエラー出ました。
もうちょっと考えてみます。ありがとうございました。
562デフォルトの名無しさん:2008/05/30(金) 01:22:07
>>561
HINSTSNCE
を256回読み直せ
563デフォルトの名無しさん:2008/05/30(金) 01:27:30
不要だからって即削除するとはさすがだw
564デフォルトの名無しさん:2008/05/30(金) 01:31:12
>>561
不要なのはhPrevInstanceの方だけだぞ

何故ほぼコピペなのにコンパイルエラー出すのか、そっちの方が不思議でならない
565デフォルトの名無しさん:2008/05/30(金) 01:33:09
>>561
hPrevInstanceは利用されていないだけでWinMainの引数として存在していないといけない。
前回エラーになったのはhInstanceの型名のtypoだ
566デフォルトの名無しさん:2008/05/30(金) 01:55:11
初心者って絶対エラーメッセージ読まないよね
567デフォルトの名無しさん:2008/05/30(金) 01:57:55
読んでも多分難しくて分からないだろうという理由(思い込み)で
読むことを放棄してるんだと思う。
568デフォルトの名無しさん:2008/05/30(金) 01:58:58
挙句の果てにスペルミスということをやっと理解した暁には
凡ミスでしたお騒がせしましたとか言うんだぜ。
569デフォルトの名無しさん:2008/05/30(金) 02:21:13
>>564
初心者の半分はコピペを知らずに手打ちしてエラーを出す
残りの半分は安易にコピペしてエラーを出す
570デフォルトの名無しさん:2008/05/30(金) 02:34:20
>>568
理解したときにはこのスレのことなんか忘れてるんじゃね?w
で、またわからなくなったときに思い出して質問しにくるんだと思う
571デフォルトの名無しさん:2008/05/30(金) 07:47:23
ったく・・・ここは質問スレじゃねえんだよ!
572デフォルトの名無しさん:2008/05/30(金) 09:51:38
Cコンパイラって、初心者にいわせれば、自分の都合に基づいてエラー出すから、
それが打ち間違いであれ、打ち間違いとかそういうエラーとは限らないってこと

HINSTANCEは、H+INSTANCEな。そもそもこれに気づかないと、打ち間違いばかりになる
573デフォルトの名無しさん:2008/05/30(金) 11:01:59
だれか俺にHINSTSNCEの読み方を教えてくれ
574デフォルトの名無しさん:2008/05/30(金) 11:09:32
まさしく ぐぐれ だな

おろかな質問の履歴がでてくるよ
575デフォルトの名無しさん:2008/05/30(金) 11:38:32
コピペだけじゃ絶対身に付かないよ。
変数や関数は何かの略称なので、それぞれの原型の意味を覚えたほうがいい。

HINSTANCE = HANDLE INSTANCE
576デフォルトの名無しさん:2008/05/30(金) 11:50:39
>>574
冗談だぜw
エイチインストスンセ
とか言ってほしかった…
577デフォルトの名無しさん:2008/05/30(金) 12:08:21
HINSTSNCE に一致する日本語のページ 1 件中 1 - 1 件目 (0.06 秒)

C言語なら俺に聞け(入門篇) Part 28
pc11.2ch.net/test/read.cgi/tech/1211198816/530
578デフォルトの名無しさん:2008/05/30(金) 12:46:56
ウケそうになかったので即レスしなかったが、全言語で3件 重複除く
もうちょいありそうな気がしたがなあ さすがに、ぐぐるコードでは0件だった

サジェッションが出てくるかとおもったが、なかったな
typoネタのちょい雑談として。
579デフォルトの名無しさん:2008/05/31(土) 07:07:33
C言語脱初心者を目指してるものです。
>>559 にあったK&Rを読もうと思ったのですが、
日本語訳と原著どちらを読んだほうがいいでしょうか?
日本語訳は異常に評判が悪いんですが、かといって自分は
そこまで英語が得意というわけでもないので困ってしまいまして。
580デフォルトの名無しさん:2008/05/31(土) 07:10:41
>日本語訳は異常に評判が悪いんですが
別にわるかないよ。
普通に読んで普通に理解できるレベル。
581デフォルトの名無しさん:2008/05/31(土) 10:37:16
誤記誤植が最初の増刷で直ってるのに、
いまだにあるかのように言ってる奴がいるだけ。
582デフォルトの名無しさん:2008/05/31(土) 12:42:07
>>579
K&Rは語調が固く、読みにくい。また活字も見にくい。
C言語のバイブルと呼ばれてはいるが、それは
裏を返せば古くて取っつきにくいということ。
もっと読みやすい本を探した方がいい。
583デフォルトの名無しさん:2008/05/31(土) 12:53:30
C言語初心者というかプログラミング初心者が読んでもちんぷんかんぷんだろうな
ただ深く理解するためには必須に近いと思う
584デフォルトの名無しさん:2008/05/31(土) 13:13:19
N88-BASICしか知らないときにK&R読んだけど、普通に覚えられたよ。
活字をよみつけてないとか、そういうレベルの人以外はK&Rでもいいよ。
585デフォルトの名無しさん:2008/05/31(土) 13:22:37
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])を指と思ったのですが・・・
589デフォルトの名無しさん:2008/05/31(土) 14:22:13
>>586
それよりmallocで確保した領域を管理するポインター進めるのって気持ち悪くない?

もうひとつインデックスを管理するint indexcount とか用意して

(p + indexcount)->age

とかで参照しないと
後でfreeできないような・・・
590デフォルトの名無しさん:2008/05/31(土) 14:23:18
p->ageを初期化してないのに読むなよ。
591デフォルトの名無しさん:2008/05/31(土) 14:24:12
>>590
つ >の後にp[0]〜p[9]の各メンバに値を代入して
592デフォルトの名無しさん:2008/05/31(土) 14:25:38
>>586
問題はそこにはないんじゃなかろうか?
問題が再現する最小のコードを張ってみてください
593デフォルトの名無しさん:2008/05/31(土) 14:28:01
実行時エラーってmallocで確保した領域のアドレスを指してポインター
を進めちゃっててfreeでエラーとかでないの?
594デフォルトの名無しさん:2008/05/31(土) 14:29:45
>>586
freeするときにpを元の位置に戻してないとか
595デフォルトの名無しさん:2008/05/31(土) 14:41:55
すいません再現しました。
http://sony.squares.net/test.txt
ちなみにfree()は省略しています。
596デフォルトの名無しさん:2008/05/31(土) 14:47:49
これだと構造体のサイズは20です。
597デフォルトの名無しさん:2008/05/31(土) 14:49:54
2分探索木って配列で取るものなのかな・・・
コストはかかるけどノードを毎回1個確保していったほうがよくね?
598デフォルトの名無しさん:2008/05/31(土) 14:50:57
あ、
//問題点1:46,47行目
はreturn p;の前にp++;しちゃってるので駄目ですね・・・

でも、問題点2のほうは・・・よく分からないです。
599デフォルトの名無しさん:2008/05/31(土) 14:51:30
(node *)NULL
(node *)malloc(sizeof(node)*(6+1))

問題とは関係ないけど、こういうキャストいらんだろ。
600デフォルトの名無しさん:2008/05/31(土) 14:51:39
>>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個ずつ取っていくスタイルなのですが
今回は練習のためにもこうしてみました。
602デフォルトの名無しさん:2008/05/31(土) 14:52:48
ちょっと意図がつかみきれないというか、要求されてる仕様を
ちゃんと理解して無い気がする・・・・
603デフォルトの名無しさん:2008/05/31(土) 14:53:34
>>595
なんか読んでたら混乱してきたけど、構造的におかしいだろ。
いろんなところで変数ずらそうとするから変なことになってる。
604デフォルトの名無しさん:2008/05/31(土) 14:54:11
>>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分くらい考えたのに気づきませんでした。
607デフォルトの名無しさん:2008/05/31(土) 15:10:54
mallocは連続した領域に確保されないこともあるんだよね?
608デフォルトの名無しさん:2008/05/31(土) 15:11:34
>>607
どういう意味?
609デフォルトの名無しさん:2008/05/31(土) 15:14:32
>>607
無いだろ
610デフォルトの名無しさん:2008/05/31(土) 15:15:06
callocやreallocじゃない
611デフォルトの名無しさん:2008/05/31(土) 15:15:54
ボインなおっぱいにポイン(し)た なんつって
612デフォルトの名無しさん:2008/05/31(土) 15:18:13
>>607
そんなわけない

指定したサイズが確保できなければポインターがNULLになって返ってくる。
613デフォルトの名無しさん:2008/05/31(土) 15:22:23
>>607
動的配列つくれねぇじゃんよ
断片化の心配はなさそうだけど
614デフォルトの名無しさん:2008/05/31(土) 15:25:22
第一断片化してる領域を渡されても関数の戻りは確保した領域の先頭アドレスだけで、
断片になってる領域の先頭アドレスだけ渡されても残りの情報はどうやって得ると思ってるんだ・・・
615デフォルトの名無しさん:2008/05/31(土) 15:26:55
不連続な3つの領域を確保してくれたんなら、ポインタ3個返してもらわないとな
616デフォルトの名無しさん:2008/05/31(土) 15:30:19
>>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);

「正常に実行された」というのは「落ちなかった」というだけなのでは。
617デフォルトの名無しさん:2008/05/31(土) 15:31:46
ってなんかリロードしたらレスがてんこ盛りで俺浦島太郎。
618デフォルトの名無しさん:2008/05/31(土) 15:37:44
>>616
それ以前にmallocした領域を管理してるポインターのアドレスを更新する
というのがかなりやばい。
619デフォルトの名無しさん:2008/05/31(土) 15:38:59
>>618
プログラム終了時にfreeされるからいいよ派なんじゃないの?
620デフォルトの名無しさん:2008/05/31(土) 15:40:18
この構造なら parent を辿っていけば元の p[1] になるから計算可能
621デフォルトの名無しさん:2008/05/31(土) 15:41:00
622デフォルトの名無しさん:2008/05/31(土) 15:46:43
VC言語で僕のちんぽをかちんこちんにするプログラム作ってください><;
623デフォルトの名無しさん:2008/05/31(土) 15:47:52
たいていのエロゲはC/C++で作られてますよ
624デフォルトの名無しさん:2008/05/31(土) 15:53:19
つーか昔作ったコアを変えてないとかそんな程度だろ。

基本の開発ツールはVC++6あたりのままってとこかな?
625デフォルトの名無しさん:2008/05/31(土) 16:06:52
スタックに、じゃなくてヒープに。
スタックに確保して、freeをサボるような書き方したいなら、allocaとかか
626デフォルトの名無しさん:2008/05/31(土) 16:25:12
CはJAVAより速いって本当?
どのくらい
627デフォルトの名無しさん:2008/05/31(土) 16:26:16
JavaVMをC/C++で実装しちゃう位
628デフォルトの名無しさん:2008/05/31(土) 16:37:22
>>626
倍くらい。
629デフォルトの名無しさん:2008/05/31(土) 16:39:24
Javaって乱暴なたとえだとエミュレーターのようなものだからな・・・
630デフォルトの名無しさん:2008/05/31(土) 16:42:21
仮想マシンだから、別に何かのハードをエミュレートするってわけじゃないお
631デフォルトの名無しさん:2008/05/31(土) 16:43:00
Web系業務系でJavaが優勢なのはなんで?
632デフォルトの名無しさん:2008/05/31(土) 16:54:23
>>631
確かCなんかで書かれたCGIだと負荷が大きいけど
サーブレットだと負荷が小さいとかだったような
633デフォルトの名無しさん:2008/05/31(土) 17:12:16
またご冗談を
634デフォルトの名無しさん:2008/05/31(土) 17:12:42
>>631
プログラマの調達が容易で保守が楽。
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
(っ´▽`)っ
ループ終了判定の後にインクリメントしてるからでしょうな。
637デフォルトの名無しさん:2008/05/31(土) 17:20:55
>>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);
}
と等価じゃないのかな?カナ?
639デフォルトの名無しさん:2008/05/31(土) 17:23:09
>>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の継続判定に++を使うのは
紛らわしいのでやめたほうがいいってことだね☆
643デフォルトの名無しさん:2008/05/31(土) 17:26:52
>>615
Linked Listみたいになってりゃ良いんじゃね?
644635:2008/05/31(土) 17:40:39
みなさん、どうもご丁寧なレスありがとうございます。

なんか、C言語は深いですね。。私は、p++が先にされてその後*p参照されてそれが終了条件になるとおもっていました。
要するに*(p++)が終了条件になると思っていました。

なぜかというと独習Cに*p++;という一文は参照先の値をインクリメントするんじゃなく
ポインタ変数をインクリメントするという解説があったからです。

まだまだ未熟なようですが、この一件に関しましてはなんとなく理解できました。

>>637さん、側近中の側近さん。お二方には、とても丁寧な解説をいただいて
とても感謝いたしております。

ほんとうにどうもありがとうございました。
645デフォルトの名無しさん:2008/05/31(土) 17:46:11
>>644
>要するに*(p++)が終了条件になると思っていました。 

そのとおり

>なぜかというと独習Cに*p++;という一文は参照先の値をインクリメントするんじゃなく 
>ポインタ変数をインクリメントするという解説があったからです。 

それも正しい

前置インクリメントと後置インクリメントの違い (++p と p++ の違い) を勉強しなおすといいよ
646デフォルトの名無しさん:2008/05/31(土) 18:12:29
安西先生・・・linkedlistにランダムアクセスしたいです
647デフォルトの名無しさん:2008/05/31(土) 18:43:22
>>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行目まで出力した時点で
一度改行するにはどうすればいいんでしょうか?
どなたか教えてください。お願いします。
649デフォルトの名無しさん:2008/05/31(土) 18:48:50
>>648
while (a<11){
printf("%d",a);
if (a == 5) printf("\n");
a++;
}
650デフォルトの名無しさん:2008/05/31(土) 19:05:23
*p++ は、

間接演算子よりインクリメント演算子の方が優先順位高いという事を知らなくて、アドレスの中身が+1される、と考えてしまう、という罠と

インクリメント演算子の方が優先順位高いから、アドレスが+1された後でアドレスが参照される、と考えてしまう罠が混在する二重の罠
651648:2008/05/31(土) 19:08:24
>>649さん
if使えばよかったんですね。
教えていただきありがとうございました。
652635:2008/05/31(土) 19:10:17
>>645
そういうことでしたか。。ここのforの条件判定の部分まで
後置インクリメントの式の評価が終わってから、インクリメントされるというのが
適用されるのですね。

普通の文では、一文が評価されてから、インクリメントされるというのは
理解していたんですが、、この条件判定の部分までそうだとはちょっとわからなかったです。

でもようやく理解できました。ありがとうございました。
653635:2008/05/31(土) 19:15:06
>>650
どうもっす。頭こんがらがってきます。。ここが一番難しいようなことを
本に書いてあるので、がんばりまっす。先に構造体とかやったので、あとは
ここだけなので。。

ありがとうございます。
654デフォルトの名無しさん:2008/05/31(土) 19:36:32
俺は下手に学校や会社で教わった奴より、独学で覚えたやつの方が信頼している
がんばれよ
655デフォルトの名無しさん:2008/05/31(土) 20:27:39
>>644
後置インクリメントの勉強でなければ

for (p = a; ;*p; p++) printf("%d ", *p);

が自然なコード。
656デフォルトの名無しさん:2008/05/31(土) 20:43:19
独習Cで色々実験中って書いてあるから勉強中なんだろう

何故while文じゃなくてfor文?とは思ったが
657デフォルトの名無しさん:2008/05/31(土) 21:44:36
1〜9の範囲の整数を入力するプログラムを教えてください
658デフォルトの名無しさん:2008/05/31(土) 21:48:42
>>657
1.文字列を入力する。
2.入力した文字列が数字であるかどうかチェックする。数字でなければアウト。
3.入力した数字文字列が1〜9であるかどうかチェックする。この範囲の数字でなければアウト。

こういう手順で。

どのあたりがわからないのでしょうか?
659デフォルトの名無しさん:2008/05/31(土) 22:03:15
テス
660デフォルトの名無しさん:2008/05/31(土) 22:05:12
for文の再設定式でi++と++iってどこが違うんですか?
661デフォルトの名無しさん:2008/05/31(土) 22:07:32
>>660
単独使用ならまったく同じ
662デフォルトの名無しさん:2008/05/31(土) 22:09:32
ふつーの使い方してる分には何も違わない。

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++は、
どういう働きをしているんでしょうか。
増えているのはわかるのですが、いつ評価されているんでしょうか?
664デフォルトの名無しさん:2008/05/31(土) 22:18:55
あたまだいじょうぶか
665デフォルトの名無しさん:2008/05/31(土) 22:20:51
#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);
だよ。二重引用符に位置が違う。
668デフォルトの名無しさん:2008/05/31(土) 22:23:56
>>665
scanf("%d, &a"); <−コレ

scanf("%d", &a); こうすればおkかな?
669デフォルトの名無しさん:2008/05/31(土) 22:24:17
>>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がインクリメントされません。
671デフォルトの名無しさん:2008/05/31(土) 22:28:55
>>667
>>668

あまりのアホさに鼻血でた.orz
ありがとうございます。
672デフォルトの名無しさん:2008/05/31(土) 22:49:32
>ちなみにsizeof(i++)は、多くのコンパイラでiがインクリメントされません。
というか未定義だろ
673側近中の側近 ◆0351148456 :2008/05/31(土) 22:58:28
>>672
(っ´▽`)っ
ようわからんけど、
3年ぐらい前にこのスレで話題に上がったような気がする・・・。
674デフォルトの名無しさん:2008/05/31(土) 23:12:25
sizeof演算子は型、変数名、または定数に作用して
型のサイズ、変数のサイズ、または定数の型のサイズを返す
i++はiの値(変数)を返すからsizeofを適用することはできない(もしやったら未定義)

じゃないの
675デフォルトの名無しさん:2008/05/31(土) 23:14:46
>i++はiの値(変数)を返すからsizeofを適用することはできない(もしやったら未定義)
それだと構文エラーにならないとおかしい気もするが
676デフォルトの名無しさん:2008/05/31(土) 23:15:58
>>674
そうすると
int *p;
sizeof(*p) は未定義?
677デフォルトの名無しさん:2008/05/31(土) 23:20:13
sizeofを単項式に作用させた場合、式を評価するかしないか(演算子を適用するか無視するか)は処理系定義なんじゃなかったっけ
678デフォルトの名無しさん:2008/05/31(土) 23:32:30
>>644
あなたの理解は間違えていない。
だが、状態を理解できていないだけだね。
while(*p) printf("%d ", *p++);
こうすればよかった。
679デフォルトの名無しさん:2008/05/31(土) 23:32:46
評価しないって決まってたはず
680デフォルトの名無しさん:2008/05/31(土) 23:36:32
いったいどれが正しいんだよ!!!
681デフォルトの名無しさん:2008/05/31(土) 23:40:27
バイナリデータから4bitを32bit毎に取り出したいんですけど、どうしたらいいのかまったくわかりません
だれか教えてください
682デフォルトの名無しさん:2008/05/31(土) 23:44:47
sizeof演算子は型または単項式に作用し、その型または項をなす変数ないし定数が持つ型のサイズをバイト単位で返す。
このとき単項式の値は評価されず、副作用を生じることもない。
683デフォルトの名無しさん:2008/05/31(土) 23:45:09
>>679
評価しないと決まっている。
684デフォルトの名無しさん:2008/05/31(土) 23:50:08
>>681
unsigned charの配列を使えば?
685デフォルトの名無しさん:2008/05/31(土) 23:51:17
>>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であろうが、
その変数のサイズに置き換えられる
とな。
687デフォルトの名無しさん:2008/05/31(土) 23:54:09
そもそもsizeofはコンパイル時に計算するんだし、処理を中に入れる必要性が謎すぎるw
688デフォルトの名無しさん:2008/05/31(土) 23:55:05
>>686
処理されないと定義されているのにそういう議論になったということは、
処理するしないではなく、なぜ処理されないのかについて議論していたのかな。
689デフォルトの名無しさん:2008/05/31(土) 23:55:41
そりゃあ嘘だ
ほとんどのコンパイラではコンパイル時に解決して定数になる場合が多いというだけで
そう処理しろと規格で決まってるわけじゃない(C99の可変長配列の問題もあるし)
690デフォルトの名無しさん:2008/05/31(土) 23:58:17
C89では副作用を生じないと規定されている
691デフォルトの名無しさん:2008/05/31(土) 23:58:24
これ以上は規格スレでやったほうがいいと思う
692側近中の側近 ◆0351148456 :2008/05/31(土) 23:58:43
(っ´▽`)っ
というか、当時を覚えている古参はいないのかな?
693デフォルトの名無しさん:2008/05/31(土) 23:59:12
>>686
マクロじゃないから当たり前といえばそうなんだけど、
プリコンパイル済みファイルを除いてもまだ残っていたよ。

コンパイル時に算出するのかな、、、と思ったけどそうでもない意見が
出てきたw
>>689 kwsk
694デフォルトの名無しさん:2008/05/31(土) 23:59:47
>>685
ありがとうございます。
この時のnはどの型でもいいのでしょうか?
というのも、4bitを32bit毎に取り出し、そのままバイナリとして出力したいと考えているからです。
お手数ですがよろしくおねがいします。
695デフォルトの名無しさん:2008/06/01(日) 00:01:13
#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;
}
696デフォルトの名無しさん:2008/06/01(日) 00:02:43
失礼。
- printf("sizeof(size) is dynamically changes:%u", sizeof(size));
+ printf("sizeof(size) is dynamically changes:%u¥n", sizeof(sz));
697デフォルトの名無しさん:2008/06/01(日) 00:04:32
>>693
その通りの意味だ
規格では「sizeof演算子はオペランドのサイズを返す」とだけ規定してある
そしてC89ではオペランドのサイズはコンパイル時に常に解決可能だったから
多くのCコンパイラはそれをコンパイル時またはプリコンパイル時に定数に置き換えるという実装を選んだ
そんだけ

C99では配列の要素数に変数を使って宣言することが許された
そのような配列に対してsizeofを作用させるならもちろん実行時に解決するしかない
698デフォルトの名無しさん:2008/06/01(日) 00:09:25
>>694
整数型ならなんでもいい
なぜなら最も小さいcharでも確実に4ビット以上あるから

ただし、たぶんunsignedであったほうが面倒が少ない
699側近中の側近 ◆0351148456 :2008/06/01(日) 00:09:50
(っ´▽`)っ
古参出てこいや☆
700デフォルトの名無しさん:2008/06/01(日) 00:13:03
>>697
へええ。C99よく知らなかったので勉強になりました。トン
701694:2008/06/01(日) 00:18:53
>>698
ありがとうございます。
例えばunsigned charなら8bitですよね。
この配列に4bitのデータを入れると残り4bitには何が入るのでしょうか?
できれば余分なデータは入れたくないなと思っています。必要な4bitのみを出力した時はどうすればいいのでしょうか?
よろしくおねがいします
702デフォルトの名無しさん:2008/06/01(日) 00:20:36
>>701
出力した?出力したい?
703694:2008/06/01(日) 00:22:28
すいません
出力したいです
704635:2008/06/01(日) 00:25:50
>>654 がんばります。ありがとうございました。Cは自分で色々と勉強できるし、工夫するのが楽しい言語ですね。
色々やってみるとおもしろいです。
>>655
なるほど。たしかに、賢いやり方に見えます。Cは書き方ひとつでわかりやすい良いソースがかけるので楽しいですね。
ここで、質問すると本当に的確な答えがでてきて、とても参考になります。本当にありがとうございます。
>>678
なるほど、そういうやり方が正しいやり方なんですね。たしかに、ソースもスマートで
わかりやすいですね。Cは色々な書き方ができて面白いですね。参考になります。

色々と教えていただき、本当に皆さんありがとうございました。感謝しきれないくらいです。
しかし、直後、プロバイダ規制を喰らい、代理レスでのお礼しかできませんので、
これ以降返事をいただいても、お礼がかけませんので(;^_^

本当にありがとうございました。しかし、commufaは規制ばかりだ。。
705デフォルトの名無しさん:2008/06/01(日) 00:28:36
>>703
言っている事がいまいちよくわからんが

4bitのみ出力なんて無理だから、
32bitを2つ取り出して
char c = 0;
c = ((p[i] & 0xF) << 4) | (p[i + 1] & 0xF);

みたいな感じでやればいいのではなかろうか
706デフォルトの名無しさん:2008/06/01(日) 01:18:22
>>701
この場合の4bitのデータというのは4bitで表現できるunsignedなデータだから、
その表現のために使う下位4bit以外にはすべて0が入る

下位4bitのみを出力したいならそれ以外のbitを無視すればいい
どのように無視するかはどのように出力するかに依存する
707デフォルトの名無しさん:2008/06/01(日) 01:25:09
4つのビットを取り出したいのか
任意の4ビットを整数(符号つきなのかそうでないのか)として取り出したいのか
はっきりしろ
708デフォルトの名無しさん:2008/06/01(日) 01:36:24
>>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 とすればワーニングが出る。
709デフォルトの名無しさん:2008/06/01(日) 01:38:32
むしろ変数は初期化して当たり前だな
710デフォルトの名無しさん:2008/06/01(日) 01:43:04
コンパイルオプションでワーニングを出せばすぐ判ったろうにって内容の
質問も結構有るみたいだけど、初心者には敷居が高いのかな?
711デフォルトの名無しさん:2008/06/01(日) 01:45:05
warningの内容の意味がわからないんだろう

初期化されていない変数が使用されています、の初期化って何?みたいな
712デフォルトの名無しさん:2008/06/01(日) 01:51:59
職業プログラマでも当たり前のように初期化しない奴がいるから困る
同じプロジェクトではやりたくないな
Javaなんかは、その辺を気にして作られたんだろうけど
「NullPointerExceptionって何><」とか、普通に言うアホもいるしな
713694:2008/06/01(日) 01:56:22
>>704
なるほど。それで行けそうな気がします。
ありがとうございます


>>706
8bitで出力させて上位の4bitを無視するようにしてやればいいということですよね?
それは考えていませんでした。ありがとうございます

>>707
4つのビットを取り出したいという意味でした。
わかりづらくて申し訳ありません。
714デフォルトの名無しさん:2008/06/01(日) 01:58:07
おまじないとして初期化してたおかげでたまたま動くのようなのもなぁ・・・・
715デフォルトの名無しさん:2008/06/01(日) 02:01:25
その意見も分かるが、たとえ1つでも中身が想定できない変数があるってのもな
716デフォルトの名無しさん:2008/06/01(日) 02:04:11
初期化してない変数をそのまま使うなんて論外
717デフォルトの名無しさん:2008/06/01(日) 02:06:25
>>712
ガッ
718デフォルトの名無しさん:2008/06/01(日) 02:06:44
>>714
おまじないとして初期化ってなんだ?
719デフォルトの名無しさん:2008/06/01(日) 02:11:10
初期化するしないにしても、普通はそのあとに値を入れると想定してるはずってことだろ
720デフォルトの名無しさん:2008/06/01(日) 02:12:49
宣言を先頭でするみたいな変なルールがない限りあんまり無いかな。
721デフォルトの名無しさん:2008/06/01(日) 02:17:43
警告以前に未定義動作だろうが
722デフォルトの名無しさん:2008/06/01(日) 02:20:36
>>720
ブロックの先頭以外での宣言ってC99以外なら規格外ですよね。
それを変なルールと表現する時代になったの?
723デフォルトの名無しさん:2008/06/01(日) 02:22:02
>>672
そういうコンパイラの定義とかを知りたい場合はどこで情報を入手したらいいんですか?
そもそもフリーのコンパイラに日本語マニュアル?なんて存在すんですか?
724デフォルトの名無しさん:2008/06/01(日) 02:25:48
とりあえず、ANSI C言語辞典、K&R両方そろえてから考えましょうか
725デフォルトの名無しさん:2008/06/01(日) 02:26:21
>>723
なぜに日本語?英語でいいだろ
726デフォルトの名無しさん:2008/06/01(日) 02:26:25
>>722
40近いおっさんプログラマが、それを普通に知らずに、
コーディング規約をC89に設定したプロジェクトで、変数を先頭以外で宣言してたわw
gccなんだが、makefile的にコンパイル通ってたんだよな
まだ若手の俺でも知ってるのに、結構認知度低いのか?C++ばっかやってた人間には見えないし
727デフォルトの名無しさん:2008/06/01(日) 02:27:18
>>712
みたいなプログラミング作法って職場毎にマニュアルで規定されているんですか?
728デフォルトの名無しさん:2008/06/01(日) 02:28:09
>>725
英語必須ですか・・・orz
729デフォルトの名無しさん:2008/06/01(日) 02:29:24
Cの場合
BCCでは宣言は最初にしないとエラー
UNIXやCygwinでは先頭でなくてもエラー出ない
730デフォルトの名無しさん:2008/06/01(日) 02:33:11
先頭で宣言しないとエラーってなんかCOBOLとかあの時代
の言語がそうだなw

最近のは途中でもOKだけど・・・

でも途中にあるのって気持ち悪くないかな・・・
731デフォルトの名無しさん:2008/06/01(日) 02:33:54
>>728
windowsでcやるのが面倒ならゲーム端末なんかの
ハックネタを参考にソッチでやってみれば?
732デフォルトの名無しさん:2008/06/01(日) 02:37:27
俺はC++やJavaで開発してるときは、できるだけその変数を初めて使う直前で宣言するようにしてる
気持ち悪いという意見も分からんでもないが、
たとえば、ローカルでしか使わない変数をグローバルには置かないだろ?置くやつもいそうだが・・・
まー、直前で宣言する理由は、それと似たようなもんだ
733デフォルトの名無しさん:2008/06/01(日) 02:40:38
>>732
あーそういう意味じゃなくて・・・

そりゃローカル変数までグローバルのように定義してたら逆に
うざくてしかたない。

言いたかったのはグローバル変数を途中の関数と関数の間に
おけるおけないのは無し

void hogeA()
{

}

int hogehoge;

void hogeB()
{
hogehoge = 0;

}
734デフォルトの名無しさん:2008/06/01(日) 02:41:42
>おけるおけないのは無し
置ける置けないの話



MS-IME・・・簡便してくれorz
735デフォルトの名無しさん:2008/06/01(日) 02:43:30
IME以前に人に物事を伝える能力に疑問があるだろw
736デフォルトの名無しさん:2008/06/01(日) 02:43:42
>>658
プログラムについてまだよくわからないので、途中まで教えてください
737デフォルトの名無しさん:2008/06/01(日) 02:45:15
ソースファイル全体レベルだと、一番上に密集させてるなー
そもそも変数の場所を探すのが大変になる
MFCだと、theAppが半端な場所に勝手に作られていた気もするがw

デバッグしてるときなら、__func__が使えない環境の場合、#undefで定義することはあるかな
738デフォルトの名無しさん:2008/06/01(日) 02:45:16
658のどこがわからないのか具体的に。
739デフォルトの名無しさん:2008/06/01(日) 02:48:33
さっさとソース書けよって意味ではなかろうか
740デフォルトの名無しさん:2008/06/01(日) 02:53:02
>>733
え?

void hogeA()
{
int i;
printf("hello");
int j;
}

こういう話だよね?

>>726
こういう当たり前レベルのことすらできないおっさんが混ざってて
かつgccな環境なら -pedantic-errors をFLAGSに突っ込みましょう
そんでもって、あれ?あれ?コンパイルできなくなったよ!?とか
慌てふためく姿を肴に酒の一杯でも飲みましょう

gcc拡張を使ってるんだという自覚があれば、コーディング規約で
どうにかしましょ。
741デフォルトの名無しさん:2008/06/01(日) 02:58:30
サンプルよこせということで?
742デフォルトの名無しさん:2008/06/01(日) 02:59:35
ブロックの先頭に書いた上でtagsとかを活用するのがよさげ。
なぜかユーザの多い秀丸にもタグジャンプ機能ついた気がする。

関数内で宣言が遠いよ、とぼやく前に関数をコンパクトにすることを
考えないとね。どんだけでかい関数作っちゃってるんですか?
743デフォルトの名無しさん:2008/06/01(日) 03:01:02
>>742
関数はコンパクトでもどうしても機能的にそのソース内に
おさめないとまずそうな関数がいっぱいあると同じく
宣言遠いよになりますよね・・・
744デフォルトの名無しさん:2008/06/01(日) 03:01:09
細かくブロックわけすればいいじゃん。
745デフォルトの名無しさん:2008/06/01(日) 03:01:32
途中まででいいということですので半分くらい。。。

#include<stdio.h>

int main(void)
{
int input;
746デフォルトの名無しさん:2008/06/01(日) 03:03:02
>>743
グローバル変数のことかしら。
であれば、それがグローバルであるべきかどうかを考えてみては?
747デフォルトの名無しさん:2008/06/01(日) 03:03:47
>>744
kwsk

それかそういうのを解説してるサイトアドレスプリーズ

>>745
それは・・・・新手のいじめですかw
748デフォルトの名無しさん:2008/06/01(日) 03:05:53
>>746
いやあまりグローバルは使って無いけど
構造体の定義とかそのソース内でしか使わないのを
あらたに定義するときは関数が増えると
遠く感じますね〜
749デフォルトの名無しさん:2008/06/01(日) 03:07:48
そういえばみなさんは関数を定義する際プロトタイプ宣言する派ですか?
それとも関数自身が使われる関数の上に書いておしまい派ですか?
750デフォルトの名無しさん:2008/06/01(日) 03:10:19
変数の宣言かぁ
オブジェクト指向ではこれらの問題点を解決してるんですよね・・
751デフォルトの名無しさん:2008/06/01(日) 03:11:59
>>749
上に書く

変数宣言を最初にやりたがる人は旅行のときにちゃんと計画を立てるのが好きな人
後からでも宣言するのは行き当たりばったりな旅行でもOKな人と勝手に思った
752デフォルトの名無しさん:2008/06/01(日) 03:16:10
>>750
cでもその辺を意識して作ればいい。

クラスのように動的に構築はしないけど

コンストラクタのような機能の関数で、グローバル変数の初期化
デストラクタのような機能の関数で、mallocした領域の開放とか
753デフォルトの名無しさん:2008/06/01(日) 03:17:13
ctorとdtorでやってることの関連性がないような。
754デフォルトの名無しさん:2008/06/01(日) 03:22:03
>>753
そりゃそもそも概念が違うし

あくまでオブジェクト指向のいい面を意識しながらってこと
755745:2008/06/01(日) 03:28:10
>>747
int a;
a=0;
{
int b; /* ブロックの先頭なのでおk */
}
ってこと。

あと、いじめじゃなくておおまじめですw

>>748
ソースファイルが
 構造体を使わない関数群
 構造体定義
 構造体を使う関数群(これがたとえば1000行)
というレイアウトの場合に、ファイル終端あたりから構造体の定義を
参照するときはやっぱり遠いですよね。
そのとき、ファイルの先頭を見に行くのか、ヘッダを見に行くのか、
ファイルの中のどこかで定義されているのを探しに行くのか
どれがよさげに思います?

個人的には他人のソースを見る機会が多いので、どこにあっても
問題ないようにタグジャンプしまくりますけど。
756デフォルトの名無しさん:2008/06/01(日) 03:29:47
>>750
確かに、他言語で解決済みの問題って、旧言語ではバッドノウハウに
なってる可能性が有るな。  自戒をこめて。
757530:2008/06/01(日) 04:44:37
>>all

すんませんでした。HINSTSNCE←全然気づきませんでした。
また質問来るからその時はよろしく・・お願いします。
758530: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がどうとか、エラーを調べたけどよくわからないです。

759デフォルトの名無しさん:2008/06/01(日) 05:12:21
コンソールアプリケーションとして扱われてるんじゃなかろうか

borlandコンパイラどうなってるのか知らないし、
統合開発環境が無いと作れない人なんで解決法の提示が出来ないが…
760デフォルトの名無しさん:2008/06/01(日) 05:19:27
自分でやって出来なければ、APIから今時入ろうだなんて
ちょっと無謀だって気もしなくもない。
(だからといってJavaや.NETを勧めるわけでもないが...)
今時APIを学びたいなんて酔狂な人はDelphiだろなやっぱり
幾分近い道は。
APIを使ったプログラミングなんて本来(超)ベテラン向け(だった)
ということは覚えておいたほうがいい。
761デフォルトの名無しさん:2008/06/01(日) 05:21:15
>>758
参考にしてるホームページよく見ろよ

WinAPIの最初の項目に書いてあるだろ
762530: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;
からわかりません

764648:2008/06/01(日) 12:06:29
すいませんまた教えてもらいたいんですけど
648に書き込んだプログラムを元にキーボードから50以下の数値を入力して
その数値から順番に出力し51になると終了するプログラムにしたいんですが
どうすればいいでしょうか?とりあえずscanfをつかうこと分かりますが、うまくつかえません
どなたか解説お願いします。ループの初期問題ですが苦戦してます。
実行例
20  ←入力
21  ←1回目出力
22  ←2回目出力


50  ←n回目出力
765デフォルトの名無しさん:2008/06/01(日) 12:13:35
>>764
for(i=n+1;i<=50;i++) printf("%d\n", i);
これで分かるですか?
766デフォルトの名無しさん:2008/06/01(日) 12:19:52
>>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;
}
767648:2008/06/01(日) 13:13:35
>>765さん
>>766さん
回答ありがとうございます。
for文を使うとそうなるんですね。正直C言語苦手なので
習った所を教科書でもう一度確認してみます。




768デフォルトの名無しさん:2008/06/01(日) 13:50:48
苦手とかいうレベルじゃねーぞw
769デフォルトの名無しさん:2008/06/01(日) 14:13:00
>>762
エントリポイントとかの勉強をするのは今がいいかも!
770デフォルトの名無しさん:2008/06/01(日) 15:28:20
初心者すぎて申し訳ないのですが
int sum = 0, v;
これはどういう意味なんでしょうか?
intの中には文字は入らないと聞いたのですが
771デフォルトの名無しさん:2008/06/01(日) 15:28:48
0はintだろ。
772デフォルトの名無しさん:2008/06/01(日) 15:32:27
int sum = 0;
int v;
こう読めなかったんじゃない
773デフォルトの名無しさん:2008/06/01(日) 15:32:48
>>770
同じ意味で分けて書くと

int sum = 0;
int v;

こう。
774デフォルトの名無しさん:2008/06/01(日) 15:33:17
>>770
int sum = 0, v;



int sum, v;
sum = 0;

は同じです。

宣言と同時に初期化をしているだけです。
775デフォルトの名無しさん:2008/06/01(日) 15:34:12
カンマ演算子を知らない奴は多いだろうな
776デフォルトの名無しさん:2008/06/01(日) 15:35:25
なんでいきなりカンマ演算子がでてくるんだ。
777デフォルトの名無しさん:2008/06/01(日) 15:37:02
>>774ですがそんな言葉があること自体しらなかった。
なんかC言語が廃れる理由ってマニアックなんですよね。
C言語に精通した人から見ると記述が少なくなって言いとかあるんでしょうけど
どうもわざわざ敷居をあげてる気がする。
778デフォルトの名無しさん:2008/06/01(日) 15:39:54
残念ながら、ほとんどのC-likeな言語で同様の記述ができます。
779デフォルトの名無しさん:2008/06/01(日) 15:40:10
>>772-773
それだとわからない人もいるかも。
780>>770:2008/06/01(日) 15:40:30
>>771-774
ありがとうございます。分かりました。
はじめはsumの中に0とvが入っているんだと思ってました。
781デフォルトの名無しさん:2008/06/01(日) 15:42:09
一応つっこんどくと変数宣言や関数の引数リストのカンマはカンマ区切りであってカンマ演算子ではない
782デフォルトの名無しさん:2008/06/01(日) 15:42:16
>>778
それは知ってるけど、宣言と同時に初期化って気持ち悪いんだよな・・・
783デフォルトの名無しさん:2008/06/01(日) 15:43:02
俺は1stepでも、変数に未知の値が入っている方が気持ち悪い
784デフォルトの名無しさん:2008/06/01(日) 15:43:30
変数が自動で初期化されない言語で、明示的に初期化する方法がないほうが気持ち悪いわ
785デフォルトの名無しさん:2008/06/01(日) 15:54:49
>>782
配列の初期化は宣言と同時じゃないとできないし。。。
786デフォルトの名無しさん:2008/06/01(日) 15:59:33
>>777
いつの間にC言語が廃れたのか知りませんが、低級言語なので
時折面倒な事があるのは確かですね。
けれど、他の高級言語のような、「中で何をやっているのかわからない」
という漠然とした不安感はないですよ。
787側近中の側近 ◆0351148456 :2008/06/01(日) 16:07:07
(っ´▽`)っ
カンマ演算子は気をつけてね☆

int i, j = 0;
で0が設定されるのはjだけ。iは設定されない。

int* i, j;
では、iはint*型、jはint型。
788デフォルトの名無しさん:2008/06/01(日) 16:07:10
宣言時以外の=は初期化じゃなくて代入だろ…
789デフォルトの名無しさん:2008/06/01(日) 16:09:23
Cが低級言語とな
790デフォルトの名無しさん:2008/06/01(日) 16:12:25
>>789
最近は中級言語なんて呼ばれることもあるらしいから、
そのうち本当に低級言語になったりしてな
791デフォルトの名無しさん:2008/06/01(日) 16:13:37
C言語が低級言語になったらアセンブラは何になるんだろうな
792側近中の側近 ◆0351148456 :2008/06/01(日) 16:14:41
(っ´▽`)っ
変数はなるべく、宣言、設定、参照、廃棄の期間(変数の寿命)が
短くなるようにするほうが好ましい。
長くなればなるほど、初期化漏れ、廃棄漏れが多くなるからね。
使う直前で設定する。使ったらすぐに廃棄する。
793デフォルトの名無しさん:2008/06/01(日) 16:14:59
ヒエログリフ
794デフォルトの名無しさん:2008/06/01(日) 16:24:17
ここでおさらい

1) Cは高級言語(人間に理解しやすい文法を持つ言語という意味)である
2) Cは低レベル言語(低い=ハードウェアに近い階層をいじくることができる言語という意味)である
795デフォルトの名無しさん:2008/06/01(日) 16:25:46
>>794
低レベル言語といわず低レベルレイヤー言語とかのうほうが
説得力増すかな?
796デフォルトの名無しさん:2008/06/01(日) 16:28:05
他のより高級な言語との対比で使ってしまったことをお詫びしまする。
797デフォルトの名無しさん:2008/06/01(日) 16:35:39
アセンブリ言語も理解はしやすいよ。
798デフォルトの名無しさん:2008/06/01(日) 16:39:11
Cで開発できるならできればアセンブラは避けたいな〜

799デフォルトの名無しさん:2008/06/01(日) 16:45:00
でもアセンブラとCの速度差は、身をもって味わったな・・・
Cと他の高級言語の差も
800デフォルトの名無しさん:2008/06/01(日) 16:56:43
>>799
今でもそんな違うもんなの?
801デフォルトの名無しさん:2008/06/01(日) 16:59:44
>>800
そりゃ違うでしょ・・・

アセンブラ(マシン語)になってくると1命令が使うクロックとか
意識して書けるけど、Cの場合はコンパイラが最適化してくれる
とは言ってもやはり効率は若干落ちる。
まあその分開発速度はCが上なんだろうけど。

他の高級言語とCの比もそうでCの欠点を補う形で
あれこれ仕組みをいれちゃったので安全なプログラミングは
できるけどその代わり速度は犠牲になったり云々・・・
802デフォルトの名無しさん:2008/06/01(日) 17:04:06
まあしかし、それなりにCPUに詳しくないと、Cより速くはならない。
803デフォルトの名無しさん:2008/06/01(日) 17:04:25
アセンブラなんて基本情報の為にちょっと勉強しただけで触った事は無いな
804デフォルトの名無しさん:2008/06/01(日) 17:52:18
ポインタ変数ってアドレスを格納できる変数のことですか?
805デフォルトの名無しさん:2008/06/01(日) 17:53:52
一般的にはそうじゃないか?
ポインタという言葉をアドレスの指定以外にも用いることあるが
806デフォルトの名無しさん:2008/06/01(日) 17:58:00
では配列名がポインタの役割をしているとはどういう意味ですか?
807デフォルトの名無しさん:2008/06/01(日) 17:58:35
アドレス以外で使ったっけ?

808デフォルトの名無しさん:2008/06/01(日) 17:59:11
>>806
できればコードを投下してみて?
809デフォルトの名無しさん:2008/06/01(日) 18:01:06
int hairetu[20];

のとき hairetu は &hairetu[0] と一緒
810デフォルトの名無しさん:2008/06/01(日) 18:05:09
>>806
mapとかでいうkeyのことか?
811810:2008/06/01(日) 18:06:12
Cスレだった忘れてくれ
812デフォルトの名無しさん:2008/06/01(日) 18:08:23
>>806
配列であろうが変数はすべてメモリのどこかに確保されるので
アドレスを持つことになります。
813デフォルトの名無しさん:2008/06/01(日) 18:12:24
>>807-812
だいたいイメージできました
アリガトゴザイマスm(_ _)u
814デフォルトの名無しさん:2008/06/01(日) 18:12:49
それはまちがい
815デフォルトの名無しさん:2008/06/01(日) 18:17:22
>>814
どれが間違い?

関数の一時な変数がコンパイルされると実はメモリ上に確保されずに
レジスタでまかなわれてるとかいう話?

とりあえずはアドレスの話なのでそんな細かいのはいいんだよ
816デフォルトの名無しさん:2008/06/01(日) 18:18:33
確かに少しあいまいです
質問の意図するところは>>809でした
>>809の場合で何でhairetu は &hairetu[0] と一緒になるのかがいまひとつわかりません
817デフォルトの名無しさん:2008/06/01(日) 18:20:27
registerストレージクラスの変数のアドレスを取得するのは違法だとかそんな話だろ。
818デフォルトの名無しさん:2008/06/01(日) 18:23:24
配列名は入れ物であってこれがなぜアドレスを示すのかが謎です
それなら&なんてはじめから存在する必要が無いようにも思えます
819デフォルトの名無しさん:2008/06/01(日) 18:24:30
>>816
それは例がintだからわかにくいかもしれないのでcharの配列で考えてみなよ
820デフォルトの名無しさん:2008/06/01(日) 18:24:39
>>816
そういう決まりだからじゃないのか?

hairetuはhairetu[20]の先頭アドレス
だから先頭の配列であるhairetu[0]のアドレスと同じ
821デフォルトの名無しさん:2008/06/01(日) 18:25:03
入れ物の置き場所がアドレス
[]の反対が&
822デフォルトの名無しさん:2008/06/01(日) 18:25:48
連続レススマン

>>818
Cは数値を渡すのが基本だからアドレスっていう数値を渡すためにポインタが出てくるんじゃないかな。
823デフォルトの名無しさん:2008/06/01(日) 18:25:56
>>816
a[b] と *(a + b) は一緒
&*a と a は一緒
a + 0 と a は一緒

であるから

&hairetu[0] == &*(hairetu + 0) == (hairetu + 0) == hairetu
824デフォルトの名無しさん:2008/06/01(日) 18:26:54
>>806
どこで聞いた話か知らないがその言葉は正しくない
正確には、「一部の例外を除き、配列名はその先頭要素へのポインタ値に成り下がる」だ
一部の例外というのは、sizeof演算子を適用するとき、&演算子を適用するとき、配列の宣言と同時に初期化するとき、のこと
825デフォルトの名無しさん:2008/06/01(日) 18:28:32
でもこれがイメージできないのはちとつらいな・・・
826デフォルトの名無しさん:2008/06/01(日) 18:35:38
>>819-825
アリガトゴザイマス
イメージはできたのですがどうも&が存在してる理由がピンときません
初めて&が出てきたので後々に&演算子を適用するという場合に&がナイト不都合が生じるということでおkですか
827デフォルトの名無しさん:2008/06/01(日) 18:37:18
配列以外に使う。
828デフォルトの名無しさん:2008/06/01(日) 18:37:27
>>826
&がなかったら、配列以外の変数のポインタが取れないじゃん?
829デフォルトの名無しさん:2008/06/01(日) 18:38:32
&(hairetu[0])の方がわかりやすいんじゃない?
830デフォルトの名無しさん:2008/06/01(日) 18:39:24
>>826
えーと関数とかにデータを渡す際、int1つ程度であれば値渡しでいいですけど
intを20個とか渡すとなるとコピーするコストがかかるので配列の先頭アドレス
を渡せばアドレスのバイト数(これは実行環境で変動)で済むので
変数のアドレスを求めたりします
831デフォルトの名無しさん:2008/06/01(日) 18:45: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;
}
834デフォルトの名無しさん:2008/06/01(日) 18:58:12
これは重要だな。
835側近中の側近 ◆0351148456 :2008/06/01(日) 18:58:59
(っ´▽`)っ
>>833は、
配列は引数で渡されるとポインタに格下げになる
というルールの例だよ。
836デフォルトの名無しさん:2008/06/01(日) 18:59:41
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;
}
838デフォルトの名無しさん:2008/06/01(日) 19:00:37
型がなんであれ、ポインタの実態はアドレスだから
32ビット環境じゃ2^32でアドレスが管理されているから
32bitすなわち4バイトであるのは既知なること。
839デフォルトの名無しさん:2008/06/01(日) 19:01:08
>>833
int func(int i[])の方がわかりやすいような
840デフォルトの名無しさん:2008/06/01(日) 19:01:16
>>835
違う違う、配列の先頭のアドレスをポインタで引き渡しているんであって
格下げでも何でもないって
841デフォルトの名無しさん:2008/06/01(日) 19:03:09
>>840に一票
ちなみに文字列定数を定義するならchar*じゃなくてchar[]だな
842側近中の側近 ◆0351148456 :2008/06/01(日) 19:03:47
>>840
(っ´▽`)っ
じゃあ、なぜsizeof(i)が配列全体のサイズじゃないのさ?
アドレスのサイズになるよね。
843側近中の側近 ◆0351148456 :2008/06/01(日) 19:04:38
(っ´▽`)っ
じゃあ、格下げというか、配列とみなさなくなるって言えばいいのかな?カナ?
844デフォルトの名無しさん:2008/06/01(日) 19:05:03
sizeofは関数じゃないの?
845側近中の側近 ◆0351148456 :2008/06/01(日) 19:05:42
(っ´▽`)っ
いや、普通にi[10]とかアクセスできるから、
配列とはみなしてるんだろうなぁ☆
単にsizeofの問題か。
846デフォルトの名無しさん:2008/06/01(日) 19:06:10
>>844
sizeofは演算子です
847側近中の側近 ◆0351148456 :2008/06/01(日) 19:07:37
(っ´▽`)っ
まあ、とにかく、sizeofを配列に対して使う時には、
それがローカル変数なのか、引数なのか確認を忘れないこと☆
848デフォルトの名無しさん:2008/06/01(日) 19:09:53
すみません、質問があります。
ファイルから読み込んだ文字列を一行ずつ配列に保管したいのですが、
自分がやると最終行だけが配列の全体に保管されてしまいます。
何がおきているのでしょうか。
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型だろうから、偶然配列全体のサイズになるだろうけど。
850デフォルトの名無しさん:2008/06/01(日) 19:13:43
32bitCPUでintが16bitってことはあったぞ
ポインタが何bitだったかは覚えてないけど
851デフォルトの名無しさん:2008/06/01(日) 19:14:42
>>842
何を言ってるんだ?
852デフォルトの名無しさん:2008/06/01(日) 19:16:54
hairetu[3]
*(hairetu + 3)
*(3 + hairetu)
3[hairetu]
とできますよ。
853デフォルトの名無しさん:2008/06/01(日) 19:17:18
まちがえてかいてしまた。
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;
}
これでも実行してね、といいたかったのです。
854デフォルトの名無しさん:2008/06/01(日) 19:17:35
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]に変えてね。
静的領域を書き換えちゃダメだよ☆
856デフォルトの名無しさん:2008/06/01(日) 19:18:36
>>854
ああああ!ありがとうございます!
857デフォルトの名無しさん:2008/06/01(日) 19:19:16
>>855
ありがとうございます。
858側近中の側近 ◆0351148456 :2008/06/01(日) 19:19:27
>>851
(っ´▽`)っ
気にすんな☆
859デフォルトの名無しさん:2008/06/01(日) 19:19:33
>>853
その配列の表記は、知らない人多いから使いたくないな
860デフォルトの名無しさん:2008/06/01(日) 19:21:12
>>842
だから char *i でも double *i でも
ポインタの 実態 は アドレス だから、環境にもよるが
扱えるメモリによって違うが、アドレスの番地を記憶している
識別子であることには変わりはないっす
861デフォルトの名無しさん:2008/06/01(日) 19:21:37
>>859
使う使わないじゃなくて、等価であることを知ることで理解が進めばと思ったです。
2[hairetu]なんて書いてたらグーでパンチする。
けど、*(hairetu + 2)は別にいいでしょ。これが同じということを知ってほしい。
862デフォルトの名無しさん:2008/06/01(日) 19:23:23
>>842
配列を引数に渡す事ができないということを言わないと。
863デフォルトの名無しさん:2008/06/01(日) 19:23:26
854補足
つまりcのデータは毎回上書きされるので
最後に読んだデータになる。

解決方法としてはc[][]とバッファを2元配列にでもするか

a[i] = malloc(strlen(c) + 1);
memcpy(a[i],c,strlen(c));

と動的に領域を確保するとか。
864デフォルトの名無しさん:2008/06/01(日) 19:24:09
*(2 + hairetu)
これも気持ち悪いな
865デフォルトの名無しさん:2008/06/01(日) 19:27:12
思想的には間違ってないが、そんなコード描いてるやついたら、俺はキレるw
866デフォルトの名無しさん:2008/06/01(日) 19:30:15
足し算引き算の順番くらい好きにやらせてくれよ
867デフォルトの名無しさん:2008/06/01(日) 19:32:30
絶対アドレス00000002から、なんかのテーブルでもあるのかなという感じw
868デフォルトの名無しさん:2008/06/01(日) 19:34:32
ごめん
その手のコードが分からない人が不具合誘発して、その尻拭いをするのはコリゴリなんだ・・・
869デフォルトの名無しさん:2008/06/01(日) 19:35:18
>>866
そうでもないぜ・・・

>>864のような記述ってBASICで作ってるお遊びプログラムの延長で
組んでるように見えるし、こういう書き方するのに限ってバグ大量に入れてるし
870デフォルトの名無しさん:2008/06/01(日) 19:41:10
定数は右に書くもんだと思ってる
871デフォルトの名無しさん:2008/06/01(日) 19:45:02
>>866
引き算は順番にしようぜ。。。
872デフォルトの名無しさん:2008/06/01(日) 19:45:28
>>845
ひどい勘違い
[]演算子は配列に適用されるものでなくポインタに適用されるもの
配列名に対して[]が使えるのは、そのとき配列名がポインタに格下げされているから
873デフォルトの名無しさん:2008/06/01(日) 19:47:18
格下げも何も、ポインタを要求する所に使ったら
ポインタ型に暗黙にキャストされるだけだろ。
874デフォルトの名無しさん:2008/06/01(日) 19:48:35
ポインタ型にキャスート(笑)
875デフォルトの名無しさん:2008/06/01(日) 20:05:11
定数は==の左に書くものだと思ってる
876デフォルトの名無しさん:2008/06/01(日) 20:06:42
警告ぐらいちゃんと嫁
877デフォルトの名無しさん:2008/06/01(日) 20:11:59
C/C++はアセンブラのなれの果て。とかいまだに思ってる自分があって、
乏しいMASM経験から、定数は右のほうに置くくせがあるのかな…と自己分析してみた
878デフォルトの名無しさん:2008/06/01(日) 20:14:02
警告を平気な顔で残してソース管理してるやつは、ほんとムカつくなー
879デフォルトの名無しさん:2008/06/01(日) 20:17:11
うん、西暦10000年問題とかまったく考えてなさそう
880デフォルトの名無しさん:2008/06/01(日) 20:17:36
>>875
それを見るたびに、ああ、これを書いた人は不安だったのかなって思ってる
881側近中の側近 ◆0351148456 :2008/06/01(日) 20:22:34
>>875
(っ´▽`)っ
それって、if(k = 0){...}を防止するための措置だよね?
if(0 = k){...}はコンパイルエラーになるから。
882デフォルトの名無しさん:2008/06/01(日) 20:24:42
>873
それはヌルポインタ定数0のことだ
883デフォルトの名無しさん:2008/06/01(日) 20:25:17
>>881
けど最近のコンパイラは前者でも警告を出すよねって話
884デフォルトの名無しさん:2008/06/01(日) 20:28:28
出ないコンパイラやmakefileもあるから、侮れないな
あとtrue=1やfalse=0という前提で書かれているソースもひっかかる
885デフォルトの名無しさん:2008/06/01(日) 20:34:23
>>877
なれの果てだねえ。

↑ポインタに格下げとか言う表現がちょっとびっくり

どうやってもアセンブラレベルだとポインタ持ってるからint が32bitだと
配列の先頭を指してるポインタに[n]*4するだけやん。
格下げも何も・・・

格下げという表現の時点で無理やりアセンブラに一枚オブラートかぶせただけって感じがする。
886デフォルトの名無しさん:2008/06/01(日) 20:36:15
>>864
2[hairetu]
ならいいか?
887デフォルトの名無しさん:2008/06/01(日) 20:36:42
>>874

a[b] は *(a + b) と等価で、
配列への整数の足し算は定義されてないから
ポインタに暗黙にキャストされるという話だろ?
888デフォルトの名無しさん:2008/06/01(日) 21:21:20
>>887
意味不明でキャストの意味を間違っているから黙っていた方が良いお
無知を晒すのは痛々しいお ^ω^
889デフォルトの名無しさん:2008/06/01(日) 21:26:56
等価っていうのは合ってるけどなw
890デフォルトの名無しさん:2008/06/01(日) 21:29:17
ポインタはポインタ。ポインタ型はないが変数の型を指定して
ポインタを宣言しないと、int型の変数をchar型のポインタを用いて
間接演算子を用いても適切に扱えんぞな
891デフォルトの名無しさん:2008/06/01(日) 21:48:18
>885
ポインタとアドレスの区別がついてないならもう一度勉強しなおすことをお勧めする

>873
違う
具体例を出すと、たとえば配列aに対して if(a) と書くと条件が真となる
しかしもしここでaがポインタでないなら(ポインタを要求する文脈ではないからそうなるはずだが)この条件は不定になってしまう
なぜなら、「配列の中身」や「配列のアドレス」でなく、配列名が指すべきものつまり「 配 列 そ の も の 」が
いかなる値を持つべきかは規定されていないからだ

配列は配列そのものを指すが、先の例外を除いて、先頭要素へのポインタに成り下がる
だから if(a) は正しく真と判定され、また一方でsizeof(a) はa全体のサイズを返し、&a は「配列へのポインタ」を返す
892デフォルトの名無しさん:2008/06/01(日) 21:49:07
よくわからん
893デフォルトの名無しさん:2008/06/01(日) 21:50:05
訂正
×「配列の中身」
○「配列の要素」
894デフォルトの名無しさん:2008/06/01(日) 21:52:20
>>891
873は833の例に対して引数がint*なんだから配列渡そうが、
ポインタ渡そうが違いはないってこと言いたいんじゃないか?
895デフォルトの名無しさん:2008/06/01(日) 21:56:32
なぜそこで833が出てくる
アンカーつけてないなら普通直前の872の話だろ
で872は845につながっている
ここで問題になっているのは845の「[]は配列に作用する演算子だ」という勘違い
896デフォルトの名無しさん:2008/06/01(日) 21:57:56
レス番つけるなら >> つけてくれ。追うのがめどい。。
897デフォルトの名無しさん:2008/06/01(日) 21:58:56
しかもここID付かないから余計面倒w
898デフォルトの名無しさん:2008/06/01(日) 22:01:30
格下げなんて俺用語使ってるからダメなんだよ。
配列-ポインタ変換と言おうぜ。
899デフォルトの名無しさん:2008/06/01(日) 22:01:55
おまいら、知ってっか?2038年問題を。っていっても、すでに対策済みだがなw
900デフォルトの名無しさん:2008/06/01(日) 22:04:08
ポインタはポインタ、配列とは無関係。これまた、ややこしいな・・・
すでにポインタの実態は、配列とポインタに対して sizeof で結論は出ていたはずだろ?
ポインタはどう足掻いても、例え動的確保をしようが、アドレスの番地に過ぎないんだよ。
割り当てが 2^32 の範囲ないであれば、8bitで1byteなら4バイト
配列は宣言した変数*要素数だって結論は出ただろ?四の五の言わずに
ポインタはポインタ、実態はアドレス
901デフォルトの名無しさん:2008/06/01(日) 22:05:10
>>891
配列を条件式として使ったらどうなるか定義されてないからポインタに変換されて、
後はそのポインタが条件式として使われる(0=偽/非0=真)だけだろ。
902デフォルトの名無しさん:2008/06/01(日) 22:08:30
ポインタに格下げの意味が分からん。ぶっちゃけ、配列のアドレスを渡そうが
コードはその配列の要素を無視して無関係な場所をポインタに
指定することも可能だが?
903デフォルトの名無しさん:2008/06/01(日) 22:10:08
お前の言ってる意味の方が分からん
904デフォルトの名無しさん:2008/06/01(日) 22:10:29
>>901
違う。
コンパイラには定義されていない構文をそのまま通してやる義理などない。それは未定義だ。
配列がポインタへ格下げされると定義されているからこそ、if(a) は正しくコンパイルされる。
905デフォルトの名無しさん:2008/06/01(日) 22:11:44
>>903
理解力の無いバカなら余計に話しするなよクズが
906デフォルトの名無しさん:2008/06/01(日) 22:12:29
うわっ、識別子の意味も分かってないバカがポインタ型とかぬかしてんぞw
以後放置よろw なんだよポインタ型ってw 出るとこに出たら笑われんぞw
907デフォルトの名無しさん:2008/06/01(日) 22:12:41
if(配列)なんて現実的でない例にどんな意味があるんだろう
908デフォルトの名無しさん:2008/06/01(日) 22:12:53
>>904
言ってる事は正しいんだが、それって 「格下げ」 なのか?
配列よりポインタの方が格下なのか?
909デフォルトの名無しさん:2008/06/01(日) 22:13:47
>>906
ポインタ型 (pointer type) は規格にも載ってる用語だが・・・。
910デフォルトの名無しさん:2008/06/01(日) 22:14:56
ポインタ型を知らないとなw
911デフォルトの名無しさん:2008/06/01(日) 22:15:01
ポインタにはアドレスを渡してんだよ。例え配列でなくても
int a; を &a でアドレスを渡すことがあろう。
ポインタで宣言された識別子は、その指定された型応じて使える
実態はアドレスに過ぎない識別子。
912デフォルトの名無しさん:2008/06/01(日) 22:18:06
っつーか、メモリのアドレスも知らなさそうな素人がコードを書いているんじゃね?
自分、大学の実験でも内面的なものを扱ったが、それくらい知っておけ
913デフォルトの名無しさん:2008/06/01(日) 22:18:23
「アドレス」 の実体は別に規定されてないけどね。
914デフォルトの名無しさん:2008/06/01(日) 22:18:58
>>908
確かに「格下げ」とか「成り下がる」とかは正式な用語ではない。
しかし、多くの場面で実際に使われている。
特にCプログラミングFAQにおいて使われていることから、
準公式な用語として認識しているプログラマが少なからずいる。

もって回った表現で言えば「縮退したデータ型に暗黙に変換される」となる
(なお、これは「キャスト」のことではない、念のため)。
ここで言う「縮退した」とは、「配列全体」(という概念)を意味する配列の名前が
「配列の先頭要素へのポインタ」になることを言う。
915デフォルトの名無しさん:2008/06/01(日) 22:20:28
規格スレ行け
916デフォルトの名無しさん:2008/06/01(日) 22:20:51
変換をキャストと言う事も正式用語でなくともよく聞くけどな。
917デフォルトの名無しさん:2008/06/01(日) 22:21:09
>>901
間接演算子って知ってる?
ttp://www.youtube.com/watch?v=RIL28wqOQGA
918デフォルトの名無しさん:2008/06/01(日) 22:21:31
>>914
それって暗黙なのか?
少なくともソース書いてる本人は意識してるはずだぞ
919デフォルトの名無しさん:2008/06/01(日) 22:22:05
そりゃ暗黙だろう。
920デフォルトの名無しさん:2008/06/01(日) 22:22:44
>>914
別に格は下がってないけど?配列の場合、先頭のアドレスを
単独の場合はとりわけ & アドレス演算子でポインタにアドレスを渡しているんだが?
しかし、変数の型に応じたポインタを宣言しないと、適切に指定したアドレスの
変数が使えんぞ。
921デフォルトの名無しさん:2008/06/01(日) 22:26:53
>911
>920
日本語でおk
922デフォルトの名無しさん:2008/06/01(日) 22:27:02
>>902=>>920 か?
なんか日本語がよく分からんのだが・・・。
923デフォルトの名無しさん:2008/06/01(日) 22:27:14
>>905
はなしし?
924デフォルトの名無しさん:2008/06/01(日) 22:28:11
void はカエレ
925デフォルトの名無しさん:2008/06/01(日) 22:29:41
質問です。
switch文を使って、数字以外のものを決めることはできないのでしょうか。
(例えば、プラスやマイナス)↓
switch(na){
case 0:
case 1: ma = +; break;
case 2:
case 3: ma = -; break;
}
926デフォルトの名無しさん:2008/06/01(日) 22:30:04
>>906
でるとこでよかー
927デフォルトの名無しさん:2008/06/01(日) 22:30:48
無理です
928デフォルトの名無しさん:2008/06/01(日) 22:31:21
>>925
1. 数値を記号と対応させる(列挙子を使うと良い)
2. 文字や文字列を使用する
3. 関数ポインタを利用する

状況次第で 1〜3 のどれかを使う。
929デフォルトの名無しさん:2008/06/01(日) 22:31:49
>>924
voidじゃないよ。

>>925
もう一体何がしたいのか分からないよ><
もう少しやりたいことを具体的に書いてみようー
930デフォルトの名無しさん:2008/06/01(日) 22:33:14
>>925
できない。
そもそも switch だろうがなんだろうが、「正負を格納するデータ型」は存在しない以上、それを記録することもできない。
整数型の変数に 1 か -1 を格納して、必要なら他の数との演算に使うこと。
931デフォルトの名無しさん:2008/06/01(日) 22:33:58
数式のグラフを表示をしたいときはどうすればいいの?
932デフォルトの名無しさん:2008/06/01(日) 22:34:27
naはintか何かで
プラスマイナスっていうのは記号で付いてこないでOK?
それとも文字列でくるのを判断したいのか?
933デフォルトの名無しさん:2008/06/01(日) 22:34:38
>>927-930
ありがとうございます。別の書き方を探してみることにします。
934デフォルトの名無しさん:2008/06/01(日) 22:34:41
グラフを表示したいだけなら Excel とか gnuplot とか使っとけ
935デフォルトの名無しさん:2008/06/01(日) 22:34:43
グラフィカルユーザーインターフェースによる
936デフォルトの名無しさん:2008/06/01(日) 22:35:24
>>931
またものすごい大雑把な質問だな。
937デフォルトの名無しさん:2008/06/01(日) 22:38:39
>>932
naはintです。naとプラスマイマスを一緒に文字列でだしたいです。
938デフォルトの名無しさん:2008/06/01(日) 22:38:52
代数に-100から100までを代入して図が動くプログラムを書いて来いと言われたんだ
939デフォルトの名無しさん:2008/06/01(日) 22:39:14
>>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;

ネタ
940デフォルトの名無しさん:2008/06/01(日) 22:40:41
どうしてもswichで処理したければ
最初にifでnaが0以上か0未満か
調べて0未満なら*-1しておけば
swichを両方で使える。
あと正だったのか負だったのかは
覚えておかないとあれだけどな
941デフォルトの名無しさん:2008/06/01(日) 22:42:26
そういえば、どっかで配列の表現使わずにポインタで
書いた方がはやいってのを見たんだが、それってどうなの?
942デフォルトの名無しさん:2008/06/01(日) 22:43:07
>938
だからそのグラフを ど こ に 出力するのかによるって言ってるだろ
943デフォルトの名無しさん:2008/06/01(日) 22:43:15
ごめんなさい、間違っていました・・・。
naで決めたプラスマイナスと英数字を一緒に表示させたいのです orz
944デフォルトの名無しさん:2008/06/01(日) 22:43:34
>>941
昔の話、今時のコンパイラなら最適化してくれる
945デフォルトの名無しさん:2008/06/01(日) 22:46:03
>>943
naの型とどういうルールで中のデータが決まるの?
946デフォルトの名無しさん:2008/06/01(日) 22:47:20
>>941
そういう場合もある。

ただし、君は以下のことを見直すべきである。

[]演算子は「配列の表現」ではない。常にポインタに対して適用される。「添字を用いた参照」ガ正しい。
947デフォルトの名無しさん:2008/06/01(日) 22:48:38
すみません、やはり宿題を片付けますスレに行ってきます。
ありがとうございました。
948デフォルトの名無しさん:2008/06/01(日) 22:48:55
>>943
char c;


case 0: c='+'; break;
case 1: c='-'; break;
949デフォルトの名無しさん:2008/06/01(日) 22:49:38
>>942
なんというか窓の中
950デフォルトの名無しさん:2008/06/01(日) 22:50:48
>>949
しまいにゃ「窓の外」につきおとすぞ
951デフォルトの名無しさん:2008/06/01(日) 22:50:51
質問主は名前欄に最初の発言のレス番号入れろよ
ここIDつかねーんだから
952デフォルトの名無しさん:2008/06/01(日) 22:52:27
>950
丸神正頼乙
953デフォルトの名無しさん:2008/06/01(日) 22:53:33
>>949
問題文貼れ
954デフォルトの名無しさん:2008/06/01(日) 22:54:06
>>953
というか宿題スレへ飛ばすべき。
955デフォルトの名無しさん:2008/06/01(日) 22:56:15
次スレって誰が立てるんだっけ?
956デフォルトの名無しさん:2008/06/01(日) 22:56:54
>>950にお願いしたら。
あと重複を避けたいので宣言してからでよろ
957950:2008/06/01(日) 22:59:26
俺かよ
ちょっと待て
958950:2008/06/01(日) 23:01:53
ERROR!
ERROR:新このホストでは、しばらくスレッドが立てられません。
またの機会にどうぞ。。。

誰かよろ


言語の入門者向け解説スレです。

教えて欲しいのではなく宿題を丸投げしたいならこちらへ。
 C/C++の宿題を片付けます 108代目
 http://pc11.2ch.net/test/read.cgi/tech/1211980711/

・C++言語はスレ違いです。
・分からない事をなるべく詳しく書いて下さい。
・ソースコードを晒すと答えやすくなるかもしれません。
・開発環境や動作環境も晒すと答えが早いかもしれません。
・質問者は最初にその質問をした時のレス番号を名前欄に書いて下さい。

前スレ
C言語なら俺に聞け(入門篇) Part 28
http://pc11.2ch.net/test/read.cgi/tech/1211198816/
過去スレ
http://makimo.to:8000/cgi-bin/search/search.cgi?q=%82b%8C%BE%8C%EA%82%C8%82%E7%89%B4%82%C9%95%B7%82%AF&andor=AND&sf=0&H=&view=table&D=tech&shw=5000
959>>956:2008/06/01(日) 23:04:03
じゃあ俺が
960956:2008/06/01(日) 23:05:31
OKかな?
C言語なら俺に聞け(入門篇) Part 29
http://pc11.2ch.net/test/read.cgi/tech/1212329099/
961デフォルトの名無しさん:2008/06/01(日) 23:08:30
962デフォルトの名無しさん:2008/06/01(日) 23:31:35
急に静かになった
963デフォルトの名無しさん:2008/06/01(日) 23:56:55
スレ立てはえーよw
ギリギリまでたてないことがほとんどだし、1000まで行ってからたつこともよくあんのに。
964デフォルトの名無しさん:2008/06/02(月) 02:17:57
質問です
voidポインタから値を参照する時、意図した型のものかどうかを判定するにはどうしたらいいでしょうか?
965デフォルトの名無しさん:2008/06/02(月) 02:21:59
>>964
判定も何もvoidポインタでもらってきても
いずれ何らかの形でキャストしなおさない?
ということは判定も何もプログラム組む時点で
わかってるはずなんだけど・・・
966デフォルトの名無しさん:2008/06/02(月) 02:23:30
元がどんな型だったのかを void ポインタから知る事は出来ない。
967965:2008/06/02(月) 02:24:11
hogeという構造体の定義があって

hoge *wp = malloc(sizeof(hoge));

これはキャストを明示してないけどね。
968デフォルトの名無しさん:2008/06/02(月) 02:26:10
明示してないだけで暗黙にキャストが発生してる
969デフォルトの名無しさん:2008/06/02(月) 02:29:06
まあとにかくvoid *というのは大きさが無いポインタ、
位置だけを知っているポインタという意味だから、
大きさが無い=中身が無いわけで、
当然void *から値は参照できない
おわかり?
970964:2008/06/02(月) 02:40:54
用語を知らないのでよくわからない書き方になってすみません

例えばvoidポインタから構造体aとしてキャストして構造体内の値を参照する、というプログラムで
何らかの原因で構造体bのポインタが入っていた場合に
キャストする前にaかbかを判定する方法があるのだろうか、と思って質問してみたんです

voidポインタから直に型を判別する方法は無いので、その点注意してプログラムを組む、ということでいいでしょうか?

あと、voidポインタ使用時に、これには気をつけろ!なんていう点があったら教えてもらいたいです
971デフォルトの名無しさん:2008/06/02(月) 02:42:19
ない。
キャストは全面的にプログラマの責任で行わなければいけない。
972デフォルトの名無しさん:2008/06/02(月) 02:45:17
>あと、voidポインタ使用時に、これには気をつけろ!なんていう点があったら教えてもらいたいです
第一に、できるだけvoidポインタなんか使わずに済ませることを考える
第二に、それでも使わざるを得ないなら必ず何のポインタから変換したのかを確実に把握できるようにする

あとは普通のポインタと同じ
973デフォルトの名無しさん:2008/06/02(月) 02:51:25
>>970
> voidポインタから直に型を判別する方法は無いので、その点注意してプログラムを組む、ということでいいでしょうか?
それでいいよー。
a、b、どちらも指す可能性があるポインタを使うと便利な場面はあるので
きちんと把握して操作することを心がけましょー
974デフォルトの名無しさん:2008/06/02(月) 02:52:47
>>970
もし、void *が指しているオブジェクトが構造体で、
しかも来る可能性のある構造体がなんなのかわかっていて、
かつその構造体の定義に手を入れることができるなら、
先頭要素に共通のフラグを埋め込むことで
(たぶん、まずint *にキャストして値を調べることで)判別できる

でもそんなことやるくらいなら素直にもうひとつ変数を用意して
そこに型の情報を示す値を入れてvoid *と一緒にやりとりしたほうがいい
975デフォルトの名無しさん:2008/06/02(月) 03:23:57
>>964
その程度のレベルでvoidポインタを扱うのは早すぎるんじゃないか?
976デフォルトの名無しさん:2008/06/02(月) 07:38:50
考え方としては、void*とセットで型に関する情報を伝播させればいい
ただしCはそれ手動な。やりようはいろいろだが、自前だ
977デフォルトの名無しさん:2008/06/02(月) 07:49:30
Javaでいうところのinstanceofが欲しいのだろうが、あれはすべてのクラスの親にObjectが存在して
ガーベジコレクションを使ってるからこそ実現してることだしな
MFCなんかだと、方法はなくはないが、そういう余計な処理がないからこそ、Cが高速であるとも言える
まー、原始的に伝えるしかないわな
enum {type_int, type_float};みたいなのを引数で渡すのが無難だろう
978デフォルトの名無しさん:2008/06/02(月) 12:33:09
>>970
void*のまま使おうと考えずに、mallocしたらすぐ適当なstructにキャストしよう。
その上で型を判断しよう。
例:
typedef struct
{
int typeID;
}Base;

typedef struct
{
Base typo;
int piyoko;
}fuga;
979デフォルトの名無しさん:2008/06/02(月) 13:31:54
うめ
しないと誰も使わない感じだね・・・
980デフォルトの名無しさん:2008/06/02(月) 13:38:27
ではこちらで。

「配列がポインタに成り下がる」という言葉を理解するためには、配列が「二級オブジェクト」であるということを理解する必要がある。
二級オブジェクトであるとは、メモリ上に場所を持つけれど、それ自体は意味のある値を何一つ持たないということである。

比較のために、こちらは一級オブジェクトである構造体の話をしよう。構造体は、代入することもできるし、そのまま関数に渡すこともできる。
これは、その構造体型の値というものが、他のどんな整数やポインタ値とも比較も演算も変換もできないけれど、概念上存在するからである。

対して、配列はそのような値を持つということが規定されていない(できるできないの話ではない。持たないと決まっているということである)。
だから配列名は配列全体を意味し、よって sizeof を作用させれば配列全体のサイズが、& を作用させれば配列全体へのポインタが得られるけれど、
決して配列に代入したり、関数にそのまま渡すことはできない。代入する、あるいは引数にコピーされるべき値というものがなければいけないからだ。

しかしこれだけでは、配列の要素にアクセスするために、& 演算子で得られた値を更にキャストするという迂遠な手続きが必要となってしまう。
そこで規格は、上に挙げた配列全体を考える場合を除いて、「配列の名前はその先頭要素へのポインタ値に暗黙に変換される」ことにした。
これによって、現在よく知られている配列を扱うさまざまなスタイルが正当性を持つこととなり、容易に配列の要素にアクセスできる仕組みが確立され、
そしてこの動作は俗に「成り下がる」とか「意味が格下げになる」と呼ばれるようになった。

再度念を押しておくが、これは「キャスト」ではない。キャストとはある型の値を(可能なら)別の型に変換することである。
配列にはそもそも値がない。ないものをキャストで変換することは不可能である。

「成り下がる」とか「格下げ」という言葉が嫌いなら使わなければよい。だが、以下のようには決して考えてはいけない。
・配列はその先頭要素を指す定数ポインタである
・なにかの値を関数に直接渡すことが出来ないときは、代わりに自動的にポインタを渡すものである
981デフォルトの名無しさん:2008/06/02(月) 15:38:26
参考になるが、入門じゃないなコレw 仕事おわったら読み直してみよう
982デフォルトの名無しさん:2008/06/02(月) 15:48:16
その辺りはC++でテンプレートを弄っていれば判り易いんだけどね。
ロートルは、構造体でさえ代入不可だと思い込んでいたりするから困る。
983デフォルトの名無しさん:2008/06/02(月) 16:56:03
Cでは”配列型”という概念は無いYO
それどころか、実は”配列”という概念すらないYO
int a[234];と宣言すると、int型の234個の連続無名変数ブロックと
その先頭の読み出し専用ポインタ変数(事実上の定数)aが宣言されたことと等価になるYO

コードブロック内の[]はすべてポインタ値に対する演算子で、表現a[2];*(a+2);2[a];はすべて等価で、
同じ無名int変数を指すんだYO
984デフォルトの名無しさん:2008/06/02(月) 17:12:19
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[] );のような
書式は、初学者向けのサンプルコードでは使わないで欲しいと思うにゃ。
985デフォルトの名無しさん:2008/06/02(月) 17:17:05
>>983
その解釈において、sizeof(a)がどうなるのか説明してみてください。
986デフォルトの名無しさん:2008/06/02(月) 17:21:24
>>983
それならどのようなものを配列と呼ぶの?
struct で括れば満足?
987デフォルトの名無しさん:2008/06/02(月) 17:22:50
>>983
>>980と意見交換してたものなんですが、配列型はありますよ。
988デフォルトの名無しさん:2008/06/02(月) 17:24:12
読み手のレベルを意識しないオナニーレスが続いてるな
989デフォルトの名無しさん:2008/06/02(月) 17:25:00
初心者に対して正しくない言葉を教えるのはよくないよねって
ことでこうなってるんじゃないかなー
990デフォルトの名無しさん:2008/06/02(月) 17:25:47
まあスレウメとあわせていいのでは?
新規質問は新スレでやってるようですし
991デフォルトの名無しさん:2008/06/02(月) 17:39:30
>>985
sizeofも一種の組み込みマクロサービス
sizeof の引き数は、変数や型ではなく、識別子 (数値やリテラルを与えるのは無効)
どんな値になるのかは、コンパイラがそのコンテクストで決定できる。
多くの処理系では、識別子aが例え読み出し専用のポインタであっても、
int a[100];のような宣言書式で定義されていれば、sizeof(a)をsizeof(int)*100として
返してくれているみたい。
sizeof演算子を使うと、宣言に修正を入れた場合でも、コード修正は少なくてすむので
多用されがちであるが、やはりどのような値を返すのかは、チェックしたほうが良い
(コンパイラを神様と思わない。使用者が期待する値を返さない場合もあるかも)
992デフォルトの名無しさん:2008/06/02(月) 17:41:54
質問です

構造体定義をした際、コンパイラが勝手にサイズ調整のための
余分なエリアを入れないようにするにはどうすれば良いでしょうか?
993デフォルトの名無しさん:2008/06/02(月) 17:43:05
>>991
>sizeof の引き数は、変数や型ではなく、識別子 (数値やリテラルを与えるのは無効)

sizeof("Hello") って出来なかったっけ?
994デフォルトの名無しさん:2008/06/02(月) 17:46:43
>>993
sizeof(0)もできるね。
まぁ、
>(コンパイラを神様と思わない。使用者が期待する値を返さない場合もあるかも)
こんなこと書いちゃう>991に期待しちゃダメってことだね。
995デフォルトの名無しさん:2008/06/02(月) 17:48:55
sizeof(main)=1と出ました
このコンパイラはバカじゃないかと思いました。(某gcc)
996デフォルトの名無しさん:2008/06/02(月) 17:50:23
>>992
packの制御はコンパイラで違う
997gcc:2008/06/02(月) 17:51:58
>>995
関数のサイズを取得しようなんて馬鹿に言われたくないね。
998デフォルトの名無しさん:2008/06/02(月) 17:52:43
>>995
何のサイズを取得したんだと小一時間(ry
999992:2008/06/02(月) 17:52:58
>>996
これまたコンパイラ依存ですか・・orz

BMPファイルを出力するプログラムにヘッダなどを
必要な構造体を持たせてるんですがCygwin(gcc?)
でコンパイルするとずれるんですよね・・・
1000デフォルトの名無しさん:2008/06/02(月) 17:53:49
cはやっぱり規格に不備があるよね。
10011001
このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。