1 :
デフォルトの名無しさん :
2008/12/19(金) 07:31:54 BE:681631889-PLT(40040)
>>1 乙
早速質問で申し訳ないが、
#include<stdio.h>
#include<stdlib.h>
int main(void)
{
int i;
srand((unsigned)time(NULL));
for(i=0;i<100;i++) printf("%d\t",rand()%RAND_MAX);
return 0;
}
でfor内ではランダムの数字が100個出てくるが
「プログラム終了→すぐに起動」を繰り返してみると
最初の数字が22000→21765→21475とランダムになってくれません。
srandかrandをどのようにすれば最初の数字もランダムにできるんでしょうか?
time()は秒単位の精度しかありません。
プロセス ID を併用すれば毎回違う値には出来る。 ただし環境依存。
Windows なら timeGetTime が使える。 これは Windows を起動してからのミリ秒単位の時間。
>>4-6 返答ありがとうございます。
上記の方法を調べてみます
転職でプログラマーを考えているんですが。 C言語を覚えた方が良いのでしょうか? javaなどがあるらしいんですが。 C言語で基礎を固めてから、他の言語へ移行みたいな感じでしょうか?
C→Javaはいろいろ難しい (そもそも"何"のプログラマーなんだ?)
マ板いけよ
転職で初心者とか、今の不況でまともな雇い口があるのかね。 もっと長期的に考えてるのなら別にいいんだけど (十分なスキルがついてからなら問題は無いだろうし)。 個人的にはまずはCとアセンブリ言語をやるべきだと思ってる。 ただ、そんなに熱心に入れ込む必要は無くて、 ある程度感じがつかめたところで C# か Java あたりを触ってみるといい。 その後 Perl か PHP でも触ってみれ。 複数の言語を扱った方が新しい言語を覚える抵抗が低くなって、 時代に付いていきやすくなる。
普通logの逆はexpですけど log10とlogの逆ってなんなんですか?
10のなんとか乗
y = log10(x) の逆は x = pow(10, y) y = log(x) の逆は x = exp(y)
15 :
デフォルトの名無しさん :2008/12/20(土) 22:54:36
ちょっと配列とポインタについて疑問が 次のプログラムを見てほしい char str[10]; char *p; p=new char[10]; ↓実行結果 printf("%p\n",p); 00902B08 printf("%p\n",&p); 0012FF7C printf("%p\n",*(&p)); 00902B08 printf("%p\n",str); 0012FF81 printf("%p\n",&str); 0012FF81 ←なんでコイツは上(下)と同じアドレスなんだ?? printf("%p\n",*(&str)); 0012FF81
配列の識別子は配列の先頭アドレスを返すからだ
>>15 普通コンパイルエラーになると思うんだが。
コンパイラ何使ってるんだ?
>>18 p=new char[10];
これがコンパイルできるはずがない
拡張子がCならね・・
>>15 1) pは割り付けた領域の先頭要素へのポインタとして評価される
2) &pはpへのポインタとして評価される
1)と2)はふつう別のものだから当然違う値になる
3) strは配列そのものだがこれはすぐに配列の先頭要素へのポインタに成り下がって評価される
4) &strは3)の法則に当てはまらない例外として配列へのポインタとして評価される
配列へのポインタと配列の先頭へのポインタは大きさは違うが指している位置は同じなので
%pで出力すると同じ値を吐く
2番目の&pは先頭アドレスを返さないのに、なぜ5番目の&strは先頭アドレスを返すのだろう。 配列の仕様??
>>22 問題点はそこじゃない
むしろ4番目と6番目がなぜ配列の先頭になるのか、がポイント
>>21 おー、どうもありがとう。
malloc使えばいいのにnew使ってしまいました。すみません
char str[10]; の str の型は char[10] なんだが、 ポインタを要求するところで str と使うと自動的に char* に変換される仕様になっている。 で、この値は配列の先頭アドレス、すなわち &str[0] に等しいという仕様になっている。 で、一方 &str の型は配列へのポインタ、すなわち char(*)[10] になる。 値は当然配列のアドレスなのだが、これは当然配列の先頭アドレスに等しい。 というわけで str も &str も配列の先頭アドレスを指すわけだ。 ただ、両者で型が違う点には注意すること。 そして、&str に * をつけると脱参照されるわけだが、 &str は str へのポインタっちゅーわけなんで、 *&str は当然 str を指す。 *&p が p を指すのと同じ理屈だ。
ポインタにはアドレスを保有する領域があって、 p はその保有しているアドレスを返し、 &p はポインタ自身の領域を返す。 int n = 10; の n が 10 を返すのと同じように、 char *p = malloc(10); の p は malloc(10) の返したアドレスを返す。 &n が n のアドレスを返すように、&p は p のアドレスを返す。 p □ ポインタ自身の領域(アドレスは &p で得られる) . └→□□□□□□□□□□ malloc で確保した領域(アドレスは p が保有している) これに対し、配列にはその配列自体のアドレスを保有する領域なんてないという点に注目。 利便性から str は先頭要素のアドレスを返す仕様になっていて、 この変は普通の変数と同じように考えることはできない。 ただ、&str が str のアドレスを返すという点は普通の変数と一緒。 str □□□□□□□□□□ 配列の占める領域(アドレスは &str で得られる) ↑ ↑ 配列の先頭要素(アドレスは str または &str[0] で得られる) ← どちらも同じアドレス(でも型は違う)
&strって使い道あるの?
配列の要素数が固定になるので、 それを期待したい時に使えなくはない。 でも、普通はそんな使い方しないよね。 typedef double matrix[3][3]; void foo(matrix hoge); matrix m; foo(m); みたいな使い方ならありうると思う。 hoge の型は double(*)[3] だ。
ちなみに C++ なら配列の要素数を取得するマクロを作成する時に使える。 ここは C のスレだから関係はないが。
↑↑の説明がすごくわかりやすくて理解深まりました。 マジトンクス
char型の配列とポインタの違いってどうやって見分けるんですか? ↓のコードだと 配列宣言の直下ではsizeof の結果256ですが、 関数の中ではポインタの大きさの4になります。 文字列を受け取る関数のほとんどは、配列宣言直後の変数でも 引数で受け取ったポインタでも同じように扱えるし、見た目の書き方 も同じですよね。 コードではどっちも同じ書き方の「sz」でアクセスできるのが不思議です。 void func(char* sz) { printf("%d",sizeof(sz)); ← 4になる(違う) printf(sz); ← qwertyと表示される(同じ) } int main(int argc,char* argv[]) { char sz[256]; strcpy(sz,"qwerty"); printf("%d",sizeof(sz)); ← 256になる(違う) printf(sz); ← qwertyと表示される(同じ) func(sz); }
>>32 その変数の宣言を見て区別する
面倒くさいなら、配列であってもポインタであっても問題が起きないような使い方をする
わかりますた
>32 Cでは関数の引数として配列を渡すことはできない。つねに配列の先頭要素を指すポインタとなる。 ついでに char a[10]; があったとき裸のaは「次の例外を除けば」その配列の先頭要素へのポインタとして扱われる。 例外 &のオペランドになった場合 sizeofのオペランドになった場合 配列宣言の初期化子になった場合 >34 いや、配列とポインタは別物なのだから、どちらでも問題ないようなコードなんて無理なんじゃない?
文字列に&って使う機会ってどんなときですかね? 見たこと無いというか。付けるなって聞いたんですが。
文字列の途中から関数に渡すとかかなあ? void hoge(char *a) { printf(a); } int main() { char a[] = "ABCDE"; // CDEの部分だけ渡したい hoge(&a[2]); return 0; }
>>36 引数に渡されてきたものが
元がポインタだろうが元が配列だろうが
どちらでも問題ないコード、と言う事だろう。
具体的に言えば、サイズは引数で渡せ、と。
>>38 >>37 の言ってるのは &a のことだと思う。
普通は使わない。
>>29 みたいな感じで、固定長文字配列の配列全体を渡す際に、
文字配列へのポインタを渡す事ならあり得るが、普通はあまり使う機会は無いと思う。
#define HOGE_SIZE (3)
void foo(const char (*hoge)[HOGE_SIZE]);
static const char hoge[][HOGE_SIZE] = {
"ho", "me", "pa", "ge",
};
foo(hoge);
/* hoge は &hoge[0] に同じだが、
hoge[0] は "ho" という文字列全体を表す配列変数なので、
&hoge[0] は上記の &a に相当する */
普通は文字列の先頭アドレスへのポインタの配列を使うし
(長さ揃ってなくてもいいし長さを指定しなくても良くて便利なので)。
void foo(const char *const *hoge);
static const char *const hoge[] = {
"ho", "me", "pa", "ge",
};
foo(hoge);
C++ならいざ知らず、Cでは「&配列」の出番は殆どないな。
int型配列の要素の平均値を求める関数を書いたつもりなのですが 要素5つで値も全部5のとき 合計は24.965399 平均値は4.993080 などと値が微妙に丸められています。 キャストするとき変になったのかもしれませんが何故でしょうか。 コンパイラーはgccです。 double avg(int array[], int elements) { double ret; int *p = array; while(p < &array[elements]) { ret += (double)*p; p++; } /* デバッグ用 */ printf("合計は%f\n", ret); ret = ret / (double)elements; return ret; }
合計は整数なんだからintで持てよ
>>36 無理ではない
具体的には以下のことをしなければいい
・sizeof、&を作用させない
・代入しない
・free()しない
>>43 自動変数のretを初期化してないようだけど
>>43 無理にポインタ演算をするのは避けた方がいい。それに、forを使った方がこの場合はシンプルにまとまる。
double avg(int array[], int elements) { int total = 0. i; for(i=0 ; i<elements ; i++) { total += array[i]; } /* デバッグ用 */ printf("合計は%f\n", total); return (double)total / elements; }
&array[elements] これは一度実体参照してるから違反になる可能性があるのかな?
ならない。 &array[elements] は array+elements と厳密に等しいと決まってる。
i++ * i++; この結果は i * i, (i+1) * i, i *(i+1) のどれになるかは不定ですよね?
>>51 いいえ、不定ではなく、未定義です。
常識的に導かれる結果になるかもしれませんし、ならないかもしれません。
>>52 評価順序は不定で、結果は未定義ということですか?
評価順序も未定義。 void hoge(foo(), bar()); の foo() と bar() の評価順は不定。 foo と bar が互いに影響を及ぼし合う副作用を持っていない場合は 「正しい」プログラムになる。 i++ * i++; は未定義。どうあっても正しいプログラムにはならない。
void は要らないや・・・
56 :
デフォルトの名無しさん :2008/12/21(日) 18:11:17
コンパイラ次第。 評価の順序そのものが規格に無く、コンパイラ実装者が勝手に判断して実装しても良いし、特に意識して実装する必要もない。 従って、どうなるかは環境によってバラバラで、やってみなけりゃわからないということ。 ・・・だったと思います。間違ってたらごめん。
マクロで do {} while(1) イディオムを使いたいのですが、 VC8では「条件式が定数です」という警告が出てきます。 これを避けたいのですが、何かいい方法ありませんか?
do { } while(0) じゃないの? 代わりに for(;;){ break; } を使うとか。
ああ、忘れてくれ。 バカなこと言ってしまった。
>>59 while(0)でした^^
for - break だと最後のセミコロンが違ってくるので、
できれば他の方法があるとありがたいです
{}
#pragma warning(disable: xxxx) /* xxxx は警告番号 */ でその警告を無効にはできる。 ただ、効果はその #pragma 以降全体なので、 そのマクロ以外の部分を使ってるところにも影響は及んでしまう。 これをよしとしない場合は・・・難しいな。 マクロを諦めて関数にしてしまうのも1つの手だ。
今時、C言語の需要はあるのでしょうか? 仕事で使ったりと?
組み込み系はまだまだ現役だろ
ゲームもな
>>63 ありがとうございます
地味に難しい問題なのですね
>([[[[)
組み込み系についてなんですが。 C言語というと標準ライブラリのstdio.hというイメージがまとわりついて。 組み込み系でもstdio.hを使用して書いていくのでしょうか? やはり、その企業のライブラリを使うのでしょうか? そこらへんがよくわからないのですが、stdio.hだと出力などですよね? たとえば自動販売機などの値段表示などstdio.hのprintf表示してるんですか? 組み込み系といってなかなかイメージがわきません。 C言語入門の本などで組み込み系の仕事もこなせるのでしょうか? そこらへんを教えてください。
>>70 組み込み系に標準出力とか普通無い。
自販機の値段制御はLEDの制御ってことになるな。
ドライバだとメモリマップドIOでメモリ読み書きしてLEDの明滅制御したりする。
上層のアプリだとドライバ担当の人が作ったライブラリとかで、
LED_SetPrice(100); // 100円表示
見たいな感じか?
制御系や組み込みは専用スレがあるから、そっちでどうぞ
71さん、ほーそういうドライバ作ってくれる担当者がいるんですね。 そういう電光掲示板みたいな出力もプログラマがアセンブラで全て自作してやるかと思ってました。 転職なんですが、C言語を使うプログラマの場合やっぱり頭はフル回転で作業するのでしょうか? それともSEが指示した通りに書いてバグとかは自分で考えてやるというものでしょうか? いきなり、在庫管理をするソフトを作れと言われても経験を積んでない場合、その企業の上司が教えてくれたり。 関数とかも最初は説明をうけたりしてちゃんと文法とかわかってれば通用するもんですか? スレ違いなようですが、こっちは栄えてるのでその道の経験者が多いような気がしてこちらに質問してます。
マ板行け
向こうのスレの住民に喧嘩売ってんのかコイツ
つか、自治厨のほうがうざい。
栄えてる所がいいならN速でも行けばいい。
>53 |「規格が明確に定義していない」には3種類あって、以下のように定義されている。 | |・処理系定義(implementation defined)の動作 |どう動作するかを実装が選択する。そのプログラムがコンパイルできないというのは許されない。 |(この構成概念を使ったプログラムは誤りというわけではない。) |(実装が)何を選んだかは(コンパイラの作者が)文書にしておかなければならない。 |規格が合法な動作をいくつか用意していてそこから選ぶことができるかもしれないし、 |必要条件をとくに課していないかもしれない。 | |・未規定(unspecified)の動作 |処理系定義の動作に似ている。ただし、どういう動作を選んだかは文書にする必要がない。 | |・未定義(undefined)の動作 |本当に何が起きても不思議はないことを意味する。規格は何の必要条件も課さない。 |コンパイルできないかもしれないし、誤った動きをするかもしれないし |(クラッシュしたり黙って誤った結果を出したり)、 |あるいはたまたまプログラマの意図したとおりの動きをするかもしれない。
すみません、他の掲示板で質問しようとしたんですが。 また同じ文章を書くのが大変で、コピペしたら、マルチポストなどと言われてしまったことがあり つい質問を続けてしまいました。すみませんm(__)m
誰だよお前
81 :
デフォルトの名無しさん :2008/12/21(日) 20:21:46
fopenでファイル開いて、ストリーム中の特定の部分(データ)だけ削除して、 それ以降のデータを手前に詰めたい(リスト構造でデータを削除するそれと同じ感じ) んだけど、何かよい標準関数ないですかね?もし自分で実装するなら、 どういうアルゴリズムがいいでしょ?
リスト構造は別にデータを詰めないでしょ。 配列構造だな。 普通に地道に詰めるしかないと思うよ。 強いて言うなら、ファイルの書き込みに失敗した時にファイルが壊れて欲しくないなら、 一旦別ファイルを作って、成功したときのみリネームするようにした方がいい。
さすがプログラム板のスレ。 きびしいぃ。 普段苦労しているいるんだろうなぁ スレに沿った話題はフレンドリーなのにねw
どれを厳しいといってるのだろう。
85 :
81 :2008/12/21(日) 21:33:50
>>82 thx。詰めるって表現が間違ってた。
ABCDEFGHIJKLMNO
のうちGHを削除↓
ABCDEFIJKLMNO
って感じ。何か無意味なデータを詰めるんじゃないんです。
最初にEOFまでのサイズ取得しておいて、削除したらその手前までのseekサイズを差し引いた分
どっかに退避して、fwiteしなおすしかないかな。。。
ABCDEFGHIJKLMNO ↓ ABCDEFGHONMLKJI ↓ ABCDEFIJKLMNOHG
>>85 標準関数でなくてよかったら、ファイルの長さを変える関数はあるだろうから、
ファイルの中身をそう書き換えて、ファイルを短くすればいいよ。
>>85 いや、特に表現に間違いはないが・・・。
リスト構造の場合は、要素を削除しても要素の位置は変わらない。
次の要素がどこにあるかって情報を持ってるからね。
でも配列の場合は間を詰める必要がある。
だからこの構造はリストじゃなくて配列だ。
ファイル直書き換えは不慮のエラーが会った時に問題があるし(ファイルが壊れる)、
標準関数にはファイルの長さを変える関数もないので、
新しくファイルを作って、成功したときのみリネームした方が無難。
90 :
82 :2008/12/21(日) 22:25:15
>>87 仰るとおり。
メモリ空間上では、データの位置は変わってませんね。
>>88 そんな関数があるんだ・・・。調べてみるよ。
>>89 「新しくファイルを作る」ですか。または、データ削除前に
一発ファイルコピってから操作開始でもOKですよね?
とりあえず、データ壊さないように弄ってミマス。
>>86 ごめん、これ見ただけじゃ、俺にゃ理解できないお。
逆順に並べ替える何かあるの???
同じような考え方を持ってる人がいるんですね。 あのCM内容は在日や韓国が日本を支配するみたいな感じですね。 飛んでる飛行機とか韓国軍の飛行機みたいだし、「この国は我々の物だ!」とか言ってる時点でそう感じる。 あのCM見るとすごい不愉快になるし、ムカツイてきます。 在日の存在や韓国の実態を知らない人はあのCMを見てなんとも思わないんでしょうね。 今頃、あのCMを作った人や在日や韓国人は笑っているでしょうね。 あのCM内容でパチンコ業界のすべてがわかります。 反日だということを! パチンコは日本の癌です。
92 :
デフォルトの名無しさん :2008/12/22(月) 00:58:51
日時情報の機軸を、紀元(1970年1月1日00:00:00 UTC)になっていますが それを変更(機軸変更)して、例えば、その日の(00:00:00)に、したい場合 どうすればいいでしょうか?
93 :
92 :2008/12/22(月) 01:01:35
紀元(1970年1月1日00:00:00 UTC)から、その日の(00:00:00)に したいんです。 3600*〜などにすべきなのでしょうか?
3600*〜とか絶対にしちゃ駄目。 閏年とか考慮しやがらねえつもりだろ。 tm 構造体を使った関数を参照するといい。
基軸変更って発想がたぶん間違い。 当日0時からの秒数が知りたいなら、そう質問すべき
96 :
92 :2008/12/22(月) 02:16:31
>>94 はい、すみません。。。
>>tm 構造体を使った関数を参照するといい。
今、調べていますが難しい・・・・
>>95 はい、まさにそうです。
どうやって、求めるか悪戦苦闘中です。
97 :
92 :2008/12/22(月) 02:37:51
tm構造体で、固定するんですね
全レスうぜえ
99 :
95 :2008/12/22(月) 02:45:51
>>96 汎用的には localtime()とmktime()を使ってごちゃごちゃ
やるんだろうけど、0時から秒数なら単にこんな感じでいいのでは?
time_t t = time(0);
struct tm *p = localtime(&t);
return p->tm_hour * 3600 + p->tm_min * 60 + p->tm_sec;
100 :
92 :2008/12/22(月) 02:58:34
>>99 ありがとうございます。。。
とても、難しいです。
time_t t = time(0);の、0はNULLと同じでしょうか?
tm_hour * 3600 でどうして3600秒をかけるのでしょうか?
参考書レベルを凌駕していて、変な質問ですみません。。
おちつけ
当日0時からの秒数なら 3600*〜で別にええべ
当日0時からの別の日のある時間までの時間を取得したい場合は やっぱり tm 構造体使わないとダメだな。
#include<stdio.h> #include<time.h> int main(void){ unsigned long x; x=time(NULL); x+=60*60*9; // 日本時間 +9:00 x%=60*60*24; printf("%02lu:%02lu:%02lu = %lu[sec]\n", x/3600, (x/60)%60, x%60, x); return 0; }
mainは白紙 printfはペン
106 :
デフォルトの名無しさん :2008/12/22(月) 09:32:36
数学わからんから厳しいな
108 :
デフォルトの名無しさん :2008/12/22(月) 10:57:17
( ̄□ ̄|||) 算数ですか…
>>104 ダメすぎ。なんでlocaltime()を使わないの?
localtime()でstruct tmにばらしたら後は(tm_hour * 60 + tm_min) * 60 + tm_secなのに。
110 :
デフォルトの名無しさん :2008/12/22(月) 14:27:56
環境:Redhat コンパイラ:gcc やりたいこと:実行ファイルを実行した時、実行ファイルの格納されているディレクトリを取得したい。 例: ~/hogeという実行ファイルがあるとして #/home/user/hoge /home/user #cd /home/user #./hoge /home/user
板違いだけど #include <stdio.h> int main() { char buf[1024]; readlink("/proc/self/exe", buf, 1024); printf("%s\n", buf); return 0; }
n個の抵抗値を算出するプログラムなんですが #include<stdio.h> int main(){ int data[1000]; //数値 int teikou; //抵抗値 int n; //n個 int i; //for文用 printf("抵抗値の数を入力:"); scanf("%d",&n); for(i=0;i<n;++i){ printf("data[%d] = ???:",i); scanf("%d",&data[i]); } for(i=0;i<n;++i){ teikou += teikou + data[i]; } teikou = teikou / n; printf("抵抗値は%dΩです。",teikou); return(0); } でコンパイルすると、 for(i=0;i<n;++i){ printf("data[%d] = ???:",i); scanf("%d",&data[i]); } ここまではうまくいってくれますが、それ以降でエラーを出します。 どこの書き方がまずいんでしょう?
>>112 何で平均してるのかは置いといて、
「エラー」ってだけで伝わると思ってるの?
116 :
デフォルトの名無しさん :2008/12/22(月) 15:10:40
#include<stdio.h> int main() { int* data; //数値 data = (int*)malloc(sizeof(int) * n); //ここにdataを使う処理を書く free(data); return(0); } すまん。nは設定してたね。 抵抗の値が1001個を入力した時に落ちると思うから 上のように動的にメモリを確保したほうがいいよ。
118 :
113 :2008/12/22(月) 15:36:07
>>117 見てなかった。
良くない設計って書いてるね。
Windowsでの開発とはお作法が違うね。
119 :
112 :2008/12/22(月) 16:10:32
>>115 並列接続ですので、個数で割ってます。
エラーというのは、コンパイル終わったあとに、コマンドラインで実行中にエラーが出て強制終了してしまうと言う意味でした。
説明不足すみません。
>>116 今回には反映させてないんですが、次回からの参考にさせていただきます。有難うございます。
考えてみた結果、コマンドラインで実行中にエラーで強制終了する理由は、
teikou += teikou + data[i]; ここでteikouを初期化してなかったのが問題だったようです。
しかし、これを直してみても、ちゃんと値が反映されなかったのですが、それの理由が
teikouを動的変数にしていなかったのが問題だったようです。
120 :
112 :2008/12/22(月) 16:11:34
最終的にこのようなソースで、出来上がりました。 レスくれた方、ありがとうございます。 #include<stdio.h> int main(){ int data[1000]; //数値 static int teikou = 0; //抵抗値 初期化 int n; //n個 int i; //for文用 char line[100]; printf("抵抗値の数を入力:"); fgets(line,sizeof(line),stdin); sscanf(line,"%d",&n); for(i=0;i<n;++i){ printf("data[%d] = ???:",i); fgets(line,sizeof(line),stdin); sscanf(line,"%d",&data[i]); } for(i=0;i<n;++i){ teikou += data[i]; //teikouは動的変数 } printf("抵抗値は%dΩです。",teikou / n); //並列接続なので個数で割る return(0); }
何で並列だと平均なのさ。 それよりstatic付けたら静的だし、 そこはエラーと関係無いと思うんだけどな。 なんつーエラーか結局不明だし。 まぁ出来上がったってならいいか。
122 :
デフォルトの名無しさん :2008/12/22(月) 16:41:09
>>120 具体的な例を出すと、答えやすかったと思うよ。
例えば、
抵抗値の数を入力:3
data[%d] = ???:"1
data[%d] = ???:"2
data[%d] = ???:"3
抵抗値は10Ωです。
となってほしいが、現状はこうなっているみたいに。
エラーが起こるだけだと抽象的すぎて、何が起こってるのか想像しないといけないだろ?
>>123 エラーメッセージの英語ぐらい読めないのか?
The variable 'teikou' is being used without being initialized. って、ちゃんと書いてあるのに。
126 :
デフォルトの名無しさん :2008/12/22(月) 16:59:22
>>125 まぁ最初はそんなもんだよ。
次からは、
エラーメッセージを読む。
質問の仕方を考える。
の2点が学べてよかったじゃないか。
あるテキストファイルがあるとして その分析をしたいんだけど。 つまりこの空白には\tがはいってるのかとか そういうのってCで書けるっけ?
おまえの口調が気に入らない
130 :
デフォルトの名無しさん :2008/12/22(月) 17:23:20
>>128 ファイルを1バイトずつ読んで、タブがあるか調べればいいんじゃね?
>>123 >平均を求めるのはたしかにおかしいですね。
うわー俺も忘れてる。「和分の積」だっけ。
>精液と動的の違いもごっちゃになっているので
どう見ても精(ry本当に(ry
>>128 開いて読んでナメて閉じる。
(データをくまなく見る事なんだろうな)
133 :
デフォルトの名無しさん :2008/12/22(月) 17:48:49
int a, b, c; a=1,b=2,c=3; a+=2,b+=2,c+=2;//ここをスマートに書くことは出来ますか?
書くことができたとしても、実行時は同じになるだろ
int a = 3, b = 4, c = 5;
136 :
デフォルトの名無しさん :2008/12/22(月) 17:52:40
>>134 まずは、出来るのですか、出来ないのですか
出来るのであればご教授ください
137 :
デフォルトの名無しさん :2008/12/22(月) 17:54:05
>>135 すみません。初期化は私が望むものではありません
俺は教授じゃねえよ
142 :
デフォルトの名無しさん :2008/12/22(月) 18:01:06
前後関係がわからないけど、a,b,cを配列にすればいいんじゃないの?
複数の変数の値を一括で2加えるような操作をしたいということだよね
>>133 int a, b, c;
a=3,b=4,c=5;
orz = 3 ブッ or2 = 4 ブッ Orz = 5 ブッ
>>133 int __attribute__((aligned(16))) abc[] = {1, 2, 3, 0};
_mm_store_si128(abc, _mm_add_epi32(_mm_load_si128(abc), _mm_set1_epi32(2)));
>>133 int *helo[4] = {&a, &b, &c,};
for(int i = 0; helo[i]; i++){
*helo[i] += 2;
}
int a = 1, b = 2, c = 3; a += (b += ((c += 2) - c + 2)) - b + 2;
「スマートに書く」とはどういうことなんだ
>>133
#define SIZE (3) int i; int a[SIZE]; for (i = 0; i < SIZE; i++) { a[i] = i + 1; } for (i = 0; i < SIZE; i++) { a[i] += 2; }
プログラミング作法のqsortの比較関数で、 int scmp(const void *p1, const void *p2) { char *v1, *v2; ・・・ というのがでてきたんですが、 vって何の略なんですか? 他の関数の仮引数でもたまに見かけたりするので気になりました。
まちげえたvalueな
ばきゅう
157 :
153 :2008/12/22(月) 22:30:14
intとは何の略ですか?
いんてじゃー
イニシャライズの略です
character 文字 short integer 短い整数 integer 整数 long integer 長い整数 floating point number 浮動小数点数 double precision floating point number 倍精度浮動小数点数 strucutre 構造体 external declaration 外部宣言
いにゅーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーむ
enumerator 列挙子
湯にオーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーん
union は略じゃないお・・・
うにおん
168 :
デフォルトの名無しさん :2008/12/23(火) 00:26:51
未だに int func(); int func(a, b, c) int a; int b; int c; { … } のような書き方してる人が居るんだけど、 コンパイルは通るんだろうけど、有りなの?
>>168 Ansi-C以前のいわゆるK&RのC。
特殊なオプションをつけないとコンパイル通らないんじゃないかな?
RubyのソースってK&Rの書き方だよな。 今のバージョンは知らんけど、わりと最近のバージョンまで。
特に弊害が生じない記法だもの トリグラフなんかとちがって
エラーにはならんだろ・・・ 「古い形式です」って警告は出るかもしらんが。
K&R式だと、コンパイル時に引数の数と型のチェックをしてくれない つまらないケアレスミスをデバッグまで引きずることになる そういう意味で生産性が低い
floatとかshortがあるとわやだがな。
道民発見
数値計算だけだとCよりフォートランのほうがつおいの?
コボルもつおいお
二次元配列で2.481784 43.755463 というまともな数値がでてる中で -1606070790904610816.000という変な数値がでてしまうときは どういう時ですか?
最近ちょっと凝ったマクロを使い始めてCが楽しくなってきたところなんだけど、便利なマクロ集みたいなサイトあるかな? マクロで作った関数もどきはインライン展開されるから、関数呼び出しのオーバーヘッドが無いんだってね。
だからって早くなるとは限らないけどな
関数呼び出しを関数もどきのマクロに変えて速くなった、と。 とりあえず双方のコードをさらしてほしい。
staticな関数はinline展開してくれることもあるし
マクロ多い他人のソース見てると「どんだけ飛ばす気だ」って思う 元の処理に戻るのが一苦労だぜ
一箇所の記述にするためのトリックとしてマクロを駆使することはあるな #if defined(M_READ) #define IMP(arg, ID) arg = GetDlgItemInt(ID) #elif defined(INIT) #endif defined(M_WRITE) #define IMP(arg, ID) SetDlgItemInt(ID, arg) #endif a.inl IMP(memA, IDC_EDIT1) IMP(memB, IDC_EDIT2) ---- #define M_READ foo() { #include "a.inl" } #undef M_READ #define M_WRITE bar() { #include "a.inl" } ま、開発環境側がメンバ追加時に 記述すべき部分を補間してくれるなら こういう技巧も無駄だろうけど
そういう条件で意味が変わるマクロは、ソースを追うのが 困難になるのでいやだなあ あと #endif defined は typo だよね
#ifdef 禁止
inlineにするとプログラムサイズが増えるというデメリットをちゃんと認識しておけよ
>>177 数値計算でCとFortran
同じじゃないの
ただし、Cでは複素数
>>180 変数を初期化してない時。
あるいは初期化してない変数を使って計算した時。
#define A 5 #define B ((int)(sqrt(A)*100)) int x; x = B; gccを使ってコンパイルしています。 上記の場合、Bは常に223になると思うのですが、 実行時に平方根を計算するのではなく、コンパイル時にBが223まで 展開されるような最適化オプションはあるのでしょうか? 実行時にsqrt関数が呼ばれないようにしたいです。
__builtin_sqrtとか
((int)(sqrt(A)*100))の計算結果を使う
苦肉の策だが。 #define CONCAT_(a, b) a ## b #define CONCAT(a, b) CONCAT_(a, b) #define STATIC_ASSERT(expr) typedef char CONCAT(STATIC_ASSERT_, __LINE__)[(expr) ? 1 : -1] #define SQRT_A (2.236067977499790) #define A (5) #define B ((int)(SQRT_A * 100)) STATIC_ASSERT((A - SQRT_A * SQRT_A) < DBL_EPSILON * A); STATIC_ASSERT((A - SQRT_A * SQRT_A) > -DBL_EPSILON * A);
197 :
デフォルトの名無しさん :2008/12/24(水) 00:28:19
UNIXで使用できるファイル削除のC言語の関数ってなんていう名前ですか? fwriteとかfeofなんかと同じANSIな感じで。
unlinkとかremoveじゃね?
>>194-196 レスありがとうございましたm(_ _)m
builtin関数は知らなかったのでググってみます。
>>196 さんの例は難しくてまだ理解できていませんがコンパイルして試してみようと思います。
ありがとうございました。
203 :
デフォルトの名無しさん :2008/12/24(水) 01:05:35
一時変数のi.j.kはどうしてi.j.kが使われるようになったの?
数学の数列のノリじゃねーの?
繰り返すリロード、沸き上がるときどきの雑記帖
そんなこと、今さらどうでも良ーじゃーんか(i - j k) なんつって
なぁ、このスレ住人全員が力合わせたら、どんなプログラムでも組めそうじゃないか? プログラムで誰かを救えないかな
宿題でもやってその辺の学生救っとけば?
>>203 Fortranの影響かな
Wikipedia-Fortran
> Fortran暗黙の型宣言 Wikipedia-Fortranより
> ・ 整数型(変数名の先頭がI〜Nのもの)
> ・ 実数型(上記以外)
ちなみにIはIntegerのI。実数(Real Number)はR以降の文字をよく使う。
何かしら名残というものは、残っているもんですな。
そういえばそんなルールあったなぁ。。
#bmi.h# void bmi(void) { double height,bmi; int weight,high; printf("身長\n"); scanf("%d",&high); printf("体重\n"); scanf("%d",&weight); height=high/100.0; bmi=weight/(height*height); printf("BMI:%1.1f\n",bmi); if(bmi>30){ printf("ピザ\n"); }else if(bmi>25){ printf("普通\n"); } else if(bmi>18.5){ printf("ちょい痩せ\n"); } else if(bmi<18.5){ printf("痩せガリ\n"); } else if(bmi<18.5){ printf("キモガリ\n"); } }
>>21 25オーバーで普通ってどんだけキモオタ仕様なんだよww
おまけに18.5アンダーの比較が二箇所あるし。
一応書いておくぞ。
肥満4度:40オーバー
肥満3度:35オーバー
肥満2度:25オーバー
やせ:18.5アンダー
>>214 レス番レス番w >21じゃなくて>213だろ。
>>120 今更だけど、並列の場合は逆数の和の逆数だね。
return(0);とreturn 0;はどう違うんですか?
普通は後者 無くていいものを付けてるのが前者 returnを関数と誤解してる奴が書いてそうなのが前者 馬鹿っぽく見えるのが前者
ただし、昔は括弧つけないといけなかったらしい。
220 :
デフォルトの名無しさん :2008/12/25(木) 02:14:07
adj[i][j] って何ですか?
二次元配列
222 :
デフォルトの名無しさん :2008/12/25(木) 02:16:34
>>216 違いは、詰めて書けるか書けないか。オクテット分削れるか削れないか。
returnを例えば、関数マクロでラップしていたら前者になると思う、見たこと無いけどね。
if (), for (), while (), switch ()なので、retrun も()付ける人がいたりする。
しかしながら、見易さの問題でしかないと思う。例えば、式がキャストやビット演算を含む場合は、付けると見易くなる場合が多い。
return foo & ~bar; return ( foo & ~bar );ソースコードに統一感が無いと批判されるだろうが、私は、使い分けている。
>>219 K&R の初版では括弧がついていたそうですよ。
括弧の内側を開ける人って、見易くした積もりなのかね。妙に間が悪いというか、間抜けに見えるだけなんだが。
return( a+b );
C の場合は ( ) をつけると return を typo してもコンパイルされてしまうが、 リンクエラーになるのであまり気にしなくていい。
ただし、その場合、エラーの検出がリンク時まで遅れる。 リンクまでに時間がかる処理系の場合、typoをしないこと。
>>225 俺も一時期開けてたが、空きすぎると間が抜けて据わりが悪いと気づいて開けなくなった。
>>223 が return を retrun と typo している件について
気付いたけどスルーした
typoってタイプミスのことなんだな。 かわいいな。
デザインパターンがまるで分かりまa データ構造を組み合わせた場合の管理とか
最もCの実力があるプログラマはどこで働いているのでしょうか?
MS
>>233 最初はわからんでもいい
大規模なプログラムを組むようになるとデザパタの有り難みを
痛感するよ
Cでデザパタってのも変な話
別に変じゃない。
まんま実装しようとすると逆に苦労するようなものもあるだろうが 考え方や設計点の整理をつけるというところは無駄じゃないかと
米国国防省とか?
242 :
デフォルトの名無しさん :2008/12/25(木) 20:06:37
意味わかんねーことしてる奴が馬鹿に見えるのは普通だろ
>>241 お前が括弧付ける派で悔しがってるのはわかった
>>218 > returnを関数と誤解してる奴が書いてそうなのが
> 馬鹿っぽく
主観ばかりで根拠が無い
>>244 お前が括弧付ける派で悔しがってるのはわかった
returnには付けないけどsizeofには付けてます 考えてみるるとちょっと変だ
それは付けないとだめな場合があるじゃんw
>>245 > お前が括弧付ける派
意味不明。俺はつけない派だしw
>>247 > それは付けないとだめな場合があるじゃんw
へ?sizeof演算子も知らないとは、主観ばかりで
客観的な動作に対する説明が出来ないなら、黙ってろよ。
誰もお前の意見なんて聞いてない。
>>249 >へ?sizeof演算子も知らないとは、主観ばかりで
>客観的な動作に対する説明が出来ないなら、黙ってろよ。
>誰もお前の意見なんて聞いてない。
自分に対するレスを予想したんだね
初歩的なことだと思うのですが質問させてください。 10進数を2進数に変換するプログラムを作りたいと思っています。 10進数を2で割ったあまりをならべると2進数になると聞いたので、以下のようなプログラムを書いてみました。 実行してみると、どんな数値を入力しても 124500412450001244996124499212449881244984124498012449761244972 が表示されます。どこがいけないのでしょうか?
わろたw
コードを貼ろうと思ったら、長すぎて書き込めませんとか言われて、 いま焦ってるところだろ?
>>251 10進数を2で割ったあまりが4や5になるわけがない
そのプログラムをさらしてみ
プログラム貼るのを忘れていました^^; #include <stdio.h> main() { int x ,i ,z[10]; scanf("%d",&x); for(i=0; i>9; i++){ z[i]=x%2; x=x/10; } for(i=9; i>0; i--){ printf("%d",&z[i]); } return 0; }
>以下のようなプログラムを書いてみました。 プログラムがありません
printf("%d",&z[i]); 何これ
エスパーチャンスだったのにね
x=x/10;がダメ
いや、これだろ for(i=0; i>9; i++)
なんかいろいろダメだな
あっ、for(i=0; i>9; i++)ではなくfor(i=0; i<9; i++)ですよね? あと、printfをprintf("%d",z[i]);に修正したのですが、実行結果はどの数字を入れても 25600000000 になります・・・
あまりにもひどすぎて吹いたwww ハローワールドからやり直せwwww
>>264 だから・・・
x=x/10; > x=x/2;
>>264 for(i=0; i<9; i++)
iが何から何までの何回実行されるか考えてみよう
発想はいいのに、おしい!
#include <stdio.h> main() { int x ,i ,z[10]; scanf("%d",&x); for(i=0; i<9; i++){ z[i]=x%2; x=x/2; } for(i=8; i>=0; i--){ printf("%d",z[i]); } return 0; } これでいいかな?
>>269 なるほど・・・ありがとうございます
10で割っていくのではなく2で割っていくんですね・・・
意味もわからずに書いてたのか…
まずは算数・・・Cはそれからだ
サン・スーですか、イーアルね
274 :
デフォルトの名無しさん :2008/12/26(金) 00:16:01
最低限覚えてなきゃいけない関数ってどんなものかね
そんなの、使用目的によって違う。それよりも、標準ライブラリの基本的な使い方を 理解して、どんなものがあるかさらっと見て、試しに使ってみるしかない。
文字列関係とファイルIO(標準入出力も)は知っておかないと、 練習用のコードもかけないな。
とりあえず、stdio.hは最低限必要ってことで
グーグルでおk
280 :
デフォルトの名無しさん :2008/12/26(金) 12:49:22
if( a = B ) この上記の文条件式は a=0、b=0、代入成功のどれを条件としているの?
flag = true if( flag ) とかしないといけないのか、さすがC
>>280 Bはbの間違いだとして
bがaに代入されて、その値が0と比較して等しくなければ条件成立
要するにb!=0だったら成立する
>>280 そのどれでもなく、
Bを代入したaが0か非0か
Windowでプログラムを作るときはTCHARを使うべき? 自分はwchar_tを使うとすっきりしていいのだが
charで何も困ったことがない
>>286 環境に依存した話になれば、Cの立場から言えば好きなようにやればよいということになる
その環境内部での手法の良し悪しについてはもはやCの言及するべきことではない
>>286 TCHARはMBCSとunicodeをオプション切り替えだけでビルドできるコードを書く時に使う。
そういうコードを書く気がないなら決めうちでいい。
wchar_tでなくてWCHARをつかうべき。
何が違うんですか?
なまえ
C言語でPS3のソフトを作りたいんですが。 作れますか?
作れます
あなたには無理です
PSで作れるのは知ってるけどSONYにお願いしなきゃいけなかったはず
>>293 個人で市販のゲームみたいなのを作りたいということであればほぼ不可能なので諦めてください
会社に入って作る場合もC++になるのでやっぱり諦めてください
とりあえずPS3で動けば何でもいいというのであれば、Linuxインストールすればおk
すいません。教えてください。 typedef struct { unsigned char blue; unsigned char green; unsigned char red; } RGB; typedef struct { int width; int height; RGB* pRgb; } DATA; と定義した状態で、 DATA data = { 10 , 20, 0}; data.pRgb = (RGB*)malloc( data.height * data.width * 3); data.pRgb[0][0].blue = 0; とやると↑の行で、 error: subscripted value is neither array nor pointer というコンパイルエラーが出ます。何が間違っていますか。
data.pRgb->blue=0の柿間違い
ああ、俺も間違えてる。。 data.pRgb[0].blue=0かな。。
たぶん data.pRgb[0][0].blue = 0; ってのは座標(0, 0)のピクセルのblueって言いたいんでしょ? pRgbはRGBの一次元配列として認識されているので2次元配列っぽくアクセスすることは出来ないよ。 そういう場合、座標(x、y)なら、 data.pRgb[w * y + x].blue = 0 みたいな感じで座標を一次元配列のindexに変換してアクセス。
ありがとうございます。 data.pRgb[someHeight * data.width + someWidth].blue = 0xff; とやればできました。 ただこういう場合に2次元配列の書き方ではできないものなんですかね。
>>303 技巧的になるけどできなくはないよ。この板で何度も取り上げられている。
でもまぁ、一次元アクセスもポピュラーだから慣れておいてもいいと思う。
どうしても馴染めないなら、int offset(int x, int y, int w) {return x + y * w;}でも作るとか。
3じゃなくてsizeof(RGB)を使え
typedef struct { int width; int height; RGB **pRgb; } DATA; data.pRgb = (RGB **)malloc( data.height * (sizeof(RGB *) + data.width * sizeof(RGB))); for(int i=0; i<data.height; i++) data.pRgb[i] = (RGB *)(data.pRgb+data.height) + (data.width * i); これでいける?
ああそうか。例えばdata.pRGB[1][1]と書いた場合にdata.pRgb[0]の位置から何バイト先かが分からないから2次元配列の形式で書けないわけか。
そういうこと Cには多次元配列というものはない、配列の配列があるだけなので、 下位の配列にアクセスするためにはそのサイズを知っていなければいけないが、 配列のサイズを動的に宣言できないから 下位のサイズが動的な配列の配列は作れないのでポインタの配列でまねるしかない C99ならできるけど
便乗して質問するけど、もし320x240固定だとしたら、どうやればいいんだろ。 たとえば関数に渡す場合なら RGB * foo(RGB * m[320][240], int x, int y) { return m[x][y]; } int main(int,char**) { RGB x[320][240]; RGB * p = foo(&x, 0, 0); } みたいに書いて、RGBの320x240の配列の先頭アドレスを渡して、それをfooでRGB *[320][240]みたいな型(文法上はエラーだと思うけど意味はわかりますよね?) で受け取りたい場合。
RGB (* m)[320][240] ってするだけだろ
あとfooで使うとき (*m)[x][y] になるね
できた。
>>311 じゃあmallocの戻りを
RGB * px[320][240];
px = (ほげほげ)malloc(320*240*sizeof(RGB *));
ってキャストしたい場合、ほげほげはどう書いたらいいのですか?
できない。 配列は左辺値になれない。
>>313 配列だから代入不可能
それでいいのか?
RGB (* px)[320][240];
に対してなら
((*)[320][240])でキャスト
つーかそもそもいらない
RGB * px[320][240]は配列なんですね。
そういえば、ポインタの配列とか、配列のポインタとか昔勉強した気がするなぁ。
もう完全に忘れてる(ってかもともと理解できてなかったのかも^^)
>>314-315 さん、ありがとうございます。
やりたいことはこうだろう RGB *(*px)[240]; px = malloc(320*240*sizeof(RGB *));
>>315 間違ってるけど別にいいか
どうせ通らないし
319 :
316 :2008/12/27(土) 03:22:07
ちょっと悩み中です。
320 :
316 :2008/12/27(土) 03:27:59
すんません。寝ます!
何かPCが重いと思ってタスクマネージャでプロセスを見てみたら、"run32dll.exe"が暴走してました どうしたらいいのですか?
323 :
321 :2008/12/27(土) 14:19:07
自己解決しました
324 :
321 :2008/12/27(土) 14:57:51
解決してません
num_tbl 型は char型が4つ、全部で4バイトです。そういえば int型も4バイト。 なので、同じ4バイト同士、一気に代入してしまいましょう。 char num_tbl[4]; *((*int)num_tbl) = 0;// 0で初期化 受け側の num_tbl を一旦 int型のポインタに変えて、その中身に 0 を代入。 1行で済むし、コピー命令も1回だけの発生ですみます。 32ビット環境で、こういうものがありましたが理解できません。 intで0は2進数で00000000000000000000000000000000だから、 00000000|00000000|00000000|00000000 になって全部0になるってことですか?
memcpyの引数の順番をいつも忘れてしまうんですが、忘れにくいうまい記憶法とか有れば教えてください。 memcpy(buf1,buf2,size); // buf1→buf2だっけ、逆だっけ……
>>325 2進数で考える人はあんまりいないけど、そういうこと
>>326 src, dst の順って覚えてる
328 :
327 :2008/12/27(土) 16:42:02
>>327 ありがとう。すっきりしました。
ところで、普通は2進数で考えずに何で考えるんですか?
>>326 代入と同じ順番
y = x; // y ← x
memcpy(buf1, buf2, size); //buf1 ← buf2
>>327 ありがとうございます。
ただ、名前付けるといつもこんがらがってました
>>329 これはわかりやすいですね!
積年の悩みが解消されそうです。ありがとうございました。
fwrite とかの 要素サイズ数 要素数 の順をよく忘れる ヘッダ見ても同じ型だから区別つかないしー
もうIDEとかエディタの機能に頼ってしまえ
ぐぐれかす
Cを書くときに最強のエディタ(GUI限定)ってなんなの?
GUIじゃないエディタってなんだよwww edか?
ほら。例のビジュア・・
qsortと行く前にこけてるけど
qsortのコードもまともじゃないような?
>>337 展開してまで見るのは面倒なのでパス。
>>335 emacsはGUI版よりも端末版のほうが私は好きです。
>>334 「最強」の基準によっても変わる。
>>331 ヘッダを見たら、仮引き数に名前がつけられていないか?
手元のcygwinでは前者が_sizeで後者が_nだ。
>>326 やはり、ヘッダを見れば判る。しかもこの場合は型も違う。
>>341 VS2003 だと仮引数無しで型のみの羅列だね…
仮引数に意味を類推できる名称がつけてあるだけでも違うなー
343 :
327 :2008/12/27(土) 19:20:11
>>328 一般的には、アドレスがバイト単位で割り振られているので
バイト単位で考えると思う。
まあ、こんな感じ
0 1 2 3
┌──┬──┬──┬──┐
│0x00│0x00│0x00│0x00│
└──┴──┴──┴──┘
なお、
>>325 の方法は、アライメントが揃ってないと CPUによっては
例外が発生するとか、0以外の場合 endian に依存するとかあるので、
一般的には注意が必要。
>>330 ごめん、src と dst は逆でした。
>>326 代入演算子と同じ順番、すなわち
buf1 = buf2, size
と憶える。
memcpyでググれば使い方出てくるのに
ある本で勉強しており構造体のとこまで来たのですが
線形リストについて具体的なソースが無く、自分で書いてみました。
http://www3.uploda.org/uporg1888553.c.html プログラムでは、終了する前までに解放している筈なのですが
メモリ使用量をモニタしていると、どうも終了してから解放されているようです。
つまり、プログラムに書いたfree()がうまく効いていないのだと
思うのですが、アドバイスお願いします。
347 :
346 :2008/12/27(土) 22:54:04
パス忘れてました。12345です。
モニタが嘘をいってるわけではない。
349 :
337 :2008/12/27(土) 23:10:38
>>338-339 もう一度考え直したのですがよくわかりません。
詳しく教えていただけませんか?
>>346 Cライブラリが一括でOSからメモリを確保しておき、
mallocとfreeはそこから領域を切り出したり、返したりしているかもしれない。
そうすると、freeしてもすぐにはOSへメモリを返すことにはならない。
>>346 そもそも、その「メモリ使用量をモニタ」している手段が判らんからなんとも言えんが、
デバッガで確認しないのはなんで?
>>349 mainのfscanfの使い方がおかしい
nが初期化されてないのにnの余りを計算している
quick.cのアルゴリズムが変(無限ループ?)
qsortでググれば、サンプルコードいっぱい見つかったけど...
>>350 その場合、ソースが意図的に動いているかは判らないということですか。
>>351 GNOMEのシステムモニタです。Windowsのタスクマネージャに相当するのかな?
デバッガは、コンパイラがgccで良く判らないもので。。
>>353 printfでいろいろ表示させるのも、基本的なデバッグ方法だよ。
mallocとfreeのところでそれぞれポインタ値を表示させれば確認できるでしょ。
355 :
353 :2008/12/27(土) 23:55:10
gdb使ってみました。 // 最初のList_New() Breakpoint 1, List_New (lastlist=0x0, init=0) at main.c:25 25 return newlist; (gdb) print newlist $1 = (List *) 0x82c9008 (gdb) continue // 次のList_New() Breakpoint 1, List_New (lastlist=0x82c9008, init=1) at main.c:25 25 return newlist; (gdb) print newlist $2 = (List *) 0x82c9018 (gdb) clear 25 (gdb) continue 0:0x82c9018 // 最初のList_Remove() Breakpoint 2, List_Remove (rmlist=0x82c9008) at main.c:36 36 return newhead; (gdb) continue 1:0x82c9028 // 次のList_Remove() Breakpoint 2, List_Remove (rmlist=0x82c9018) at main.c:36 36 return newhead; ポインタの値が一致しているので、一応きちんと動作している、と 考えてよいのでしょうか。
>>352 >nが初期化されてないのにnの余りを計算している
nにはMAXを入れるのでしょうか?
>quick.cのアルゴリズムが変(無限ループ?)
quick.cもq1.cも教科書の物をそのまま使っています。
10行目のwhile(x[j] > x[end] && j>i)i--; の && j>iが抜けていたのですが、
ここを修正しても結果が出ませんでした。
ではあちこち移し間違っているのでしょう なめるように見直せ
>>346 >>353 メモリは、全て開放(free())されているよ。ただし、プログラム終了時に、OSに返されている。
大体、メモリの確保量が少ないので、free()しても返されていないだけ。
昔、どれだけ確保すれば、free()したときに返されるか試したことがあったが、もう忘れた。
ソース探したんだけどなぁ、見付からなかった。
Linux(kernel 2.6.18-92.x)上で、GCC 4.1.2でやってたけど、一度の確保量が216 Bytesくらいだったかな。
360 :
355 :2008/12/28(日) 00:18:11
>>358 どうもありがとうございました。安心しました。
初心者です char str[256]; これの説明でstrは文字が256文字納められる配列とあったのですが、 「a」は1バイト、「あ」は2バイトでデータの量が違うのに同じ文字数配列に格納できるのでしょうか そうではなくて「a」は256文字で「あ」は128文字分しか格納できないのでしょうか どなたか教えてください
2バイトの文字なら128文字分しか入らないよ
>>357 なめるように見直したら、所々のミスが見つかりました。何度も見直したつもりだったのですが、すみません。
それで、比較回数と交換回数を求めるように改良したいのですが、 うまくカウントしてくれません。
どこを直せば良いでしょうか?
int hikaku = 0, koukan = 0;
i = start;
j = end -1;
while(1){
while(x[i] < x[end])i++;
hikaku++;
while(x[j] > x[end] && j>i)j--;
hikaku++;
if(i >= j) break;
tmp = x[i];
x[i] = x[j];
x[j] = tmp;
koukan++;
i++;
j--;
}
tmp = x[i];
x[i] = x[end];
x[end] = tmp;
printf("比較回数: %d\n", hikaku);
printf("交換回数: %d\n", koukan);
>>362 ありがとうございます!
もやもやが晴れました!
>>363 int hikaku = 0, koukan = 0;
を関数の外に出してみれ。
>>361 確かに char str[256]; に1バイト文字を256文字入れる事ができるが、
C の文字列を扱う場合は通常最後に 0 を入れるので
実質的には255文字しか入れる事が出来ない。
全部2バイト文字だと127文字だな。
もちろん、2バイト文字127文字+1バイト文字1文字も可能だが。
>>365 なるほど! しっかりとカウント出来るようになりました。
しかし、出力がおかしいです。
比較回数: 29140
交換回数: 11347
比較回数: 29142
交換回数: 11347
比較回数: 29144
交換回数: 11347
比較回数: 29146
交換回数: 11347
という風に、たくさん表示されます。これも関数の外に出すのでしょうか?
printfを#includeの下や最後の}の下に持って行ったのですが、これではコンパイル時にエラーが出ます
なんども申し訳ないです。
>>361 蛇足だけどソースをutf8にしたりすれば確かめられるだろうけど、
一文字3バイトになったりすることもあり2バイトとは限らないので注意
>>367 int hikaku = 0, koukan = 0;
をmain関数で参照できるようにしてみれ
>>369 戻り値ってやつでしょうか?授業でやってないことなのでわかりません。
もし良ければ教えてください。
まんどくさい、グローバルに宣言して、mainで0に初期化しておいて、ソーと関数の中でカウント、 最後にmainで表示でおk。
ちゃんと理解していないのにいきなり高度なことができると思ってるのか 基本からやりなおせ
「習ってない」は中学で卒業しろ
基礎はすっとばしておいてあとで人に聞けばいいや という根性では誰からもそっぽを向かれるぞ
足し算引き算のできない人間が微分積分を理解できるとでも思ってるの? 馬鹿なの?
微積分を持ち出しておいて、足し算、引き算かよ・・・
>>363 逆順だと動いてるように見えるけど、
そのコードだとうまくソートされないよ。
このスレを見てると痛感するが、教育改革の第一歩は自習の義務化だな。なんか矛盾してるようなきもするが
>>379 むしろ自習を促すような教育技法、いや教育理念を教員側が持つ必要があるのでは?つまるところ科挙制度がまかりとおる世間一般の通念が問題なのでは?みんな手を抜きすぎ。
>>370 これにめげずに本を読めば、いろいろわかってきて楽しくなると思います
教科書が悪いかも試練。
writeの進捗状況を画面表示したいのですが進捗を知るにはどうしたらいいですか。
fwriteの進捗状況を画面表示したいのですが進捗を知るにはどうしたらいいですか。
OSとCライブラリを作り変える
別スレッドでファイルサイズをチェックすれば
388>> 上書きの場合無理。
↓ んじゃ、別スレッドで中身をチェックすれば。 ↓ 中身が(殆ど)同一だったら無理。
最終的に書き込むサイズがわからないの?
fwriteの進捗状況ってのはfwrite呼んだあとにディスク(その他)へ書き出されるまでの間の進捗状況を逐一表示したいんだろ?
1バイトづつ書き込む
char b[64]; char c[8][8]; printf("%p\n", &b[0]); printf("%p\n", b); printf("%p\n", &b[63]); printf("%p\n", b + 63); printf("\n"); printf("%p\n", &c[0][0]); printf("%p\n", c); printf("%p\n", &c[7][7]); printf("%p\n", c + 63); としたとき最後の2行の表示が違うのは何故なのですか?
>>394 printf("%d, %d\n", sizeof(b[0]), sizeof(c[0])); とかやって、結果を見ると思いつくかも。
>>394 &c[7][7]
同値
&(*(*(c + 7) + 7)) シンタックスシュガー
(*(c + 7) + 7) 最適化
同値
&(*((char *)(*((char *[7])c + 7)) + 7)) 明示的に書いた
または、
&(*(*((char *)c + sizeof(char *[7])*7) + sizeof(char *)*7))
cから、sizeof(char *[7]) * 7進んで、その進んだcの間接参照から、sizeof(char *) * 7進んで、その逆参照のアドレス値
((char *[7])c + 63)
または、
((char *)c + sizeof(char *[7])*63)
cから、sizeof(char *[7]) * 63進んだアドレス値
もういいや
もっともらしく嘘を書いてしまった。 s/&(*(*((char *)c + sizeof(char *[7])*7) + sizeof(char *)*7))/&(*(((char *)c + sizeof(char *[7])*7) + sizeof(char *)*7)/
日本語処理について質問です。 以下のコードでキャラクタ文字みたいに、"京"ならp[1]、"へ"ならp[2]で表示させたいんですが。 何も表示されません。short型だとエラー。int型だと"ク"になってしまいます。 コンパイラはBorland C++ Compiler 5.5です。 #include <stdio.h> void main() { int p[] ={"東京へ行きたい"}; printf("%c",p[1]); }
むちゃしやがって。。 %cは1バイトの文字しか対応しないんだろ。
>>398 ワイド文字版を使う
#include <wchar.h>
#include <locale.h>
int main(void)
{
wchar_t p[] = L"東京へ行きたい";
setlocale(LC_ALL, "");
wprintf(L"%lc\n", p[1]);
return 0;
}
>>400 ありがとうございました。解決しました。
入門書何冊か探したけどこういう事は載ってないんですよね。
402 :
デフォルトの名無しさん :2008/12/28(日) 21:01:04
自分で調べる力を授けようとする目的からして必要かどうか筆者の見識が分かれているのだろう
その自分で調べるっていうのは本で調べるってことじゃないの?
単に入門書レベルでは扱わないだけだと思うが そういえば自分は多バイト文字というものをどこで知ったんだろう…覚えてない
405 :
デフォルトの名無しさん :2008/12/28(日) 21:08:59
その調べる本の種類を「はじC」とか想定するのかよ 特定の書籍を揶揄する気はないが、おまえさんの言う「本」てのは何のつもりだったのかね
406 :
デフォルトの名無しさん :2008/12/28(日) 22:59:37
charって127から-127まで扱える事に聞きたいんですが char a=100; printf("%d",a); とやれば100と出ます。 ですが、 char a; scanf("%d",&a); printf("%d",a); とやるとscanfでうけとった数字たとえば33とかがうまく表示されないんですが どうすればいいんですか?教えてください
俺は文字コードをperlの正規表現やるときに学習したな
408 :
デフォルトの名無しさん :2008/12/28(日) 23:07:29
charって127から-127まで扱える事さん、いますか?
>>406 %d指定子はintへのポインタをとらなければいけない。
charへのポインタを指定したら間違いなくおかしなことになる。
整数をcharの変数に入れたいだけなら、intの変数に%dで
(あるいはshortの変数に%hdで)値を格納してからcharの変数に代入すること。
または、環境が許すなら%hhdを使うこと。
410 :
デフォルトの名無しさん :2008/12/28(日) 23:10:48
あと、少なくとも127から-127までという決まりなのは、signed char。 現実には、0から255までのunsigned charとcharが同じ大きさということもよくある。 さらに、signedでも2の補数使って-128から127になるのが現在主流。 そもそも、8ビットより大きい可能性もあるが、今ではかなり珍しい。
36ビットマシンとかあったんだっけ?
64ビット時代がきたらcharが16ビットになる そんなふうに考えていた時代が俺にもありました
オクテット単位で扱えないと結局不便だろうから (既存のメディアを扱うことを考えると) char のビット数は簡単には変わらんだろうね。
414 :
デフォルトの名無しさん :2008/12/28(日) 23:53:37
おっとできました intでもshor intでもいったん代入して char a; int i; scanf("%d",i); a=i; printf("%d",a); これでもできましたshortでもできました。ありがとうございます。 ついでに、ビット長ってありますよね? char 8ビットなどint 16または32 ビットってあんまりイメージわかないんですが。 ビットが大きくなっていれば小数点10桁など大きい数字を扱えるんですが。 ビットとかC言語をやる中で気にしなくてもいいんでしょうか?
ビットってのは単に2進数での桁のことだ。 ビット数を気にしなくても組めるプログラムは多いが 気にした方がいいケースもある。 オーバーフローしそうな場合とか、 ビット演算すると計算が楽になる場合とか。 まあ、プログラマなら65536までの2の累乗を覚えて 16進数←→2進数変換を頭の中でできるようになっとけ。
桁は英語で digit と言う。 2進法(binary)+桁(digit)=ビット(bit)となる。 ~ ~~ 3進数の桁を trit とか言ったりもする。
↑もトリって言うね
>>415 なっとけなんて言うことないだろ。
言われなくたってどうせ嫌でも頭に入るさ。
419 :
デフォルトの名無しさん :2008/12/29(月) 00:21:22
4進数が出てこないのは、ある種の「狭さ」だな
420 :
デフォルトの名無しさん :2008/12/29(月) 00:21:38
今までビットなんて気にせずプログラムを学んでたんですが むずかしいですね。 あ、あとちなみに、関数の読み方などが理解不能なんですが int scanf(const char *format , ...); int printf(const char *format, ...); これらは気にせず printf("hello");など書いていたんですが。 戻り値がintなのにprintfを使えるって変じゃないですか? intがあるからreturnもありそうなんですが。 int main(void)と書くのですが何故 int printf();とは書かないんでしょう それとconst char *format, ...この意味がさっぱりです*formatの意味は%dや%cなどとわかったんですが const charこれは"hello"や文字の部分を表してるのでしょうか?それと, ...は変数などのprintf("%d",xxx); xxxを表してるんでしょうか?詳しく教えてくださいお願いします
>>419 んー、非常に大雑把な議論によると、計算機のビット数は2進よりも3進のほうがいい、という結論が得られています。
あるいは平衡3進法ということばもあります。
3進法は(すくなくとも理論の上では)多少なりとも意味があるので、よく目にするものだと思います。
一方4進法にさしたる意味はありません。
>>420 printf の戻り値は出力した文字のバイト数。
大抵そんなもの使わないので無視してるだけの話。
>>421 ネイピア数 e ≒ 2.7 に近いほど最良で、
2 よりは 3 の方が e に近いから、だっけか。
でも、回路は2進法の方が作りやすいんで、
結局2進法に軍配が上がるというところだな。
ビット演算も分かりやすいし。
計算量の多い問題が解けるっていう量子は 机上の空論だったんだろうか
>>420 > あ、あとちなみに、関数の読み方などが理解不能なんですが
> それとconst char *format, ...この意味がさっぱりです*formatの意味は%dや%cなどとわかったんですが
> const charこれは"hello"や文字の部分を表してるのでしょうか?
それは関数のプロトタイプの書き方で、関数の引数や返り値の型を表示するやりかたですね。
int printf(const char *format, ...);
を例にすると、
関数printf() は第一引数の型は const char へのポインタ、第二引数以降は可変長引数、返り値の型は int
を示しています。
Cに慣れるまでスルーしていいと思います。
> 戻り値がintなのにprintfを使えるって変じゃないですか?
たしかに printf() の返り値は私もチェックしたことはありませんね。printf() 自身は値を返すことができても、
そのように明示しなければ、それはそれでOKなんでしょうね。(文法書みてませんので憶測ですみません。)
printf("hello"); でいいと思いますし、普通だと思います。
大昔の流儀では
「(void)printf("hello")と書け」
というのがありました。(lint ... 私もつかったことないや)
>>419 多値変調のことも忘れないでくださいって話?
状態遷移から1、0をはきだすのはCで十分なの?
430 :
デフォルトの名無しさん :2008/12/29(月) 05:06:26
「WOLF RPGエディター」とは?
・高度なRPG開発が可能な、完全無料のゲーム作成ツールです。
・製作者はなんと「モノリスフィア」やツクール2000でシルフェイド幻想譚などを製作した
SmokingWOLF氏だよ。
・雰囲気はRPGツクール2000に近い。RPGツクール2000で自作システムを作りこむ際に
不満だったところがいろいろ解消されていて、かなり自由度が高いです。ただし
その分初心者には難しいかも。すでにツクール2000で自作システムを組むのに
慣れた人やRPGツクールでは物足りないけどプログラミングはちょっとという方にお勧め。
・作成したゲームは自由に配布したり、コンテストに投稿することも可能。
また本ソフトを持たない人でもプレイ可能!ファイル暗号化も完備してるよ!
・要望、不満点、バグ報告などなど書き込みお願いします。今もどんどん進化中です。
・それとマップやキャラなどのドット素材もじゃんじゃん募集中ですので
一度サイトにお越しくださいませ。
・このツールで作ったゲームをサイトで紹介してるから、ダウンロードしてどういう
ゲームが作れるのか見てみてね。
2ちゃん本スレ
http://pc11.2ch.net/test/read.cgi/gamedev/1229261856/l100
趣味でプログラムをと考えています。 たとえば2chのスレ等の特定の言葉を集計、カウントしたり 画像掲示板の画像を自動で集めたりみたいなWeb上で動作するものを作ってみたいです。 OSはXP、数年まえに手書きでへぼいHP作ったり、JAVAで画像表示とかで少し遊んだ経験のみです。 おおすめの言語がありましたらご教授お願いします
Cでないことは確実。 Rubyがいいんじゃないかな。Rubyスレで聞いてみな。
計算式 x=pow((1.0+h),(1.0/h)) これを、for文で hを1から限りなく0にしていくときの計算結果を 表示させるプログラムを作りましたけど、 いきなり最初の答えが間違ってしまいます。 hに1を代入して計算させても、「2」にならず、「inf」とか表示されてしまいます。 使っている変数宣言は 全てdouble で、コンパイラはgcc です。 教えてください。お願いします。
コードもなしにエスパー回答を待つのが流行ってるのか。
0 からループを回してるに1票
すみません。コードは次のものです。 #include <stdio.h> #include <math.h> double ans(h) { return pow((1.+h),(1.0/h)); } int main(void) { double h; for (h=1.0; h>0; h=h-0.001) printf("%10.8f %20.18f\n", h, ans(h)); return 0; } 以上、よろしくお願い致します。
- double ans(h) + double ans(double h)
%20.18fなんかじゃなく%.18gを使えばいいのに。 ans()の引き数の型を指定しておけばいいのに。
>>437 ,438
修正したところ、計算されました。
printfの書式の扱いもまだ不慣れで fとgの違いもよく分からないですけど、
調べてみます。ありがとうございました。
調べてから言え
442 :
431 :2008/12/29(月) 12:55:19
誤爆だったことに今気づいた
443 :
デフォルトの名無しさん :2008/12/29(月) 12:55:44
なんで符号付きsigned 符号なしunsignedがあるんですか? 何もしなくても符号がつきますよね?符号がつかないコンパイラだけ必要っていみですか?singedは? short intも intかlong intを使えば良いのに。 詳しく教えてください
昔はメモリが少なかったんだよ
>>443 signedだと(主に最上位の)1ビットが符号付きかそうでないかに使われるじゃん?
1ビット分違うだけで表せる幅が倍になるよね、多分。
>>443 charだけは何もしない場合にsignedになるかunsignedになるかが環境に依存する
変数のサイズについてはメモリ効率に関する選択の問題
447 :
394 :2008/12/29(月) 15:06:02
亀レスすいません
>>396 &c[7][7] 同値*(c + 7) + 7ということですが
c同値&c[0][0]だから
(c + 7)同値c[7]同値&c[7][0]ですよね
printf("%p¥n", &c[7][0]);
printf("%p¥n", c + 7);
printf("%p¥n", *(c + 7));
実際全部同値でした。
しかし何で(c + 7)と*(c + 7)が同値なんでしょう?
そもそも(c + 7)は&c[7][0]に同値だから、
*(c + 7)はc[7][0]に同値なのではないのですか?
また、&c[7][7]を表わすのに(c + 7) + 7としてしまうと、
c+14になってc[14]同値&c[14][0]となるから
(c + 7)を1バイトにキャストしなければならないのですね?
何でこれが間接参照演算子*でできるのでしょうか。
どうも私自身間接参照演算子についての理解が足りないようです。
ご教示お願いします。
>>443 2バイト事に扱いたい場合とかもあるんだぜ。
>>443 signed というキーワードは signed char 以外では特に指定する意味がない。
char に関しては
>>446 なので、符号つきであることを保証したい場合には付けないといけない。
intを省略するために使うこともできるけどね。 cf. static signed foo; struct { signed bar:2; };
ビットフィールドだと、 構造体のサイズを気にしない場合は int と書くことに大した意味がなかったりするから、 signed/unsigned とだけ書く事があるね。 struct hoge { signed a : 4; unsigned b : 1; unsigned b : 3; };
変数名変えるの忘れてた。3つ目は unsigned c : 3; だ。
454 :
デフォルトの名無しさん :2008/12/29(月) 18:55:29
アルゴリズム関係の書籍は何であんなに高いの? 一冊2万5000円とかおちょくってるの?ねぇ
P2P推奨っていうことでは?
456 :
デフォルトの名無しさん :2008/12/29(月) 18:58:05
そんなんで赤字になるような奴は対象外ってことさ
>>458 本当だ…なんか一桁多いなぁ…それだけの内容ってことか?
ぶっちゃけパ王が便利すぎるからボウシなんかいらないよ
誤爆すいませんっしたぁーーーー
こりゃひどい。
>>459 広い範囲のアルゴリズムが載っているからだとおも
海外とかだと、もっと安いのかな、
見やすくするためソースファイルの分割に挑戦したのですが、その過程で一つだった関数を分け、 さらに変数の共有を行うために、異なる関数(分割前は一つだった)で共有したい変数は 全てグローバル変数にしました。 そのため別にヘッダーファイルを作成し、インクルードするなどしています。 なんだかややこしい方法を取ってる気がするのですが、これでいいのでしょうか?
>>465 よくない。
結合度と凝集度でぐぐれ。
あと、複数の関数で共有するデータは、構造体へのポインタで持ち回れ。
(例: fprintf等のf系の関数。「FILE *」でデータを共有している)
グローバル変数だと誰が何処で書き換えるかわかったもんじゃないし、
マルチスレッド化すると破綻する。
ある関数と、その何10階層も下にある関数でのみ使用する共通変数があるとして、その変数を何10階層も引数の形で渡していくのと(途中の関数ではその変数の読み書きはしない)グローバル変数にするのではどちらの方がよりよいプログラムだろうか
グローバル変数への参照を取得する関数を定義する そもそも何10階層も呼ぶ設計がおかしい
普通はその変数以外の情報も一緒に渡すし、 それが構造体なんてこともよくある話。 その構造体の中にその変数があれば、 受け渡しのコストはそもそも存在しない。
スタックの方がキャッシュヒット率が高いから あんまグローバル変数にしても高速化が見込めない可能性もある。
プログラムの広範囲で使う変数もグローバル変数じゃなくて mainのローカル変数にしてアクセス用の関数を作ったほうがいいの?
はい
あんまりよくなくね?
>>473 広範囲で使うデータをグローバル変数にして、マルチスレッド化や
マルチインスタンス化するときに痛い目に遭ってるのをしばしば
見掛ける。
排他制御
ていうかアクセス用の関数って具体的にどういうものなの?ミューテックスとかを使うの? マルチスレッドとかなら利点がわかるんだけど標準のコード書いてるときに利点がわからない
>>478 C++でいうprivateメンバにアクセスするpropertyみたいなもん
どういう痛い目に合うのか具体的に教えて欲しい
>>481 グローバル変数の実体は1個しか存在しない
別々のことやってるスレッドで1個の変数を共有したらどうなると思う?
そんでそれを回避するためにローカル変数に直して、
それを各関数に受け渡す仕組みを作り直す手間がどれくらいあると思う?
そんな手間か?だいたいマルチスレッド化を常に考えてプログラミングって馬鹿だろ それよりもっと一般的なグローバル変数の弊害を考えろよ
>>483 マルチスレッド化を考えないことは必ずしも馬鹿ではないだろうが
常に考えることは間違いなく馬鹿ではないよ
手間でないと思うならそれは君が大規模なプログラムを組んだことがないだけだろう
>>483 どこからでも扱えて、何か起こった時のデバッグ範囲が広大になることだな。
>>484 そりゃ大規模なプログラムなら全体かかる修正は何でも大変だろww
まぁここ入門スレだからな・・
だよな・・・・・・・
グローバル変数が問題になるのは常にアクセス権の話であって本質的にはどれも同じだよ マルチスレッド化にからむ話とそれ以外をわけて考えてるのがおかしい
グローバル変数は使う場所と宣言の場所が離れてるから名前を忘れやすくなる。 ローカルなら、エディタ画面でおさまる範囲に書いてあるけど。
>>486 そんなことはないぞ・・・。
もしそういう状況になってるのだとしたら、
それはお前のプログラムの組み方が悪い。
なに質問スレでくだらない議論してんだよお前ら
ふとした疑問なんですが autoっていう修飾子あるじゃないですか あれを明示してるひとって見たことありますか?
グローバル変数でも static つければ範囲狭められるし、 errnoみたいな伝統的に使われてるものもある。 なんか「グローバル変数=悪」って思い込んでるのかもしれないけど うまく使えば、プログラムをシンプルに出来る うまく使えば、プログラムを高速にできる うまく使う方法を議論する方が建設的
グローバル変数を使うと、往々にして安きに流れて、それ特有の「お作法」を発生させてしまうことがよくあります。1週間たったらすっかり忘れてしまうのでした。 値をいれるのはここだけ、あとはみんな参照、くらいでとどめておきたいのですが、ね。
>>493 autoは記憶クラスです。修飾子ではありません。
>>494 errnoがグローバル変数とは限らない。
少なくともWindowsや最近のUNIX系OSは軒並スレッド毎に固有。
>>498 もちろん知ってるよ
UNIXのマルチスレッド対応時に真っ先に問題になる部分だからね
とりあえず自分がよくグローバルにするのは起動時パラメータで与えた動作モード
プロの人はプログラムを打ち込み始める前に設計図的なものを全部作っちゃうの?
>>486 全体に影響があらざるを得ないレベルの修正は確かに大変だが、
全体に影響を与えるようなことが起こりにくいように作ることは可能だよね
>>501 ある程度の構成は決めるけど、細かいところまでは決めないで作り始めてるよ。
大枠から作っていくというか。
プロの人に限らず、経験を積めば道を大きくそれることなく進めていけるようになるし。
>>501 そういう方法論もある
最近だと「あらかじめ完璧な設計を用意するなんて無理だろ」という前提に立って
コードを書きつつ柔軟に設計を変更する開発手法も出てきている
あらかじめ完璧なものが作れるなら、マイクロソフトはこんなに成長してないぜ
>>501 設計書にもレベルがあってですね。
ここは譲れないというものから、大枠は決めて後はどうぞというものまで。
あまりガチガチにやっちゃうと工数ばかりがかかってなかなか進まない、
適当過ぎると最初の進捗は良好だけどなかなか終わらない。
まあ、そのへんのさじ加減がむつかしい。
D言語は気持ち悪いぐらいautoだらけだが、 Cでautoなんて書く馬鹿はいないだろ。電力の無駄遣い。
どっかのC言語をパクって適当に構文足した言語は autoの意味を最近変えようとしてる。 だから、C言語ではauto使わなくても将来的にはautoを使うコードってメジャーになるんだろうなぁ
それだけautoに意味がなかったってことだろうな。 予約語の意味かえるなんてそうそうできることじゃなし。
>>508 うちは背景色よりも前景色の方が輝度低いのでautoと書くべきなのか。エコ的に
嘔吐と書くか
char 以外への signed もまだ auto よりは使う機会はなくもないし、 register は古いプログラムでは使われてることもあるが、 auto は本当に役立たず。 そのおかげで C++0x では貴重な予約語をゲットできたわけであるが。
[[auto]]とかならなくてホントによかったと思う。
あうと って呼んだらアウトですかね。 それで問題なく通じればいいか。
auto ← あうと alt ← あると
malloc ← まろっく char ← ちゃー stdio ← すたじお
auto???? alt[ernative] m[emory]alloc char[actar] st[andar]d io
auto????ってw これをさらに略されても逆に困る あうとと読んでもドイツ人にはすんなりかもしれない
>>517 2番目、ふざけて書いたつもりなんだろうけど
本気でcharを「キャラ」とか読んでるとしたら大笑いだぞ。
ネイティブの人は普通に「チャー」等と発音して、「キャラ」なんて言う人居ないから。
charがチャーじゃなくてキャラだとしたら
intはイントじゃなくてインテと発音して
macはマックじゃなくてマクドと発音してるんだよな。
キャラでもチャーでもなくて、チャラが正しい。
>>520 イントとインテがどうとかとかアホだろ、本来なら母音つかねーから無意味な話だろwwww
>>522 その母音が付かない「charの発音の仕方」が、C FAQにすら載ってるんだけど
>>523
char の話なんかしてないけど?
ぬるぽ
が
っ
ばかじゃねーの
アンカー付けずに悪態つく奴は 厭世家気取りの厨二病患者だって ばっちゃが言ってた!
「が・・・あ・・・離れろ・・・死にたくなかったら早く俺から離れろ!!」
ほんと腐ってんな。
ばーかばーか
>>520 マクドと聞くとMcDonald'sが想起されるわけだが
C言語にもぬるぽはありますか? あったとしてもJavaのパクリですよね^^
Cに言語つけるのにJavaには言語つけないの?ジャワのことなの?原人なの?
539 :
デフォルトの名無しさん :2008/12/30(火) 12:21:31
知らんguage
wchar_tってなんて読むの?
だぶちゃーてぃー
ブチャラティでおk
この味は!、、、嘘をついている味だぜ、、、
入力した数値を、英語で表すプログラムを作成しています。 #include<stdio.h> #include<string.h> int data[100]; char line[100]; int i; int end; int main(){ fgets(line,sizeof(line),stdin); sscanf(line,"%d",data); end = strlen(line);
for(i=0;i<end;++i){ switch(data[i]){ case 0: printf(" zero "); break; case 1: printf(" one "); break; case 2: printf(" two "); break; case 3: printf(" three "); break; case 4: printf(" four "); break; case 5: printf(" five "); break; case 6: printf(" six "); break; case 7: printf(" seven "); break; case 8: printf(" eight "); break; case 9: printf(" nine "); break;}}return 0;}
コンパイルは無事できましたが、表示の結果が、 「333」や「55555」だと zero zero zero zero zero zero zero zeroとなりますが、 「1」や「5」だと one zero five zero となります。 NULL文字が悪さしているような気もするのですが、どこがおかしいのでしょうか?
>>546 printf(" %d %d ", data[0], data[1]);
>>547 ありがとうございます。
data[0]に「333」の数値ごとは入っていたわけですね。
ちょっと改良してみます!
549 :
546 :2008/12/30(火) 14:39:30
すみません、 「500」 このような数値を1つずつ、各要素に配るにはどうすればいいのでしょう?
文字として扱え
>>549 各桁をバラすってこと?
int n = 500;
data[0] = n % 10;
data[1] = n / 10 % 10;
data[2] = n / 100 % 10;
もともとその数字は外部から入力したものじゃないの? まあ数値を文字列にするのはitoa、、、いや char data[xxx]; sprintf(data, "%d", n); とか。
553 :
デフォルトの名無しさん :2008/12/30(火) 18:45:19
xxxは禁句な
プログラミングも学歴(特に数学)ですよ。 重回帰分析やらのプログラムを高卒プログラマが組める事は少ないですよ。 組めない人は絶望して下さい あなたは理系ですらない底辺IT奴隷ウィッシュ☆
重回帰分析を実装できない大学卒は掃いて捨てるほどいるけどなぁ。
556 :
デフォルトの名無しさん :2008/12/30(火) 22:00:45
その文章のどこから大卒が出てきたのか理解しがたいが?
コピペに反応するお前らが理解しがたいよ
>>556 学歴の一例として挙げただけだろう。理解しようとなんか考えなくていいと思う。
560 :
デフォルトの名無しさん :2008/12/30(火) 22:36:09
今もC言語だけの仕事ってありますか?
>>560 あるだろう。
携帯でもアプリはJavaだけど、ドライバーはCで作ってあるんじゃないの?
あとは通信ソフトとかかな。
それすらもC++に替わってきているんじゃないの? どれだけC++の機能を使えるんだか知らないけど。
C++コンパイラがあるところはC++で作るだろうから。 Cのみというケースは、あるとすればクロス系の組み込みソフトかな?
沢山あるよ。客先自身が古いソースの保守をしている場合、思考停止に陥ってCで書き続けることはよくあるから。
というか保守案件で大幅にC++で書き直すアホはいないだろ
役所とか古いUNIXのシステムで動いてるところはずっとCでやってるところもまだまだ少なくない
いや、保守案件じゃない。新しく書き起こす場合でさえ、Cを使い続けているんだ。 ある客先には一応根拠を聞いてみたんだ。 ・内製ライブラリはC++対応していない。 # extern "C"でC++から使えると言う発想はないらしい。 ・OS間でコンパイラの互換性がないのでSTLは使えない。 # 何故かターゲットOSにHP-UXがあり、何故かバージョンアップできないらしい。 ・C++でnewやテンプレートを使う程度なら、Cでも同じことができる。 # と、何故か信じ込んでいる。 あるプログラムが余りに無駄な処理をしているから、たまたま手元にC++で 同等の処理をするプログラムがあったので「使いませんか?」と提案したら、 「C++の保守をする気はないんで、Cに書き換えるなら採用します」と来たもんだ。 挙句、「なんで最初からCで書かないのか理解に苦しみます」と言われるに至って、 これはもう、何を言っても無駄だと悟りましたよもう。
まぁ単純に人員の問題じゃね 胸張って「C++使えます」と言える人は 「C使えます」という人よりずっと少ない
C++使えないプログラマが足を引っ張って 日本の情報技術のレベルを落としてるのは間違いないよな。
ソフトはハードより硬い 誰か言ってたなあ
プロとしての自覚が無いんだよ。 そんなだから失敗案件増やして会社が傾くんだ。
マ板でやれ
C++もできないでプログラマを名乗るなよな
線形リストのノードへのポインタを1020ノード単位で配列に格納し、 任意のノードを検索する際に検索を高速化しようと思っているのですが、 ファイル分割をする際にどのような分割をすればよいでしょうか リスト処理と配列処理(ノードへのポインタ追加や削除など)をソースファイルごとに別にすべきでしょうか それともリストに内包される処理として、リスト処理関数の内部にそのまま実装すべきでしょうか?
>>574 ファイルとソースファイルはそれぞれ何を指してて、リストと配列との関係は何なの?
>>574 list.c
addlist() {...}
dellist() {...}
その1020って数字はどっから出てきたんだ
よくぞ訊いた。 1000か1024なら理解できるけど、俺は本筋でないから黙っていようと思ったのに。
すみません。言い方が悪かったです。 list処理と配列処理自体をそれぞれ独立させ、それらをまとめる処理関数を作るべきか list処理内部でごっちゃで実装してしまうか 図で表すと インターフェース(以下二つの処理をまとめた外部へ公開する関数) リスト.c-|-配列.c または 配列をそのまま組み込んだリスト.c
すげぇ、ここまで説明下手になれるなんて。
>>578 データ 1020 バイト+ポインタ 4 バイト = 1024 バイトだと思うが。
ポインタが8バイトとか2バイトだったらどうするんだyo!
1024 - sizeof (struct node*) でおk
>>579 配列をそのまま組み込んだリスト.c
のほうが100倍よい。
>>581 意味わからん
それがどうして1020ノードになる
1ノード1バイトなんじゃね?
>>579 不可分ならまとめて作れ
個別で使う可能性があるなら個別に作れ
それくらいしか言えんよ
質問です。int型のオーバーフローやdouble型のオーバーフローはどういうコードを書いて検知したらいいんでしょうか? よろしくお願いします。
double ならオーバーフローしたら∞になるから isinf で検出可能。 int での検出はアセンブラ使わないと不可能なので、 C では計算前にこの計算をしたらオーバーフローになるかどうかを 予めチェックするしかない。
590 :
221 :2009/01/01(木) 00:05:39
あけましておめでとうございます。 今年もご指導もほど宜しくお願いします。
externで定義したグローバルな構造体にアクセスするのと 関数に、引数にポインタ変数として渡し、アクセスするのでは 速度的にどれくらい違うのでしょうか。 0.01msec単位で速度を詰めたいのですがどっちがいいのか 判断つきません。
実測しろと言うのがわからんのかボケ
気にせず引数にしろ。 大丈夫、0.1ms以上の桁で改善できる項目なんてほかにいくらでも湧いて出てくる。
引数とグローバル変数ではキャッシュ効率も変わるので 実測してみないと何とも言えない。
595 :
588 :2009/01/01(木) 00:42:12
>>589 早速回答ありがとうございます。
int型に関しては、具体的にはこんな感じでいいのでしょうか?
int main(void) {
int a, b;
printf("Input two integral numbers:");
fflush(stdout);
scanf("%d %d", &a, &b);
if (a > INT_MAX/b) {// オーバフロー検知?
printf("overflow\n");
return -1;
}
printf("a*b = %d\n", a*b);
return 0;
}
bに0が来たらどうするんだろうか
>>595 0とか負とか考えると不十分やね。
64ビット型が使えるならこういう方法もある。
#include <stdint.h>
int64_t n = (int64_t)a * b;
if (n < INT_MIN || n > INT_MAX) {
// オーバーフロー
}
stdint.h がない場合も、long long か __int64_t あたりが使えるんじゃないかな。
598 :
588 :2009/01/01(木) 00:53:20
>>596 しょぼいコードですみません。ゼロ除算のチェック以外は、だいたいこんな感じでいいんでしょうか?
どういう感じで書くのが、int型のオーバーフローチェックの一般的な書き方なのか分からなくて・・・
int c = a * b if (c / a != b) { /* オーバーフロー */ } これでいいんじゃね。
一般的には計算途中でのint型のオーバーフローチェックはしない 計算の元となる数字に上限下限を設定して(入力データ仕様というやつ) 各々の数字の入力時に範囲チェックを行い、範囲外ならハジくのが普通かな? もちろん範囲内の数字なら、プログラムで行われるすべての計算でオーバーフローは発生しないという 保障をする必要がある
601 :
588 :2009/01/01(木) 01:12:19
>>597 ,599
なるほど!! ありがとうございます。
まあそんなとこだろうな プログラム内で発生しうる値の大きさをちゃんと把握しておけと
>>599 だから 0 の場合を(ry
if (a != 0 && c / a != b) {
/* オーバーフロー */
}
だな。
a が 0 なら必ずオーバーフローしないのでこれで問題は無い。
604 :
デフォルトの名無しさん :2009/01/01(木) 11:02:55
上記をドモルガンの法則を用いて改変↓
どう、ホモるかの法則で↓
606 :
デフォルトの名無しさん :2009/01/01(木) 11:42:35
#include <stdio.h> int main(void) { char i[80]; int a; for(a=0; (i[a]=getchar())!='\n'; a++){ printf("%c",i[a]); } return 0; }
607 :
デフォルトの名無しさん :2009/01/01(木) 21:49:45
かけ算九九表を作ったんですけど #include <stdio.h> int main(void){ int test[10][10]; int i,j; for(i=1; i<10; i++){ for(j=1; j<10; j++) test[i][j]=i*j; } for(i=1; i<10; i++){ for(j=1; j<10; j++) printf("%3d",test[i][j]); printf("\n"); } return 0; } 1| 2| 3|を9|までやりたいんですが、if文をいじくって if(test[i][j]==test[j][1])などとやってもだめでした 表示のやり方教えてください。
>>607 printf("%3d",test[i][j]);
を
printf(j == 1? "%3d|": "%3d",test[i][j]);
に変更する。
609 :
デフォルトの名無しさん :2009/01/01(木) 22:07:48
おお!できました! ありがとうございます。 そのif文がprintfの中でも使えるとは、思ってもいませんでした。 ? 真:偽ですよね!本当にありがとうございました。
三項演算子
>>607 がやりたいことはこういうことではなかったのか?
#include <stdio.h>
#define N (9)
int main(void){
int i, j;
printf(" |");
for(j=1; j<=N; j++){
printf("%3d", j);
}
printf("\n");
printf("___|");
for(j=1; j<=N; j++){
printf("___");
}
printf("\n");
for(i=1; i<=N; i++){
printf("%2d |", i);
for(j=1; j<=N; j++){
printf("%3d", i*j);
}
printf("\n");
}
return 0;
}
612 :
デフォルトの名無しさん :2009/01/01(木) 22:39:21
611さん まさにそんな感じです とても参考になります ありがとうございました。
613 :
デフォルトの名無しさん :2009/01/01(木) 23:01:35
bitとかのことなんですが 32bitだとintは4バイトですか? 32/8=4 32bitだとメモリは4GBまでつめるってことですか? 求める公式がいまいちなんですが32bitを8bitでわればメモリ4GBが求まるってことでしょうか? 公式の出し方知ってる人おしえてください。 64bitは8GBですよね?
tree 木 book 本 ... のように英単語とその訳語が並んでいるtxtファイル(英語と日本語の単語間はタブ区切りです)を読み込んで、 オープンハッシュ法によるデータベースを作ろうとしています。 ファイルを読み込むプログラムを void command_hread (char *fname, lnode **db, int size) { FILE *fp; char *index, *data; int i; if((fp = fopen(fname, "r")) == NULL) printf("Cannot open the file.¥n"); else{ while(fscanf(fp, "%s%s", index, data) == 2){ i = hash (size, index); db[i] = list_insert (index, data, db[i], my_strcmp); } } } のように書き、indexとdataに入った英単語と訳語を自前の関数でハッシュテーブルに登録しようとしているのですが、Bus Errorが起きてしまいます。 自前の関数は他の所では使えているので、ファイルの読み込みのあたりでエラーが出ているのだと思うのですが、どこらへんが悪いのでしょうか・・・?
>>614 index, data を適当に
char index[255], data[255];
などと確保しておく必要がある。
>>613 ビットは2進法での桁を表す言葉。
2進法(binary)+桁(digit)=ビット(bit = b + it) という風にして作られた造語。
~ ~~
例えば2進数 1010011 は7桁あるので7ビット。
ただ、ビット単位でデータを扱うのはサイズが細かすぎて不便なので、
普通は数ビット1かたまりでデータを扱う。
その最小単位がバイト(byte)。
コンピュータが一度に「口に入れられる」(扱える)単位ということで、
噛む(bite)になぞらえてバイト(byte)と名付けられた。
そういうわけなので、コンピュータによってバイトのサイズは異なるわけだが、
今のコンピュータでは1バイト=8ビットなものが多い。
積めるメモリの上限は OS によって異なる。
例えば 32ビット版の Windows XP は 3GB までのメモリしか使えない。
単に OS の制限であって、法則とかはない。
>>613 >>616 >単に OS の制限であって、法則とかはない。
OSの制限はあるけど、法則ないというわけじゃないんじゃない?
32bit System
2^32 = 2^2 * 2^30 = 4G
64bit System
2^64 = ... (単位考えるのメンドクサイから省略)
とりあえず「メモリ空間」とか「アドレス空間」とかでググってみるといいかも
618 :
デフォルトの名無しさん :2009/01/01(木) 23:31:17
616さん 1バイト=8bitってことは 32ビットマシンは4バイトを一度に処理できるってことですか?
>>617 16ビットシステムでも1GB扱えるわけで。
今のセグメントの扱いだと4GB超えられないのは確かだが、
それも単にCPUをそういう風に作ってしまったからというだけで、
32ビットのシステムだから4GBを超えられないというわけでもない。
間違えた。 ×1GB ○1MB もう単位の感覚があの頃と変わってしまっているね。
>>618 そういうこと。
まあ、一度に処理できるというか、
4バイトを1つの数値として扱えるというか。
ただ、4バイトを一度に処理できるけども、
1バイト単位で処理することもできる。
1ワードでぐぐれ
Cで、 「一定時間毎にあるデータが任意のフォルダに保存される状況の下、データが保存される度にその保存されたデータに対してある処理を行う」 というようなことを行わせることは可能ですか? 可能な場合、どういう風にすれば出来ますかね?sleep命令とか?
Windows ならフォルダの更新を監視する API があったと思う。 別の OS でも似たようなものはあるかもしれないが、俺は知らない。 まあ、どちらにしろ対象 OS のスレに行った方がいい気がする。
>>624 >>625 そういうAPIがあるんですね。
出来そうな気がしてきました。色々調べてみます。
ありがとうございました。
#defineマクロでfor_eachマクロを作りたいのですが いまいちうまくいきません typedef struct _list { int data; list *next; list *prev; }list; #define list_for_each() この先どうしたらいいのでしょうか
そんなマクロは作らなくてよろしい。 制御構文を変更する類いのマクロは 混乱を来す要因になる。
毎回リンクリストを書くの嫌だ なんとかしてくださいよ助けてくださいよ もうかれこれ50回ぐらい書いてる
それだけ書いたなら、どうマクロ作ればいいか自ずからわかると思うが。
#define list_for_each(sp, ep, fn) do{ \ for(list_for_each_p=sp; list_for_each_p!=ep; list_for_each_p=sp->next) \ list_for_each_p->fn(); \ }while(0)
まちがった for(list_for_each_p=sp; list_for_each_p!=ep; list_for_each_p=list_for_each_p->next) \
こっちのほうがいいんじゃないかな fn(list_for_each_p);
>>627 typedef struct _list list;
struct _list {
...
list *prev;
};
とかじゃないとコンパイルエラーにならね?
予約識別子を使うなよ
_俺が予約だ!
処理系作ってる最中なんだよ。 放っといてくれよ。
638 :
デフォルトの名無しさん :2009/01/02(金) 05:09:06
すみません、for文で数値の100が来たら、終了すると したいのですが、できませんので、助言お願いします。 for文の中でif(b==100) までわかりました。
なにを終了するのかはっきりしないが、forループを終了するなら if(b==100) break;
いやいや、for文の括弧の中で、for( ; b!=100; ) で
分からんよ、○+× = 5 になる2つの値がいくつかあるように、答えは1つではないし 正解と言えるけど、比較して〜の方がと決め付けるのはどうかと。
単純に640の方が範囲が狭いだろw
644 :
デフォルトの名無しさん :2009/01/02(金) 11:02:32
電卓を作ろうとしているんですが。 #include <stdio.h> int main(void){ int i,j; int a[3][3]={ {1,2,3}, {4,5,6}, {7,8,9}, }; printf(" _________\n"); printf(" |_________|\n"); for(i=0; i<3; i++){ for(j=0; j<3; j++) printf(j==0?" |%d":"%4d",a[i][j]); printf(j==3?"|":"%4d",a[i][j]); printf("\n"); } return 0; } _________ |_________| |1 2 3 | |4 5 6 | |7 8 9 | この形まで出せたんですが下の形の_______________を出力したんですが。 どうすればいいんでしょうか? printf(i==3?"_":"_");などとやってもできませんし 教えてください。
printf("-------");
C の質問というより AA の質問だなw - か ~ を使えばいいんじゃない? 全角文字使えるなら  ̄ でいいだろうけど。
電卓の厚みをあらわすために=======はどう?
648 :
デフォルトの名無しさん :2009/01/02(金) 15:52:14
質問させてください. for (;;) このセミコロン2回にはどういう意味があるんでしょうか. H8マイコンのプログラムソースにこのような"for"の使い方がされていて いるのですが,どういう処理がされているのか分かりません. よろしくお願いします.
for は普通 for(i = 0; i < 10; i++) のように使うが、 それぞれの部分は必要ないなら省略することが可能。 全部省略すると for(;;) になる。 この場合、無限ループになる。
650 :
デフォルトの名無しさん :2009/01/02(金) 15:58:39
>649 なるほど,ありがとうございます
>>648 forの2番目のところを省略すると、常に真と解釈されるので、無限ループになる。
H8は関係なくC言語の規則な。
#defineで(2^32)-1の値をを定義したいんですけどその場合ってやはり先にその値を計算しておいて #define EXAM 4294967295 みたいにするほかないんでしょうか? #defineのところで関数をうまく使ってその場で計算して定義するようなことってできないでしょうか?
#include <stdint.h> の UINT32_MAX では不満か?
1LL<<32-1
>>652 32bit環境用
(~0U)
64bit環境用
((1<<32)-1)
どっちでも用
0xFFFFFFFF
(~(~0<<32))
マクロで定数を定義するのに、先に計算しとかない理由がわからない。
負数の表現が2の補数以外の処理系でもちゃんと動くようにしたんじゃないかな。
2つの値を戻したいんですけど構造体とポインタどっちを使ったほうがいいとかってありますか? 使い分けが知りたいんですが……
俺は引数にポインタしか使わない。
好きにしたまえ
その関数のためだけに構造体を用意してくるとかはちょっと・・・・・
使い分けが分からないならもうちょっと勉強進めてみたら? 「線形リスト」の作成とか
>>658 構造体が小さければ、戻り値で返してもいいんじゃないかな。大きければ引数に構造体のポインタで返せばいいんじゃないかな
>>655 <<32 をしても何も起きない32ビットCPUもあるだろう。
>>652 実行時に計算が行われるようなマクロは、その結果が実行時に変化する場合にだけ意味がある。
素直に数値を計算して叩きこむこと。
>>665 コンパイル時に計算が行われるようなマクロをすっとばして
自分で計算するなよwww
情報系の1年でC言語を習い始めたんだけど学校じゃLinuxなのに 自分のPCはWindowsだから家で復習とかが出来ません windowsでもc言語を勉強できるようなソフトはないんでしょうか?
Cygwin使え。
669 :
デフォルトの名無しさん :2009/01/02(金) 21:20:45
たしかに cygwin はいいですねえ。一応シグナルもOKみたい。宿題スレで使っています。
>>669 宿題スレにきていただければいいかと。まれに神が光臨します。
673 :
デフォルトの名無しさん :2009/01/02(金) 21:36:43
671さん 2級は500行以上のコード書くんですよ? 1級なんてすごい難しい気がします
神よりも頭のおかしい奴の方が降臨率高いけどな。 今日も朝から暴れてたし。
>>673 仕事だと500行はあっという間に超えてしまうから安心してください。
>>673 レベルとしては1級であっても
基礎的なことは習得しました
ぐらいなんだと思ってください
初段からが一人前。
ちょっとしたゲームでも5000行超えますね^^
679 :
デフォルトの名無しさん :2009/01/02(金) 21:52:37
>>667 VirtualBox, VMware, VirtualPC
↑
このへんぐぐってみれ
Windows上の1アプリとして学校とそっくり同じ環境が作れる
>>678 N-BASIC 時代なら1画面プログラムでゲーム作るとかよくあったぜ。
>>673 ちょっとしたツールでも丁寧に作れば、簡単に 1000ステップを超えると思います。
>>674 コードを書いたらちゃんと見てあげているし、いいところはいい、と褒めてあげているのに、まだ殻を破ることができないのですね。
何様w
連結リストの勉強で mallocやcallocで確保した領域は必ずfreeで開放するべきと書いてあるが free書き忘れたり違ったアドレスを開放しようとしてもコンパイル(Borland C)が警告してくれないし 普通にプログラムの実行もできてるため、ちゃんと開放されているか不安です 一応領域確保と開放をするごとにprintf("%p")でアドレスを確認しながら恐る恐る実行してるのですが freeし忘れたり変な所を開放したりするとどうなるんですか?
コンパイル compile コンパイラ compiler
>>684 ・ free し忘れると
メモリリークと呼ばれる状態になる。
プログラムが終了するまでずっとそのメモリを開放する手段が無くなる。
ループ内でこれをやっちゃうと、どんどん開放できないメモリが増えていって
そのうちメモリが一杯になる恐れがある。
・ 変な所を開放すると
死ぬ。
・ 変な所を開放すると 死ぬ。 がくがくぶるぶる((((;?Д?))))
>>684 一般的な環境で言うなら
解放忘れて、別に何も起こらない
終了後にOSがきちんなんとかしてくれる
変なとこ解放したところで、せいぜいそのプログラムが落ちる程度
ただマルチスレッドとかで扱ういろいろだと
終了後も領域解放されないままとかもありえる
あとは、確保した領域がすべて解放されたかチェックするツールとかあるよ
>free書き忘れたり違ったアドレスを開放しようとしてもコンパイル(Borland C)が警告してくれないし free()に渡すのは識別子ではなくポインタの値で、 これは実行時に決定されるものだから、 コンパイル時に警告できるはずがない 重要なことは、領域を確保する部分と開放する部分が 常に対で呼ばれるようなインタフェースを作ること なるべくなら割り付けた領域のアドレスをナマで持ち歩くことは避けて、 構造体などに含めてそのポインタを受け渡しする FILE構造体とfopen()とfclose()の関係を思い浮かべると良い
>689 constみたいに、free可能なポインタにつけるキーワードがあれば便利だったかもね
> free()に渡すのは識別子ではなくポインタの値で こういう知ったかは困るね。識別子の意味が分かってないようだし。
>>691 君がその言葉の意図を分かっていないだけだろう。
初心者は char* hoge = malloc(size); とやると、
char* p = hoge; free(p); とすることに不安を覚えるものだ。
脊髄反応、やはり宿題スレでwhile文の指摘をされて、馬鹿とか言ってファビョってた あの基地外か。以後放置よろ。識別子なんて、調べればすぐに分かるし、余計な 一言で、全て間違いにしてしまう奴は、知ったかの自身過剰の墓穴掘りだから。
詳しい回答ありがとうございます。 きちんと領域の確保と解放ができるように気をつけます
malloc の返す値が予め分かっていれば、 別に定数をポインタ型にキャストしたものを free しても問題はない。
識別子を渡しているわけじゃないだろ。 渡しているのは識別子などにより構成される式の値だ。
識別子なんてのはマシン語にまで翻訳してしまえば消えてなくなるもの。 それがまるでさも実体を持っているかのように考えるのは愚昧。
>>697 誰もそんなことは言っていないが?識別子が何なのか?についてだぞ?w
都合の悪い物はスルーするところが面白い。
「関数」に「渡す」のが値 「引数」に「与える」のが識別子 コンパイラがチェックするのは引数と識別子の型だけ 何もおかしくはない
int size = strlen(hoge); char* str = malloc(sizeof (int) + size + 1); str += sizeof (int); *((int*)str - 1) = size; strcpy(str, hoge); printf("size = %d, str = %s\n", *((int*)str - 1), str); free(str - sizeof (int)); CString でやってることを C で再現してみたもの。 str - sizeof (int) は識別子ですか。そうですか。
unsigned long i = (unsigned long)malloc(256 * sizeof(char)); /* some statements */ free((void *)i); 値( (void *)i )が、渡されるわけで識別子は関係ない。 free(malloc(256 * sizeof(char)); この識別子は、なんだろうか。 とか書くと特殊な例に過ぎないと返されそうだな。
引数として式の値を渡す。 free(malloc(256 * sizeof(char));において、その式はmalloc(256 * sizeof(char)という関数呼出式である。 free(hoge);において、その式はhogeという識別子からなる一次式である。 がんばって好意的に解釈すればこんな感じ? 文法上、ある種の式は識別子単体そのものであることから引っ張ってみた。
707 :
デフォルトの名無しさん :2009/01/03(土) 07:53:54
すみません他人のソースを読んでいて 分からないところがあり、質問なんですが struct hoge { unsigned a:12; unsigned b:4; } :12とか:4はどんな効果があるのですか?
>>707 変数を制限するもの
その例だと
変数aは12ビット
変数bは4ビット
で表すことのできる整数のみを扱える。
709 :
デフォルトの名無しさん :2009/01/03(土) 08:05:14
ビットフィールド
>>708 ありがとうございます
がってんいきました
711 :
デフォルトの名無しさん :2009/01/03(土) 12:01:17
#include <stdio.h> #include <string.h> int main(void) { char hoge[3][80]; int i; for(i=0; i<3; i++){ gets(hoge[i]); } do{ printf("moji\n"); scanf("%d",&i); if(i>=0 && i<3;) printf("%s",hoge[i]); }while(i>=0); return 0; } 1-3までの数字をいれると入れた文字が出力されます。 だけど0からはじまるんですが、i--;で配列をずらしているんですが。 hoge[i-1];とやっても出力エラーがでてしまいます やはりデクリメントでしかずらせないんでしょうか? (hoge[i]-1)でも無理です。
if(i>=0 && i<3;) ← このセミコロンが気になる〜
if (i>=1 && i<=3) printf("%s",hoge[i-1]); じゃないのか?
完全二分木ではない二分探索木の深さを求めるには、葉までの深さを一つ一つ求めていくしかないのでしょうか?
>>688 >確保した領域がすべて解放されたかチェックするツールとかあるよ
んー、ポインタください。
私は自前でmalloc()/realloc()/free() にラッパかぶせてしのいでいます。
何故calloc()はラップしないのだろう……
>>714 ん、そうではありますが、リカーシブにすれば簡単です。
>>683 前途ある中学生をいじめるのはかわいそうでしょ?
簡単かどうかじゃなくて O(1) や O(logN) で求めたいけど O(N) かかっちゃうのはどうにかならんの? って話じゃない? ノードを追加する際に深さをノードに保存しておくようにすると O(1) で取得できるようにはなるよ。 その代わりノードの追加に少しコストが増えるけど。
>>719 末端の方でノードを追加すると、それから上の全部の深さ変数を更新しなければならないのですか‥‥‥。
そっちも時間かかっちゃだめなの?
ノードを追加しようとノードをたどっていく際に 深さ変数をインクリメントするだけだから 大したコストじゃないよ。 削除する際も同様ね。
正確に言えばノードをたどって戻っていく際に、だな。
724 :
673 :2009/01/03(土) 15:52:03
トランプ表示のプログラムを作りました tramp.h void tramp(void); void tramp(void) { int x=0; printf("select Number:"); scanf("%d",&x); if(x>=1&&x<=9){ printf("\x1b[0m"); printf("\n"); printf("\x1b[37m --------\n"); printf("|%d |\n",x); printf("| |\n"); printf("| :) |\n"); printf("| |\n"); printf("| %d |\n",x); printf(" --------\n"); printf("\x1b[0m"); }else { printf("1~9 Input\n"); } }
725 :
673 :2009/01/03(土) 15:52:44
main.c int main(void) { int x; for(;x!=EOF; x++) { tramp(); } return 0; } 横に3個や5個などトランプを横に表示したんですが、改行されて複数の場合縦に表示されてしまいます。 3個並べれば神経衰弱などが作れそうな気がするんですが。 詳しい方教えてください
途中で、もう片側の方がはるかに深い、ということでそれ以上戻る必要がない、という場面も考えられますしね。
改行しなければ良い。 3個や5個表示したその後に改行する。
728 :
673 :2009/01/03(土) 16:03:00
727さん その手で試した事があるんですが、型を作るのが大変でした。 試してみます。 最近、テキストベースで絵を表示するプログラムにはまっています。
エスケープシーケンスはカーソルを移動させることもできるよ。
単機能ごとに関数分けるとやりやすくなると思うけどな。
731 :
デフォルトの名無しさん :2009/01/03(土) 16:37:50
C以前の問題なのですが #include <stdio.h> int main(void) { printf("ハローワールド"); return 0; } をコンパイルして、XP上で実行たら確認するまもなくウィンドウが閉じてしまいました。 実行後、ウィンドウが自動で閉じるのをとめるにはどうすればいいのでしょうか?
・ printf の後に putchar(); を実行させる。 ・ デバッグなしで実行する お好きな方を
間違えた。 getchar(); だった・・・。
735 :
デフォルトの名無しさん :2009/01/03(土) 17:00:47
>>732 >>734 ありがとう御座いました。
プログラムに動体視力を求めれたのかと思いきちんと実行できているのかわからず困っていました。
ありがとう御座います。
736 :
714 :2009/01/03(土) 17:01:04
>>717 >>719 いえ、オーダーはあんまり気にしてません。
どちらかというとコードを書くのが楽なのはどんなプログラムかなーと・・・
再帰で書くとするとどんな感じにすればよいのでしょうか・・?
適当に書いてみた。 デバッグとかはしてない。 static int get_depth_rec(node* node, int depth) { if (node == NULL) { return depth; } int ldepth = get_depth_rec(node->lnode, depth + 1); int rdepth = get_depth_rec(node->rnode, depth + 1); return max(ldepth, rdepth); } int get_depth(node* node) { return get_depth_rec(node, 0); }
while(j=10-i++) < モロにコンパイラが警告を出していますね 代入式と条件式の区別が出来ない人って、やーね。デリカシーが無いというか。
それをエラーにしないC言語は漢だ。その是非はともかく。
while((j=10-i++)!=0)もしくはwhile((j=10-i++)>0)って書けば満足なのか? 冗長だし、比較が1ステップ増えるのが無駄だと思うんだが。
コンパイラを黙らせることができるから無駄ではない
警告の意味もわからずにそれを出なくするための小細工するのは有害
意味が分かってるから問題ない
意味がわかってりゃ出なくする必要がないこともわかるはずだがw
いや、必要あるだろ。 それも分からないようでは未熟きわまりない。
警告なんて概念自体が害悪。 警告もエラーと同等のものとして潰すべき物だ。 今回の例で言えば、typo で = になっている部分と明確に区別し、 これは typo で = になってるわけじゃないですよ、と、 ソースを読む人とコンパイラとの両方に示す意味がある。
なんでここ来てるんだよw 宿題スレでももう一個の方でも、もとのところに帰れよ。 それとも、どこに書き込んでるかわからないほど顔真っ赤なのか?
とうとう自分にレスをし始めたか・・・
749 :
デフォルトの名無しさん :2009/01/03(土) 17:56:26
>>741 おまえさんの手元のコンパイラ1つ黙らせられれば済む話か?
while((j=10-i++))でいいんじゃないの?
代入式じゃだめで条件式じゃなきゃいけないって言ってるからそれじゃ納得しないかと思って。 ()をつけても代入式じゃなくなるわけじゃないし。
752 :
デフォルトの名無しさん :2009/01/03(土) 18:09:10
つーかこれはコメント残さないとどうしようもないから for文になおしちゃうかな
754 :
デフォルトの名無しさん :2009/01/03(土) 18:12:51
ん、for なら警告しないんだっけ? # そんな LR にいちいち付き合ってらんねー
代入と比較を別にするって意味だろう。多分。
>>738 はwhile((j=10-i++))についてはどう思うのか聞いてみたいところ。
>756はコンパイラとしては代入文そのものじゃなくなるから不満はなくなるが、 果たしてすっとこどっこいな人間が読んだらどう思うか不安にはなるな。
for (j=10,i=1; j>0; j--,i++) とかさ
代入式の値であることは()をつけてもつけなくても変化ないんだけどね。
質問します /* main.c */ int main(void) { f(); return 0; } /* sub.c */ int f(void) { return 1; } /* sub.h */ int f(void); みたいな関係があったとき、main.cに追加することになるのは下のいずれかになると思います。 extern int f(void); #include "sub.h" これらの違いがわからないので教えてください。
#include するかしないか。
>>762 関数宣言については
何も付けない場合は extern がついてるのと同じになる
extern を書かなかったら、 それ以前に static int f(void); と書かれていない限り、 extern が指定されたものと見なされる。
765 :
714 :2009/01/03(土) 19:34:46
766 :
760 :2009/01/03(土) 19:43:32
回答ありがとうございます。 ではmain.cに追加するのが int f(); #include "sub.h" の違いはどうなのですか? この場合はまったく同じかもしれませんが一般的な違いを教えてください。
void の有無が違う。 int f(void); は引数がない。 int f(); は引数に関する情報がない。(引数はあるかもしれないし、ないかもしれない) 引数が無いのなら void と明示する方が良い。 (C++ だと () も (void) と同じになるのだが)
768 :
760 :2009/01/03(土) 19:50:46
>>767 そうなるのですか。
main.cに追加するのが
int f(void);
#include "sub.h"
の2つのうち1つならこれらの違いはどうなるんですか?
#include は コンパイルの実行前にあらかじめファイルの内容を埋め込む感じの命令 だから一緒になる
#include するかしないかだけの違いしかない。 #include は指定したファイルの中身がそこに埋め込んでファイルを合成する命令だからね。
#で始まる行はcppが処理する cc(Cコンパイラ)とcpp(Cプリプロセッサ)ぐらいは知っといたほうがいい
773 :
760 :2009/01/03(土) 19:57:59
なるほどわかりました。ありがとうございます。
774 :
C初心者 :2009/01/03(土) 20:08:33
ポインタを利用した二分探索木の作成がどうしても分からないのですが、どなたか教えてください。
調べた上でわからないなら、ここで聞いてもわからないよ
そもそも初心者がいきなり手を出すものでもない気がするよ。
777 :
デフォルトの名無しさん :2009/01/03(土) 20:16:47
宿題臭がする
struct cell { int type; union { struct cell *first; struct XXX * data; }; struct cell *second; }; struct XXX があつかうデータな とか?
>>774 アルゴリズムがわからないならまずC言語以前の問題です
アルゴリズムを理解しているならC言語で実現する上で何がわからないのか整理してもってきなさい
>>774 適切な教科書が思いつければいいのですが。
とりあえず基礎的なC言語の教科書を1冊マスターしていただければみえてくると思います。、
関数のプロトタイプ宣言でお聞きしたいのですが、どちらが正しいのでしょうか void keisan(float x,float y); void keisan(float, float); 上は引数に変数がついている書き方ですが下は型だけで変数がついていません
どっちも正しい
>>781 関数プロトタイプの引数リスト内での引数名はオプションで、書いても書かなくてもいい
785 :
デフォルトの名無しさん :2009/01/04(日) 00:28:27
VC++2008で少し複雑なプログラムを作ろうと思うんですけど、行数が多くなりすぎてソースが見にくくて困っています。 そこで機能ごと(関数ごと)に別々のファイルに分けようと思ってるんですが、普通はどのようにしているのでしょうか? 定義としてヘッダファイル、機能ごとにcppファイルを作るというスタイルは普通はやらないんでしょうか? 行数が多くてもcppファイルは1つしか作らないのでしょうか? 初心者でそこら辺はよくわからないので、教えてください。
> cpp ここは C スレだ。 C++ ならクラス事にファイル分けるとしか言いようが無い。
>>785 機能ごとに分ける。
機能A a.h a.c
機能B b.h b.c
・・・・・・・・・・・・
これがふつう。
1つのcファイルは小さなプログラムを一人で作るときは、まあそれでいい。
プロジェクトで複数人で開発をするときは、ファイルがひとつだと、同時にいろんな
ひとがファイルあける事になって同時更新の問題が発生する。
1関数1ファイルはファイル数が多くなるので管理が難しい。(わけがわからなくなる)
てなことで、プログラムをいくつかの機能に分解し、その分解された機能ごとに
cファイルをつくるのが現実的ではないだろうか。
以前行ったCの現場ではモジュールって呼んでたかな 一つの実行形式ごとに一つのモジュール+共通関数用に1モジュール だったからなかなかひどい目にあった
789 :
デフォルトの名無しさん :2009/01/04(日) 01:45:53
scanfで可変長の文字列を取得して、それを別の関数に渡してファイル操作のときに使いたいのですが、うまくいきません。 具体的にはmain関数で scanf("%s",&filename); でファイル名を取得して 関数(filename); で渡し void 関数(char){ fp=fopen(filename,"r"); という風に使いたいのです。ポインタなどを使えばうまくいくと思うのですが、試してみてもうまくいきません。 どのようにすればいいかわかる方いたら教えてください、お願いします。
int i=0,j; while(j=10-i++) これは適切ですか?
>>789 妙な加工をせずに
コンパイル可能なコードを書いてくれ。
>>789 タイプミスだとおもいますが
void 関数(char)->void 関数(char*)
ですよね。
fp=fopen(filename,"r");
if (fp == NULL) perror(filename);
とやると、オープンエラーのときのエラー種類とオープンしようとしたファイル名が
表示されます。それをみればわかるかな?
>>790 コンパイルできるという意味では適切なプログラム。
圧倒的多数の人間がコーディングスタイルとして良くないと言うであろうという意味では不適切。
>>789 void 関数(const char* filename)と書けばいい。
>>789 char filename[4096];
/* scanf("%s", filename); */
fgets(filename, sizeof(filename), stdin);
filename[strlen(filename)-1] = '\0';
foo_func(filename);
/* static or [extern] */
void foo_func(/* const */ char * filename) {
/* ... */
}
コンパイルできるというのであれば、何でもありだな。 あくまでもそれは、while文のループを止める条件として、正しいか?
char filename[適当な大きさの数字]; scanf("%s",filename); 関数(filename); void 関数(char *filename){ fp=fopen(filename,"r");
正しい。
799 :
デフォルトの名無しさん :2009/01/04(日) 02:04:35
791-797 ありがとうございました!できました。いろいろ調べてこの方法も試してみたんですがタイプミスしてました。 つまらない質問にも答えてくださってありがとうございました。 それと聞きたいのですが、 char *filename と char* filename は何か違いがあるのでしょうか?
違いはない。各自の好みの問題。
C++ では int& i; で書くのが素敵、という本をみたことがありますが、さてはて。
>>799 スレ違いの話になるかもしれないが、
foo_type *foo; /* K&R Cスタイル */
foo_type* foo; /* C++禿スタイル */
foo_type * foo; /* 中立派スタイル */
C言語でもC++でも、ポインタ指定子の結合は、foo_type (* foo); だから、
foo_type* foo_bar, foo_baz;とやっても、 foo_type (* foo_bar), foo_baz; にしかならないのは有名。
こういう間違えを防ぐために、typedef foo_type* foo_type_ptr;
foo_type_ptr foo_bar, foo_baz; とやることもある。この場合、foo_bar, foo_bazは、ともにfoo_type_ptr型となる。
また、変数宣言は、1行にひとつとして、コメントをつけるようにすれば、問題ないという人もいる。
foo_type* foo_bar; /* @in@piyo_ptrのalias */
foo_type* foo_baz; /* foo_barのalias */
のように宣言する。
型* 変数名; 式でやってると配列へのポインタとか関数へのポインタとかで詰まる
804 :
デフォルトの名無しさん :2009/01/04(日) 02:47:21
>>789 ですが、ファイル名を6つ取得したいので2次元配列を使いたいのですが、やり方がわかりません。
char filename[適当な大きさの数字][5];
scanf("%s",filename[適当な大きさの数字][i]);
関数(filename[適当な大きさの数字][i]);
void 関数(char *filename[][]){
fp=fopen(filename[適当な大きさの数字][i],"r");
としてみたのですが、ダメでした。何回も悪いんですけど、教えていただけないでしょうか?
#define MAX_PATH 260 int i; for(i = 0; i < 6; i++) { char filename[MAX_PATH]; fgets(filename, MAX_PATH, stdin); 関数(filename); } void 関数(const char *filename) { FILE *fp = fopen(filename, "r"); }
>>803 これが C++ だと 型 *&参照名; とかかなり違和感ある。
>>804 まずscanfの使い方からわかってないだろう
ちゃんと理解してないのにいきなり難しいことをやろうとするな
> char filename[4096]; もうね、コヒーを一気にゴクゴクと飲んで、口から噴射して顔にぶっ掛けてやりたいくらいだわw
>>804 君の欲しいのは 「適当な大きさのcharの配列」6つからなる配列
君が宣言したのは 「大きさ5のcharの配列」の適当な大きさの配列
%s指定子を使ったときにscanfに与えるのはcharへのポインタ
君が与えたのはcharの値
君が関数に渡したいのは「大きさ5のcharの配列」へのポインタ
君が関数の引数に書いたのは「大きさが不定のcharへのポインタの配列」へのポインタ
fopenに与えるのはcharへのポインタ
君が与えたのはcharの値
char filename[6][適当な大きさの数字]; for ( i = 0; i < sizeof(filename)/sizeof(filename[0]); ++i ) { scanf("%s", &filename[i][適当な大きさの数字]); 関数(&filename[i][適当な大きさの数字]); } void 関数(/* const */ char * filename){ fp=fopen(filename,"r"); 以下は参考程度に、配列の配列(通称、多次元配列)を関数に渡すとき void 関数(char filename[][適当な大きさの数字]){ /* または、void 関数(char *filename[適当な大きさの数字]){ */ /* または、void 関数(char (*filename)[適当な大きさの数字]){ */ fp=fopen(&filename[i][適当な大きさの数字],"r"); 関数側での使い方は、いろいろある。が、適当な大きさの数字を固定しないといけないので、あまり使われない。 構造体に入れて渡したり、要素数を渡すことが多い。 int foo(foo_t **ptr_to_ptr, size_t column, size_t row);みたいにね。
ここは「入門篇」
>>804 どんな入門書使ってるか知らないが、まず配列のところへ戻ってやりなおすこと
>>810 ソースに日本語が混ざるとすげー気持ち悪いなw
>>804 >char filename[適当な大きさの数字][5];
>scanf("%s",filename[適当な大きさの数字][i]);
>関数(filename[適当な大きさの数字][i]);
>
>void 関数(char *filename[][]){
>fp=fopen(filename[適当な大きさの数字][i],"r");
すべての行に間違いがあります!
>804
「理解」しないで「動いた」からって先へ進むな
>>789 のをどう変更して、それがどうして動いたか理解したのか?
このスレはきびしいきびしいのです
お前ら、この言葉を忘れてるぞ 宿題丸投げは宿題スレへ
>>817 ただ動くソースコードがほしいだけならそのためのスレがちゃんとある
いや、横レスだから
っつーかさぁ、C言語なんてやってて面白いか?なんか、人生の大事な時間、時期を 無駄に食いつぶしてしまったって感じがするぜ。どうせプログラミングをやるなら、 名の残るゲームの開発チームにでも加わりたいもんだぜ。
面白いです。 はい、次の方どうぞ。
821が役立たずなのはCのせいじゃないな。
プログラミングから一旦はなれてアルバイトする ノシ
>>814 え?一度やってみたいのですが、やっぱり無理がありますかね?
どこぞで「は」というプリプロセッサがあったようなきがしたような。
インクルードしないでprintf関数を使う方法をお願いします。 プリプロセッサの事があまり好きではないので^^ 大体標準なのに一々インクルードとか面倒じゃないですか?
>>826 ん、プログラムを作成・実行する環境と言語自体とを(わりあいに、ですが)くっきりとわけるための#includeと思っていただければ。
>>826 インクルードしない方が面倒臭いと思うんだが。
832 :
デフォルトの名無しさん :2009/01/04(日) 23:09:30
良い乱数でばっちり分散したintが得られ場合、 内部のbit的には全て2分の1で0 or 1であり、 charみたくint以下の型に入れても 乱数としてうまく分散していると期待して良いですか?
いい
サンクス!!
836 :
デフォルトの名無しさん :2009/01/04(日) 23:26:34
議論にはなってないな
837 :
デフォルトの名無しさん :2009/01/05(月) 00:26:53
下の例のような文字列や小数などが入り混じったchar型の変数の配列があります。 これから小数だけを取り出してファイル出力したいのですが、何かいい方法はあるでしょうか? char name[0]=frame char name[1]=0.123 ←取り出したい char name[2]=23 char name[3]=1.234 ←取り出したい
取り出す前に入らないだろ
839 :
デフォルトの名無しさん :2009/01/05(月) 00:40:15
たぶん0.123という文字列として入っているのだと思います そんなことはありえないでしょうか?
>>837 strtod()を使って、文字列の最後までパースできているか確認するとか。
char型変数の配列の配列じゃないの?
それぞれ文字列だとすれば、字句解析して実数っぽかったら取り出せばいいのでは。
843 :
デフォルトの名無しさん :2009/01/05(月) 00:51:29
>>840 小数と整数の判別はどのようにすればいいでしょうか?
strtodを使うと整数も一緒に取り出してしまう気がするのですが
844 :
デフォルトの名無しさん :2009/01/05(月) 00:53:10
>>842 中には小数点を使っている文字列もあるので、字句解析は難しいかと思いまして
>>843 そういわれたらそうだな。
文字列に含まれてるのが、数字のみで、中に一個だけ少数点が含まれていたら、
実数と判断するとか、地味に判定ルーチン書けばいいかな。
846 :
デフォルトの名無しさん :2009/01/05(月) 00:57:20
>>845 中には「11:13:28.015」というような文字列も含まれているので小数点での判別は実質無理なんです
解1) FILE *fp=fopen("out.dat","w+"); for(i=0;i<NameSize;++i){ double dval = atof(name[i]); char cval[256]; sprintf(cval,"%lf",dval); if(strncmp(cval,name[i],strlen(cval))!=0){ if(((int)dval)!=dval){ fprintf(fp,"%lf\n",dval); } } } 別解) std::ofstream ofs("out.dat",ios::out); for(int i=0;i<NameSize;++i){ try{ double val = boost::lexical_cast<double>(name[i]); ofs << val << std::endl;} catch(boost::bad_lexical_cast){} } コンパイル確認はしてません。
あ、別解の方intじゃないことの確認し忘れた……
>>843 まず、strtol()を通して、文字列の最後までパースできていたら整数。
整数でなかったらstrtod()を通して実数か判断するって方法でもいいか。
実数が指数表記とかされないんだったら、
>>845 の感じで、
自分で判定ルーチン書いても、あまり手間は変わらないような気もするけど。
てっとり早くやるならsscanf()で。
>>846 だから数字のみかで判定も入れればいいじゃん。
int isReal(const char *s)
{
int ccount = 0;
for (;*s; s++) {
if (*s == '.')
ccount++;
else if (!isdigit(*s))
return 0;
}
return ccount == 1;
}
動作確認してないからバグってるかも。
852 :
デフォルトの名無しさん :2009/01/05(月) 01:30:30
>>851 この方法で判別できました。ありがとうございました!
この問題はかなり悩んだんですが、こんなすぐ解決してくださるとは思いませんでした。
本当にありがとうございました!
関数の実引数をそのままローカル変数として使うより、 いったん新しく作ったローカル変数に移し変えたほうが効率的なんでしょうか それとも実引数は完全なるローカル変数といっしょの扱いでいいのでしょうか よくわからないけどアセンブリレベルでスタックとかレジスタとかどうかなーと思いまして
(fp=fopen()) ==NULL ってのは分かるが while(条件式のみ)ってのは如何なものかと。
え?条件式のみの方がよい良いんじゃね?
>>853 コンパイラを作るのなら意識すべきだし、最適化を行なわないなら若干変わる。
しかし、普通は全く同じように使えると思っていい。
よく判らないなら、アセンブリレベルで気にしても意味がない。
>>855 1行目が何を言いたいのか全く判らない。
通常、whileの条件判断部でファイルオープンすることは考えにくいし、まして
ファイルを開けない場合にループするなんて尚更考えにくい。
858 :
673 :2009/01/05(月) 11:15:06
独習Cという本に書いてあるんですが。 #include <stdio.h> int main(void) { int *p,r; p=&r; r=100; printf("%p\n",p); *p++; printf("%d : %p\n",r,p); return 0; } この場合 出力が 0xbffffbbc 100 : 0xbffffbc0 なんですが、 インクリメントの*p++;じゃなくてp++;と同じなんですが こういう書き方もあるよ、みたいな感じでうけとっていいんでしょうか? 値をインクリメントは(*p)++;なんですが *p++;の使い道がよくわかりません、p++と全く同じ感じなんですが
>>858 --
独習Cという本に書いてある
んですが。
な
んですが、
インクリメントの*p++;じゃなくてp++;と同じな
んですが
値をインクリメントは(*p)++;な
んですが
*p++;の使い道がよくわかりません、p++と全く同じ感じな
んですが
--
で、何が言いたいの?
まず共通する部分を抜き出してみよう。解読の基本だ。
>>859 五箇所に「んですが」が発見される。これを右から読む。「がすでん」
東シナ海では中国が日本との国境線付近でガス田を開発している。
平湖ガス田、断橋ガス田、天外天ガス田、春暁ガス田、そして今回問題となっている樫ガス田の五つ。
ガス田の数もぴたりと一致する。
つまりこれは中国が開発している東シナ海のガス田のことを指しているものと推察される。
更に「んですが」の一文字前の文字に注目して欲しい。
最初だけ「る」で残り四つは「な」だ。
つまり今回問題となっている樫ガス田についての極秘情報が暗号化されて
「独習Cという本に書いてあ」の部分に含まれていると考えられるのだ。
実に巧妙だ。
5ガス田の名前を間違えた 春暁、断橋、冷泉、天外天、龍井、だ 樫は天外天の日本名だな
typedef int (*tenarray)[10]; tenarray func();//int型の要素を10持つ配列へのポインタを返す関数 これを、typedef宣言しないで書くことってできるんですか?
863 :
673 :2009/01/05(月) 15:13:35
859さん 860さん 日本語のおかしさを責めないでください でもおもしろかったです
865 :
デフォルトの名無しさん :2009/01/05(月) 16:19:06
C言語の開発環境を作りたいのですがボーランドのC++をインストールしたいのですがログオンできません。 アカウントを作らなければいけないのでしょうか?あとアカウントの登録情報を変更したい時はどうすればいいですか?
866 :
673 :2009/01/05(月) 16:37:47
#include <stdio.h> int main(void) { int k[10][5]; int i,j,x; for(i=0; i<10; i++) for(j=0; j<5; j++) k[i][j]=1+j; for(i=0; i<10; i++){ for(j=0; j<5; j++) printf("%d",k[i][j]); printf("\n"); } return 0; } k[10][5]の配列に、1,2,3,5 6,7,8,9.... などと配列全部まで入れたいんですが、うまくいきません。 どなたか教えてください。
#include <stdio.h> int main(int argc, char *argv[]){ int k[10][5]; int i,j; for(i=0; i<10; i++) for(j=0; j<5; j++) k[i][j] = 5*i + j; for(i=0; i<10; i++) for(j=0;j<5;j++) printf("%d\n",k[i][j]); return 0; }
間違えた。1から入れるんだったね #include <stdio.h> int main(int argc, char *argv[]){ int k[10][5]; int i,j; for(i=0; i<10; i++) for(j=0; j<5; j++) k[i][j] = 5*i + j + 1; for(i=0; i<10; i++) for(j=0;j<5;j++) printf("%d\n",k[i][j]); return 0; }
869 :
673 :2009/01/05(月) 16:55:03
#include <stdio.h> int main(void){ int k[10][5]; int i,j; for(i=0; i<10; i++) for(j=0; j<5; j++) k[i][j] = 5*i + j; for(i=0; i<10; i++){ for(j=0;j<5;j++) printf("%3d",k[i][j]); printf("\n"); } return 0; } これで整頓して表示できました。 ありがとうございました
>>864 なんか表記する仕方があるのかと思ってました。
ないんですね。ありがとうございました。
あるよ。
872 :
673 :2009/01/05(月) 17:09:39
#include <stdio.h> int main(int argc, char *argv[]){ int k[10][5]; int i,j,*p; p=(int *)k; for(i=0; i<10; i++) for(j=0; j<5; j++) k[i][j] = 5*i + j; printf("%d",*(p+(9*5)+2)); return 0; } もう一つ質問があります。 独習Cには1元配列の場合 int i[80]; int *p; p=i; これで配列のアドレスを入れられるんですが。 int i[10][5]; int *p; p=(int *)k; 2次元配列の箇所には、 p=(int *)i; などとキャストしてようです。何故キャストするのかわかりません。 キャストを行わないで、p=i;などとやったらエラーがでます。 キャストは型を変えるはずなのに、intという型の配列を何故またintにキャストするのでしょうか? int *の*の意味もよくわかりません。 どなたかint*のキャスト意味や、何故キャストするのか教えてください
iはint型ではない。int[10][5]型だ。
874 :
673 :2009/01/05(月) 17:19:32
全然わかりません。 キャストっていうのは float x=10.2; printf("%d",(int)x); などと使って、小数を省いたりするように書かれてあったんですが、何故(int *)なんでしょうか??
>>862 >>864 int (*func(void))[10]
{
}
とすればできる。
解答者のレベルも目を覆うものがあるな。
>>874 >873を理解できないのなら、先ずはそこから。
877 :
デフォルトの名無しさん :2009/01/05(月) 17:47:42
878 :
865 :2009/01/05(月) 17:52:00
すいません。僕の質問に誰か答えてくれませんか?プログラミングしたいです。
880 :
デフォルトの名無しさん :2009/01/05(月) 17:53:02
visual stdio2008にしとけ
881 :
デフォルトの名無しさん :2009/01/05(月) 17:59:01
>>878 登録キーが必要かどうかはバージョンによる
コンパイラに限ったことではなく、ソフトウエア一般の話として、
ライセンス条件がわからないとき何をすべきかという問題なので
あなたの問いはスレ違いの可能性がある
いや、どう見てもスレ違いだろ。
>>858 (*p)++ との違いを示すための例なんじゃね?
>>875 長年、喉につかえていた魚の小骨が取れた気分です。ありがとうございます。
>>858 #include <stdio.h>
int main(){ int i;
char foo[2][16] = {"aaaaaaaaaaaaaaa","bbbbbbbbbbbbbbb",};
char *ap, *bp;
ap = foo[0]; bp = foo[1];
for(i = 0; i < 15; ++i) printf("%c", *ap++);
printf("\n");
for(i = 0; i < 16; ++i)printf("%c", (*bp)++);
printf("\n");
printf("%s\n", foo[0]);
printf("%s\n", foo[1]);
return 0;
}
aaaaaaaaaaaaaaa
bcdefghijklmnopq
aaaaaaaaaaaaaaa
rbbbbbbbbbbbbbb
*p++は、値を参照してからポインタ演算
(*p)++は、ポインタがさす値を逆参照し、その値をインクリメント
#で、あってんのかな?
unsigned int型変数では、演算によるオーバーフローは発生しない
が正しいというのが理解できず。。オーバーフローしないの?
>>669 の2級
>>858 使用例
char foo[16]="aaaaaaaaaaaaaaa", bar[16], *ap, *bp;
ap = foo; bp = bar;
while(*bp++ = *ap++);
887 :
673 :2009/01/05(月) 18:57:57
886さん for(i = 0; i < 16; ++i)printf("%c",foo[1][i]+1); for(i = 0; i < 16; ++i) printf("%c", *bp++); 配列だとbcdefghijklmnopqとでませんね。 bの次のcccccccccccとでます。 配列でfor(i = 0; i < 16; ++i) printf("%c", *bp++);と同じような事はできるんですか? それとキャストの p=(int *)k; が未だにわかりません。
888 :
865 :2009/01/05(月) 19:02:47
解答ありがとうございます。スレ違いみたいなので他のスレで聞いてみようと思うのですがどんなスレッドで質問すればいいですか?あとvisual stdio2008はお金がかかるのですが無料開発環境と比べてどんなメリットがありますか?
いや無料のがあるだろ
890 :
673 :2009/01/05(月) 19:04:49
888さん たぶんお金がかかっているだけあって、補完機能やデバッカ機能などあると思います。 お金かけずにフリーソフトのコンパイラがあると思います
891 :
デフォルトの名無しさん :2009/01/05(月) 19:08:00
スタックオーバーフローが発生する実際の様子を観察することを目的として、 自動変数の配列のサイズとエラーの関係のプログラムを作成ししてみたところ、 stackavail 関数のところでエラーが発生してしまいました。 OSはwindowsでコンパイラはcygwinです。下にソースをのせときます。 #include<stdio.h> #include<malloc.h> int main() { char A[3000]; A[0]='\0'; printf("stack: %d\n", stackavail()); printf("done\n"); return 0; } stackavail関数の使い方が間違っているのかよく分からなかったので どなたかアドバイスの方よろしくお願いします。
892 :
デフォルトの名無しさん :2009/01/05(月) 19:11:09
>>891 どんなエラー?
Cygwinがstackavail()という非標準関数をstdio.hに持っているかどうか
はオレは知らない。
質問です。 c言語でコマンドラインから引数を受け取ってファイルを 処理するプログラムがあったとします。仮にtest.exeとします。 カレントディレクトリには、以下のファイルが存在します。 a.txt b.txt c.txt test.exe そして、「test *.txt」 とコマンドを打ったら、 a.txtを引数としたプログラムが実行されて、プログラム終了。 ↓ b.txtを引数としたプログラムが実行されて、プログラム終了。 ↓ c.txtを引数としたプログラムが実行されて、プログラム終了。 みたいなかんじで動作するのでしょうか?
>>894 test a.txt b.txt c.txt
896 :
デフォルトの名無しさん :2009/01/05(月) 19:19:57
>>893 /cygdrive/c/DOCUME~1/owner/LOCALS~1/Temp/ccqpUnTx.o:jikken.c:(.text+0x3b)
fined reference to `_stackavail'
collect2:Id returnec 1 exit status
というエラーです。非標準関数が入っていないからなんですかね?
なかった場合は新しく入れることは可能なんでしょうか?
897 :
888 :2009/01/05(月) 19:38:08
解答ありがとうございました。とりあえずVisual Studio 2008 のスタンダードの購入を検討してみます。一番手っ取り早そうなので。
>894 するかもしれないし、しないかもしれない。 実際にプログラムが呼び出されるまでにどういう形でコマンドラインが処理されるかはOSに依存するし、 受け取ったコマンドライン引数をプログラムがどう処理するかはそのプログラムによるし、 開こうとするファイル名をどう処理するか(具体的にはカレントディレクトリの問題)もOSに依存する
899 :
デフォルトの名無しさん :2009/01/05(月) 19:45:46
Visual Studio 2008 Express Edition」の日本語正式版を無償公開
888はわかってんのかわかってないのか
>>894 ワイルドカードの展開は、Unix系ならシェルが行なうし、
Windows系ならそのまま渡して、それを各プログラムが展開するよ。
>>897 >899はよめますか?
「無償公開」とは、「ただでだうんろーどできます」といういみですよ。
903 :
デフォルトの名無しさん :2009/01/05(月) 20:17:45
904 :
897 :2009/01/05(月) 20:23:44
どうやってダウンロードすればいいのか分からないのでDVD−Rを買うのが一番早いかなと思ったんです。 開発環境をダウンロードした経験がないので。本当の初心者ですみません。
そんなこともできないんじゃあきらめたほうがいい
906 :
デフォルトの名無しさん :2009/01/05(月) 20:28:19
907 :
デフォルトの名無しさん :2009/01/05(月) 20:29:25
vcsetup.exe というのがダウンロードされるのでそれをクリックだな。
>>903 >896を見る限り、stackavail()なる関数が見つからないのだろ。
どこで知ったか知らんが、それを知った場所で聞けよ。
909 :
デフォルトの名無しさん :2009/01/05(月) 20:33:53
>>904 にVisual Studio 2008 Express Editionが使えるのか?
ダウンロードも分からんのに。
911 :
デフォルトの名無しさん :2009/01/05(月) 21:00:30
webインストーラーは、次へをクリックしていくだけだったはず。 これで駄目ならDVD買っても無理。
673は、配列とポインタの違いが分かっていない悪寒。 あとポインタの型の違いと、ポインタがどこ指しているかとか。 というか、初心者にはVisualStdioよりも、 cygwinや、*nixの方が幸せな環境だと思うんだが。
ONIX
>>894 ワイルドカード(* or ?) の展開は shell の仕様になります。dos の command.com は
>>895 のようには展開してくれませんでした。
NT の cmd.exe はどうでしょうかね。(やったことない)
915 :
914 :2009/01/05(月) 22:41:07
916 :
894 :2009/01/05(月) 23:23:33
携帯からでID違います。 具体的にどのように展開されるのでしょうか? いまいち理解できません。すみません・・・ test.exe *.txt ↓ test.exe a.txt b.txt c.txt と展開されるのでしょうか?
.exe がDOSを暗示しているのならそうではない。 *.txt のままargvに入る。 unixのばあいだけそうなる。
DOSでもコンパイラによっては展開してくれたな
>>918 ワイルドカード展開をおこなってくれるルーチンがあったような気がします。lha のソースでみたような。
>>917 そうでしたっか?
*.txtのワイルドカードはUnixの場合シェルが展開するのですよね
DOSのコマンドプロンプトは展開してくれないのかなあ?
LSI-Cは展開してくれるようにもできてたのでラクだったな
922 :
894 :2009/01/06(火) 00:09:03
*.txtがそのまま渡されるとして、 プログラム上で.txtが含まれる全てのファイルを参照することは可能なのでしょうか? 具体的なコードを提示して下さると助かります。
>>922 ファイルシステムについての質問は常に、OSに依存するという答えになる
>>922 #include <stdio.h>
int main(int argc, char *argv[])
{
int i;
for (i = 0; i < argc; i++) {
printf("argv[%d]: /%s/\n", i, argv[i]);
}
return 0;
}
925 :
924 :2009/01/06(火) 00:12:41
勘違いした!無視して
すげえ恥さらし
>>922 恐らくは可能だろうけれども、その詳細はシステムに依存する。
928 :
894 :2009/01/06(火) 00:23:40
システムはWindowsです。 コマンドプロンプトでの動作しか想定していません。 開発環境は、BCC developer(スペル適当)です。
XPでコマンドプロンプトからの起動ならプログラムにはワイルドカード展開した結果が渡されるんじゃない?
>>928 BCC なら、"wildargs.obj" を明示的にリンクすることで
スタートアップルーチンの中で展開するようになるよ。
リンク方法は、解るよな?
明示的にリンクしないと、ダミーがリンクされる仕組み。
933 :
デフォルトの名無しさん :2009/01/06(火) 00:48:44
for(i=0;i<10;i++){ sprintf(&filename2[i][MAX_SIZE],"%c%d1.csv",number,i); sprintf(&filename2[i+10][MAX_SIZE],"%c%d2.csv",number,i); } MAX_SIZEは300、numberは1を入れて実行し for(i=0;i<20;i++){ printf("filename2[%d]=%s\n",i,&filename2[i][MAX_SIZE]); } で結果を確認してみると filename2[0]=101.csv ・ ・ filename2[8]=181.csv filename2[9]=・ filename2[10]=102.csv ・ ・ filename2[17]=172.csv filename2[18]=182. filename2[19]=リ・ となってしまいます。なぜかわかる方いますか?
sprintfの最初の引数が書き方がおかしいから
&filename2[i][MAX_SIZE] これは何を指していると思うの?
936 :
デフォルトの名無しさん :2009/01/06(火) 00:57:55
2次元配列の場合はどのように書けばよいのでしょうか?
>>936 だから、&filename2[i][MAX_SIZE] はどこを指していると思っている?
またお前か お前は二次元配列以前に配列がわかってないだろう char array[SIZE]; というものがあったとき、 1) array 2) array[0] 3) &array 4) &array[0] それぞれの意味を説明できるか?
939 :
デフォルトの名無しさん :2009/01/06(火) 01:04:59
filename2[i][MAX_SIZE]の番地ですか?
>>939 そうだけど、それが具体的にどこだか図示できる?
で、そこにsprintfで書き込んだら何が起きると思う?
numberの書き出しを%cでやってるのもおかしい?
>>942 出力結果から見るとそこは'1'を入れてるんだろうけどね
944 :
デフォルトの名無しさん :2009/01/06(火) 01:17:15
>で、そこにsprintfで書き込んだら何が起きると思う? その番地に書き込んでくれると思っていました。 ですが、その番地に書き込みたいときはどうすればいいのでしょうか?
>>944 本当にわかってないんだな
char filename[10][MAX_SIZE];
というものがあったとき、メモリは以下のように確保される
【filename[0][0]】【filename[0][1]】【filename[0][2]】 …(以下、【filename[0][MAX_SIZE-1]】まで)
【filename[1][0]】【filename[1][1]】【filename[1][2]】 …(以下、【filename[1][MAX_SIZE-1]】まで)
(中略)
【filename[9][0]】【filename[9][1]】【filename[9][2]】 …(以下、【filename[9][MAX_SIZE-1]】まで)
便宜上段分けしたが、一行目の最後は二行目の頭につながっている
だからfilename2[0][MAX_SIZE]は実際にはfilename2[1][0]のことだ
ここまでで、自分が何を間違ってるかわかったか?
946 :
897 :2009/01/06(火) 01:23:48
開発環境のインストールができました。教えてくださった方々ありがとうございました。 プログラムを作りたいのですがどうしたらいいですか?明日にでも教えてもらえたら嬉しい限りです。
>933はまず>938に答えること お前はまずそこから勉強しなおしだ
948 :
デフォルトの名無しさん :2009/01/06(火) 01:27:01
>945 値を配列の最後に入れようとしていたということですか?
>>936 正しいソースが欲しいだけでCを理解するつもりがないなら宿題スレへ行くこと
>>948 今、「値」と「最後」をそれぞれどういう意味で使ったか厳密に説明してみ
何の値なのか、最後ってのは具体的にアドレスで言うとどこか
951 :
デフォルトの名無しさん :2009/01/06(火) 01:29:02
>>938 1)と2)は配列の先頭の値
3)と4)は配列の先頭の番地
ですか?
953 :
デフォルトの名無しさん :2009/01/06(火) 01:30:43
>>950 値は101.csv などのこと
最後はfilename[0][MAX_SIZE-1]などのこと
ですか?
954 :
894 :2009/01/06(火) 01:32:33
>>929 ありがとうございます。
それでググったやり方だと僕がやりたいことに
ぴったりなコードが書けます。
他にレスして下さった方々もありがとうございました。
955 :
デフォルトの名無しさん :2009/01/06(火) 01:36:17
>>951 違う
1)は配列そのもので、ただしほとんどの場合配列の先頭の番地に意味が格下げになる
2)は配列の先頭の値
3)は配列そのものの番地で、ポインタとしての型(指しているものの大きさ)は違うけれど、場所としては先頭の番地と同じ
4)は配列の先頭の値の番地だから配列の先頭の番地と同じ
958 :
デフォルトの名無しさん :2009/01/06(火) 01:54:27
sprintfの最初の引数には変換した出力を格納する文字列を与えるということですが、 これは具体的に何を与えてやればいいのでしょうか?先頭の番地でしょうか?
>>951 まず array 、これは配列自体だが、いくつかの例外(初期化、&演算子、sizeof演算子)を除いて
「 array の先頭要素へのポインタ」として扱われる
これはCの言語仕様で決められていることなので、そういうものだと思うこと
次に array[0] と書いたとき、これは *(array+0) と同じ意味になる
言ったように array は先頭要素へのポインタになって、それに整数を足すとそのぶんだけ先の場所を指す
( array+1 なら配列の1番目の要素を、array+2 なら2番目の要素を指すポインタになる)
この場合は足すのが 0 だから0番目の要素つまり先頭要素で、それを * 演算子で実体参照している
つまり array[0] は array の先頭要素
&array は上で言った例外のひとつで、これは「 array へのポインタ」になる
指している場所は array の先頭要素へのポインタと同じだが、整数を加算したときの結果が異なる
「 array の先頭要素へのポインタ」はこの場合「 char へのポインタ」で、これに1を足すと「 char 1個ぶん後の領域」を指すが
「 array へのポインタ」は「 char[SIZE] へのポインタ」で、1を足すと「 char SIZE*1個ぶん後の領域」、つまり array を飛び越えた領域を指すようになる
普通はこれを意識して遣うことはないが、二次元配列(配列の配列)を使うときにはこれが問題になってくる
ここまでは理解できたかな?
>>958 そうだよ
もちろん、その先頭の番地以降に十分な領域が確保されてなきゃいけない
>>957 オーバーフローするだろう
0xffffffff + 1 -> 0
>>956 番地に格下げとはまた新しい。ポインタに格下げね。
>>960 じゃあ問題とその解答が間違えているということでしょうか?
>>957 オーバーフローエラーとかは発生しないってことかも?
>>963 そういうこと。
>>960 そういう風に扱える範囲を超えたら
上のビットを無視した結果(UINT_MAX + 1での剰余)にならないといけないと決まっている。
966 :
デフォルトの名無しさん :2009/01/06(火) 02:05:51
>普通はこれを意識して遣うことはないが、二次元配列(配列の配列)を使うときにはこれが問題になってくる どのような問題が起こるのでしょうか?
>>958 「文字列」って表現してある教科書は多いけど、不正確なんだな
実際には単なる領域へのポインタ
で、通常は配列自体が領域の先頭の要素へのポインタになるので、
ふつう配列をそのままぶちこむ
&とか使わずに
char filename[SIZE];
としたら
sprintf(filename, " (以下略
>>966 あとで説明するからまず一次元配列を理解しなさい
969 :
デフォルトの名無しさん :2009/01/06(火) 02:08:58
>>967 2次元配列の場合だと、下のようになるということですか?
char filename[5][SIZE];
としたら
sprintf(filename[0],"(以下略
重要なことだからしっかり理解しないといけないと考える回答者と 面倒だから答えだけ教えてくれればいいのにという質問者のせめぎ合い よくあることだけど、悲しいことだね
>>969 そうだけど、この場合の filename と filename[0] はなんなのか説明できる?
972 :
デフォルトの名無しさん :2009/01/06(火) 02:12:41
>>971 どちらもfilenameの先頭のアドレスじゃないですか?
sprintf(filename[1],"(以下略 これと等価な他の書き方を書いて。 それと、これがどこのアドレスになるかを言ってみて。 &filename[0][MAX_SIZE]
>972 そろそろアドレスとか番地とかいう言葉から卒業すること filenameは○○へのポインタ filename[0]は○○へのポインタ ○○を埋めなさい
976 :
デフォルトの名無しさん :2009/01/06(火) 02:17:49
ポインタはアドレス、番地と同じ意味で使っていいんですか?
>>976 違う
ポインタはアドレス(番地)と、指しているものの型をいっしょにした概念
978 :
デフォルトの名無しさん :2009/01/06(火) 02:22:53
>>975 filenameはfilenameの先頭要素へのポインタ
filename[0]はfilenameの0番目の要素へのポインタ
>>964 int型変数はどうなんでしょうか?
int型変数では、演算によるオーバーフローは発生しない
「はい」ですか「いいえ」ですか?
>>979 発生する。
発生した場合、未定義動作。
そろそろレス数が少ないから総括してしまうが char filename[5][MAX_SIZE]; と書いたとき、 filenameは「『char MAX_SIZE個からなる配列』5つからなる配列」で、 これはすぐ「filename[0]を指す『char MAX_SIZE個からなる配列』へのポインタ」に成り下がる filename[0]は「char MAX_SIZE個からなる配列」で、 これもすぐに「filename[0][0]を指すcharへのポインタ」に成り下がる sprintfに与えるのは「確保された十分な大きさの領域の先頭を指しているcharへのポインタ」で、 この場合filename[0]〜filename[4]を与えることができる 君の最初のコードは何が間違っていたかというと、 filename[i][MAX_SIZE]が、filename[i]の最後の要素であるfilename[i][MAX_SIZE-1]を飛び越して 実際にはfilename[i+1][0]になってしまっていて、そこへのポインタを&演算子で作り出して与えてしまった &filename[i+1][0]はfilename[i+1]と同じことだから、つまりfilename[0]〜filename[9]を与えるべきところで filename[1]〜filename[10]を与えてしまった このとき、filename[10]はfilenameという二次元配列全体をも飛び越した場所、つまり確保されていない領域を指している そこにsprintfで書き込んだからおかしくなった わかったかな?
>978 違う filenameはcharのSIZE個の配列5個の配列で、その先頭要素(charのSIZE個の配列)へのポインタになる filename[0]はfilenameの0番目の要素(charのSIZE個の配列)で、その先頭要素(char)へのポインタになる
983 :
デフォルトの名無しさん :2009/01/06(火) 02:34:31
>>981 とてもわかりやすい説明ありがとうございます。
今日教えていただいたことはだいたい理解したつもりですが、また忘れないように勉強しときます
filename と &filename[0] filename[0] と &filename[0][0] ポインタとして演算をする時は、それぞれ同じように振る舞うということを覚えておくといいよ
985 :
デフォルトの名無しさん :2009/01/06(火) 02:41:24
>>984 ポイントを絞った解説ありがとうございます。自分もまさにそのように覚えようとしていました。
下のようにプログラムを書きなおしたのですが、最後だけうまくいきません。
for(i=0;i<10;i++){
sprintf(filename2[i],"%d%d1.csv",number,i);
sprintf(filename2[i+10],"%d%d2.csv",number,i);
}
for(i=0;i<20;i++){
printf("filename2[%d]=%s\n",i,filename2[i]);
}
結果は
filename2[0]=101.csv
filename2[1]=111.csv
・
・
filename2[18]=182.csv
filename2[19]=192.
となってしまいました。これはなぜでしょうか?
切り貼りしないでソース全部貼れ
987 :
デフォルトの名無しさん :2009/01/06(火) 02:49:37
char filename2[19][MAX_SIZE]; で宣言していたのを char filename2[20][MAX_SIZE]; で宣言すると解決しました。 配列は0から始まるので20個使いたいときは[19]で宣言すればいいのではないんでしょうか?
988 :
デフォルトの名無しさん :2009/01/06(火) 02:50:04
int 型(符号つき32 ビット整数)および、unsigned int 型(符号なし32 ビット整数)のそれぞれの最大値の求め方を教えてください。 バカな質問ですいません。
宣言時は要素の数を指定する 使う時は0から使う
>>987 20個使うときは[20]で宣言して[0]から[19]までの20個を使う
ほんっとに基本がわかってないんだな! 配列の大きさは0スタートじゃないよ
992 :
デフォルトの名無しさん :2009/01/06(火) 02:51:23
>>989 そうなんですか、知りませんでした。
初心者以下のミスをしてしまいました。どうもすみませんでした。
INT_MAX UCHAR_MAX でぐぐれ
>>988 #include <limits.h>
INT_MAX int 型最大値
UINT_MAX unsigned int 型最大値
996 :
デフォルトの名無しさん :2009/01/06(火) 02:58:21
乙うめぇw
>>983 一発で区別を完全に理解できるものではないと、誰しも考えていると思います。そのたびごとに面倒がらずに振り返っていただければ。
>>981 お疲れ様です。頭が下がります。
生め
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。