1 :
デフォルトの名無しさん :
2005/06/22(水) 19:12:51 BE:31057128-#
前スレ埋まっちゃったなぁ
3 :
デフォルトの名無しさん :2005/06/22(水) 19:48:51
pthread について質問です。 pthread_cleanup_push によってクリーンアップハンドラを登録します。 そのクリーンアップハンドラの中で、さらに pthread_cleanup_push を呼び出すことは許されるのでしょうか。 というのは、確保したリソースをクリーンアップハンドラで解放したいのですが、この解放処理に排他制御が 必要なのです。 排他処理には mutex を使っているのですが、pthread_mutex_lock の前に pthread_cleanup_push を行って pthread_mutex_unlock を登録しているのです。 いかがなものでしょうか?
>>3 >>1 標準Cではできない事の質問は使用している開発環境のスレへGo! (←ここ注目)
5 :
3 :2005/06/22(水) 19:57:59
>>4 おっと、失礼しました。
と言っても、pthread はどこのスレに行けばいいんですかね?
開発環境は vi で書いて gcc でコンパイルしてるんですが、GNU ってことでもないし・・・
もしよろしければ、道案内していただけれると助かります。
6 :
3 :2005/06/22(水) 20:01:01
>>5-6 =3
何故、質問誘導スレに行くと言う発想が出ないんだ?
10
11 :
デフォルトの名無しさん :2005/06/22(水) 22:57:58
早速質問です>< C言語をはじめたばかりであまりわからないのですが、 ビットシフトはなんの役に立つのでしょうか? 何卒、ご指導の程よろしくお願いしますm(_ _)m
>>11 始めたばかりの人間にはわからないような場面で役に立つ。
Cスレ風物詩となっちゃってるよ…
ファイルのディレクトリ選択をしたいのですが、もっと効率のいい方法を教えてください。 int main(void) { FILE *a; int dir; char fname[64],*str; char buf0[256]="C:\\Documents and Settings\\Dai\\My Documents\\C\\"; char buf1[256]="C:\\Documents and Settings\\Dai\\My Documents\\C\\test\\"; printf("どこに作成しますか?\n(0:C 1:test)\n--->"); scanf("%d",&dir); if(dir==0){ str=buf0; } else if(dir==1){ str=buf1; } printf("ファイル名を入力\n--->"); scanf("%s",fname); strcat(str,fname); if((a=fopen(str,"w"))==NULL){ printf("Can't open\n"); return 1; } fclose(a); printf("終了〜( ´∀`)\n"); return 0; }
>>15 効率って、どんな点での話をしてるの?
バッファを 2個も取って、メモリの利用効率が悪いから改善したいって話?
それとも、もっとお手軽な関数は無いのかって話?
細かいことだけど、そのコード dir が 0 でも 1 でもなかったら str が不定になって、具合悪いよ。
つうか環境依存なカテゴリーなんだが。
18 :
15 :2005/06/22(水) 23:36:03
>>16 すいません。
・バッファをなるべく減らしたい
・ポインタよりも効率のいい方法はないか
・ifの部分をもっと改善できないか
という点について教えていただきたいのです
あくまで「ディレクトリ選択」が目的なので例外処理は後回しです。
>>19 ディレクトリそのまま出さなきゃよかった。。。orz
>>18 バッファを一個にして、さらにスコープを細かく区切ってスタックの使用量を減らしてみた。
char buf[256] = "";
char *str = buf;
{
const char dirname = NULL;
do {
int dir;
printf("どこに作成しますか?\n(0:C 1:test)\n--->");
scanf("%d", &dir);
if(dir == 0) {
dirname = "C:\\Documents and Settings\\Dai\\My Documents\\C\\";
}
else if(dir == 1) {
dirname = "C:\\Documents and Settings\\Dai\\My Documents\\C\\test\\";
}
} while(dirname == NULL);
str += sprintf(str, "%s", dirname);
}
printf("ファイル名を入力\n--->");
scanf("%s",str);
{
FILE *a;
if((a = fopen(str, "w")) == NULL) {
printf("Can't open\n");
return 1;
}
fclose(a);
}
printf("終了〜( ´∀`)\n");
return 0;
22 :
21 :2005/06/22(水) 23:49:46
まちがった × const char dirname = NULL; ○ const char *dirname = NULL;
23 :
21 :2005/06/22(水) 23:51:57
さらに間違ってた・・・ × if((a = fopen(str, "w")) == NULL) { ○ if((a = fopen(buf, "w")) == NULL) { ショボいソースなのに何度も書き込むハメになって・・・ もうダメだ・・・
24 :
15 :2005/06/22(水) 23:59:23
>>21 ありがとうございます。
sprintfとconstはまだ勉強してないのでこれから調べます
>>15 int main(void)
{
FILE *a;
int dir;
char fname[2][256]={"C:\\Documents and Settings\\Dai\\My Documents\\C\\",
"C:\\Documents and Settings\\Dai\\My Documents\\C\\test\\"};
printf("どこに作成しますか?\n(0:C 1:test)\n--->");
scanf("%d",&dir);
printf("ファイル名を入力\n--->");
scanf("%s",fname[dir] + strlen(fname[dir]));
if((a=fopen(fname[dir],"w"))==NULL){
printf("Can't open\n");
return 1;
}
fclose(a);
printf("終了〜( ´∀`)\n");
return 0;
}
26 :
15 :2005/06/23(木) 00:09:35
>>25 おお
これならifも省けますね!
二次元配列を使う発想やstrlenの使い方も私の頭にはなかったです。
ありがとうございました。
>>25-26 dirが配列の範囲内かどうかのチェックをしないと駄目だろ。
28 :
15 :2005/06/23(木) 00:18:18
>>27 例外処理はelseなりwhileなりでできるので後回しなんです。
>>26 バッファを減らすという課題がクリアできてないね。
行数が減ればOK?
30 :
15 :2005/06/23(木) 00:54:22
>>29 >>21 さんと
>>25 さんのプログラムを参考に、両立できるようがんばってみます
ちなみに私的には
バッファ<単純化(≒行数削減)
です
どんな長さのディレクトリ名でも256バイト確保ちゃってるのはどうかと char *dir_list[2]={ "C:\\hoge\\", "C:\\hoge\\hage\\" } てな感じにしといて、 ファイル名と結合する為の専用バッファを1つ使うとメモリは減らせる でも、文字列コピーになるので、処理は重くなる
>>31 >>25 みたいに最初からバッファに展開しておくのだって、内部的にはバッファ上に文字列をせっせと作ってるわけだから、
そんなに軽い処理じゃないっしょ。
しかもデータ領域もコード領域も肥大化して、メモリ効率があんまり良くない。
処理系依存の話になるけど、linux に入ってた gcc で最初から文字列をバッファ上に展開しておく方のサンプルを
コンパイルしてアセンブラソースを吐かせてみると、オリジナルの文字列をデータ領域に持ちつつ、関数の入り口で
4バイト単位でスタック上に文字列をコピーがずらずら並んでて、さらにバッファの後ろを 0 でクリアする処理になってる。
mov がひたすら直列展開されてるからスピードは遅くはないんだろうけど。
そのコピーを無くしたいんなら、
>>25 でいうfname[][]を
単にstaticな配列にしておけばいいだけ
しかしみみっちい、つかどうでもいい話しとるな。
34 :
32 :2005/06/23(木) 01:53:59
>>33 そうすると
scanf("%s",fname[dir] + strlen(fname[dir]));
がいやな感じになりそう。
一度きりの実行ならいいけど、何度も呼ばれる関数だとダメだよね。
つか、みみっちい話なのには同意。
でも
>>32 は
>でも、文字列コピーになるので、処理は重くなる
についてのコメント
器が小さいからね。
もともと
>>15 の質問が「効率の良い方法教えて」
だったからね。
いきずまってます、助けてください。 2つの文字列(20文字以内)をキーボードから入力し、1つの配列にし、 printf関数の%sによって表示するプログラムを作成しなさい。(ポインタを使うこと) [実行例] str1 : Big str2 : City str3 : BigCity
>>37 #include <stdio.h>
int main()
{
printf("マルチ氏ね"
return 0;
}
41 :
デフォルトの名無しさん :2005/06/23(木) 11:55:32
char ary [] = {1, 2, 3, 4} int a; int形のaに整数型でaryを連結したものを入れるにはどうすればいいのでしょうか? a = 1234 のようになるようにしたいんです。
a = ary[0] * 1000 + ary[1] * 100 + ary[2] * 10 + ary[3];
43 :
デフォルトの名無しさん :2005/06/23(木) 12:28:29
x = 0; for(i=0; i<4; x=x*10+ary[i++]);
なんでわざわざ x=0 を外に出すのか
Cでcsvを使って大量にデータを扱うプログラムを書かないといけないのですが、 ● ● ● ● とデータを一度書き込んだ後 ●○ ●○ ●○ ●○ と横にデータをつけ加えていく方法はあるのでしょうか?
>>46 何がわからないんだ?ファイルに○を挿入したいの?
48 :
デフォルトの名無しさん :2005/06/23(木) 17:24:17
>>46 読んで書いていくしかないと思うよ
最初から○分の隙間をあけてあればよかったけど
49 :
デフォルトの名無しさん :2005/06/23(木) 19:12:20
サンプルプログラムの中に for(;;) というのが出てきたのですが、これは何なのでしょうか?
52 :
デフォルトの名無しさん :2005/06/23(木) 19:28:14
csvのデータを変数floatに格納したいのですがどのようにすればいいでしょうか? 3.23456,2.32,3.2213 2.322,2.2,3.3333 2.33,2.1,11.123 たとえばこの小数点を含むcsvのデータを float型の二次配列に代入したいということです float[0][0]には3.23546が float[2][1]には2.2が入ります。
>>47 数字のデータなんですが、1行1万列ぐらいで、20行ぐらいあるんです。
>>48 一度、配列に全部入れてから一気に書き
出そうとも思ったんですが、データ数があまりにも多くて・・・
>>54 あのな、「方法はあるのでしょうか? 」という質問だった筈だろ。
こんな場所でもちゃんとした回答が欲しいなら、ちゃんとした質問の仕方しろ。
>>54 コンピュータにとっては、一万くらい大した量じゃないだろ。
sizeof(float) * 10000 * 20 = 781 KB
for(;;)はコンパイラの最適化で消されますか?
>>59 質問の意味が分からんというか、何を期待してんの?
一意に消されるとは胃炎。つか普通消されるように書かねーよ。
returnの後とかな。
61 :
デフォルトの名無しさん :2005/06/23(木) 19:49:02
質問。 int a[100]; この場合、 「a」でポインタを取得できますが、このときのポインタの型は int (*)[100] ですか? よく、 int *p = a; とやりますが、これは、int(*)[100] が、 int*へ、暗黙の型変換されてい ると理解すればよいのでしょうか?
>>61 そうではない。
単純にint*になる。
int a[100][100]だと int (*)[100]になる。
単純に2次以上だと配列のサイズが型情報に入ると思えばよろしい。
63 :
デフォルトの名無しさん :2005/06/23(木) 20:02:37
>>53 scanfはファイルからカンマ区切りで読み込む機能がついているのでしょうか?
よくわかりません。
>>63 そーゆーのはmanとかgoogleとかで調べようね。
>>54 テンポラリファイルを使うってのはどうよ?
>>54 int newdata[]
に追加データが入っているものとする。
i = 0;
while ((c = getc(reader)) != EOF) {
if (c != '\n') putc(c, writer);
else {
printf(",%d\n", newdata[i++];
}
}
こんな感じでどうだ。無駄なメモリは一切食わん。
67 :
デフォルトの名無しさん :2005/06/23(木) 20:35:57
#include<stdio.h> #include<stdlib.h> #include<string.h> int main(void) { char buf[1024]; int len; float data; float num[2]; int i; FILE *fp = fopen("test.csv", "r"); if(fp == NULL){ printf("読み取り失敗です\n"); exit(2); } fgets(buf, 1024, fp); printf("buf=%s\n", buf); len = strlen(buf); data = atof(buf); printf("data=%.10f\n", data); fscanf(fp, "%f,%f,%f", &num[0], &num[1], &num[2]); for(i = 0; i < 3; i++) printf("num[i]=%f\n", num[i]); printf("test\n"); fclose(fp); return 0; }
しつれい fprintf(writer, ",%d\n", newdata[i++]); だな。
69 :
デフォルトの名無しさん :2005/06/23(木) 20:36:09
四苦八苦してなんとかファイルを一行ずつ読み出すことに成功しました。 しかし、これからどうやって変数に代入したらいいのかわかりません。 3.23456,2.32,3.2213 このデータからどうやってカンマ区切りの少数を3つ取り出せばいいのか…。
>>69 sscanf("3.23456, 2.32, 3.2213\n", " %f, %f, %f ", &boke[0], &boke[1], &boke[2]);
72 :
デフォルトの名無しさん :2005/06/23(木) 21:19:52
#include<stdio.h> int main(void) { float boke[2]; sscanf("3.23456, 2.32, 3.2213\n", " %f, %f, %f ", &boke[0], &boke[1], &boke[2]); return 0; } これを実行したらエラーR6002 floating-point support not loaded が出て動きません。 今までこんなエラー出たこと無いのですが…。
73 :
デフォルトの名無しさん :2005/06/23(木) 21:36:05
#include<stdio.h> int main(void) { float boke[2]; sscanf("3.23456, 2.32, 3.2213\n", " %f, %f, %f ", &boke[0], &boke[1], &boke[2]); printf("boke[1]=%f boke[2]=%f boke[3]=%f", boke[0], boke[1], boke[2]); return 0; } printfを用いて値を表示させるようにしたらエラーは出なくなるけど強制終了…。 なんでだろう…?
76 :
デフォルトの名無しさん :2005/06/23(木) 23:31:43
>>74 msdnが入っているのですが、読んでも専門用語だらけでなかなか理解できないのが現状です。
ヘルプを読解できるようになるためのサイトなどはないでしょうか?
>>75 ライブラリールーチンが無いのはわかったのですが
そもそもライブラリルーチンというものが何かわかりません…。
>>76 マジレスするならば、
馬鹿は去れ。馬の耳に念仏。
79 :
デフォルトの名無しさん :2005/06/23(木) 23:45:38
>>77 すみません。一日7時間程度やってるのに全然身につきません。
馬鹿なのはわかってます。
でも、やり始めたのだからある程度のレベルまでは行きたいんです。
>>78 定義ってヘッダファイルに記載されているやつじゃないんですか?
#include<stdio.h>で完了しているのでは。
リンクの先は読まない、理解しようともしない、説明も聞かない 最悪だな
とりあえずネットで検索するなり本を買うなりして 基礎からキチンと勉強する事をおすすめする 今までにでた単語を検索するだけで勉強になるぞ
82 :
デフォルトの名無しさん :2005/06/23(木) 23:58:11
>>81 そうですね。とりあえず検索のスキルを高めてみたいと思います。
本は図書館に行っていろいろ読んでいるのですが
難しいのばっかりでなかなか身につきません。
>>79 #include<stdio.h>の中に書いてあるのは関数の宣言。
.┌━┐ ┌━┐ ┃┌╋──╋┐┃ └╋┘ └╋┘ ┃ ・ ・ ┃ ┌━━┐ ●━╋┐ ┌╂━━━━╂┐ ┃ └━┷┴━━╂┘ └╋━┘ 同じスレにはコピペ ┌╋┐ ┌╋┐ できるけど、違う ┃└╋╋━━╋╋┘┃ スレにはコピペでき ┃ ┃┃ ┃┃ ┃ ない不思議コピペ ┃ ┃┃ ┃┃ ┃ └━┘┘ └└━┘
>>79 おまえが作ったプログラムから呼び出される printf だとか scanf だとかその他もろもろの関数ってのは、
その中身(=実体)を誰かがコーディングしておいてくれてるわけ。
おまえが作ったプログラムをコンパイルして実行ファイルを作ると、お前の作ったプログラムに
そのだれかが作っておいてくれたプログラムコードがくっつけられるわけ。
そのくっつけられる printf だとか scanf だとかの実体のことが、ライブラリルーチン。
ちなみに、そのくっつける処理のことをリンク、くっつけるプログラムのことをリンカって言う。
printf だとか scanf だとかは、おそらくおまえが書こうとしても書けないくらい複雑なルーチンで、マジメに作ると
そのプログラムサイズもそこそこ大きいものとなる。
そこで、一部機能を省略して、プログラムサイズを抑えた printf や scanf がある。
ここで省略された機能が、小数に関する処理。
%f だとかの小数に関することが指定されると、エラーを起こして終了するように作られてる。
おまえの環境では、普通にコンパイルして実行ファイルを作ると、この省略版のライブラリが使われるんだろ。
だから、おまえが小数を使ったプログラムを作ったならば、省略版じゃないほうのライブラリをリンクしてもらうよう、
コンパイルのときにオプションをつけて指定しなくちゃいけない。
その方法は、おまえの環境のマニュアルなりなんなりを読むと書いてあるだろう。
printf()作ろうとしても無理だから・・。と、言っているおれは自作の リエントラントなprintf()を制御系用途に持ってたりもするがな。
87 :
デフォルトの名無しさん :2005/06/24(金) 00:16:33
>>85 そんな難しい事言われても、さっぱりわかりません。
>>87 やる気はあるようだね。
若ければ(小〜高1程度)なら可能性はあるが、大学生以上だとしたらダメぽ。
オプションで/FPi87というのを有効にする必要があるってこと。
プロジェクト設定のどっかに「浮動小数点を使う」とかないかね。
それにしてもなんでそんな設定になってんだろうな。
>>87 は特殊な環境orターゲットでやってんのか?
x87が使えない
>>87 って、切ないな。
>>92 アホだ。finitされてないヨおじさん。
94 :
デフォルトの名無しさん :2005/06/24(金) 00:36:14
>>85 詳しい説明ありがとうございます。
なるほど、思った以上に複雑な構成になっているのですね…。
リンカというのは聞いたことがあります。
MSDNのライブラリ見て調べてみます。
>>87 中々わかりませんよね。一緒にがんばりますか。
>>88 大学4年です。研究で必要になったのでやり始めました。
…もう遅いですね。
オプションってすごい量あるんですね。
全部見ていってみます。
>>90 家ではVisualC++ 6.0ですが
学校ではVisual Studio .NET 2003を使っています。
ちなみに、R6002のエラーはどちらでも出ます。
ファイルの数値の読み取り方について質問があります。 そのファイル(data.txt)の中身としては 1 2 3 4 5 6 7 8 9 10 11 12 13 14 のように1行目は4列の整数データがあるのに 2行目は3列のデータ、3行目は5列のデータと、 行数によってまちまちの列数のデータがそれぞれスペースで区切られています。 このようなファイルから3列目のデータだけを 配列に格納していきたい場合はどのようにすればいいのでしょうか?
>>95 while (fgets(buf, sizeof(buf), fp)) {
sscanf(buf, "%*d%*d%d", array[idx++]);
}
char型で文字列を格納した配列がアルファベットかどうか1文字ずつ判断していく方法はありますか? isalphaはint型じゃないと無理なんで…
char c if((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')){ /* alpha */ } それかintにコピして比較
100 :
61 :2005/06/24(金) 01:43:39
>>97 isalphaの引数がintなのはEOFが引数としてきた時のこをを考慮してだ。
別にcharのをキャストして渡しても問題ない。
明示的にキャストする必要もないが。
101 :
デフォルトの名無しさん :2005/06/24(金) 01:48:17
#include<stdio.h> float boke[2] = {0}; int main(void) { boke[1] = 1.0;//浮動小数点を使ってやる。 sscanf("3.23456, 2.32, 3.2213\n", " %f, %f, %f ", &boke[0], &boke[1], &boke[2]); return 0; } いろいろ検索してみると浮動小数点を明示的に使ってやら無いとだめみたいですね。 こうやるとエラーが出ませんでした。 しかし #include<stdio.h> int main(void) { float boke[2] = {0}; boke[1] = 1.0; sscanf("3.23456, 2.32, 3.2213\n", " %f, %f, %f ", &boke[0], &boke[1], &boke[2]); return 0; } こうなるとコンソールがクラッシュします。 どちらも明示的に使っているはずなのになぜ?
102 :
デフォルトの名無しさん :2005/06/24(金) 01:48:46
他のライブラリとdefineがかぶった時はundefすれば回避できますが、 typedef した型名がかぶってしまった場合回避する方法はありますか?
エラーメッセージも言えねえのかよ
>>102 該当インクルードファイルをインクルードしない。
或いは問題のキーワードをマクロで置き換えてtypedefさせない。
#define → #include → #undef
すいません。エラーメッセージ書き忘れてました。 "0x0040117e" の命令が "0x01168124" のメモリを参照しました。メモリが "read" になることはできませんでした。 プログラムを終了するには [OK] をクリックしてください プログラムをデバッグするには [キャンセル] をクリックしてください コンパイルはできるみたいなんですが実行すると上のメッセ-ジがでます。
>>101 boke[2] は boke[0], boke[1] の二つしかないよ。
確保される場所が違うから片方で落ちたんだろうね。
>>102 無いかな。
とりあえず思いつかない。
#defineで誤魔化すようなことはできるけど。
>>104 sscanf(buf, "%*d%*d%d", & array[idx++]);
じゃないかな。
>>102 無い。
ダブらない名前をつけるしかない。
111 :
97 :2005/06/24(金) 01:58:17
う〜ん…isalpaでも大丈夫なんですか… 下みたいなプログラムを作ったんですけど、実行しようとすると強制終了してしまいます。 どこが悪いのか教えてください #include<stdio.h> int buf_check(int buf[],int str); main(){ char buf[64]; int str; printf("文字列を入力してください\n"); scanf("%s",buf); str=strlen(buf); if(buf_check(buf,str)==0){ printf("文字列の中にアルファベット以外の文字があります\n"); } } int buf_check(int buf[],int str){ int i; for(i=0;i<=str;i++){ if(isalpha(buf[i])==0) return 0; break; } }
>>105 なるほど。やってみます
ありがとうございました
113 :
デフォルトの名無しさん :2005/06/24(金) 02:00:47
>>111 int buf_check(char buf[], int str)
もう少し正しく書けば
int bun_check(const char buf[], int str)
115 :
96 :2005/06/24(金) 02:01:45
116 :
デフォルトの名無しさん :2005/06/24(金) 02:01:56
>>108 なるほど、存在しないboke[2]に値を入れたから落ちたんですね。
float boke[3] = {0};
にすれば解決できました。
しかし、グローバル変数にしたら存在しないboke[2]に値入れてもエラー出ないんですね。
バグの原因になりそうです。
>>115 %*d は勉強になりました。
ありがとうございました!
>>116 エラーが出ないのはたまたま。
意図しないメモリ領域を書き換えていることには間違いなくて、どんな結果を起こすか想像もつかない。
119 :
デフォルトの名無しさん :2005/06/24(金) 02:05:33
>>118 なるほど。気をつけないといけませんね。
120 :
114 :2005/06/24(金) 02:06:47
ありがとうございます! でも。書き直して英字の文字列を入力しても文字列の中に アルファベット以外の文字があるといわれてしまいます… #include<stdio.h> int buf_check(const char buf[],int str); main(){ char buf[64]; int str; printf("文字列を入力してください\n"); scanf("%s",buf); str=strlen(buf); if(buf_check(buf,str)==0){ printf("文字列の中にアルファベット以外の文字があります\n"); } } int buf_check(const char buf[],int str){ int i; for(i=0;i<=str;i++){ if(isalpha(buf[i])==0) return 0; } }
>>120 それコンパイル通る?
全部がアルファベットだった場合、その関数は return 無しに終了しない?
122 :
121 :2005/06/24(金) 02:12:32
コンパイルは通るんだな。 へぇ
>>120 forの条件が間違ってる
最後に非0をreturnしてない
124 :
120 :2005/06/24(金) 02:19:06
ありがとうございます! そういえばfor文の条件はi<=strじゃなくてi<strですね 書き直したら正しく動きました
>>124 問1
buf_check の第一引数に、const が付いている理由は?
先生にツッこまれる前に考えておいた方がいいよ
126 :
125 :2005/06/24(金) 02:31:49
う〜ん…内容が変わらない(変えられない?)からみたいな感じですか?
127 :
デフォルトの名無しさん :2005/06/24(金) 02:53:33
#include<stdio.h> #include<stdlib.h> #include<conio.h> int main(void) { float boke[1000][8] = {0.0}; char data[1024]; int i = 0; FILE *fp; if ((fp = fopen("test.csv", "r")) == NULL){ printf("Could not open file"); exit(-2); } while ((fgets(data, 1024, fp)) != NULL){ sscanf(data, " %f, %f, %f, %f, %f, %f, %f, %f " ,&boke[i][0], &boke[i][1], &boke[i][2], &boke[i][3], &boke[i][4], &boke[i][5], &boke[i][6], &boke[i][7]); printf("boke[%d][0]=%f \nboke[%d][1]=%f \nboke[%d][2]=%f \nboke[%d][3]=%f \nboke[%d][4]=%f\n" "boke[%d][5]=%f \nboke[%d][6]=%f \nboke[%d][7]=%f\n", i, boke[i][0], i, boke[i][1], i, boke[i][2], i, boke[i][3], i, boke[i][4], i, boke[i][5], i, boke[i][6], i, boke[i][7]); i++; } fclose(fp); return 0; } やっとこさCSVファイルからデータを読み込むプログラムのベータ版ができました。 しかし、fgetsの戻り値がなぜかファイルの終わりになってもNULLになりません。 ループから抜けられないでスキャンし続けてエラーになります。
あーいや、bokeをそのまま使って完成度高めてくとは・・・(笑 たぶん、最後に改行だけがあるんじゃないかな。 sscanfはスキャンに成功したフォーマットの個数を返すから、 それを拾って判定するべきかも。
129 :
デフォルトの名無しさん :2005/06/24(金) 03:19:41
while (1){ fgets(data, 1024, fp); if ( flag == EOF) break; flag = sscanf(data, " %f, %f, %f, %f, %f, %f, %f, %f " ,&boke[i][0], &boke[i][1], &boke[i][2], &boke[i][3], &boke[i][4], &boke[i][5], &boke[i][6], &boke[i][7]); printf("boke[%d][0]=%f \nboke[%d][1]=%f \nboke[%d][2]=%f \nboke[%d][3]=%f \nboke[%d][4]=%f\n" "boke[%d][5]=%f \nboke[%d][6]=%f \nboke[%d][7]=%f\n", i, boke[i][0], i, boke[i][1], i, boke[i][2], i, boke[i][3], i, boke[i][4], i, boke[i][5], i, boke[i][6], i, boke[i][7]); i++; } return 0; } sscanfならEOFがきちんと返ってきて正しく終了できました。ありがとうございました。 今後の課題は要素の数(この場合は8)が変わってもそれに応じて 変数の値を確保し、値を読むプログラムに完成度を高めて生きたいと思います。 bokeをそのまま使ったのはなんとなく語呂がよかったからです(苦笑
>>127 出来てきたね。
上達したかったら、例えばcsvの1列が100個ある場合とか、考えてみるといい。
いまのやり方だと無理がある。
プログラミングは常に「楽しよう」と思わないとダメ。
131 :
デフォルトの名無しさん :2005/06/24(金) 03:25:39
>>130 なるほど、プログラミングの負担が軽くなって楽になるように努力しろということですね。
なるべくコンパクトにまとまるように考えてみます。
仕事で大量のデータ使うならデータベースを使うけどな。
133 :
デフォルトの名無しさん :2005/06/24(金) 04:49:13
拡張子を指定して一時ファイル名を生成したいんですが 簡単な方法はありますか?
一時ファイル名を生成してから、拡張子を追加する
>>129 ちょっと待て。sscanf()の戻り値をチェックしたらその後fgets()する必要はないだろ。
136 :
デフォルトの名無しさん :2005/06/24(金) 08:37:07
変数の修飾の仕方で質問です。 次のような感じでいいんでしょうか? ポインタの指し示す先の値が volatile のとき volatile char *p; ポインタの値が volatile のとき char * volatile p; そして、 volatile char **p; のときは、どこが volatile になるでしょうか?
それでいい。 volatile char は char volatileと同じ。 修飾される。
138 :
136 :2005/06/24(金) 09:05:58
>>137 修飾されるか否かではなくて、どこが修飾されるかの問題なんです。
volatile char **p; … 1
char * volatile *p; … 2
char ** volatile p; … 3
みたいな書き方をしたとき、
3 は p そのものが、2 は *p が、1 は **p が volatile ってことでいいんですよね?
ようするに、volatile なメモリ領域を指し示すポインタの配列ならば 1 を、
volatile じゃないメモリ領域を指し示す配列の中身が volatile ならば 2 を、
volatile じゃないメモリ領域を指し示す volatile じゃない配列を指し示す volatile なポインタならば 3 を、
ということでいいんでしょうか?
139 :
136 :2005/06/24(金) 09:12:11
関連して質問ですが、main のプロトタイプを void main(int argc, char **argv) と書いたりしますが、より適切には void main(int argc, const char * const *argv) になったりしますか? また、 void main(int argc, char argv[][]) の書き方を同様に修飾するなら、どんな書き方になるんでしょうか?
140 :
デフォルトの名無しさん :2005/06/24(金) 09:30:17
文字列の連結関数についての質問です。 strcat() は自動的に領域を割り当てないということで、 以下のようなコードを書いて見ました。 これって、 1. C言語的に間違ってないでしょうか? 2. 普通はどうやるのが適切なんでしょう? みんなが普通にやりそうなことなので、 サンプルを探したのですが、 あらかじめ領域を確保してるやりかたしか みつけられませんでした。 ソースは後述 ↓
141 :
140 :2005/06/24(金) 09:31:04
#include <stdio.h> #include <stdlib.h> #include <string.h> char* stringCatEx(char *pBaseString, char *pAddString) { if (pBaseString == NULL) { pBaseString = (char *)calloc(1, strlen(pAddString) + 1); } else { pBaseString = (char *)realloc(pBaseString, strlen(pBaseString) + strlen(pAddString) + 1); } pBaseString = strcat(pBaseString, pAddString); return pBaseString; } void endStringCatEx(char *pString) { free(pString); pString = NULL; } int main() { char *pString = NULL; pString = stringCatEx(pString, "aaaaa "); pString = stringCatEx(pString, "bbbb\n"); pString = stringCatEx(pString, "ccc ddd"); pString = stringCatEx(pString, "\neee"); printf("%s\n", pString); endStringCatEx(pString); return 0; }
142 :
137 :2005/06/24(金) 09:39:06
>>136 複合宣言子パーサを書いてみるとよくと分かると思う。
簡略して言うと、宣言は識別子を基点に右を優先して解析していく。
宣言は左側にあるから、修飾は後にされるわけ。
> void main(int argc, const char * const *argv)
そうだね、適切かもしれないけど、慣用と違うってことで違和感あるかも。
ポインタ使う時にわざわざconstポインタにしないといけないしね(キャストしてもいいが)。
> void main(int argc, char argv[][])
*と[]は等価ではないよ。↑は宣言としてはエラーになる。
[]はあくまでサイズ未定義の配列(の先頭アドレス)だから。
>>140 - 141
どうだろう、微妙だなぁ。
mallocされたバッファが前提条件になるし、
stringCatExではそれをチェックする手立てがない。
C言語的には間違ってないと思うけど、endStringCatExのpString = NULL; は意味無い。
効率上問題なければこれでいいと思う。
ポインタだけチェインしてって、あとで一気に割り当てて連結したり、
普通にオーバーしないくらいのバッファを予め割り当てたり、
いろいろやり方あると思うけどね。
143 :
137 :2005/06/24(金) 09:41:14
> 宣言は左側にあるから、修飾は後にされるわけ。 この言い方は撤回。 「宣言が左側にあれば、修飾は後にされるわけ。」というべきだったか。
>>141 第一引数の領域は malloc なり calloc なりでアロケートされるメモリ領域っていう前提でいいのかな?
それならそれでOKだと思うけど、後でその文字列領域をちゃんと free しないとだめだよ。
そして、もし間違って上記以外のポインタを渡してしまった場合、この関数がどう動作するか予測できなくなるよ。
145 :
140 :2005/06/24(金) 09:48:04
>>142 さん
お返事ありがとうございます。
C言語になかなか慣れないもんで、こんなレベルのソースです(はずかしや)
ポインタのチェーンで一気に割り当てってなんかよさげな気がしてきました。
ちょっとサンプルでも作ってみようかと思います。(わかるかなぁ)
146 :
144 :2005/06/24(金) 09:50:00
あっとごめん。ちゃんと free してるね。 ただ、endStringCatEx の中で pString = NULL; とやってるけど、呼び出しもとの pString が更新されるわけではないから そこに注意。 呼び出しもとの pString を更新したいならば、 void endStringCatEx(char **pString) { if(pString != NULL) { if(*pString != NULL) free(*pString); *pString = NULL; } } にして、呼び出し元もそれにあわせて変更、かな。
>>142 argvはアプリケーションに向けて可変の領域が割り当てられていることになっているので
constではない。実際、書き換えても不都合はない。
148 :
144 :2005/06/24(金) 09:55:12
ちょっと質問。 if(pString != NULL && *pString != NULL) { ・・・ } みたいな書き方って、意図した通りに動くことが保証される? この if だと、pString != NULL が成立しなかった時点で *pString != NULL は評価されちゃいけないし、 何らかの都合で pString != NULL よりも先に *pString != NULL が評価されてもいけないよね。 この辺のことは最適化と関係しそうだけど、C言語としての規定ではどんな感じなんでしょう? 自分はこういうときには if を 2段にして書いてたけど。
>>145 普通は、そこまで凝ったことして非効率にするより、個別に意識して書くことを選択するわけで……
そうそう、calloc()/realloc()の戻り値のチェックも忘れないようにね。
>>147 呼び出した側がどんなメモリ領域を渡したかではなくて、その関数がそのメモリ領域をどう処理するのかで
プロトタイプが決まるんじゃないいの?
const * な関数に const じゃない領域を渡しても問題無いし、キャストもいらないよね?
いや、main の由緒正しいプロトタイプが何かって問題はさておいて。
>>148 きちんと仕様くらい自分で調べられるようになろう。
&&と||については、只の演算子ではなく評価をショートカットできることが規定されているので大丈夫。
152 :
140 :2005/06/24(金) 10:06:07
>>149 さん
「個別に意識して書くこと」といいますと・・・(^^;
すいません。どんなことなのかわからないです・・・。
すっごく効率悪そうなので、
なんかいい方法はないのかなぁとは思ってるんですが。
なにせC言語の世界がまったく見えてないもんで・・・。
1. 最初はどれぐらいの情報(最終的なstringの長さ)になるかわからない。
2. stringは次々と追加していきたい。
というのがやりたいことなんです。
えーと、たとえばHTMLをC言語で動的に組み上げるみたいな。
153 :
137 :2005/06/24(金) 10:11:43
>>140 言っといてアレなんだけど、
「ポインタのチェーンで一気に割り当て」ってのも問題が無いわけじゃない。
alloc系呼び出し回数は少ないけど、例えばmallocで割り当てた領域の文字列を
チェインされて、どっか別の所で開放されてしまったら、
チェインを連結する時にメモリアクセス違反になるだろうね。
140さんのやつも、生でchar*を使うから問題があるんで、
うまくカプセル化すればそこんとこは問題ないと思うよ。
>>147 「問題ある」とは言ってないぞ。漏れは好きくないが。
#argvについて、もう一つ言えば、argv[argc」== NULLも保証されてる。
#ターミネートされてるんなら、argcは何のために・・・?
154 :
148 :2005/06/24(金) 10:12:25
>>151 ありがとう。
調べたいのはやまやまなのですが、その記述にどのような手順でたどり着くのか、キッカケが無いと見当を
つけるのもなかなか難しくて・・・
あつかましいながら改めて確認なのですが、式が && の左側から評価されることも保証されてるってことでOKですか?
つまりは、演算子の優先順位と結合規則順に式が評価されることは保証されるのか?と言うことなのですが。
155 :
154 :2005/06/24(金) 10:16:33
&& と || は特別的な扱いというならば、おそらくその評価順は保証されてるんでしょうね。 むしろ == なんかの方が気になってきました。 個別の回答よりも、もしよろしければ仕様へのポインタを示していただけると大助かりです。
シンプソン法で積分を求めるプログラムを書いてみようと思い, マクロの復習をかねようということで,マクロ関数を用いて 以下のソースを書いてみたのですが 57行目で構造体の要素がどれも定義されていないと怒られます. いろいろと調べ,考えたのですが解決できませんでした. どなたか何が原因か教えてください!! ソース ↓
阻止
>>143 うーん・・・
その言い回しを理解するのにはちょっと時間がかかりそうです。
宣言が左にあれば、修飾は後ということは、
char * volatile *p;
は、volatile はその左の char * を修飾しているということになりますか?
そうだとすれば、char * 自体が volatile で、p はそのポインタを指し示すポインタ、ということになるわけですか。
じゃあ
volatile char **p;
と
char ** volatile p;
の読み方はどんな感じになるんでしょうか?
#include <stdio.h> #define hantei 0.0001 #define ABS(num) ((num)>=0 ? (num) : -(num)) #define Odd_Even( c ) {\ c->odd = 0;\ c->even = 0;\ c->y0 = (*f)(a);\ c->y2n = (*f)(a + n * h);\ for(i = 1;i < n;i+=2) {\ c->odd+=(*f)(a + i * h);\ }\ for(i = 2;i < n - 1; i+=2) {\ c->even+=(*f)(a + i * h);\ }\ } #define total(c) (( c>-y0 + c>-y2n + 4.0 * (c>-odd)+ 2.0 *( c>-even)) * h / 3.0) double myfunction( double ); double simpson(double, double, double (*) (double));
typedef struct Menseki{ double y0; double y2n; double odd; double even; }menseki; main() { double a, b; scanf("%lf", &a); scanf("%lf", &b); simpson( a, b, *myfunction); } double myfunction(double x) { return(1.0/x); }
161 :
156 :2005/06/24(金) 10:28:33
うぎゃー 阻止されてしまいましたw 159と160がソースですので よろしくお願いします
>>153 malloc なんかは呼出回数が少ないに越したことは無いんだけど、realloc は多少何度も呼び出しても
差し支えないんじゃないかな。
できるだけコストがかからないよう、メモリ領域が移動しないように再割り当てしてくれてるんだから、
ユーザー側で実装を複雑にするよりも、そういう機能を積極的に活用した方がメリットが多そう。
164 :
156 :2005/06/24(金) 11:05:48
>>163 わかりづらくて申し訳ありません.
S2 = total(men);
としてマクロ関数を呼び出しているところです.
なお,ここをコメントアウトすると今度はこの下で
同じマクロ関数を呼び出すところで同じエラーがでるので
この関数に問題があるのではとおもっています...
よろしくお願いします
>>164 1. mem ではなくて &men を渡すべきじゃないか
2. マクロの定義において、c を (c) に置き換えるべきじゃないか
166 :
315 :2005/06/24(金) 11:37:56
続き double simpson(double a, double b , double(*f) (double)) { int n=2; int i; double h; double S1 = 0, S2 = 0; menseki *men; men = (menseki *) malloc(sizeof(menseki)); h=(b-a)/(double)2; Odd_Even(men); S2 = total(men); while( ABS(S2 - S1) >= hantei) { n*=2; h/=2; Odd_Even(men); S1 = S2; S2 = total(men); } printf("Intergral : %lf\n",S2); free(men); }
167 :
315 :2005/06/24(金) 11:39:17
>> 165 ごめんなさい 肝心の部分のソースを忘れてましたorg マクロの部分を書き換えて試してみます!
168 :
ktc :2005/06/24(金) 11:41:57
問2. 入力された文字列を連続して表示するプログラムを関数を使って作成せよ。 問3. 入力された文字列の文字を逆から表示するプログラムを関数を使って作成せよ。 やってください。お願いします。
>>168 >>1 > ソース丸投げ、宿題、書籍 は専門の別スレがあるのでそこへさようなら。
死んでください。
170 :
ktc :2005/06/24(金) 12:04:09
できないから死んでとかいうん?
171 :
143 :2005/06/24(金) 12:14:49
>>158 ここで複合宣言子の規則について詳細に書くつもりはないが、
char * volatile *p;
は、左の char * を修飾している。そりゃそうだ。
volatile char **p はcharを修飾している。
char ** volatile p はchar**を修飾している。
パース過程はこんな感じかな。
pは・・・
pはvolatile修飾された・・・
pはvolatile修飾された・・・へのポインタである
pはvolatile修飾された・・・へのポインタへのポインタである
pはvolatile修飾されたcharへのポインタへのポインタである
172 :
315 :2005/06/24(金) 12:16:42
>>165 やはりcを全て(c)に置き換えても同じエラーがでます...
あー何時間考えてもわからなーい!!
パット見、これが一番怪しいわけだが… ×>- ○-> でわ?
> できないから死んでとかいうん? m9(^Д^)プギャー
176 :
315 :2005/06/24(金) 12:48:08
>>173 おおおーー 正にそのとおりでした!
やっと頭痛の種が消えました
本当にありがとうございます
178 :
デフォルトの名無しさん :2005/06/24(金) 13:17:42
if(memcmp(buf1,buf2)==0) { } 上記の判定があるのですが、buf1に文字列ABCD buf2に文字列ABCがあったと します。今まではbuf1にbuf2が含まれていても、完全一致でも どっちでもよかったのですが、今回から完全一致にしないといけなくなりました どうしたら良いですか?
>>178 memcmpにはもう一個引数があった筈だが。
なんで strcmp 使わないんだ、っつー話ですな。
181 :
デフォルトの名無しさん :2005/06/24(金) 13:21:34
すみません。長さの引数わすれました。sizeof(buf2)がぬけました
>>181 だから何故strcmp()を使わないのかと。
183 :
デフォルトの名無しさん :2005/06/24(金) 13:27:13
strcmp使います。ありがとうございました。
なんかワラタ
おもしろいw
>>177 できるだけコストがかからないよう、メモリ領域が移動しないように
~~~~~~~~~~~
187 :
186 :2005/06/24(金) 13:37:04
あれ、あらためて man を引いてみたら、“できるだけ”ですら移動しないなんて書いてないな。 スマソ この実装について前になんかのドキュメントで読んだ気がするんだけど、気のせいだったかな。
>>187 仕様で「できるだけ〜」とか書いても意味無いから。
もちろん、大抵の実装においてはあまり移動しないようにしてるだろうけど。
>>186 規格やmanがどうあれ、実際がどうなのか試してみたほうが実際的じゃね?
int main(void)
{
char *p;
printf("%p\n", p = malloc(sizeof(p)));
printf("%p\n", p = realloc(p, sizeof(p) + 10));
printf("%p\n", p = realloc(p, sizeof(p) + 20));
printf("%p\n", p = realloc(p, sizeof(p) + 30));
printf("%p\n", p = realloc(p, sizeof(p) + 40));
return 0;
}
案の定、途中で別のmallocとかはさむとアドレス変わるようだね。
まぁしかし、漏れのWinでは出来るだけ移動しないよう、必死にしがみついてるようにみえる。
190 :
初心者 :2005/06/24(金) 13:59:19
C言語をやる時ってお金かけなくてもできますか?
できます。
>189
同じく linux でこれやってみた。
void main()
{
void *p1 = NULL, *p2 = NULL;
int i;
for(i=0; i<100; i++) {
printf("%p %p\n", p1=realloc(p1, i*100), p2=realloc(p2,i*100));
}
free(p1);
free(p2);
}
できるだけ移動しないようがんばってる。
でもこのことに強く縛られるコーディングは、環境依存になっちゃうかな。
やっぱ規格に無いことを仮定するわけにはいかないかな。
とは言え、普段は realloc はできるだけメモリ領域を移動させないようがんばってくれてる、として扱っちゃってるけど。
>>190 本くらいは買った方がいいかも。
コンパイラなどはタダで手に入る。
193 :
デフォルトの名無しさん :2005/06/24(金) 14:38:18
こんなとき dataTable の 配列の数を取得する関数なんてないでしょうか? この場合は KOUZOUTAI の配列3つなので、「3」 を返すようなものです。 struct KOUZOUTAI{ char *hoge; char *hage; }; struct KOUZOUTAI dataTable[] = { {"aaa", "aa"}, {"bb", "bbb"}, {"c", "cccc"}, };
つsizeof(dataTable)/sizeof(dataTable[0])
試してないけど、これでどうだろう sizeof(dataTable)/sizeof(*dataTable)
196 :
デフォルトの名無しさん :2005/06/24(金) 16:41:27
すみません。おしえてください。 結果をリダイレクトする為にCソースコード内で テキストに追加モードで結果出力するコードを書きたいです。 ストリーム?とかいう言葉を耳にした事はあります。 できればUNIXでもWindowsでコンパイルしても有効な方法がいいと思ってます よろしくお願いします。
.┌━┐ ┌━┐ ┃┌╋──╋┐┃ └╋┘ └╋┘ ┃ ・ ・ ┃ ┌━━┐ ●━╋┐ ┌╂━━━━╂┐ ┃ └━┷┴━━╂┘ └╋━┘ 同じスレにはコピペ ┌╋┐ ┌╋┐ できるけど、違う ┃└╋╋━━╋╋┘┃ スレにはコピペでき ┃ ┃┃ ┃┃ ┃ ない不思議コピペ ┃ ┃┃ ┃┃ ┃ └━┘┘ └└━┘
198 :
デフォルトの名無しさん :2005/06/24(金) 16:42:40
sin(x) = x - x3/3! + x5/5! - ...を計算ができません。 教えてください!
201 :
デフォルトの名無しさん :2005/06/24(金) 16:46:48
>>200 テイラー展開ってどうすればいいでしょうか?
まだ、はじめたばかりなんで全然わかんないんです。
203 :
デフォルトの名無しさん :2005/06/24(金) 17:31:48
スペースで区切ったいくつかの文字列を一気に入力して、それぞれの文字列を 二次元配列に格納するにはどうすればいいんでしょうか?全然わかりません・・
.┌━┐ ┌━┐ ┃┌╋──╋┐┃ └╋┘ └╋┘ ┃ ・ ・ ┃ ┌━━┐ ●━╋┐ ┌╂━━━━╂┐ ┃ └━┷┴━━╂┘ └╋━┘ 同じスレにはコピペ ┌╋┐ ┌╋┐ できるけど、違う ┃└╋╋━━╋╋┘┃ スレにはコピペでき ┃ ┃┃ ┃┃ ┃ ない不思議コピペ ┃ ┃┃ ┃┃ ┃ └━┘┘ └└━┘
>>201 Cの話とは違う話だけど、
sin を微分すると cos、cos を微分すると -sin になる。
f' ってのは f を一回微分すること、f'' ってのは f を二回微分すること。
さらに sin(0) = 0、cos(0) = 1 を踏まえれば、式を解くことができるでしょ。
出来上がった式をループで表現するなりなんなりでがんばってみ。
というかなんで
>>198 が解きたくてテイラー展開(またはマクローリン展開)さえしらないんだ?
普通逆だろ。
宿題ばっかりだな
大学ならマクローリン展開は一年前期で習うわけだが 高専とかかな?
マクローリン展開をマクロ展開だけで計算しよう。 なんちゃって。
「ーリン」はどこへ?
画面にchをno回連続して表示する関数 void put_nchar(char ch,int no){・・・} を作成し、この関数を利用して平行四辺形を表示するプログラムを作成せよ。 実行結果 平行四辺形を作ります。 横幅:5 高さ:3 * * * * * * * * * * * * * * * 上の実行結果の例では、1行に*を5個表示する関数put_nchar()を3回呼び出す。 呼び出す時には実引数chには'*'を指定する。 ずれてるかもしれないけど、この問題教えてください
215 :
デフォルトの名無しさん :2005/06/25(土) 00:09:56
ところで、皆さんは、自宅でプログラミング打ってますか?自分、 プログラミングを家でやりたいと思っているんですが、どんなコンパイラが いいか知りたいんですけど、ちなみに、c言語です
217 :
デフォルトの名無しさん :2005/06/25(土) 00:38:14
216 見れないよ。
最近よくimeのサーバが止まるキガス…
>>217 URLをドラッグ&コピーしてブラウザに貼り付けるとイイよ。
([ショートカットのコピー]ではなく[コピー]で。)
>>150 余談だが、VCではconstを付けると落ちる。
>>223 え?
int main(int argc, char const * const argv)
とかいて、
**argvのなかをかきかえるとおちるということ?
なんで?
落ちないよ。
>>223 なんで落ちるんだろう?
手元の VC++ 6.0 で
#include <stdio.h>
int main(int argc, const char * const *argv)
{
printf("hello world! %d, %p\n", argc, argv);
getchar();
return 0;
}
を実行してみたけど、普通に動いたよ。
トレースして落ちる原因を探ってみたいね。
とゆうか、main()をどう宣言しようが それを呼ぶ側のコード(argvを確保してるコード)は変わらない んだから、ふつうに考えりゃおちるわきゃない
>>227 もしかしたらさ、もし C++ のコンパイラだったりすると、プロトタイプの違いで意図しない関数エントリにリンクしちゃったりして?
>223がトレースしてくれれば話は早い。
>>228 ああ、なるほど、type safe linkingならそうなりそうだが
C++であってもmain()の宣言が適当でも動くよな
なんでだろう
C言語で、fgetsに複数行入力できるような機能を追加したような 関数を作りたいのですが、どうすればいいですか。
fgetc()をループ
fgetsをループでいいんじゃ。。。
>>232-233 前に入力した行までback spaceで戻って修正する機能が
欲しいのです。
>>234 それは入力されるプログラム側ではなく、入力する端末エミュレータ側の問題。
なんだ、こういうことじゃないか #include <stdio.h> void *fgets_n(void *buf, size_t bufsize, int getlines, FILE *fp) { int i = 0; char *p = buf; if( p == NULL || bufsize <= 0) { return NULL; } if( bufsize > 2 && getlines > 0 && fp != NULL ) { int ch, line_cnt = 0; while( i < bufsize-1 && EOF != (ch = fgetc(fp))) { p[i++] = ch; if( p[i-1] == '\n') { if( ++line_cnt == getlines ) break; } } } p[i] = '\0'; return buf; }
>>236 どうもです。
これってどのようにして使うのですか。
fgets とおなじ。 一度に取得したい行数を引数getlineで指定。 あんまり、使い道はないかと思うけどw fgets にあわせるなら、こうだな。 #include <stdio.h> void *fgets_n(void *buf, size_t bufsize, int getlines, FILE *fp) { int i = 0; char *p = buf; if( p == NULL || bufsize <= 0 || fp == NULL || feof(fp)) { return NULL; } if( bufsize > 2 && getlines > 0) { int ch, line_cnt = 0; while( i < bufsize-1 && EOF != (ch = fgetc(fp))) { p[i++] = ch; if( p[i-1] == '\n') { if( ++line_cnt == getlines ) break; } } } p[i] = '\0'; return buf; }
>>238 どうもです。
やっぱりbackspaceで戻れないのは仕方ないみたいですね。
複数行の入力の参考にしてみますです。
そろそろビットシフトしていいですか?
遅レスじゃが
>>133 ANSI標準ではないが、mktemp()という関数があるから
ソース探して参考にしなはれ
なんだこの低レベルな遣り取り。 >236=238は>234も読めないらしいし、>234=>237は>235も読めないらしい。 そもそも1行内は編集可能なのはfgets()とは無関係だと判っていないのだろうか。
自分から低レベルとか言っといて 話に入ってくるなよw
>>243 低レベルだから入れるんじゃないか。
高レベルなら入る必要ないしね。
C言語は比較的低レベルな言語ですが?
まぁ文句は誰でもできるからな。 難しいのは誰もが納得する代案を提示することだ。
そこで織田信長ですよ
int 人間 = 50; if ( 人間 <下天のもの ) return like(夢, 幻); return NULL;
>>247 正直、織田信長を最初に知った時、
このネーミングセンスに驚いたよ。(w
>>223 そもそもargvは書き換え可能でなければならないわけだが。
>>250 それは main を呼び出す側に課せられた条件でしょ?
main の中以降で argv を書き換えないならば、const 指定しても問題ないはずじゃないの?
>>252 タイプ数を減らすことはオプティマイザが最適化するヒントを減らす以上に価値のあることなのか?
ヒント:エントリポイント
なぜか関数の一番初めにprintfを書いても それすら実行されずにsegmentation faultになります どなたかおたすけおぉぉ void klt_data() { D('z'); FILE *fp; char buffer[MAX_BUFFERSIZE]; char file_name[MAX_FILENAME]; double eigen_vector[MAX_IMAGESIZE][MAX_IMAGESIZE]; double eigenT_vector[MAX_IMAGESIZE][MAX_IMAGESIZE]; int dim_num,n; int x,y,i,j; D('z'); /* 固有ベクトルファイルのオープン */ printf("固有値ベクトルファイルの名前:"); scanf("%s",file_name); fp = fopen(file_name,"rb"); if(NULL == fp){ printf("その名前のファイルは存在しません。\n"); exit(1); } 以下続
あ Dはprintfですー
>>255 printf()の最初の引き数はなんでしょう。
あほかい。
#define D(a) fprintf(stdout,"-------------------debug %d--------------------\n",a) と定義してます. 途中でintとかもだせるように intにしいときました
>あ Dはprintfですー >#define D(a) fprintf(stdout,"-------------------debug %d--------------------\n",a) >と定義してます. >途中でintとかもだせるように intにしいときました 書いていることが矛盾だらけ。
>>261 あー、わかった。
標準出力はバッファリングされている可能性あり。
>>262 ごめんなさい まだCのことがよくわかってなくて・・・
printfじゃありませんでした fprintfです.
それとintもだせるように%dにしましたの間違いです
どうして一番初めすら実行されずにsegmentation faultになるのか
どうしてもわかりません
よろしくお願いします
>>255 その関数はなくて、他の部分に問題があるんじゃないのかな?
あと、MAX_IMAGESIZE と MAX_IMAGESIZE の定義はいくつくらいになってるの?
あんまりデカいと stack overflow するかも。
つーか、stack overflow のせいで segmentation fault が出てるのかも?
とうとうmallocを使う時がきたようだ。
>>263 すいません 知識不足で申し訳ないのですが どういう意味でしょうか?
>>265 その二つはともに1024です.
ひとつ思いあたるのは,この関数を呼び出す前にサイズが40000
の配列を用いているのでそれが原因でしょうか?
でも,この関数単体で実行させてもsegmentation faulltになります・・・
malloc・・・それは最後のフロンティア・・・
>>267 1024 * 1024 * sizeof(double) = 8MB
そういう配列が 2個もあるから、スタックに 16MB 以上のデータがあることになるよね。
スタックって有限だから、そのデータがスタックに収まりきらないんだよ。
malloc で確保した方がいいよ。
>>269 やっと理解しました ありがとうございます!
mallocはなんか難しいそうで敬遠していましたが
チャレンジしてみようと思います
最後のフロンティア・・・
恐ろしい
>>270 使うデータを構造体にして、それを一括で malloc すると便利じゃないかな。
typedef struct {
double eigen_vector[MAX_IMAGESIZE][MAX_IMAGESIZE];
double eigenT_vector[MAX_IMAGESIZE][MAX_IMAGESIZE];
} MYDATA;
みたいにして、
void klt_data()
{
FILE *fp;
char buffer[MAX_BUFFERSIZE];
char file_name[MAX_FILENAME];
MYDATA *data;
data = malloc(sizeof(*data));
}
こんなかんじ。
MYDATA のメンバに、関連する変数も一緒に入れておくといいと思う。
あと、malloc したメモリがいらなくなったら free を忘れずに。
>>270 >>263 標準出力はバッファリングされるので、printf()で毎回出力されるとは限らない。
エラーチェックの目的で使うなら、バッファフラッシュを行なうかバッファリングされないエラー出力を使うべき。
>>272 たいていは標準出力は改行でフラッシュされるようになってるはず
(標準エラー出力はとっととフラッシュされる)
>>271 どうも親切にありがとうございます.
そのとおりにやってみたところなぜかエラーが!
自分で考えてみようと思います
>>272 273
念のためstderrに出力するようにします!
>>274 必要なヘッダファイルが include されてないとか?
まあがんばれ。
276 :
デフォルトの名無しさん :2005/06/25(土) 18:55:03
int の二重配列へのポインタの定義方法について質問です。 typedef int ARRAY[4][4]; ARRAY *p; これはうまくいきます。 これを typedef を使わないで書きたいと思い、 int[4][4] *p; としたら、コンパイルでエラーとなりました。 どのように書くべきでしょうか?
#if (sizeof(wchar_t)==2) hoge() #endif みたいなことってできますか? wchar_t==2とint==4をやりたいのですが。。
すいませんhoge();ですね↓
>>277 automake/autoconf でも使えば?
>>279 ありがと!
int (*p)[4][4]; でイケました!
283 :
274 :2005/06/25(土) 19:12:35
>>275 >>271 何度も申し訳ないのですがやはりできません
いろいろと調べてためしに以下のようにして
コンパイルしたのですが
confllicting type for data等のエラーメッセージが出てしまいます...
typedef struct mydata{
unsigned int matrix[MAX_DATA_NUM][3];
unsigned char image1[MAX_IMAGESIZE][MAX_IMAGESIZE];
unsigned char image2[MAX_IMAGESIZE][MAX_IMAGESIZE];
}MYDATA;
MYDATA *data;
data = (MYDATA * )malloc(sizeof(MYDATA));
284 :
277 :2005/06/25(土) 19:13:26
280さん、ありがとうございます、調べてやってみます。
>>282 4x4 の int の配列を指し示すポインタが欲しいのですが、
>>279 で合ってますか?
>>279 だと添え字が一次元分しか指定できませんが、もう一つの添え字のサイズはいくつになるのでしょう?
また、
>>281 において
printf("%p\n", &(*p)[y][x]);
にて各要素のポインタを確認しましたが、正しい位置を示しています。
しかし
>>279 の方法では
printf("%p\n", &p[y][x]);
で同様のポインタを示しますね。
どう理解したらいいでしょうか?
>>285 君は一次元配列を指すときにどうやっとるのか
int a[N];
int *p = a;
だろ。ここには要素数の情報は無い。
二次元以上になって、要素数が必要になるんだが、Cの多次元配列ってのは
要するに配列の配列だったりするから、最後の配列の分だけは要素数が
要らない。それ以外の要素数がいるのは、その配列に格納する要素のサイズ
を知るのに必要だから。
>>283 confllicting type for data ってことは、data の定義がコンフリクトしてる、ってことだよね。
グローバル変数とかで data ってキーワードをなにかに使ってない?
とりあえず、その関数内の data っていう名前を別のに変えてみたら?
で、 int a[M][N]; int (*p)[N] = a; とすれば、 for (i = 0; i < M; ++i) for(j = 0; j < N; ++j) { p[i][j] = ...: } } のように、要するに普通に二次元配列を使うのと同じやりかたで使えるよ。
>>286 >288
あー、わかりました。
int (*p)[4] の 4 は、二次元目の 4 なんですね。
一次元目の 4 は特に指定する必要が無いと。
でも、sizeof(*p) は意図した値にはならないですね・・・
>>289 一次元配列を指すただのintのポインタから、配列のサイズは取れんだろ
それと同じ
291 :
:2005/06/25(土) 19:36:19
#include <stdio.h> #include <string.h> struct profile{ char sex[5]; char name[10]; char adress[100]; char telnum[20]; int old, height, weight; }; int main(void){ struct profile member[5]; int i; for(i=0; i<4; i++){ printf("プロフィールを入力してください\n"); printf("性別\n"); scanf("%s", member[i].sex); printf("名前\n"); scanf("%s", member[i].name); printf("住所\n"); scanf("%s", member[i].adress); printf("電話番号\n"); scanf("%s", member[i].telnum); printf("年齢\n"); scanf("%d", member[i].old); printf("身長\n"); scanf("%d", member[i].height); printf("体重\n"); scanf("%d", member[i].weight); }
292 :
:2005/06/25(土) 19:36:42
for(i=0; i<4; i++){ printf("プロフィールを表示します\n"); printf("性別:%s", member[i].sex); printf("名前:%s", member[i].name); printf("住所:%s", member[i].adress); printf("電話番号:%s", member[i].telnum); printf("年齢:%d", member[i].old); printf("身長:%d", member[i].height); printf("体重:%d", member[i].weight); } return; }
293 :
:2005/06/25(土) 19:37:38
コンパイルは通るんですが年齢を入力するとエラーが出ます なぜでしょうか?
>>290 たしかにそれはもっともなのですが、malloc するのに sizeof 一発でサイズが取れた方が便利ですよね。
というときには、
int (*p)[N][M] = malloc(sizeof(*p));
使うときには
*p[i][j] = xxx;
みたいに使うことになりますよね。
int (*p)[M] = malloc(sizeof(p) * N);
だとサイズの取得部分が煩雑な気もしますし、一方で
p[i][j] = xxx;
で使えるのはスマートだし、
うーむ・・・
scanf("%d, &member[i].old); 身長と体重も同様にな
296 :
:2005/06/25(土) 19:43:16
>>295 サンクスです。初歩的なミスですいません。初心者なんで
>>294 そもそも三次元配列を指すポインタで二次元配列を操作するのは型的に
正しくない。
int a[M][N];
int (*p)[M][N];
で、p = a;
とはできんし、p[i][j]と書けないのは、そういうこと。
malloc()うんぬんは、コードで言うとただの一行だけの問題だから、
瑣末な話と考えるが。
>>297 その辺の理解はできてきたつもり。
ただ、これは配列だからそういう数通りの書き方があって、その解釈をどうするのか、という問題になるけど、
たとえば structure の場合、
MYSTRUCT a;
MYSTRUCT *p;
で
p = a;
とはできないし、p.member とも表現できないのと同じなのではないでしょうか?
二重配列のメモリ領域を指し示すポインタと、二重配列そのものとして振舞うポインタとはちょっと意味が違って、
この辺はプログラマが意図に応じて定義を意味的に正しく使い分けるべきではないかと思いました。
それを踏まえて、自分のケースにおいてどちらが適切かよく考えてみます。
ありがとうございました。
# malloc の一行だけではなく、memcpy したり通信したりでサイズを取得する機会は多いです
299 :
274 :2005/06/25(土) 20:04:37
>>287 やはりdataの名前を変えても同じエラーがでます
ああ いったい原因はなんなのだろう!
>>299 とりあえず関数の変数宣言のところを一通り抜き出してみたらどうかな。
MYDATA *data って、関数のローカル変数なんだよね?
301 :
274 :2005/06/25(土) 20:42:51
>>300 今はグローバル変数として宣言してます
宣言部は以下のような感じです
#include<stdio.h>
#include<stdlib.h>
#define D(a) fprintf(stdout,"-------------------debug %d--------------------\n",a)
#define MAX_DATA_NUM 40000
#define MAX_IMAGESIZE 1024 /* 縦・横の最大画素数 */
#define MAX_BRIGHTNESS 255 /* 最大階調値 */
#define MAX_FILENAME 256 /* ファイル名の最大長 */
#define MAX_BUFFERSIZE 256 /* バッファ最大長 */
static int matrix_size;
typedef struct mydata{
unsigned int matrix[MAX_DATA_NUM][3];
unsigned char image1[MAX_IMAGESIZE][MAX_IMAGESIZE];
unsigned char image2[MAX_IMAGESIZE][MAX_IMAGESIZE];
}MYDATA;
MYDATA *data;
data = (MYDATA * )malloc(sizeof(MYDATA));
int x_size1, y_size1,x_size2, y_size2;
それはCのソースなのか? 関数の外側の宣言部で data = malloc(...) はマズいだろ 君はmain()を書かずに全部のプログラムを書く気か
>>301 そんなところに malloc 置いちゃだめだよ。
MYDATA をローカル変数にして、関数の中で malloc しな。
typedef はその位置でもいいけど、最初のグローバル変数宣言の前、#define 群の次くらいがいいんじゃないかな?
>>302 >main()を書かずに
その手があった!
今、お前のおかげで全然関係ない問題を解くことが出来そうだ
>>304 C++?制御系?それともWinMain()?(ワラ
306 :
274 :2005/06/25(土) 21:09:26
先ほどもお世話になったものですが またまた壁にぶつかってしまいました 1 1 1 1 1 1 1 1 1 のように数字が三つならんでいるファイルから数字を読み, それを配列にいれたいのですが,なぜか入っている数字を 出力すると2289044等のなぞの数字がでてきます どなたか落ちからぞえを. char buffer[MAX_BUFFERSIZE]; unsigned int matrix[MAX_DATA_NUM][3]; for(;i < matrix_size;i++) { if(buffer[0] != '#'){ fgets(buffer, MAX_BUFFERSIZE, fp); sscanf(buffer, "%d %d %d", &x, &y, &gray_scale); fprintf(stdout, "%d %d %d\n", &x, &y, &gray_scale); matrix[i][0] = x; matrix[i][1] = y; matrix[i][2] = gray_scale; } }
>>309 printf では、数値の出力時に渡すのはポインタじゃないよ。
変数につけた & を取ればよろしい。
>>310 うぐぅ ありがとうございます
馬鹿な間違いをしてすいません 先生
312 :
デフォルトの名無しさん :2005/06/25(土) 23:20:56
a>>bってどういう意味ですか?
>>312 aをbだけビットシフトするだなんてふざけるな!
いつからビットシフトすることになったんだよ!
314 :
デフォルトの名無しさん :2005/06/25(土) 23:27:25
ビットシフトですか!初めて知りました 「>>」はどっちにシフトするんですか?
>>314 直感的にこっちと感じる方向があるだろ。
だからビットシフト馬鹿を相手にするなって
318 :
デフォルトの名無しさん :2005/06/25(土) 23:34:49
お手数をかけました ありがとうございました
シフトだけじゃなくてローテートもあればいいんだけどなぁ・・・
>>315 >直感的にこっちと感じる方向があるだろ。
ところで、明日はどっちですか?
322 :
デフォルトの名無しさん :2005/06/25(土) 23:41:10
2分木を前順になぞって出力する関数は下のように書いたんですけど、 中順、後順でなぞって出力する関数はどういう風に書いたらいいですか? っていうか、プログラムのこの部分だけじゃ書けないですかね… void walkNode(stNode* lpSt){ /*2分木を前順でなぞっていくwalkNode関数の内容*/ printf("%c, ",lpSt->nodename); /*2分木の要素を出力*/ if(lpSt->left) walkNode(lpSt->left); /*子左側を再帰的に呼び出す*/ if(lpSt->right) walkNode(lpSt->right); /*子右側を再帰的に呼び出す*/ }
printfを1つ目のifの後においてみたり2つ目のifの後においてみたり してみ?
324 :
デフォルトの名無しさん :2005/06/25(土) 23:58:44
>>323 ありがとうございます!
へぇ…2つとも簡単にかけるんですね…。もう一回勉強しなおさなければ…
>>324 前順ってどんな順?
ついでに、中順、後順ってどんな順?
左の先端からが前順だとすれば、
>>322 のコードはおかしくない?
なんで、誰も突っ込まないんだ…
>>255 > void klt_data()
> {
> D('z');
> FILE *fp;
>
> あ Dはprintfですー
printf()の呼び出しの後に変数宣言は出来ないだろう。
327 :
C99 :2005/06/26(日) 00:18:34
できないCもあるな
出来ないほうが多いな。
問題の本質はそこじゃないからだれも突っ込まないんだろ。 コンパイルが通りませんって質問ならまだしも。
さっき妹がいるはずの居間に行こうとしたら電気カミソリの動作音のような音が聞こえて引き返してきたのですが、僕はこの後どうすべきでしょうか?
素っ裸で居間に乗り込み、小刻みにジャンプしながら「僕は能登真美子ちゃん!」と何度も叫ぶ。
334 :
デフォルトの名無しさん :2005/06/26(日) 11:15:45
ねぇもしかして ポインタをいったんNULLってしたら そのポインタにアドレス覚えさせることはもうできない? そんなんだとシュクダイ終わらないんだがどうしよっか?
なんだかよく分かりませんが、そんなんだと ジェダイだかシュクダイも終わりそうにないですね。
ポインタ変数のことなら、ほかにもうひとつポインタ変数を用意して、そっちにアドレスを保存しておけばいい。
337 :
354 :2005/06/26(日) 11:20:28
実際どうなの? けっこー困ってる ボーランドのフリーのやつ使ってんだが 動いてくれないんだよな
338 :
sage 334 :2005/06/26(日) 11:22:13
>336 即スレサンクス それ使って考え直しますわ
>>334 死んどけ。つーか、真面目に質問したいなら宿題スレか初心者スレにでも逝け。
340 :
デフォルトの名無しさん :2005/06/26(日) 13:45:25
データ表現としての2分木の長所って何かありますか? 自分が考えたのは、長男次弟方式による実現によって任意の木を2分木にできるっていうものなんですけど… 他に何かあったら教えてください
長所:とくになし 趣味:アニメ鑑賞、枝刈 血液:log型
342 :
デフォルトの名無しさん :2005/06/26(日) 14:11:02
C言語の本を読んでたらポインタのところで->という記号が出てきます。A->Bとか。これはどういう意味なんですか?
ポインタAの指し示すオブジェクトのメンバB
(*A).B のこと
>>342 構造体へのポインタから構造体のメンバを参照するときに使う。
(*A).Bと同じだとか書いていなかったか?
346 :
デフォルトの名無しさん :2005/06/26(日) 15:20:43
ソースコードを読んでてわからないので質問させてください。現在、libxcastのmember.cというライブラリを読んでいます。
以下の関数についてわからない点があるので、誰か教えてください。
/*
static int
Xcast6GetSrc(struct xcast_group *g, struct sockaddr_in6 *dst)
{
int fd;
int ret;
int i, found;
struct sockaddr_storage src, dstn;
struct sockaddr_in6 dstd, *sin6;
socklen_t len;
SOCKET_ADDRESS_LIST *psal;
DWORD alen;
fd = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP);
if (fd < 0)
return fd;
dstd = *dst;
dstd.sin6_port = htons(DISCARD_PORT);
ret = Xcast6NormalizeAddr(&dstd, &dstn, &len);
*/
変数"len"と"dstn"が初期化されてないまま使用されているのですが,これはどういう意味なんでしょうか?
オリジナルのソースはい次の場所にあります。
http://sourceforge.net/project/showfiles.php?group_id=30760&package_id=22808 僕自身のレベルは、UNIXのechoコマンドが読める程度と考えてください。
ご教授お願いします。
>>346 Xcast6NormalizeAddrの中で値を参照することなしに代入しているのではないだろうか。
引数で受け取ってるだけやん
349 :
デフォルトの名無しさん :2005/06/26(日) 15:33:40
346です 347,348さん、ありがとうございます。 すいません。Xcast6NormalizeAddrのなかをざっと検索したところ 関数内で初期化してました。 変数を宣言するだけだと、メモリに領域を取るだけで、その領域にはゴミがあるという 話を以前に聞いたことがあったので、なぜゴミを参照するのか疑問に思ったので質問させてもらいました。 こんな書き方あるんですね。 というか、あんがい普通だったりするんでしょうか? 今度からは、もうちょっと慎重に原因追求してから質問させていただきます。 本当に申し訳ありませんでした。
>>349 > というか、あんがい普通だったりするんでしょうか?
ごくごくふつう。
関数Aに変数Bのアドレスを渡したからといって
Aの中でBの値を参照しているとは限らないわけで、Bを更新しているだけなら
Bの値が初期化されていなくても問題ないわけだ。
そういうのをout引数と言ったりする。
351 :
349 :2005/06/26(日) 16:04:25
350さん、ありがとうございます。 out引数と言うんですか。 自分でも恥ずかしい質問をした(よく調べればわかるという点で)と思っているのですが またひとつ勉強になったので、得るものが大きかったです。 ありがとうございます。
まぁあれだ、VBやったことあるならByValとByRefの違いだな。
353 :
349 :2005/06/26(日) 17:22:31
そう言われるとよくわかります(笑)
355 :
349 :2005/06/26(日) 17:46:15
ソースまでいただけるなんて。 ありがとうございます。 これだけのことをしていただいたのですから 最後まであきらめずにコードを読みきりたいと思います。 本当に感謝しています。
>>356 とりあえずif文の無駄な{}を減らす。
n==0,1のときzいらねーし
>>358 ではどのようにすればいいのでしょうか?
質問文だけだったら pow 使って一発とか言ってしまいそうだ。 >if(n>=2) ここが else if になっていないところが分かっててやってんじゃないのか?という疑念を誘われるところだが、 for 文をこの前に持ってこい。 あと、abs だが (X)*-1 にするより (-(X)) にする方がいいんじゃないの?
>>356 こんなんでどう?
double pow2(int x, int n) {
unsigned int bit = 1 << sizeof(int) * CHAR_BIT - 1;
double a, result = 1.;
if (n > 0) a = x;
else {
a = 1. / x;
n = -n;
}
do {
result *= result;
if (bit & n) result *= a;
} while (bit >>= 1);
return result;
}
ひんと double pow2(int x, int n) { if(n<0) reutrn 1 / pow2(x, ?????); if(n==0) ?????; // if(n==1) ?????; // なくてもいい ????? }
double z=1; int i; for(i=1;i<abs(n);i++) z*=x; return (n>=0)?(double)z:(double)1/z;
return の (double) イラネ
365 :
356 :2005/06/26(日) 19:03:04
>>360 あとでforを挟もうと思って忘れてました;
absに関してはそうします。
>>361 unsignedとかsizeofとか知らないので調べつつ読んでます。
>>362 n==0,1はmain内で処理するということですか?
だとすると、関数ごとの役割が曖昧になるので嫌です。
>>363 >for(i=1;i<abs(n);i++)
こうすると私の環境では無理でした。
最後の行は参考にさせていただきます。
>>364 確かに"1/z"以外はいりませんね。
ありがとうございます。
366 :
デフォルトの名無しさん :2005/06/26(日) 19:24:14
掛け算 a×b (例)4×7=21 #include <stdio.h> int main(void) { char a,b,i,ans; a=4; b=7; ans=0; for(i=0;i<b;i++){ c += a; } printf("a×b = %d",ans); } ↑これを、ビット列を使ったコードに書き換えたいのだが… どうすればいいでしょうか?><;
367 :
361 :2005/06/26(日) 19:24:26
>>365 >>362 のアドバイスを基に改良
double pow2(int x, int n) {
unsigned int bit = 1U << sizeof(unsigned int) * CHAR_BIT - 1;
double result = 1.;
if (n < 0) return 1./pow2(x, -n);
do {
result *= result;
if (bit & n) result *= x;
} while (bit >>= 1);
return result;
}
>>366 > ビット列を使ったコード
これは具体的にはどういうこと?
370 :
↑訂正します :2005/06/26(日) 19:26:47
int main(void) { char a,b,i,ans; a=4; b=7; ans=0; for(i=0;i<b;i++){ ans += a; } printf("a×b = %d",ans); }
371 :
デフォルトの名無しさん :2005/06/26(日) 19:29:18
はじめまして。物凄く初心者なので、分からなかったので教えてください。 A.txtというファイルから2桁の整数を3回読み込んで、 fgetcを使って総和を求めたいのですが、10の位と1の位の区別ができません。 宜しければ、区別の仕方を教えてください。
372 :
356 :2005/06/26(日) 19:34:02
暫定的に↓のようになりました。
>>361 さんのコードを参考に又変えるかもしれませんが、ありがとうございました。
double pow2(int x,int n)
{
int n2,i,z=x;
n2=abs(n);
if(n==0)
return 1;
else if(n==1)
return x;
for(i=1;i<n2;i++)
z*=x;
return (n>=2)?z:(double)1/z;
}
fgetcを使って読み込むならばともかくも、fgetcを使って総和を 求めたいとは何事!
374 :
うんこプログラマ :2005/06/26(日) 19:35:59
>>368 >>370 は、掛け算を「*」を使わずに、「a を b 回 加算」して答えを求めています。
ですが、私は、これを、シフト演算を用いたコードに書き換えたいのです。
例えば、2×4は、00000010を左に2ビットシフトして、00001000と出来ますよね?
これを、例えば、4×7や5×3など、の計算もできるようにしたい。><;
377 :
デフォルトの名無しさん :2005/06/26(日) 19:40:44
>>373 すいません、説明がへたで。
fgetcで読み込んで、読み込んだ2桁の数字を
足していき、総和を求めたいという事です。
>>374 懲りずに失礼
#include <stdio.h>
#include <limits.h>
int mul(int a, int b) {
unsigned int answer = 0, bit = 1U << sizeof(unsigned int) * CHAR_BIT - 1, ua = a > 0 ? a : -a, ub = b > 0 ? b : -b;
do {
answer <<= 1;
if (ub & bit) answer += ua;
} while (bit >>= 1);
if (a > 0 && b < 0 || a < 0 && b > 0) answer = -answer;
return answer;
}
int main(void) {
printf("%d", mul(3, 7));
}
double pow2(int x,int n) { int n2,i,z=1; n2=abs(n); for(i=0;i<n2;i++) z*=x; return (n>=0)?z:(double)1/z; }
>10の位と1の位の区別 なぜしたいの?
381 :
356 :2005/06/26(日) 20:22:56
>>379 おお!
そんな方法があったんですね。
ありがとうございました!
382 :
デフォルトの名無しさん :2005/06/26(日) 20:28:24
計算して総和を出すとして、txtに35という数字があった場合 fgetcでは区別しなければ、計算できないと思ったからです。 他に方法があるのであれば教えて頂けませんか?お願いします。
384 :
デフォルトの名無しさん :2005/06/26(日) 20:35:25
>>382 さん
scanfは使わないでという事なんですが。
問題としてはtxtから2桁の数字を読み込んで、
それを宣言しておいた値に入れていき、全て読み込んだら
終了して、総和を出すという物なんですが。
本当にすいません。
宿題か?
>>371 /* 負の数は非対応 */
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int main(int argc, char **argv)
{
int ch, sum, n;
FILE *fp;
if( argc < 2 || NULL==( fp = fopen(argv[1],"r")))
{
perror("fopen");
return EXIT_FAILURE;
}
sum = n = 0;
while( EOF != ( ch = fgetc(fp)))
{
if( isdigit( ch ) )
{
n = n * 10 + ch - '0';
}
else if( n != 0 )
{
sum += n;
n = 0;
}
}
printf("総計 : %d\n", sum);
fclose(fp);
return EXIT_SUCCESS;
}
sscanf使え
389 :
デフォルトの名無しさん :2005/06/26(日) 20:46:02
宿題とは違うのですがC言語の勉強を始めて、ネットに こんな感じの問題があったのですが、PCを換えてたら サイトがもうなくて答えが分からないまま今の状態に なったというわけなんです。
390 :
デフォルトの名無しさん :2005/06/26(日) 20:49:25
>>387 さんありがとうございます!
それでためしてみます。本当にありがとうございます。
391 :
うんこプログラマ :2005/06/26(日) 21:20:46
今度からはその口調に見合ったHNにしてくれ。
393 :
デフォルトの名無しさん :2005/06/26(日) 21:31:04
C++を勉強すれば基本的にはCも身につけることができるの? それともまったく別物?
>>393 別物でもないけど自動的にってほどでもない。
C++からCの関数を利用する方法を知ってればさしあたり十分。
似て非なるもの。 まずはCの構文や、標準関数を一通り使えるようになってから、 C++ へ進むことをお勧めしておく
推奨されるアプローチが違う。
>>393 C89なら、100%じゃないけどC++のサブセット。
だから、C++を勉強すればCの仕様の大半は理解したことになるんだが
C++だけをやっていたのでは、そのサブセットの範囲、限界、差異といったものは
意識することが無いだろう。だから、Cもやってみないと、身にはつかないと
思う。ま、C++を理解したんなら、すぐだけどね。
>>393 まったく別物だと思った方がC++を勉強しやすいと思う。
399 :
デフォルトの名無しさん :2005/06/26(日) 21:45:19
そういや俺らが大学に行ってたころ(10年前)は Cさえ押さえれば、他の言語にも入りやすいからって理由で 全員必修として「C」+オプションで他の言語って形だったけど 今でもそうなのかね? 当時はJavaもなかったし、それが妥当だったのかも知れないけど
このスレのFAQまとめたようなサイトはないんかいな
>393なんてでまくってそうな質問に思えるが。
404 :
デフォルトの名無しさん :2005/06/26(日) 21:58:46
関係ないですけど、↓の問題分かりませんか? 100 PRG030 START 110 LD GR1,A 120 ADDA GR1,A 130 ADDA GR1,A 140 ST GR1,WK 150 ADDA GR1,WK 160 ST GR1,WK 170 RET 180 A DC 4 190 B DC 8 200 WK DC 1 210 END 実行後のGR1を16進数で記述せよ。 140,150行目を1命令で記述せよ。
>>403 FAQかもしれないが、唯一の正解のない質問だな
そういうのはFAQ向きじゃないと思われ
正解が一つかどうかは関係ないと思うがないのはわかった
>>404 それCASL?
ST GR1, WK
ADDA GT1,WK
ってことは、ようするに GR1 を 2倍するってこと?
C言語で文字定数の型がint型なのは何故ですか?
>>408 式の値を評価する際にはどうせintに拡張されるから
じゃまいか。
>>412 じゃあアフォの俺にもわかるように
おしえてけれ
EOFは文字定数じゃないと思うんだが
文字定数以外を表せないだろ
>>416 はぁ?
こいつ、むちゃくちゃ馬鹿だ
「文字定数の型」を問題にしているのに、「文字定数以外を表せない」
ことに何か問題があるのか?
>>416 は文字定数の意味を理解していないに100ペリカ
ドングリの背比べ
つーか、sizeof('a')とかやってみろって話。
で、推測じゃないちゃんとした答えは?
ある文字列を渡してその中の全角スペースを カンマ などに置換する関数を作りたいのですがどうすればいいのですか?
>>422 エスケープシーケンスで判断することになると思いますが、
文字コードに依存します。
>>423 EOFの事を言ってるなら
標準ライブラリの仕様に合わせるために言語仕様を決めたというソースは?
'abcd'と互換性保ちたかったんじゃないの?
X3010:2003(ISO/IEC 9899:1999)には 単純文字定数は、型intをもつ。 と定義されてあるそれ以上でもそれ以下でもない。
何故なのかと理由を問うているのに規格で決まっているからってアホですか?
よくわからんが、int型と定義したのには何らかの理由があったと思うんだけど。 直感的にchar型でも良さそうなのに。 実際、C++だとchar型と定義されていてC言語と定義が違うし。
charは符号(MSB)が未定義だから、符号付の場合、'ア'とかが負の値になって、 なんか知らないけど、困るんじゃね? 違うかな・・。
>>429 charやshort、それらのunsignedの右辺値は常にint/unsigned intに昇格される規則があり、
int/unsigned int未満の型の右辺値は存在しないことになっているから、
文字定数の型はは昇格済みの型のintにしたのではないかと思う。
C++で文字定数がcharになったのは関数の多重定義の都合上。(shortやcharなどの右辺値も存在する)
433 :
デフォルトの名無しさん :2005/06/27(月) 22:01:30
#include <stdio.h> void main() { int score[6]; int sangoukei; int goukei; double heikin; int i; char kyoukaname[][30]={"国語","数学","英語","公民","世界史","理科"} i=0; while (i<4) { printf("%c:",kyoukaname[i]); scanf ("%d",score[i]); sangoukei +=score[i]; i++; } while (i<7) {
434 :
デフォルトの名無しさん :2005/06/27(月) 22:01:41
printf("%c:",kyoukaname[i]); scanf ("%d",score[i]); sangoukei +=score[i]; goukei +=sangoukei+score[i]; i++; } heikin=(double)goukei/i; printf("3教科合計:%3d 全教科合計:%3d 平均値:%3d\n",sangoukei,goukei,heikin); } 12行目と26行目でコンパイルエラーです。 初めて3日。独学なので質問できません。。。 どうかナイーブに直しかたおせえてくらはい。
ソースが2つあって、 ソース1にデータAの中身を書き換えるプログラムを。 ソース2にはsleep( )で60秒間カウントするプログラムを作りました。 それでソース1を実行して、データAの中身を書き換えると ソース2のsleep( )が動くようにしたいのですが、どうしたらいいでしょうか?
>>434 まずはソース読め
質問する時は最低限エラーメッセージ書け
次に
>>1 を読め
そしてどっかいけ
>>433 12行目は宣言の終わりにセミコロンが無い。
残りはscanfを例えばこういう風に使ったことあるだろう。
int n;
scanf("%d", &n);
というわけでアドレス演算子を付けろ。
>>424 遅れましたがヒントありがとうございます。
440 :
433 :2005/06/27(月) 22:53:16
ありがとうございます。すまんです。
441 :
デフォルトの名無しさん :2005/06/27(月) 22:58:50
int aaa(int test[3][3]) { ・・・・ ・・・・ ・・・・ return test[0][3] } というようにリターンで配列を返すことってできますか?
>>441 test は配列だけど test[0][3] は配列じゃないよ
444 :
デフォルトの名無しさん :2005/06/27(月) 23:01:20
あ、違いますね test[0]を返すことが出来ますか? と聞くべきでした
aaaが返す型は配列ではないようだが。
>>432 それ本当?前半の規則については知っているけど
C言語では char の符号は処理系定義だからというのが
理由だと思ってた。
C++ の char は必ず符号ありだから
文字定数のサイズが1バイトでも問題ない
基本文字集合は必ずCでもC++でも正数だから
あー両方正しいのかな
447 :
441 :2005/06/27(月) 23:08:09
int aaa(int test[3][3]) { a=test[0][0]+test[0][1]+test[0][2]; b=test[1][0]+test[1][1]+test[1][2]; if(a>b) return test[0]; else return test[1]; } このようなことをしたいと考えています このように配列を返すことは可能ですか? で伝わるでしょうか
配列を返すってゆーか配列の先頭のポインタを返すってゆーか
>>446 今X3014を読んだが、C++でもcharが符号ありかどうかは処理系定義になっている。
C++で文字定数がcharになった理由はD&Eにそう書いてある。
>>441 int (* aaa(int test[3][3]))[3]{
return &test[0];
}
あえて書けばこうだけど、447を見る限りint *にしておくべき。
>>447 戻り値の型をintからint *にしてみろ。
453 :
446 :2005/06/27(月) 23:21:31
>>450 C++ でも char の符号は処理系定義だったのか…
嘘言ってゴメソ
「にそう書いてある」の「そう」は
>>432 のことね?
D&E本買おうかな…
ファイルをオープンする際に、 ファイル名を固定せずに、任意のファイルをオープンするようにはできるのでしょうか?
fopen(str,"w"); とか
>>455 その方法でできるんですか。
ありがとうございます。
457 :
408 :2005/06/28(火) 05:15:10
いろいろ教えていただきありがとうございます。 まだまだ勉強が足りないようです。 細かい仕様の部分の理解が足らないみたいです。
458 :
デフォルトの名無しさん :2005/06/28(火) 10:18:08
C言語の初歩の方の質問です。 int n1, n2; これはintn1,n2;では不可ですか? また、int n1,n2;ではどうでしょうか? スペースの使い方がよくわかりません。どなたか教えてください。
前者は不可後者は可 a-zA-Z0-9_はつながってると判断されるからintn1という一つの変数(識別子)とみなされてエラーになる。 だからスペースによる区切りが必要 n1,n2は間に , があるから区切られてるとみなされて別々の扱いになる。
>>458 たぶん
>>458 のintn1はたぶん間にTabがあるんだと思うよ。
判っていると思うけど
461 :
デフォルトの名無しさん :2005/06/28(火) 16:13:26
C言語の勉強をしていてソートを始める前にオーダで つまずいてしいました。そこで質問なんですが 関数f(n)を F(n)=1+3+3^2+3^3+・・・+3^n とする時、f(n)のオーダはO(3^n)である事を証明しなさい。 誰かおわかりの方教えて下さい。
sprintf( str,"%s\n", str ); これって危険?
>>461 対数を取って、定数項を消去して終わりだろ。
>>462 恐らく大丈夫だろうけれども、安全である保障はない。
strcat(str, "\n");
とか
sprintf(strchr(str, '\0'), "\n");
か
char * p = strchr(str, '\0');
p[0] = '\n';
p[1] = '\0';
とでもするのがいいのでは?
>>462 C99ではたしか引数にristrictが付いていた気がするからまずいと思う。
>>464 一番下違和感がある。それよりもchar *p = str + strlen(str);の方が見慣れた感じがする。
こんな単純なときなら迷わずstrcat()を使うけど。
466 :
デフォルトの名無しさん :2005/06/28(火) 16:51:50
ESC[x;yH のほかに、 画面に出力した行を戻るやり方ってありますか? XPでは出来ないみたいなんですけど。
>>466 厳密にやりたいならスレ違い。
同じ行で先頭に戻るだけでなんとかなるなら、'\r'を出力してみるとか。
独習Cが一通り終わって、一応C言語によるプログラミングが出来るようになった(?)ようなので RS-232Cを使ってリモコンだらけの自宅のホームシアターをパソコンで制御出来るようにしたい のですが、C言語でRS-232Cを制御するには一体どうしたら良いのでしょうか?
469 :
デフォルトの名無しさん :2005/06/28(火) 17:19:31
>>468 厳密にやりたいならスレ違い。
COMをopenして読んだり書いたりしてみるとか。
>>468 たいがいのOSではシリアルポートデバイス(WindowsならCOM1だとか)を開いて読み書きすることになるが、
ふつうはボーレート、スタート/ストップビット、パリティビット、etc....の細々した設定が必要になるんで、それだけじゃだめ。
で、その辺の設定の仕方は完全に環境依存。
double fact(double n) { return ((n == 0.0 ) ? 1: n * fact(n - 1.0)); } これの意味を教えてください (n == 0.0 ) ? 1: の部分がよくわかりません
>>472 それは三項演算子といって、if文みたいなもん
条件式?真の場合:偽の場合
みたいに書く
>472 蛇足だけど計算誤差があるから浮動小数点数で等値比較(==)するのは危険。 fabs(n) < 0.0001 とか -0.0001 < n && n < 0.0001 とか範囲比較する方が良いと思う。
イプシロン
477 :
デフォルトの名無しさん :2005/06/28(火) 22:27:18
1 abc 2 defg 3 hijk -1 **** 0 1 10 0 2 34 1 2 55 2 1 28 -1 -1 0 1 上のようなデータが書かれたdatファイルがあり、これをプログラムで読み込んで、 char型 x[****より上の要素の数(この場合3)][10] / ヽ. | a b c | x | d e f g | | h i j k .| ヽ. / int型 y[****より上の要素の数][****より上の要素の数] / ヽ. | 0 10 34 .| y .| 0 0 55 | | 0 28 0 | ヽ. / n = 1 (←一番下にあるデータ) のように配列に格納するようなC言語ソースファイルを作ってもらえないでしょうか?
宿題スレにいけばいいと思うよ
宿題スレではスルーされてしまったようで、さらに期限も迫っているので 申し訳ないと思いながらもこちらにも書かせていただきました
マルチはもっと嫌われるというのに。
481 :
468 :2005/06/28(火) 23:06:03
>>470 >>471 どうもありがとうございます。独習Cをやっただけじゃどうにもならないみたいですね。
482 :
初心者です :2005/06/29(水) 03:30:54
C言語に詳しい方、どうか助けて下さい。m(_ _)m 最近C言語に興味を持ち、『10日でおぼえるC言語入門教室』と言う本を購入し、 本書どうり試してみたのですが、 E2209 sample1.c 1:インクルードファイル’stdio.h’をオープンできない 警告 W8065 sample1.c 4:プロトタイプ宣言のない関数’printf’の呼び出し(関数 main) ***1 erros in Compile *** となってしまい、本書の3ページから進めず困ってます。(;´Д`A ``` bcc32.cfgファイルは、 -I"c:\Borland\Bcc55\include" -L"c:\Borland\Bcc55\lib" ilink.32.cfgファイルは、 -L"c:Borland\Bcc55\lib" 本書どうりやったのですが…。。。 私の¥2,200+税…。_| ̄|○ 出版社のHPに相談したのですが返信もなく、本当に泣き入ってます…。(ノДT)アゥゥ ちなみにsample1.cファイルは、 #include <stdio.h> main() { printf("Hello!"); return 0; } です。。。 C言語にお詳しい方、お教え頂けないでしょうか? pathの設定も、最後に;C:\Borland\Bcc55\bin加えました。 私には原因がわからないのですが…。。。 C言語にお詳しい方、助言お待ちしてます。。。m(_ _)m
>>482 -I"c:\Borland\Bcc55\include"
のパスは合ってるの?パスの意味が分からないなら、スレ基地外い。
bccは動いてるんだから bcc32.cfg.txtに一票
bcc32.cfg の内容を転記してるってことは、その本にはそのファイルの説明があったってことなんだろうな。 てことは、本をよく読めばどう設定すればいいのかも書いてあるんだろうが、その辺どうなの?
487 :
デフォルトの名無しさん :2005/06/29(水) 13:12:43
C言語で二つの整数値を読み込んで後者が前者の約数であれば BはAの約数です。と表示しそうでなければ BはAの約数ではありません。と表示するプログラム教えてください 二つの整数を入力してください。 整数A:12 整数B:6 BはAの約数です。 こうなるようお願いします なんか何回やってもうまくいかないんで
小学校の算数からやりなおせ。
どうやったか少しは晒してくれ。 判定はこんな感じでいいと思うが、どうか。 if (a % b==0){ scanfで&を忘れているみたいなオチを予想。
490 :
デフォルトの名無しさん :2005/06/29(水) 13:24:45
いや教えてくださいよ
492 :
初心者です :2005/06/29(水) 15:18:50
C言語にお詳しい皆様、ありがとうございました。m(_ _)m 出版社の方から、.cfgファイル付きの返信がきました。 自分の作った.cfgファイルの種類はテキストドキュメントで、送って頂いた.cfgファイルはCFGファイルでした。。。 出だしつまずきましたが、これから本ともと取れる様がんばります!(`・ω・´)シャキーン
494 :
デフォルトの名無しさん :2005/06/29(水) 16:10:24
ANSI C で 文字列(便宜上この表現)の操作を行いたいのですが、 なにか参考になるWebページ、ライブラリなどないでしょうか? ANSI Cだと、"string1" と "string2" の間の文字を切り出したい! みたいなのでも、結構冗長な処理になっちゃいますよね・・・
>>492 とりあえず真っ先に、
エクスプローラのメニューから「ツール」を選択
→「フォルダオプション」
→「表示」タブを選択
→「詳細設定」の中の「登録されている拡張子は表示しない」のチェックをオフ
しとけ。さもないと今後も同じような目にあう。
>>494 ポインタ操作、sscanf()、snprintf()、<string.h>の関数などを適切に使い分けろ。
ただしマルチバイト文字を適切に処理するのは面倒なので、
日本語はUnicode化してワイド文字で扱ったほうがラク。
Cで文字列を扱う際に、メモリ管理がどうしても面倒になる点は、あきらめるしかない。
alloca()でいい場所では積極的にalloca()を使え。ただし非標準なので移植性には欠ける。
後は、正規表現ライブラリを使うも良し。
UNIX系OSならばPOSIX互換のものが大抵利用できるはずだが、
他のOSにも移植されており有名なのは
GNUのregex、PCRE、鬼車などかな
マルチバイト処理を考えてお勧めなのは鬼車。
ワイド文字を扱えるのは俺の知る限りboostのregexだがこれはC++用ということになる。
いい加減すれ違いに構うなや。 bccなら専用スレがあったろう。
>>494 >494の例だとCじゃなくても複雑だと思うが、「s1文字列のm文字目からn文字をs2文字列で置き換える」
なんて処理はCでも数行で書けるから冗長だとは思わんがなぁ。
#難解かどうかは別。
C言語とC++とかの違いって何ですか?
>>499 C++は
Simula67風のオブジェクト指向とCの性能が欲しかった人が
「クラスつきのC」なるものを作ったのがはじまりで、
その後機能拡張しつづけてこんなに大きくなりました
みたいな言語です
ベースはCですが、その他にクラス、継承、テンプレート、参照、インライン関数、
演算子オーバーロード、などなどといった、よりリッチな機能を提供します
>>500 ありがとうございます。
これから始めるならC++の方がいろいろ利点がありそうですね。
>>501 まずはCから入った方がいいんじゃないかな。
Cの標準関数を一通り使えるようになってからC++をやってはいかが?
>>502 Cから始める場合でもBorland C++ Compiler 5.5を使えばよろしいんでしょうか?
C++やるのにCの知識が必須。 というのは嘘。わざわざ遠回りせずにC++をやるがよい。 C++やる場合BCCは古いのであまりお勧めできない。 学習用ならCygwinのgccを、ツールを作るならVC++のツールキットかMingWinがよい。
DigitalMarsもあるよ
504さんを否定する訳じゃないけど、いろいろ道はあると思うんだよね。 個人的にはCを一通りやってから、RubyやPythonなどの超高級言語をやった方が いろいろ経験できてよいんじゃないかと。 アセンブラを除けば最低級と最高級に近いものをかじるわけで、 その他のC++とかはその間に位置するわけだから。 単純にC++がやりたいんなら、そのままC++をやればいいんだけど、 プログラミングをやりたいんなら、いろいろ経験するほうがいい。
>>506 やっぱCから入った方が覚えやすい気がする。
単純にC++よりも覚えることが少なくていいと思う。
実用的な面からも、まだCでの開発は多いから、どこまでがCで、どこからがC++なのかということを把握できていいんじゃないかな。
おれは BASIC→アセンブラ→C→C++、Java、etc. の順だったけど。
おれはBASIC→C→アセンブラ→Perl、Python・・・かな。 実はC++は本読んだりしたけど、本格的に使ったことは一度もない。 高級スクリプト+Cの方がいい気がしちゃうんだよね。 仕事でやってるわけじゃないからだと思うけど。
printf/scanfよりcout/cinの方がわかりやすいとは思わないのかよ。 char配列/ポインタはstd::stringよりやさしいか?
言語を覚える順番なんて些細なことなんだから気にすんな。
>>509 わかりにくいけど、わかってしまえば問題を生みにくい
ってとこかな
512 :
デフォルトの名無しさん :2005/06/29(水) 19:16:54
アセンブラ使えないくせに、Cをやるのは無茶ですか?
514 :
501 :2005/06/29(水) 19:42:42
いろいろ助言頂きありがとうございます。 OSは98なんですが、Microsoft Visual C++ Toolkit 2003はサポートしていないそうです。 98で使っている方はいらっしゃいますでしょうか?
Win98でやろうとしたがそもそもインストール時にはじかれた。
>>509 ポインタはC++でも重要なポイントなんだから、それをキッチリ勉強する上で C は適材じゃないかな。
文字列(メモリやポインタ)の操作なんて、学ぶところが多いでしょ。
まあ、高水準言語らしく低水準な部分は極力触らないようにするってのもいいと思うけど。
>>514 Cygwin入れてgcc。
プログラミングに纏わる諸々の知識も身に付く代わりに敷居が高い罠。
つーか、言語相談でもコンパイラ相談でもスレ違いだ。
わざわざCを使わずともC++でポインタの勉強はできると思うが。 C++なら本質的でない部分で随分ラクができるし Cでしか必要でない下らないテクニックを覚える必要が無いし 手続き型的指向に染まってしまうことを回避できる std::stringとSTL使えるだけでも随分違う。自分でリストやツリーを 作る、といったことも一度はやってみたほうが良いが、それをCで やる必要はない。
strxx 系、 memxx 系の理解はポインタ、メモリ操作の勉強になる。 C++じゃ、便利なライブラリがある分、ダイレクトな理解の妨げになるかもしれない。 Cの主要ライブラリなんて、高々2、30程度なんだから、一通り見ておいてもたいした労力ではなかろ。
>>519 誰もlibcの関数を使うなとは言ってない
libcの関数はC++の関数でもあるのだから
言語としてCをわざわざ選択する必要が無いと言ってるだけだ
>502の言う、「Cの標準関数を一通り」は>519の言う「主要ライブラリなんて、高々2、30程度」とは違う気がする。 つーか、スレ違いだってばよ。
「XXではYYという便利な仕掛けがあるので、ダイレクトな理解の妨げになる。 ZZなんてたいしたことはないので、一通り見ておけ云々」 この構文を使えば、PASCALのようなキッチェなプログラミング言語を使ってる香具師を 批難したり、DMAの直接入力でOSを放り込んだりすることを今更勧めたり、 プログラマは皆量子力学を披露するべき、みたいな文章が簡単に作成できます。 キモは、何を指しているのかよくわからない、「ダイレクトな理解」。
「プログラマは皆アセンブラをやるべきだ」という主張ならわからんでもない 「Cをやるべきだ」という主張は正直中途半端で疑問が残る いまどきC++ではなくCでなければならない仕事って、そんなに多いか?
>>492 遅レスだがほっとけない。
うぃんどうずというもののべんきょうから
はじめましょうね、いいこだから。
だれもCじゃなきゃ出来ない仕事の話などしておらん。
もうそろそろその宗教論争止めませんか? 言語の使い方が人それぞれ違うんだし、 理論的にどっちがいいなんて導ける筈無いんだから。 ついでに言えば、かなりスレ違いだし(その論争専門のスレなかったっけ)。
すいません printfで浮動小数の%fで右寄せにするにはどうすればいいのでしょうか・・・ %f3.2みたいにしたんですがうまくできません・・・ 3.00 10.23 100.00 ↑ 揃ってないけどここで揃えたい
>>527 %3.2f の 3 の数字を、もっと充分な桁数にすればいいんじゃない?
とりあえず %6.2f はどうよ?
>>528 できました!!
あなたは私の恩人です!ありがとうございます!
キーボードから入力した任意のファイルを開く操作を以下のようにしたのですがcore dumpしてしまいます。 なぜでしょうか?お願いします。 void open_r(FILE *fp){ char *str; gets(str); if((fp=fopen(str,"r"))==NULL){ puts("E1"); exit(1); } }
突っ込みどころ違(ry
>>475 浮動小数点演算に必ず誤差があると思ってる奴はアホ。
誰が必ず誤差があると書いてるのか
537 :
530 :2005/06/29(水) 22:48:57
>>531 gets以外を使うとしたらどのようにしたら良いのでしょうか?
>>532 ちょっとmallocつかってやってみます。
fgetsをつかう。
malloc なんか使わんでも、 char str[256]; とかで十分だろ。 それ以前に、その関数open_rはどこから呼ばれるのか? FILEポインタはちゃんと渡されているのか?
541 :
530 :2005/06/29(水) 23:15:56
>>538 fgetsの場合は
fgets(str,256,stdin);
のような形でいいのでしょうか?
>>540 なるほど。
関数open_rはmainから呼ばれて
int main(void){
FILE *fp0,*fp1,*fp2,*fp3;
printf("読み込むファイルを指定してください>>");
open_r(fp0);
open_r(fp1);
・・・
のようになってます。
とりあえずfgetsつかってみます。
>>541 fgets(str, sizeof str, stdin);の方が配列の大きさを気にせず、機械的にこうすれば良いと覚えられるので楽。
でたw 一番アホなやり方ww バッファが溢れた場合誤動作してしまう最悪なコーディングwww バカ丸出しwwww
545 :
530 :2005/06/29(水) 23:25:16
>>541 ありがとうございます。プログラムの反応が明らかに違いました。
しかし入力ファイル名はa.txtなのですが、a.txtと入力したにも係わらずなぜか開けずE1と出力されます@@
ちなみに今のopen_rはこのようになっています。
void open_r(FILE *fp){
char str[256];
fgets(str,sizeof str,stdin);
//ファイルが開けなかったらE1
if((fp=fopen(str,"r"))==NULL){
puts("E1");
exit(1);
}
}
当然a.txtは実行ファイルと同じディレクトリおいています。
実行ファイルと同じディレクトリ==カレントディレクトリではないこともある。
>>541 open_r()で開いたファイルポインタをmain()に返してそっちで読み書きしたいなら
FILE *open_r(void)
のようにして、戻り値として返却するか、
void open_r(FILE**)
のようにして、ポインタ渡しにしなければダメ
>>545 fgets()で読んだバッファのケツには改行文字\nがついてるから
それを切り捨てろ
548 :
530 :2005/06/29(水) 23:28:21
>>539 ,544
すいません、見落としてました@@;
っということは上の結果がE1にいってしまうのは、
\nが入っているからということですか?
549 :
530 :2005/06/29(水) 23:30:08
なんとか解決しそうです。 ありがとうございます!
>534 確かに整数なら桁あふれしない限り正確に表現可能だな。悔い改める。
553 :
デフォルトの名無しさん :2005/06/30(木) 01:08:19
#include <stdio.h> void main(){ char a[20]; char *table[10]; int i,l; for(i=0; i<8; i++){ gets(a); table[i] = a;} for(i = 0; i<8; i++){ printf("%s\n", table[i]);} }
554 :
デフォルトの名無しさん :2005/06/30(木) 01:12:19
C:\Documents and Settings\Owner\My Documents\4>char.exe
ame //キーボード入力
ika
usi
ebi
oni
kame
kiri
kuri //キーボード入力終了
ame //出力
ika
usi
ebi
oni
kame
kiri
kuri
>>553 で↑のように出力されて欲しいのですが
実際はkuriが8回でて終わってしまいます。
どうしたら意図した出力結果が得られるのでしょうか?
char *table[10]; for(i=0; i<8; i++){ gets(a); table[i] = a;} ↓ char table[10][20]; for(i=0; i<8; i++) gets(table[i]);
>>555 スレタイ嫁
無意味なレスするくらいなら消えろ低学歴
>>557 無意味なレスするくらいなら消えろ低学歴
>>558 オウム返ししかできないようじゃやはり低学歴か
>>560 どうしたんだ?お前、大丈夫か?
学歴コンプレックス?なに真っ赤になってんの?
>>561 お前邪魔だから消えていいよ低学歴君
ここにいても役に立たないしな
暇人だな専門生よ
■■■荒らし注意報■■■ PC技術系板全般で粘着荒らしが猛威をふるっています。 正しくないことが明らかな意見を肯定し続ける、煽りに便乗して中身のないレスを連投するなど症状が見られますので、ご注意ください。
おまえらいい加減にせよ
質問に対して回答以外のレスをつけるやつが居るから荒れる原因になるんだよ。反省しろ。
>>567 どれの事だ?
どう見てもスルーできない馬鹿が原因だな
わざとであろうけれど
スルーしなければならないような屑カキコをするほうに問題があると思うが
急速にスレの質が低下してまいりました
スレの質、ってなんだ? 何が良なんだ?
572 :
痔々ぃ :2005/06/30(木) 06:40:57
なぜ構造化代入ができると思ったのだろう? 最近のプログラマは費用とか考えないのだろうか・・・
C言語で下のようなデータ列に y = a*x^6 + b*x^5 + c*x^4 + d*x^3 + e*x^2 + f*x + g という6次式に近似して、それぞれの係数a,b,c,d,e,f,gを表示するような 数値計算プログラムが組みたいのですが、曲線近似なんてしたことないので どうしたらいいのか分かりません。教えてください。 xy ─────── 21265 21366 21468 21568 21668 21768 21875 21992 220138 221202 222209 223211 224216 225219 226221 ───────
574 :
573 :2005/06/30(木) 17:15:10
すいません、データにスペース入れていませんでした。 x y ─────── 212 65 213 66 214 68 215 68 216 68 217 68 218 75 219 92 220 138 221 202 222 209 223 211 224 216 225 219 226 221
数学板向きかな。 3次なら兎も角、6次式ってかなり無理がある気がするけどね。 点数少ないし。
577 :
デフォルトの名無しさん :2005/06/30(木) 18:33:23
可変個引数を取るマクロの定義はできますか? やりたいのは、 MYMACRO(fmt, ...) を printf("%s(%d): " fmt, __FILE__, __LINE__, ...) みたいに展開することです。 MYMACRO("%s の点数は %d点です", name, pts); とやれば printf("%s(%d): " "%s の点数は %d点です", __FILE__, __LINE__, name, pts); というようにです。 なおこのマクロでは、展開の都合で fmt は文字列定数という制限が付くことになります。
>>577 無理。
類似品として、MYMACRO((...))でいいのならなんとかなる。
#つまり、フォーマット文字列から先を全部纏めて置換するわけ屋根。
579 :
577 :2005/06/30(木) 18:45:13
>>578 やっぱり無理ですか。
ところでその代替案は、つまり
#define MYMACRO(arg) printf("%s(%d): ", __FILE__, __LINE__); printf(arg)
と定義して、
MYMACRO(("%s の点数は %d点です", name, pts));
みたいに使うということですか?
580 :
577 :2005/06/30(木) 18:48:40
定義が違うか。 #define MYMACRO(arg) printf("%s(%d): ", __FILE__, __LINE__); printf arg ですね?
main関数の中でscanfを使って角度を入力させ、独自の関数の中で入力された角度をラジアンに変換したい んですが、どうすればいいんですか?
>>581 その通りにすればいいのでは?
それぞれのステップで何をすればいいのか判らないなら初心者スレへ、
丸投げしたいなら宿題スレへどうぞ。
printfの戻り値ってK&R見てたら「書き出された文字数」ってかいてあるけど snprintfでは「書き出すのに必要な文字数」であって「実際に書き出された文字数」ではないのですか? 例: r=snprintf(aBuff, 2, " %d", -987); で結果は r=5,aBuff={' ','\0',・・・} になるのですが・・・
585 :
デフォルトの名無しさん :2005/06/30(木) 22:05:43
586 :
デフォルトの名無しさん :2005/06/30(木) 22:50:22
XP上でVC++6.0で_beginthreadex を使えないんです。原因分かる方ヘルプゥゥ! もちろんprocess.hしてます。 ・・・・・コンパイラメッセージ・・・・・・ warning C4013: 関数 '_beginthread' は定義されていません。
588 :
デフォルトの名無しさん :2005/07/01(金) 00:02:36
二次元配列を動的に割り当てたくて、以下のようにしたのですが問題があります。 //p[3][4]っぽくしたい int **p = (int **)malloc(sizeof(int *) * 3); for(i = 0; i < 3; i++) p[i] = (int *)malloc(sizeof(int) * 4); このようにしたのですが要素のアドレス的な連続性がないです。(p[0][3]の次がp[1][0]になってない。) なので、 for(j = 0; j < 3; j++){ for(i = 0; i < 4; i++){ p[j][i] = i + (j*4); printf("%d, \n", *((*p) + i + (j*4))); } } のようにした場合に、p[j][i]に値は入るのですが、*((*p) + i + (j*4))では同じ位置を指してくれません。 p[j][i]も*((*p) + i + (j*4))も使えるように二次元配列を動的に割り当てることは出来るのでしょうか?
>>588 int (*p)[4] = (int (*)[4])malloc(sizeof(int) * 3 * 4);
Cならmallocのキャストはいらなくね?
int n = 4; int (*p)[n] = (int (*)[n])malloc(sizeof(int) * 3 * n); とかできないじゃん
void **Alloc2(size_t x, size_t y, size_t size)
{
void **p = malloc(sizeof (void *) * x);
void *pY = malloc(size * x * y);
size_t i;
for (i = 0; i < x; i++)
p[i] = pY + i * y;
}
void Free2(void **pp)
{
free(*pp);
free(pp);
}
こう使える。
int **p = (int **)Alloc2(3, 4, sizeof (int));
//
>>588 の後半
Free2((void **)p);
結論。あきらめてただのint *pとアクセス関数またはマクロを使え ってことかな?
ったくうんこだなー
覚えたての配列へのポインタが使いたくて仕方がなかったんだよ
>>589 は
>>593 それ、二つの領域をつなげてallocするとfreeの手間がラクになりそうだが
alignさせるのがちょっと面倒か
>>596 こうか?
size_t IndexSize = sizeof (void *) * x;
void **p = malloc(IndexSize + size * x * y);
void *pY = p + IndexSize;
ところでAlloc2()、return書き忘れた……。
○| ̄|_
アホ草。一次元配列ガッポリとって自分で添え字管理すれば十分
>>597 それだと、doubleの配列とかで問題になるだろ
>>600 宣言前でmalloc呼んでるからじゃね?
Alloc2がreturnしてないからとか?
こういうの見ると、さっさとC++に移行しると 言いたくなるな
> p[i] = pY + i * y; error C2036: 'void *' : サイズが定義されていません。
>>603 そうやって逃げてちゃウデは上がらないでしょ。
>>605 こういうのは不要なウデだと思うんだがなあ
スレ違い
ひでぇ〜もんだな
610 :
デフォルトの名無しさん :2005/07/01(金) 05:34:36
変換指定というものの、 %09.9f の.9の部分は何をどう表してるんですか? ^^ もし変換指定子がdなら.9は省略してもおkですか? 自分が持ってる本には、「表示する最小の桁数を指定します。省略した場合は、整数の場合は1であるとみなされます」とあります。 教えてくださいorz
611 :
610 :2005/07/01(金) 06:47:54
^^の場所ずれてますねorz すいません
本の説明のとおり、小数点以下の表示桁数だよ。 たとえば数値が 12.34567 だとすると %.9f なら 12.345670000 ってなるし %.3f なら 12.346 ってなる。 小数点の左側は全体の表示桁数ね。 %09.3f なら 00012.346 ってなる。 %dなら小数点はいらない。っていうか普通付けない。
613 :
610 :2005/07/01(金) 14:13:28
>>612 よく分かりました!
ありがとうございましたm(__)m
614 :
デフォルトの名無しさん :2005/07/01(金) 15:51:16
#include?<stdio.h> #include?<math.h> double?f(double?a,?double?p,?double?x) { ??return?(exp(-x*x/(2.0*a*a))*cos(3.14*x+p)); } int?main()?{ ??double?a,?p,?x;? a=0.6; p=0.0; ??for(x=-3.14;x?<=?3.14;x+=0.01)?{ ????printf("%.2f , %f\n",?x,?f(a,?p,?x)); ???} ??return?0; } gnuplotでこのプログラムのグラフを表示させたんですが、上手くいきません。 どこを直せばいいと思いますか?
615 :
デフォルトの名無しさん :2005/07/01(金) 15:52:55
すいません?の部分は空白だと思ってください。
616 :
デフォルトの名無しさん :2005/07/01(金) 16:06:10
#include?<stdio.h> 修正しました。 #include?<math.h> double?f(double?a,double?p,double?x)?{ ??return?(exp(-x*x/(2.0*a*a))*cos(3.14*x+p)); } int?main()?{ ??double?a,?p,?x; ??a=0.6; p=0.0; ??for(x=-3.14;x?<=?3.14;x+=0.01)?{ ????printf("%f , %f\n",?x,?f(a,?p,?x)); ??} ??return?0; }
インデントは全角スペースか&nbsp;使え
618 :
614〜616 :2005/07/01(金) 16:20:33
あれ、また?が…何でだもうわかわからん。 すいません、僕の書き込みは無視してください。 お騒がせしてすいませんでした。
>>618 gnuplotがダメならExcelで試してみるとか。
まぁ、いずれにしてもCの話じゃない罠。
error C2181: else 文が if と一致しません。 これはどういう意味でしょうか?
>>620 ・括弧の対応が合ってない
・ifが無いのにelseがある
>>620 そんなわかりやすいコンパイルエラーなんだから少しは分かれよ
コンパイラがかわいそうだ
ヒント:日本人とは限らない。
事故解決しました
>>624 2chが読めるんならこの程度の日本語は読めるとおもわれ
627 :
デフォルトの名無しさん :2005/07/01(金) 22:51:58
ごにょごにょと計算してその結果が a[0]=3.14 a[1]=1.23 a[2]=2.34 ・・・・ と配列に入っています(実数で) これをテキストファイルに出力したいのですが本に載ってるやり方で出来ませんでした intからdoubleうんちゃらかんちゃらとかよくわかんないです 整数データじゃないと出力できないんでしょうか?
>>627 for (i = 0; i < N; ++i)
printf("%f ", a[i]);
とかで出力できんのか
629 :
627 :2005/07/01(金) 22:54:40
画面には出来ます ファイルに書き出したいんです
hoge.exe > a.txt でリダイレクトしろ。
>>629 リダイレクトでもいいし
fp = fopen("out.txt","w");
としたあとで
printf(...)のかわりにfprintf(fp,...)を使えばよい
freopen("FileName", "w", stdout) もしくはリダイレクト もしくは fprintf。
633 :
627 :2005/07/01(金) 23:09:36
fprintfを使ったらとりあえずできました 本にはfputsが載っていてそれだとエラーでした リダイレクトは知っているのですが、そのほかにも大量に色々計算していて 最終的に結果のみを出力したかったので質問しました (リダイレクトしてテキスト開いて結果だけコピーして・・・というの面倒なので) またエラーでたら来ます
>>633 エラー出たら来るじゃなくて、考えてわからなかったら来いや…
635 :
デフォルトの名無しさん :2005/07/01(金) 23:30:56
線形論理の古典論理のLKの推論の∨(または)右 Γ→凵AC/Γ→凵AC∨D および Γ→凵AD/Γ→凵AC∨D となるプログラムをCで表してほしいです。
マルチポストいくない
637 :
588 :2005/07/01(金) 23:45:46
遅くなりましたが、なんとなく分かりました。ありがとうございました
638 :
前スレ392 :2005/07/02(土) 08:05:50
>>前スレ394 どうもありがとうございました。m(_ _)m
だれかダイテル本の解答を教えてくれ。 この本で勉強したヤツらはみんな、 正解なのか不正解なのか分からないまま ムンムンとした欲求不満状態で読み進めていったのか?
最初から正解がちゃんとある本を買えばええ。
質問です。 多次元配列 int* a[51][10] をある関数に引数として渡したいのですが、 func(int[][] a)としたらコンパイルエラーとなりました。 どうすればいいのでしょうか? よろしくお願いします。
642 :
641 :2005/07/02(土) 10:49:03
プロトタイプ宣言として void func(int[][] a)としたらコンパイルエラーとなりました。
643 :
641 :2005/07/02(土) 10:57:12
func(int** a)で対応できました。 ポインタのポインタですね。 失礼しました。
644 :
デフォルトの名無しさん :2005/07/02(土) 11:02:05
何方かフリーのCコンパイラ(登録なし)知りませんか??
>>644 VC Toolkit, gcc, LSI Cなどいろいろある。
646 :
テンプレ抜けてたね・・・ :2005/07/02(土) 11:14:35
>>643 それだと a[y][x] みたいな使い方をしたときに、おそらく期待した動作をしないよ。
>>276 >>279 >>281 ・・・
>>288 ・・・ あたりの一連は参考になるかな。
とどのつまり、func(int (*a)[10]) と定義して a[y][x] と使うか、
func(int (*a)[51][10]) と定義して (*a)[y][x] として使うかのどっちかかな。
意味的な違いで使い分ければいいと思う(int[10] の行の集合を指し示すポインタなのか、int[51][10] の二次元の塊を指し示す
ポインタなのかってこと)。
a++ ってやったときに、前者の定義だと y が一つ進んだポインタになるし、後者の定義だと次の int[51][10] のメモリブロックを
指すポインタになる。
func(int (*a)[10])だとこれを呼ぶときにはfunc(a);となる。 func(int (*a)[51][10])だと、func(&a);としなければならない。
ちなみにint a[4][51][10];と宣言した変数 a なら後者のfuncへfunc(a);と呼べる。
>>648 だからそれが意味的な違いって言うことだよ。
int[51][10] の領域を一つの実体としたデータ構造なら、&a とやって渡すのが妥当だじゃないか?
実際構造体もそうなわけだし。
typedef int BOKE[51][10]
と定義したタイプがあったとすれば、その実体は
BOKE x;
だし、それを受け取る関数は
func(BOKE *a)
だし、それにポインタを渡すなら func(&x) でしょ。
二次元配列丸ごと全部で一つのデータ構造なのであれば二次元配列を指し示すポインタとして、一次元配列の
集合というデータ構造ならば一次元配列を指し示すポインタとして定義するべきだと思う。
たとえばコンソール画面の内容を二次元配列に入れてたとして、その画面を何画面も持ちたいときなんかを
考えれば、a++ とやったときにポインタが一行進むべきなのか一画面進むべきなのか、どちらが妥当か?
という問題だと思う。
651 :
650 :2005/07/02(土) 11:49:12
あ、
>>648 を否定してるとかそういうことじゃないよ。
データ構造の表し方についてコメントしたかっただけ。
(アプリ)[学習] C言語の初歩missionC(美少女と一緒にゲーム感覚で覚えられます)(ccd).rar e5Vh8m7eY0 238,635,666 51d68b5eaf5514b488f03bda66c98a63
missionCとmissionJの違いにワラタ
C言語を始めて学習したいと思い、ヨドバシに何かソフトを買おうと 行ってきたのですが、C#とかC++とかあって何を買う方がいいのか 迷いました。 この2つの違いとボーランドとマイクロソフトはどちらを買えばいいのか ご教授ください。
>>654 悲しくなるほどスレ違い。それらはどちらも「C」ではない。
マイクロソフトっていくらで買えるの?
>>654 C++コンパイラは普通Cもコンパイルできる
C#コンパイラは普通Cはコンパイルできない
CをやりたいんならC++用の開発環境を探しなさい
学生ならMSのVisual Studio the Spokeがただのアカデミック版より安く買える。
>>657 ご丁寧なお返事ありがとうございます。
CとC++とC#の違いを教えて下さい。
C 昔Unixを高級言語で書きたいということで作られたというだけあって高級言語の中では低級言語に近い。 C++ 元はCへSimulaのオブジェクト指向を加えたい、ということから始まった。 Cユーザを引き連れたいということで、Cのソースは基本的にそのままC++でも使える。
C言語を勉強しているのですが exit(); するときに、 exit(1); ではなく、stdlibの"EXIT_FAILURE"を使い exit(EXIT_FAILURE); としたほうが、汎用的になる とあるのですが、意味が書いてありません 検索してみても、意味の記述はありませんでした どのような意味で、どのような利点があるのでしょうか?
>>659 C++はCのスーパーセット(上位互換)と思っていれば大体間違いはない。
つまり根っこは同じで、Cに色々と仕様を追加して拡張された言語だ。
だから、C++用の開発環境は通常Cも扱えるし、扱う。
C#は構文的にC系統の言語を受け継いではいるものの、全く別物の言語。
>>662 俺的には利点は全く無いな。
exitに渡したいのは0/1だけじゃないし、
EXIT_SUCCESSやEXIT_FAILUREは規格で0/1と定められているから、
何かを隠蔽しているわけでも環境によって値が変わるわけでもない。
関数内で作った変数を、違う関数内で使いたい場合はどのようにするのでしょうか? グローバル変数を使おうと思ったのですが数が多いので グローバル変数を使わずにできる方法等あれば教えてほしいです どうかよろしくお願いします
>>665 構造体でも使ったらどうだ。
struct param { int a, char *b, ... };
void set(struct param *p) { p->a = 1; p->b = "hello"; }
void get(struct param *p) { printf("%d %s\n", p->a, p->b); }
とかそんなかんじだ。
>>666 製品版てのは C++ Builder とかじゃない?
これは、Windowsアプリ開発のためのGUIエディタとか、
デバッガとかが入った統合環境。
って、これはもうスレ違いな質問
>>668 本当にありがとうございました。
向こうのスレで聞いてみます。
Cのこと何も知らない癖に出来ますって言って
就職活動してるんです。
>>669 おまえの人生そこで終わりだ
マをなめるな
>>669 そうか
がんばれよ!
で、デスマ要員になってさっさと死ね
見栄をはる奴にはコード書くのはむずいと思うのは俺だけか?
673 :
665 :2005/07/02(土) 20:08:45
>>668 ありがとうございます
すいませんが、構造体は少し調べてみたのですが
よくわかりません
他には方法はないでしょうか?
>>673 Cの標準的な関数の使い方を一通り眺めれば、どんな風にするとうまくいきそうかわかるんじゃないかい?
たとえば strcpy なんかは、内部で文字列のコピーを作って、呼び出し元の変数に値を返してるとも考えられる。
localtime なんかは、内部で展開した各種値を構造体に返すようにできてる。
ようは、呼出元に値の返却先を用意して、関数はその領域に対して値を格納するように作るのが一般的。
675 :
665 :2005/07/02(土) 20:39:33
調べてみてもわからないのですが ->の矢印は.と同位なんですかね? それと、他にも質問があるのですが struct param { int a, char *b, ... }; の場合 param *pは最初にmain関数で宣言するのですよね? そしたら、 void hoge(struct param *p)とすることでどこからでも呼び出せるということでしょうか? この場合、hogeを呼び出すにはmain関数内で hoge(*p); とするのでしょうか? 始めたばかりでよくわからないのですが教えていただけると幸いです
>>673 構造体なんて、使ってみればそう難しくないさ。
typedef struct {
int add;
int sub;
int mul;
int div;
} ANSWER;
void calc(int a, int b, ANSWER *pans)
{
pans->add = a + b;
pans->sub = a - b;
pans->mul = a * b;
pans->div = a / b;
}
int main()
{
ANSWER ans;
calc(1000, 100, &ans);
printf("1000 + 100 = %d\n", ans.add);
printf("1000 - 100 = %d\n", ans.sub);
printf("1000 * 100 = %d\n", ans.mul);
printf("1000 / 100 = %d\n", ans.div);
return 0;
}
>>675 ->と . は順位が同じというだけでもちろん意味は違う。
>>675 struct は、typedef して使うと扱いやすいよ。
>>676 のサンプルを参照。
こうしておくと、ANSWER っていう型でコードを記述できるから、ラクチン。
-> は、その左側が構造体へのポインタの場合に使う。
p->x は (*p).x と同じ。
>>676 では、関数 func は ANSWER をポインタで扱ってるから、それに対してアクセスするのに -> を使ってる。
main では、ANSWER の実体を扱ってるから、それに対してアクセスするのに . を使ってる。
さてお前等 . と -> の違いをどう説明するか
680 :
678 :2005/07/02(土) 20:48:01
× 関数 func ○ 関数 calc
681 :
665 :2005/07/02(土) 20:51:29
ありがとうございました!! よくわかりました!!
こいつなかなか筋がいいと思わないか?
typedefとかstructって、変数初期化されるんだっけ? なんか、考えてみるとそうだった気がしてきた いま書いてるコード自分で初期化してるや
>>684 どんな型でも初期化子が存在すればそれで初期化される。
そうでない場合、グローバル・staticなら0で初期化され、自動変数なら初期化されない。
>>686 グローバル・static なら 0 で初期化されるって、保証されてるの?
688 :
684 :2005/07/02(土) 21:13:53
ごめん
staticだったか
年はとりたくないもんだね
じゃあ、
>>676 はまずくないか?
int a=0; 見たいな感じで初期化したいのですが 0以外で初期化するには何がありますか? int a=NULL; とかでも、初期化されてるんですか?
>>688 ans は calc の結果返却先だから、初期化されてる必要は無いでしょ。
692 :
689 :2005/07/02(土) 21:22:49
ごめんなさい 初期化と言う言葉はてきとうじゃなかったですね 0とかnullにしたいです
int a=0; の何が不満なのか。
694 :
689 :2005/07/02(土) 21:27:18
0とすると、0をセットしたみたいに思うので nullとかでできるならそっちのほうがいいと思いまして
695 :
デフォルトの名無しさん :2005/07/02(土) 21:28:05
ライブラリを作ります。 そのライブラリは、使用に先立って初期化処理をしておく必要があります。 普通このような初期化処理は、ライブラリを使うプログラムが明示的に呼び出すものだと思います。 しかしそうではなく、リンクしただけで実行の際に自動的に初期化処理が走るようにすることはできないでしょうか。 また同様に、プログラム終了時の後始末処理を自動で行うようにはできないでしょうか。 (これは、初期化処理が自動で走りさえすれば、そこで atexit ハンドラを登録することで何とかできそうですが) ところで libc なんかは、内部的な初期化処理というのは行っていないのでしょうか?
環境依存なんだな
>>694 #define INIT_VALUE 0
a = INIT_VALUE;
とでもすればいい。
慣習的に、NULLはポインタに対して使われるものなので、
整数に対して使うのはお勧めできない。
方法はあるだろうけど、環境依存になるだろうな。
>>697 そんなのもお勧めできないだろ。
a = 0に慣れる以外に道はない。
>>695 libcの内部的な初期化というのは大抵行われていると思っていいがその段階で何らかの関数を呼び出させるというのは無理。
C++が使えるのなら非公開のクラスを作って、そのコンストラクタで1通りの初期化をし、その型のグローバル変数をを無名名前空間に置くなんて技が使えるけど。
初期化済みフラグでも用意して初期化し忘れで他の関数呼んだときに エラー出して自衛するしかないな。
>>695 ライブラリロード・アンロードのラッパ関数作って、
そこで初期化関数呼び出せばいいんじゃない?
ELFならinitとfinitをexportすればいいだろうけど。
Win32ならDllmain()だな まあ何にせよ環境依存だ
コマンドラインアプリケーションで int main(int argc, const char **argv){ として、引数を取得しているのですが その引数の評価をoptionという関数でやろうと思い int option(int argc, char **argv){ として、うけとり評価をしようと思っているのですが optionを呼び出す際になんと呼び出せばいいのでしょうか? option(argc, argv);だと warning: passing arg 2 of `option' from incompatible pointer type と、いわれます ポインタと言うのがよくわからないのですが この場合ワーニングを出さないにはどのように書けばいいのでしょうか?
>>704 int main(int argc, const char **argv)
→int main(int argc, char **argv)
706 :
695 :2005/07/02(土) 23:18:04
一般的な方法は無いってことですね。 いろいろなアドバイスありがとうございました。
>>705 むしろ option の方に const を付けるのがいいんじゃないか?
708 :
704 :2005/07/02(土) 23:21:09
すいません constしてるのにconstしてない変数に代入してっぞって意味でしたか
>>707 どっちでもいい。argvはconstである必要はないし、そうであってもいいから。
最初のscanfで\nが残るんだろ。 空のfgets発行するか、scanfに\n追加するか、rewind(stdin)しとけ。
ひどいコードだな マジックナンバーを使うなとは欲いうが まったくもって意味がわかってないと見えるな
714 :
710 :2005/07/03(日) 00:09:51
711,712 ありがとうございます。出来ました。 学校の課題で、scanfとgetsしか基本的に使っていないので、 getsを使用せざるを得ないので... 713 それは自分に対するレスですか? マジックナンバーは最初から課題で指定されているので。
>>714 MとかNじゃ、マジックナンバーを避けたことになっていない。
適切な名前を与えることによって初めてマジックナンバーを避けたことになる。
>scanfとgetsしか基本的に使っていないので、 >getsを使用せざるを得ないので... 習ったものしか使えない?チミは高校生かね? 宿題ならスレ違いだし。
717 :
710 :2005/07/03(日) 00:52:56
>>715 MとかNは最初からそうするように指定されているので。
>>716 そういう意味じゃないですが、説明するのが面倒なので省略します。
まあ、とにかく、ありがとうございました。
このスレ関係ないところに突っ込みすぎ
>>709 どっちでもいいってか、option がどういう関数か、ってことだろ?
option が渡されたポインタが指す領域を書き換えないなら const を付けるべきだと思うが、いかがか?
話がずれとる
>>719 両方の選択枝を提示してあとはご勝手にって言うのが筋だと思う。
722 :
719 :2005/07/03(日) 02:24:50
>>721 コンパイルが通すことが目的ならそれでいいんだろうけど、
せっかくキーワードを付ける付けないが絡んで出てる問題なんだから、おれは正確な定義をするためのアドバイスをしたいな。
main の argv は慣例に則って const は付けなかったとしても、option の引数にはぜひとも const を付けていただきたいところ。
つーか、入力のみの変数なのに const を付けないプログラマが多くて、一緒に仕事すると萎えるって現状があるから
余計そう思ってるだけかもしれないけど。
const char const * const * const argv
const付けるかどうかは、optionの仕様による。
たとえばgetopt(3)の宣言は
int getopt(int argc, char * const *argv, const char *optstring)
だったりするんだよな
(**argvは書き換えないが*argvは書き換える)
>>704 はconstをよく理解していないようだし、自分で全部説明して
面倒見る気なら構わないが、そうでなければ悪戯に混乱させるだけじゃ
なかろうか。
>const char const const が二個着いてるがこれ大丈夫なの?
ワニングが出るだろうな。
>>727 VCが甘いだけで、実際には規格外じゃなかった?
>>725 説明したけりゃ回りに突っかからずに704に説明すればいいだけの話では。密度の薄いスレだなー
gcc -Wall -ansi でも一応コンパイルは通った。
つか、意味もなくconst付けられても困る。
>>729 俺は「説明したい」ワケじゃないし、別に周りに突っかかってない。
「constにこだわりたい」といってるのは
>>719 だ
734 :
719 :2005/07/03(日) 03:19:46
あれ、おれが周りに突っかかってると言われてるのかな? option の定義についての一つの話題として意見を書いたつもりだったんだけど、おかしなこと言ってた?
ま、もうどうでもいいじゃん、あとは質問者が好きなようにすれば。 はい次次!
密度が急激に低下 し て い ま す
const このスレの話題
mainがその他の場所で書き換えるかもしれない。
mainの引数を他の関数に渡すときの話でしょ。
mainがその他の関数に渡した引数を書き換えるかどうかは、その他の関数の知ったこっちゃないだろ。
>>742 その他の関数の引数にconstを付けるかどうかの話じゃないんだっけ
勘違いしてたらスマソ
>>743 関数Aがポインタ引数の参照先を書き換えないのであれば、
そのポインタ引数はconst修飾すべきである
という、一貫してそれだけの話をしている。main()は関係ない。
(・ω・´) つ 今日のボクの日記 const char * const * const a = NULL; char * const * const b = NULL; const char ** const c = NULL; a = NULL; // NG *a = NULL; // NG **a = NULL; // NG **b = NULL; // OK *b = NULL; // NG b = NULL; // NG **c = NULL; // NG *c = NULL; // OK c = NULL; // NG const って不思議だな・
>>745 char に NULL を代入するのはいかがかと
さぁ、次はNULLの話題だよ!
>>744 それは元の質問から派生した、どちらかというとどうでもいい内容じゃないかな?
main() { return 333; } メインの戻り値は、どうせ使われていないので、何でも良いと とあるお方に聞いたのですが、これは正しいのでしょうか? 「シェルを使う時は気にする必要がある」とよく見かけますが、 シェルがどーのとか言うのは良く解らないので、知識に溢れる方 の意見を伺いたいです。
>>749 NULLが0じゃない処理系があるなんて、すっかり忘れてた。
ポインタを if(p) { ・・・} なんて評価しちゃうこと、よくあるな・・・
気をつけよう。
5.3: ポインターがヌルポインターでないかどうかのテストの省略形 「if(p)」は有効なのか? ヌルポインターの内部表現が0でない場合は どうなるのか。
,、‐ ''"  ̄ ``'' ‐- 、 /イハ/レ:::/V\∧ド\ /::^'´::::::::::::i、::::::::::::::::::::::::::::\ ‐'7::::::::::::::::::::::::ハ:ハ::|ヽ:::;、::::::::::::丶 /::::::::::::::/!i::/|/ ! ヾ リハ:|;!、:::::::l /´7::::::::::〃|!/_,,、 ''"゛_^`''`‐ly:::ト /|;ィ:::::N,、‐'゛_,,.\ ´''""'ヽ !;Kいいかげん殺すよ ! |ハト〈 ,r''"゛ , リイ)| この種の話題は聞き飽きてる `y't ヽ' // ! ぃ、 、;:==ヲ 〃 `'' へ、 ` ‐ '゜ .イ `i;、 / l 〉 ` ‐ ´ l`ヽ / ! レ' ヽ_
>>751 それは問題が無いことが保証されているはずだ
定数ゼロをポインタに代入する場合は、常にヌルポインターとして扱われるし
ポインタとゼロが比較される場合には、ヌルポインターかどうかの比較になる
ヌルポインタの実値がゼロでない処理系であれば
if ((long)p)
とでも書けば、まあ違いが出るだろう
>>750 シェルってのは、ユーザーの指示により実行ファイルを起動したりするプログラムのこと。
DOSプロンプトなんかはユーザーが入力したコマンドによって実行ファイルを起動するし、Windowsのエクスプローラは
実行ファイルがダブルクリックされることによってそれを起動する。
で、実行されたプログラムは、シェルに対して数値を返すことができる。
処理が正しく実行され、正常に終了した場合なんかは、0 を返すようにしておくのが一般的。
なんらかのエラーが発生したときには、適当な番号を割り振って、それを返すようにしたりする。
シェルは、複数のコマンドをまとめて実行させる仕組みを持っていたりして、MS-DOSのシェルならバッチコマンド、
UNIXのシェルならシェルスクリプトなんて呼ばれる仕組みがそれ。
複数のコマンドを実行する都合、どれか一つのコマンドがエラーで終了したときなどには、以降の処理をキャンセル
したりなど、処理の流れを変えたかったりする。
そういうニーズに対応するため、コマンドはシェルに対して終了コードを返し、シェルはその値によって処理の
流れを変えられる仕組みを持っている。
だから、あんまりそういう使い方を意識していないならば、とりあえず0でも返しておくのがいいと思う。
返せる値の範囲は処理系によるけど、0〜255くらいにしておけばあんまり問題は起きないと思う。
ちなみに、コマンドはシェルから起動される以外に、別の実行ファイルから実行されることもある。
その実行元のプログラムは、実行したファイルの終了コードを取得することができるよ。
あんまりシンプルに書けなかったけど、わかったかしら?
>>755 なげーよ。
ちなみにUNIXシェルの場合、127を超える戻り値を使うのは薦められない。
まあ、0〜3程度の小さな整数を使うのが普通だな。
>>755 goo job. カンポキだ ちくしょう
// 意外にも貴重なレスが貰えてしまった (・ω・´) ありがとございます
>>754 便乗質問させてください。
もし NULL = 0x100 の処理系があったとします。
p = 0;
とやると、p に 0x100 が代入されるということでしょうか?
そして、p = 1 のときに p-- とやってしまうと、p はいくつになるのでしょうか?
関連して、p = 1 のときに
p2 = --p;
とやったときの、それぞれのポインタの値も気になります。
この流れでなんでそんなことすら分かんねーんだよ…
>>758 > p = 0;
→ (long)p == 0x100
> p = 1 のときに p-- とやって
→ (long)p == 0x0 (pがchar*のとき)
> p = 1 のときにp2 = --p;とやったとき
→ (long)p == 0x0
(long)p2 == 0x0
じゃないかな、多分
762 :
758 :2005/07/03(日) 05:38:44
>>760 質問しておいてアレですが、それで正しいと思います。
>>761 すまん。faqを読めばしっかり書いてあったね。
ようするに、ポインタに絡む定数0は、コンパイラがヌルポインタに置き換えるんだね。
コンパイル後に結果的にポインタに値0が代入されたり比較されることになっても、コンパイル時にコンパイラがしたような
変換はされないということだ。
だから
>>758 の p-- の結果は 0 になるし、0 になったときに 0x100 に置き換えるようなコードが挿入されるわけでも
ないわけだ。
あと、NULL の define が 0x100 になってると思ってたことが間違いだってことにも気付いた。
なんで exit(1); は、エラー時に使うのに return 1; は通常終わりに返すんですか? return 0; はエラーなんですか?
> exit(1); > は、エラー時に使うのに そんなことは決っていない。 > return 1; > は通常終わりに返すんですか? そんなことは決っていない。 > return 0; > はエラーなんですか? エラーの場合もある。
まともなレスしないんだったら口ふさいでろよ
>>763 exit は、呼ばれるとプログラムを即座に終了するから、エラー時の処理の中断に都合が良くて使われるというだけの話。
たとえば main から関数を呼び、その関数も関数を呼び・・・ 関数の呼び出しの奥深いところで処理を中断したくなった場合、
exit を使わないでプログラムを終了するためには、奥深い関数から一つ一つ return していき、かつ処理が中断される旨
何らかの方法で main に伝えなくちゃいけない。
そういう面倒さを手っ取り早く解決するため、エラー時には exit を使ったりする。
個人的には main の return で必ず処理が終わるように構成するのが好きだから、exit は使わずに、エラーだろうと
なんだろうと main の return に到達するようにして、そこでエラーコードを返すようにしてる。
main での return 0 は、大抵はエラーではなくて正常終了のときの返却値。
普通 retun 1; しないか? 俺だけ? いままでずっと 1でしてきたけど
「普通」という言葉は微妙だが、 普通は return 0; だと思う。
>>767 成功に0, 失敗に1を返しておくと外部コマンドとして呼び出して
yourcommand && echo succ || echo fail
みたいな感じで成否で分岐できるようになるよ。
俺今まで5年間間違ったコードかいてきたの? 結構ユーザいるけど誰からも、訂正きたことないけどな........
EXIT_SUCCESSで検索してみれ
>>770 他のコマンドと連携するものじゃないんでしょ?
だったら何返しても問題は出ないでしょう。
だけどコマンドラインプログラムなんかでは、正常時には 0 を返しておくのが懸命だと思う。
773 :
770 :2005/07/03(日) 11:56:52
ありがとう 他のコマンドとの連携はないかな Xlib使ってなんかを表示関連がおおいから 全コード修正行ってきます....
CFAQ読めば済む話ばかりだな。 横着せずに、まじめに勉強しろよ。
775 :
770 :2005/07/03(日) 12:52:07
ふぅ、main関数の returnだけ全部修正してきた CFAQなんて読んだことないし、Cの勉強もしたことないのであしからず OSのコードとか、自分が使ってるアプリのコード読んでCは大体覚えていったかな まぁ、 return 1;は 初期に自分で書いたコードはなってなかったから どっか勘違いしてたんだとおもうな
人の数だけそしてその体験の数だけC FAQはある。 リンク先のFAQもその一つに過ぎない。 その死後硬直した一面的な情報にしがみつくのはいかがな物かと。
で?
スマソ、誤爆した。
>>770 はおまえらなんかよりぜんっぜんコードかけるやつだと思うが
リスト構造わかんねぇぇぇぇぇぇぇぇぇぇぇぇ
770がコード書けないと言ってるやつがいたのか?
文字列1、文字列2をフィールドに持つ構造体を定義して、 それをある一定数、配列で宣言し、それを定義した数だけ入力して、 結果をbinファイルに出力し、出力されたbinファイルから読み出して画面に出力する。 例えば、 struct 2ch { char name[100]; char ita[150]; } x[10]; を定義して、main関数内で、人数を2として、 1人目 x[0].name=nanashi; x[0].ita=program; 2人目 x[1].name=mona; x[1].ita=program; を定義し、その情報を"2ch.bin"に出力し、 次に"2ch.bin"から情報を読み出して、 画面に出力する。 こういうコードを書きたいのですが、binファイルに出力するところまでは出来るのですが、 その先が分かりません。 解決法をよろしくお願いします。
>>783 ようするに、構造体の配列の内容をファイルに出力することと、
ファイルの内容を構造体の配列に戻すことがやりたくて、
とりあえず出力まではなんとかできた
という話?
ファイルから構造体の配列に値を戻せれば、後の表示はできるんだよね?
ちなみに、ファイルにはどんな形で出力したの?
fwrite(x, sizeof(*x), n, fp);
みたいに出力したなら
fread(x, sizeof(*x), n, fp);
で戻せるし、その他の方法で出力したのであれば、読み込みもその形式に合わせる必要があるわな。
それとも、書き込み時と読み込み時に一度だけ fopen したファイルポインタを使いまわそうとしたけど
うまくいかないって話?
785 :
783 :2005/07/03(日) 14:32:33
>>773 コード書き換える前に、ユーザに連絡するのが先だろ。
もし終了コード見ているプログラムがあったらどうするんだ?
787 :
デフォルトの名無しさん :2005/07/03(日) 14:42:44
>>785 fp=fopen("2ch.bin", "r");
for(i=0;i<n;i++) {
char *p;
fgets(x[i].name, sizeof(x[i].name), fp);
if((p=strchr(x[i].name, '\n')) != NULL) *p='\0';
fgets(x[i].ita, sizeof(x[i].ita), fp);
if((p=strchr(x[i].ita, '\n')) != NULL) *p='\0';
}
fclose(fp);
これでどうだろう。
fgets は改行コードもバッファに入れるから、それを削除するコードを入れてみた。
fgets の EOF を監視して、ファイルの終わりを判断したりなどの改良の余地あり。
表示したいなら、この配列の内容を心行くまで表示すればいい。
>>786 バグの重要度も考えずに大騒ぎするアホ降臨
>>788 別にreturn 1やってもバグじゃないんだし、
大騒ぎして書き換えるほどのものじゃないと思う。
790 :
787 :2005/07/03(日) 15:05:02
fgets のかわりに fscanf(fp, "%[^\n]\n%[^\n]\n", x[i].name, x[i].ita); とかやるのもいいかな? バッファをあふれないようにするのが課題だけど。 fscanf(fp, "%100[^\n]\n%150[^\n]\n", x[i].name, x[i].ita); とかすればいい? つーか、バッファがあふれるようなケースだと、他に考慮しなくちゃいけないことがいろいろあって面倒だね。
結局、fgetsなど使わずに一文字ずつ読み込んで処理するのが一番便利。
792 :
783 :2005/07/03(日) 15:48:02
>>787 ありがとうございます。
790のやり方だと、うまく出来たっぽいのですが、
787のやり方だと、なんだかうまく出来てるか、出来ていないのか良くわかりません。
もともとのx[i]を表示しているように見えます。
試しに、x[]に戻すのではなくて、他にy[]を作って、そっちに読み込んで
出力したいのですが、どうすればよいでしょうか?
そもそもfputs()はputs()と違って文字列だけ出力して、最後に改行文字は出力しないから、 785のコードではすべてのデータが1繋がりに出力されて、どこまでがnameだかitaだか区別できない。
出題の「結果をbinファイルに出力し」に対し fputs()はなんか違うと感じるのは俺だけですか? 784のようにfwrite()じゃないの?
(アプリ)[学習] C言語の初歩missionC(美少女と一緒にゲーム感覚で覚えられます)(ccd).rar ラクスの呪いFO9sOp6TIu 238,635,666 9b3a16d2ec13b33cc8d039119f1228d30cd9a888
構造体のレイアウトから見ても、ファイルへのセーブ/ロードは fwrite/fread一発だろうな。それが一番簡単だし固定長レコードで 扱いやすい。 無論画面から読み取るのはscanfなりfgets/strtokなりを使う必要があるが。
初心者のうちは、構造体をそのまま読み書きするのはやめとけ。
・OSやコンパイラを変えてデータを読み込むと破綻するかも。 ・ポインタ・ハンドルは読み込んでも無意味。 注意事項はこんなものか。
初心者だからこそ、「そういうことが出来る」ことは知っておいていいと 思う。 ファイルをバイナリエディタで見れば、エンディアンや浮動小数点の 表現の問題はすぐに分かるだろうが、 コンパイラやハードウェア、OSを変えても互換性のあるファイル形式、 といった話になってくると、初心者レベルを超えたもっと高度な要求になる。 そういうことは、一度はやってみないと、なかなか理解できないものだ。
802 :
783 :2005/07/03(日) 18:34:36
fwrite,freadを用いてやってみたいのですが、上手くいきません。 fwrite,freadを用いた場合のコードを教えていただけませんか?
コピペウゼー
++a + a++ って、いくつになるの?
16777216
0xcccccccc として
>>805 自信を持って私が答えよう。
答は、「いくつになるか、予測不可能」だ。
>>805 そろそろこういうのも演算順序規定して欲しいよな
いまどきこの程度で最適化がどうのこうのもねーだろ
811 :
デフォルトの名無しさん :2005/07/03(日) 19:36:45
Cやってるけど、GUI使ったアプリ作りたい。 Cの初心者本終えたら、C++移っていいのかな?
いいよ。
今更かもしれないけど。 かくほう for (i = 0; i < n; i++) { fwrite(&x[i], sizeof(x[cnt]), 1, fp); } よむほう(nが分かってるなら) for (i = 0; i < n; i++) { fread(&x[i], sizeof(x[cnt]), 1, fp); }
cntってなによ
いつものくせでつい。
(^^)って入力したのに山崎渉と出力されません。 これは致命的な欠陥だと思います。
>>813 /* やれやれだぜ */
fwrite(x, sizeof(*x), n, fp);
fread(x, sizeof(*x), n, fp);
819 :
デフォルトの名無しさん :2005/07/03(日) 23:17:07
if( no % 2 ) puts(" その数は奇数です。"); これは、if( no % 2 ) の後ろに;がないんですが、行が2つに分かれてもおkなんですか?
>>819 Cの;は行末に配置する何者かではなく、構文上の「文」を終端するためのモンだ。
だから、文の終端以外には、別に行末でも;はおかんでもよい。
822 :
デフォルトの名無しさん :2005/07/03(日) 23:26:02
in=fopenでバイナリとしてロードファイルがあります。 fgets(buf,5,in);として4バイト読み込み、この4バイトを10進数の数値として表示させたいのですが、どうすればいいかわかりません。 教えてください。
823 :
デフォルトの名無しさん :2005/07/03(日) 23:36:03
>>820 >>821 即レスdクスです。
このスレのおかげでずいぶん助かってます。本当にありがたいです。
cnt'n'hok
>>822 fgets じゃなくて fread を使うといいと思う。
>>822 4バイトintをバイナリイメージのままファイルに書き込んであるのなら、fgets()は禁物。
int foo;
fread(& foo, sizeof(foo), 1, fp);
とでもすればいい。
但し、エンディアンに注意。
828 :
デフォルトの名無しさん :2005/07/04(月) 08:47:10
C言語をはじめたばかりであまりわからないのですが、 ビットシフトはなんの役に立つのでしょうか?
>>828 バイト単位ではなくビット単位のデータを扱うときに役にたちます。
たとえばデータ圧縮では、データの単位がバイトではなくビットであることが多々あります(しかも一連のストリーム上の
データのビット長が固定長に統一されているわけではなく、いろんな長さのデータ(1bit〜数十bitとか)が混在してたりします)。
ビットシフトは、ビット単位のデータを寄せ集めてバイト(あるいはワード)の形にまとめたり、あるいはその分解をするときに
大いに役に立ちます。
使い方がわからないうちは恐らく使う必要も無いので、今のところシフトについてそんなに気にする必要は無いでしょう。
こんにちは 質問があります。 関数内のローカル変数として、 void func(void) { int num[5]; } とあるのですが、 これを、 int ind=10; void func(void) { int num[ind]; } としたらコンパイルエラーになりました。 配列の要素数を変数で動的に変えることはC言語(C++でもかまいません)の規則上不可能なのでしょうか? よろしくお願いします。
832 :
830 :2005/07/04(月) 12:17:29
C99とは何なのでしょうか。
>>830 ソース上で、配列のサイズを変更したいだけなら
const int ind = 10;
void func(void)
{
int num[ind];
}
本当に動的に確保したいなら
int ind = 10;
void func(void)
{
int* num = (int*)malloc(sizeof(int) * ind);
free(num);
}
ポインタのことで質問したいのですが typedef struct{ int a; char b[20]; } HOGE; void hoge( int argc, char **argc, HOGE *c){;} void main(int argc, char **argv){ HOGE c; hoge(argc, argv, &c) } というコードの意味がわかりません hogeを呼ぶときに argcはint型なのでそのままいけることはわかるのですが argvと、&cはなぜこのような表記になるのでしょうか? argvは、**argc, cは、*cにはなぜならないのでしょうか? すいませんが説明していただけるとありがたいです
>>837 「ポインタについて何も知らないからぜんぶ説明してください」に見え
るぞ。入門書でも読みなさいな。
839 :
837 :2005/07/04(月) 14:09:17
入門書をいくつか読んだのですが理解できません cは単に勘違いしていました mainで宣言したcのポインタをhogeのポインタ型変数のHOGE *cに、 渡すと言う意味ですね すいません失礼しました ですが、argvがどうしても理解できません すいませんが説明していただけないでしょうか?
840 :
837 :2005/07/04(月) 14:12:47
ちなみに、あっているかわかりませんが 私の推測というか見た感じのイメージでは char **argcと宣言しているのでargcにはポインタのポインタが記憶されていて argcとして渡すことで、hogeのchar **argcで、それをポインタのポインタとして解釈して受け取る みたいなかんじなのでしょうか?
>>840 その前に、hoge の第二引数は argc で合ってるの?それとも argv?
842 :
837 :2005/07/04(月) 14:17:08
すいません argvです 失礼致しました
C言語はじめたばかりだけどポインタって単純に int a; //int型のa変数 int *b; //int型の変数の先頭アドレス( bにはアドレスがはいっていて b = aでaの値が入るわけではなく // *b = a で、アドレス先にaの変数がはいる b = &a; //aの先頭アドレスを bにいれる って感じでとらえたんだけど俺間違ってるの?
>>837 物事はシンプルに考えよう。
argcもargvもmain()で受け取ったままhoge()に渡している。
すなわちhoge()ではmain()と同じようにargcやargvを使える。
以上。argc, argvについてそれ以外に余計なことを考える必要はない。
cについてはそのアドレスをhoge()に渡している。
すなわちhoge()ではmain()の内部で定義されたcをポインタを介してアクセスできる。
もし仮に、hoge()からさらにhage()にそのアドレスを渡したいのであれば、
void hage(HOGE * c){...;}
となり、
hoge()内部からhage(c);と呼ばれることになる。
int *b; この場合、bにはアドレスが入っていてそこに変数を入れることができるわけではなく アンパサンドを使って他の変数のアドレスを入れることができる これがわかったらポインタってわかると思うんだけど わからないひとはなにがわからないのかね?
どっかの良い解説ページにポインタ貼った方が早い気が。
*pとp[]の違いって何ですか?
>>848 特に無いよ
添え字が使える・使うべきときはp[]使うし
添え字が使えない・使わないべきときは*p使う
>>849 演算子の優先度が違う。
p[x]は*(p+x)と等価だと、お釈迦様も言っておる。
それとも宣言とか引数の中での話?
C言語をはじめたばかりであまりわからないのですが、 ビットフィールドはなんの役に立つのでしょうか?
役に立ちそうで役に立たない。
>>854 環境限定でデータをキツキツに詰め込む時に使う。
メモリマップドIOには結構使えると思う。
"H8 SCI BRR SSR" 辺りで検索するとビットフィールド使いたくなる 理由が分かるかも。
こんにちわ
質問があります。 { }の範囲のことを何と呼ぶのでしょうか? 「区画」? 何か定義されてる名前があると思いますが。
スコープ
括弧
ぺちゃぱい
横顔
{} 遠くから見た埴輪君
______________ {本日は晴天なり| ~~~~~~~~~~~~~~~ どこでも簡単吹き出し君二号
873 :
863 :2005/07/04(月) 21:45:40
わりとがんばったのに 一人しか付いてきてくれなかった
if文でどちらかの条件をみたしたら真っていうのできないですか? k=1の時の場合なら if(k==1){ } ですよね。k=1またはk=3の場合に真の処理をしたいのですが
>>875 if (k == 1 || k == 3) {
}
ちなみに両方の条件を満たした場合というのは&&。
878 :
デフォルトの名無しさん :2005/07/04(月) 23:39:51
#include <stdio.h> float avg(int ,float ,float ); main() { float x,y; int n; printf("データを入力してください!"); n=1; while(n){ printf("入力値%d= ",n); scanf("%f",&x); if(x == 0.0) break; n++; } float avg(int n,float x,float y) { float b; b = (x+y)/2; return b; } このプログラム回らないんですけど、 どうしたら、回りますか?? 教えてください。お願いします
>>878 マルチかよ。
しっかりインデントつけろ、そうすりゃ分かる。
>>878 これあげるから 二 度 と 来 な い で ね ♥
#include <stdio.h>
float avg(int n,float x,float y) {return (x + y) / 2;}
int main(void) {
float x, y; int dummy;
printf("データを入力してください!");
if (scanf("%f%f", &x, &y) != 2) return 1;
printf("%fと%fの平均:%f\n", x, y, avg(dummy, x, y));
return 0;
}
>>880 じゃどういう次元?
インデント揃えて、足りないブレース一個でコンパイルは通るが?
ヒント:「平均」とは?
885 :
デフォルトの名無しさん :2005/07/05(火) 00:12:53
>>881 (・・?)ナゼ?、関数がうえにあるのでしょうか??
>>880 おしえてクンの次元が違うということでFA?
889 :
デフォルトの名無しさん :2005/07/05(火) 02:35:13
main関数じゃない関数で宣言した変数を違う関数から使う方法はありませんか?
>>890 別に変数の宣言は関数内部でなくても構わない。
int n;
void f()
{
n=1;
}
int main()
{
f();
printf("%d\n",n);
return 0;
}
892 :
890 :2005/07/05(火) 03:52:03
いや、グローバル変数はだめなんですよ 完全に、main関数じゃない関数で宣言した変数です
int *intptr(){ static int ret; return &ret; } main(){ int *p = intptr(); *p = 10;
>>890 ない。
どうしてもやりたければ、変数の値をコピーすることで代用するしか無い。
895 :
890 :2005/07/05(火) 04:26:41
変数の内容をコピーってどういうことですか?
>>895 具体的に何をしたいのか書かないと答えようがない。
void f(int *pa,int *pb)
{
int a,b;
a=ごにょごにょ
b=もにょもにょ
*pa=a;
*pb=b;
}
int main()
{
int a,b;
f(&a,&b);
printf("a=%d,b=%d\n",a,b);
return 0;
}
staticで宣言されてたり、mallocで確保されてるなら、 コピーしなくても、ポインタを返すだけでもいいんでないの?
898 :
890 :2005/07/05(火) 05:07:47
うんこやないねんから、そんなこてゃできへんよ やりたいことは、 Display構造体の変数をdisp関数で作って、 それを、どっからでも使えるようにしたい グローバル変数はだめ 今までは、mainで宣言してdispに構造体を渡してたけど dispで宣言しなわかりづらいからね
なぜグローバル変数がダメなんだ?
900 :
890 :2005/07/05(火) 05:20:33
グローバル変数はつかったら負け
ダメな理由はわかってるんだろうな…?
わかってないでそんなこと言ってるんだったらそれこそ負け組だが。
グローバル変数使ったってファイル分けりゃカプセル化可能。
Cでグローバル変数を使わずにできるアプローチは
>>896 か
>>897 。
それが嫌ならC++。
ファイル分けりゃとか言ってる時点で
>>901 もボケ
どの辺がボケなんだか言ってみろよ。static変数使えば名前の衝突もないだろ。 最近中身のない煽りが多くてイライラしてんだよ。とっとと消えろ。
プログラムの流れが読みにくくなるし、初期化の問題も絡んでくるだろ ファイル分けてカプセル化とか、アホかお前は
カプセル化って言ってるだろ。 別ファイルなんてブラックボックスなんだから流れなんが見えなくていい。 インターフェースさえ明確ならそれでいい。
カプセル化したら、そのままじゃ、メインから使えないわな。 まあ、その場合、通常はポインタをゲットする関数を作るわけだが。 > プログラムの流れが読みにくくなる カプセル化の意味ねーーーー 普通は読みやすくするためにカプセル化するんだよ 初期化は、disp内で変数宣言するって言ってるんだから、 disp内でやればいいだろ
しまった、かぶったか
>>898 main() { Display display; disp(&display); }
のかわりに
main() { Display *display; display = disp(); }
とすればいいだけの話か?
「どこからでも使えるように」って言ってるから、 main以外の関数からもポインタを取得できるようにするには、 disp関数をイニシャライザとして、 コレとは別にポインタ取得用の関数が欲しいと思うのは俺だけ?
910 :
デフォルトの名無しさん :2005/07/05(火) 09:13:25
おいおい、まだ109かよ。
置換マクロでの戻り値の取得方法を教えて下さい。 プログラム中に双方向リストのノード追加や削除と言った操作があるのですが、双方向リストが2つ以上存在する為、リストごとの追加や削除といった操作を置換マクロを使って一元管理したいのです。 削除や挿入操作は引数があれば出来たのですが、挿入操作は新しくリストを生成した後、そのリストのポインタを返却したいのです。 (関数であればreturn文で問題無かったのですが……) どうか、置換マクロでの戻り値の方法を教えて下さい。
最近ダメ出しだけで、代用案を出せない煽りが多すぎる。
914 :
890 :2005/07/05(火) 11:13:10
ダメなりゆうわかってないんだろうな とかそれ以前にダメっていってるのに まさか あほなの? あほなんでしょ? 質問者の注文どうりの答えが出せないんなら 口ふさいでろよ
>>911 関数でええやん、という気もするが。
挿入操作が式 foo、式 bar、その後値 newlist を返すとすると、
#define LIST_INSERT(oldlist,ent) foo, bar, newlist
とカンマ演算子を使うとか、
#define LIST_INSERT(oldlist,ent,dest) foo; bar; dest = newlist
と代入先もマクロ引数に含めてしまうとか。
>>898 Display *disp()
{
static inited = 0;
static Display d;
if(!inited) {
初期化処理とか
inited = 1;
}
return &d;
}
これでどうか?
呼び出すだけでポインタが得られる。
これやるよりはファイル分け案の方が読みやすくなる気がするけど。
だけど、こういう方法だと、Display の実体をもう一つ欲しくなったときとかに修正が大変になるから、
全ての関数に Display* を渡すようにするのが汎用性が高くなると思う。
上記関数に引数を与えられるようにして、関数を賢くすればいいのかもしれないけど。
>>914 >ダメなりゆうわかってないんだろうな とかそれ以前にダメっていってるのに
理由以前にダメなんですか。へー
>質問者の注文どうりの答えが出せないんなら
どうり?
>口ふさいでろよ
園児か。
プログラムなんて動けばいい。所詮紙くずに書くようなメモに過ぎない。 グローバル変数があるんだから素直に使っとけばいいじゃん。 コメントなりなんなりで、間違えないよう注意するようにしてさ。 と、思う俺は負け組み?
お前等Displayがなにかわかってないだろ Display *disp; disp = XOpenDisplay(NULL); だぞ、 Displayはポインタで宣言する
>>918 適材適所でしょ。
グローバル変数にして有利になると思えばそうすればいいだけ。
errno なんかもグローバル変数なわけだし。
ついに突っ込んじゃったよ みんなわかってなくてレスしてたのが面白かったのに
>>919 ポインタだろうとなんだろうと
>>916 の方法でイケるのではいか?
ようするにこうか?
Display *disp()
{
static Display *d = NULL;
if(d==NULL) {
d = XOpenDisplay(NULL);
その他処理
}
return NULL;
}
923 :
922 :2005/07/05(火) 12:32:21
まちがえた × return NULL; ○ return d;
>>921 もしかしてdispをグローバルにできない理由って、
Display *disp = XOpenDisplay(NULL);
int main()
{
・・・
}
って書いたらコンパイルが通らなかったからですか?
925 :
デフォルトの名無しさん :2005/07/05(火) 12:41:37
>>914 一番の解決策は設計を見直す事だと思うよ。
>>914 だから、そもそもできないって言ってるのに。
927 :
デフォルトの名無しさん :2005/07/05(火) 15:25:53
char *で定義されたパラメタから以下の文字列が引継がれます 'EXPORT/HOME/USER/DATA0706.TXT' パス部とファイル名称部をうまく切り分ける方法を教えてつかあさい
_splitpath _makepath 環境依存だったりして(ぉ
つーか POSIX に basename と dirname があるだろ。
int i; char *p; char *tmp[20]; for(i=0;p=_mbschr(str,'/');i++) { tmp[i]=p; } 思いつきカキコ(動作するのか?) 後ろからn番目の特定の文字cを探すことって 結構あるんだが、良い方法がわからん
ああ、ミスったまま・・・市にたい
933 :
927 :2005/07/05(火) 17:38:43
みなさま。ありがとうございました。 作動しはじめました。
これを再帰にしてください。 abc(int x,int y,int j,int k){ int i; if(x<y){ for(j=x;j>0;j--){ if (x % j == 0){ k = j; if(y % k == 0){ printf("CMN = %d\n",k); j = 0; } } } } if(x>y){ for(j=y;j>0;j--){ if (y % j == 0){ k = j; if(x % k == 0){ printf("CMN = %d\n",k); j = 0; } } } } }
すみませんちょっと教えてください typedef struct { char cHage1 : 1; char cHage2 : 1; } HAGE; の : ってどういう意味があるんですか? あと static Hage; って変数の宣言見たんだけどこれってなに型?どういう意味なの? よろしくおながいします。
>>935 ビットフィールドでググレ。
> static Hage;
int 型
>>935 int は省略しない方がイイ
C99ではアウトだから余裕があるなら直すべし
2次元配列のポインタの宣言なんですが int a[5][5]={ {1,2,3,4,5}, {6,7,8,9,10}, {11,12,13,14,15}, {16,17,18,19,20}, {21,22,23,24,25}}; int b[5][5]={ {3,6,9,12,15}, {18,21,24,27,30}, {33,36,39,42,45}, {48,51,54,57,60}, {63,66,69,72,75}}; //値はどうでもいい int c[5][5]; int *p_a,*p_b,*p_c; p_a = a; p_b = b; p_c = c; intをいっぱい書いてるのにも特に意味はありません。 最後の三行の部分でエラーが出てしまいます。メッセージは 「error C2440: '=' : 'int [5][5]' から 'int *' に変換することはできません。(新しい動作 ; ヘルプを参照) 指示された型は関連がありません; 変換には reinterpret_cast、 C スタイル キャストまたは関数スタイルのキャストが必要です。」 です。わけわからんちんorz 宿題っぽい匂いはかもし出してますが、宿題じゃありません。 どこがおかしいのか指摘おながいします
int (*p_a)[5][5], (*p_b)[5][5], (*p_c)[5][5];
940 :
939 :2005/07/05(火) 22:10:30
違った、これjじゃそうはできないか。 pa_a = &a;なっちまう。 int *pa_a = a[0]; こうだな。
こうもかけるが、いやな感じだな。 int *p_a = *a;
int (*p_a)[5], (*p_b)[5], (*p_c)[5];
>>939-942 なるほど・・・多次元配列に関するポインタにはポインタ自体の配列を
なんちゃらしないといけないんですね。
ありがとうございますた!
>>943 何か勘違いしてるだろ。
int (*p_a)[5];
は配列ではないぞ。
a[0] は配列だな。
うむ。配列自体へのポインタとでも言えば良いか。
ポインタの配列 と 配列へのポインタ
ここらへんがわかればもう、Cはお腹いっぱいって感じだぉね と言ってみるテスト
シンタクス汚くて理解しにくいだけなんだけどな 関数ポインタと配列が絡んでそれを返す関数ポインタへの配列とかな 要は一度きっちり理解して、後はtypedefでも使ってろってだけだが
950 :
943 :2005/07/05(火) 23:37:09
>>946 これでなんとなく分かったような分からんような
もっと勉強してきますλ.....
新ルール?
>>951 for(j=0; j<9; j++){ // 10回も回すな!
fflush(stdin); // 前回scanfのゴミが残ってるから掃除しとけ
scanf("%c",&bs);
CFAQ嫁 fflush(stdin); // 前回scanfのゴミが残ってるから掃除しとけ
scanf を scanf("%c%*c",&bs); に変える else printf("入力が違います\n次は?->"),j--; を最後に付け加える
てか、Cなんだから//コメント使うなよ C99前提か?
C99じゃなくても一行コメントは有名所のコンパイラは対応してるだろ
>>957 コメント程度の問題で
敢えてコンパイラ独自拡張に手を染めることも無かろ?
誰か○×ゲームを作れる神はいませんか?orz 2人が交互に座標を指定していくというもの。 課題で出たけどワケワカラン('A`)
コメント程度っていうんなら気にするなよ
質問と関係なく間違ってもいないことをグダグダ言うアホはスルー
座標を指定していくって 座標を指定する時点で○×じゃないだろ
>>967 ごめn 横ラインチェックのところ
if ( p[v*3] == p[h + v * 3] && p[h + v * 3] ) に直しといて。
これじゃ、2段目以降が判定されていない、迂闊。
あと定数散りばめてたり、e キー押した時は exit になってたり、めちゃくちゃだから
その辺の修正ぐらいしといてくだせぇ
969 :
デフォルトの名無しさん :2005/07/06(水) 05:46:31
970 :
969 :2005/07/06(水) 05:48:52
>>969 まず簡単な検索の概要について説明してもいいんじゃない?
そこまでソース読んで汲み取れと?
>>969 細かく見てないから、移動のルールとかはよく解らんが、
探索のアルゴリズムの大まかな流れはOKのような気がする。
がしかし、移動において変数frontが常に0のままなのだが・・・・
973 :
969 :2005/07/06(水) 07:25:37
>>971 そりゃそうですね・・・orz
概要ですが、
現在の状態から展開できるだけ全ての状態を展開して、
それに対して順列を使って番号付けして、現在の状態と対応させておいて、
目標状態になったら格納しておいた状態番号と状態に従って最初の状態までたどって
解を得るといった感じです。
974 :
デフォルトの名無しさん :2005/07/06(水) 09:24:09
int型整数の三乗値を返す関数はどうすればいいですか?
int a = 3; a = a * a * a; return a;
Display *hoge; hoge = XOpenDisplay(NULL); if( !hoge ){ perror(XOpenDisplay); } とはどういう意味でしょうか? !hoge はどういういみなのでしょうか?
どんな入門書にも書いてある
かいてない
979 :
デフォルトの名無しさん :2005/07/06(水) 09:40:19
>>974 抜けてました
int cube(int x) {/*・・・*/}
を作成せよでした
980 :
デフォルトの名無しさん :2005/07/06(水) 09:46:53
かいてませんから。 if (a != b) { というのがありますから、hoge ではないということ。 0か、そうでないかでtrue | false を判定。 例えば while(FindNextFile(省略)) は一見出られないが、 実際は確実に出られる。 hoge を-1,0,1,100 にして さあ、実験。
自分で調べる気が全く無いんだな、976=978は。
>>976 の場合
絶対にエラー終了するんでないかい?
!演算子の意味が書いてないなんて、
976=978=980は、なんて名前の入門書を使っているんだい?
>>979 宿題は(以下略
うむ、始めたばかりの俺様も思った アドレスが入ってるから絶対にperrorにながされるんじゃないの?
> アドレスが入ってるから絶対にperrorに は? もしかして、 FILE *fp; fp = fopen(...); if (!fp) { perror(...); } も、必ずエラーになると思ってる?
初心者は回答するなよ。 !hogeは、hoge == 0 と等価だ。
987 :
984 :2005/07/06(水) 09:58:17
ごめんねばかで それは、fopenでエラーが出たらperrorに流されるんでしょ あ、ifは正の数だったら流すんだっけ?
988 :
984 :2005/07/06(水) 09:59:15
989 :
デフォルトの名無しさん :2005/07/06(水) 10:02:11
printf( "ファイルの大きさ : %ld\n", FileSt.st_size ); 上記で表示される結果(数値)を char strLine[MAX_PATH];で定義したシンボルに格納したいのですが どうすればよいでしょうか?
> あ、ifは正の数だったら流すんだっけ? おい
>>989 数字を文字列に直して入れたいのか?
だったら少しは頭を使え。
992 :
デフォルトの名無しさん :2005/07/06(水) 10:11:56
>>991 はいその通りっす。
char strSize[10];
wsprintf(strSize,"%d",FileSt.st_size );
strcpy( strLine,strSize);
でコンパイルは通るのですが、値がとれていないようです。
おながいします。
もしかしてもしかすると 頭悪い?
994 :
デフォルトの名無しさん :2005/07/06(水) 10:46:09
はいオフコースです師匠!! お慈悲を〜
>>984 > アドレスが入ってるから
アドレスが入っている、と言う時点で間違い。
996 :
986 :2005/07/06(水) 12:02:32
997 :
989 :2005/07/06(水) 12:57:32
すみません。私のC言語も助けていただけますと嬉しく思います。
998 :
デフォルトの名無しさん :2005/07/06(水) 13:03:13
記念カキコ v(^-^=)
999 :
デフォルトの名無しさん :2005/07/06(水) 13:05:01
1000 :
デフォルトの名無しさん :2005/07/06(水) 13:05:26
1000GET!! v(^-^*)
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。