[表示 : 全て 最新50 1-99 101- 201- 301- 401- 501- 601- 701- 801- 901- 1001- 2chのread.cgiへ]
Update time : 03/13 21:05 / Filesize : 260 KB / Number-of Response : 1002
[このスレッドの書き込みを削除する]
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧] [類似スレッド一覧]


↑キャッシュ検索、類似スレ動作を修正しました、ご迷惑をお掛けしました

スレを勃てるまでもないC/C++の質問はここで 3



1 名前:デフォルトの名無しさん mailto:sage [2007/08/19(日) 20:07:56 ]
スレを勃てるまでもない低俗なC/C++の質問はここでお願いします。

過去ログ
スレを勃てるまでもないC/C++の質問はここで
pc11.2ch.net/test/read.cgi/tech/1167476845/
スレを勃てるまでもないC/C++の質問はここで 2
pc11.2ch.net/test/read.cgi/tech/1178503366/

411 名前:デフォルトの名無しさん mailto:sage [2007/10/15(月) 20:13:04 ]
C++なんですが、AfxsetResuseで
明示的にリソースを設定した場合
リソースの解放も明示的に行う必要が
あるんでしょうか?

412 名前:デフォルトの名無しさん mailto:sage [2007/10/15(月) 20:44:31 ]
>>411
C++標準には、そのような識別子は定義されていないが?

413 名前:デフォルトの名無しさん mailto:sage [2007/10/16(火) 04:05:24 ]
質問です。

以下のように書いたとき、
arrayの各要素は10で初期化されると思っていたんですが、
コンパイルして実行してみるとarray[0]のみ10で
残りは0で初期化されてました。
配列の各要素をすべて同じ値で初期化するにはどうすれば良いんでしたっけ?
よろしくお願いします。

#include <iostream>

int main(int argc, char** argv)
{
int array[10] = {10};

for (int k = 0; k < 10; ++k) {
std::cout << array[k] << std::endl;
}

return (0);
}

414 名前:デフォルトの名無しさん mailto:sage [2007/10/16(火) 04:33:10 ]
int array[10] = {10,10,10,10,10,10,10,10,10,10};

0以外の数字で全て同じ数値で初期化するには、いちいち全部書かなきゃダメ。

めんどくさいなら for(i=0; i<10; i++) array[i] = 10; みたいにループで初期化する。

415 名前:デフォルトの名無しさん mailto:sage [2007/10/16(火) 04:50:04 ]
int array[10] = { FILL(10,10) };
みたいにプリプロセッサで書けないかなぁ…

416 名前:デフォルトの名無しさん mailto:sage [2007/10/16(火) 05:02:13 ]
C++ならクラスにしてコンストラクタで初期化させればええやん

417 名前:デフォルトの名無しさん mailto:sage [2007/10/16(火) 07:03:56 ]
std::vector<int> array(10, 10);

418 名前:デフォルトの名無しさん mailto:sage [2007/10/16(火) 08:47:11 ]
>>414
0以外のときは駄目だったんですね。
全然知りませんでした。

ありがとうございました。


419 名前:デフォルトの名無しさん mailto:sage [2007/10/16(火) 12:25:23 ]
あれ?自動変数は0に初期化されるんでしたっけ?



420 名前:デフォルトの名無しさん mailto:sage [2007/10/16(火) 12:43:56 ]
いいえ、普通の自動変数は初期化されません。
但し、構造体や配列の初期化指定子の数が足りない場合は0が補われます。
従って、all bit 0が数値0を表わさない実数型であったとしても、数値0が保証されます。

421 名前:デフォルトの名無しさん mailto:sage [2007/10/16(火) 13:34:07 ]
プログラム的にmain関数内でforループの中で配列を宣言するのはどう思いま
すか?配列の領域がループ回数分かわるのでforループの中にいれたいのですが。


422 名前:デフォルトの名無しさん mailto:sage [2007/10/16(火) 13:36:43 ]
>配列の領域がループ回数分かわる
ここが意味不明なので何とも言えない。

423 名前:デフォルトの名無しさん mailto:sage [2007/10/16(火) 13:41:17 ]
forループの中で1ループごとにファイルを1つ読み込んで
そのファイルの行数を配列の領域としたいんです。
だからファイルをかえるとファイルの行数もかわり、領域もかわるというわけ
です。わかりにくいですか

424 名前:デフォルトの名無しさん mailto:sage [2007/10/16(火) 13:44:09 ]
あーなるほど、言いたいことは判った。

配列って言うか、動的メモリ領域の話ね。
ループ外で全く使わないなら、ループ内で定義していいんじゃない?
つーか、そうすべきだと思うけど。
# 但し、殊にCではアナクロ的に関数の先頭で全てのローカル変数を宣言しないと気が済まない人もいるから注意。

425 名前:デフォルトの名無しさん mailto:sage [2007/10/16(火) 13:55:16 ]
ただそのときに
その配列の前にファイル読み込んで行数確認して
配列の領域確保して
またファイル読み込んでそこの配列に代入というプログラムにしてるんです。
無駄にファイル読み込んでるとかいわれそうだけど。

最初に全てのファイルの領域を確保する
配列を定義してもいんですが、その行数をまた違う配列でも使うので、
それは避けたいんです。

426 名前:デフォルトの名無しさん mailto:sage [2007/10/16(火) 14:04:46 ]
ファイルの二回読み自体は仕様的に問題ないなら構わないと思う。
しかし、寧ろそれだけ複雑ならループ内を全部別関数にするべきじゃないのか?
main()はあくまでもコマンドラインとのI/Fだと思うんだが。

427 名前:デフォルトの名無しさん [2007/10/16(火) 14:06:45 ]
STLなら自動拡張する

428 名前:デフォルトの名無しさん mailto:sage [2007/10/16(火) 14:20:06 ]
まあそうなんですけど。
今つくってるのは1つのファイル(これを入力)に対して
forループ回違うファイルを読み込んで処理して
それぞれファイルでの値を出して一番高いものを出す。
その一番高いものが入力と合ってたら正解みたいなプログラムなんですけど。
これをmain関数内でやってるわけなんですが、
入力が複数として、この複数の入力の中で正解がいくつあるかって最終的には
したいんです。

今のmain関数も別関数として
入力をいれる処理をmainとして、元のmain関数において正解のものを
returnさせて正解率を出すべきですよね?


429 名前:デフォルトの名無しさん mailto:sage [2007/10/16(火) 14:27:02 ]
抽象的に過ぎてよく判らんw

こんなもんじゃないのかな?
main()
{
問題処理();
}

問題処理()
{
統括ファイル読み込み();
for () {
個別ファイル処理();
if (正解判定()) {
正解処理();
}
}
}



430 名前:デフォルトの名無しさん mailto:sage [2007/10/16(火) 14:32:14 ]
んなもんですね。。ありがとうございます。
mainから問題処理のところを手作業でやってもいんですけど
入力データが100くらいあるから手作業だとだるすぎるので。
今求められてるのは正解率ですから。しかし何かの機械の実装って本当にめん
どくさいね。まだ社会人じゃないから実情は知らないけど。


431 名前:デフォルトの名無しさん mailto:sage [2007/10/16(火) 14:33:04 ]
オジサンの弱った頭には、ややこしくて理解できん。
話を整理してもらえないか。

432 名前:デフォルトの名無しさん mailto:sage [2007/10/16(火) 14:36:26 ]
宿題スレじゃないんだし、エスパーごっこはそろそろ終わりでいいんじゃないか?
>430だって>429までの流れを踏まえて少しは自分で頭を使いたいだろうし。

433 名前:デフォルトの名無しさん mailto:sage [2007/10/16(火) 14:44:07 ]
もうforループの中で配列宣言つかっていいてのと
ファイル2回読みはOKかどうかもわかったので失礼します

434 名前:デフォルトの名無しさん mailto:sage [2007/10/16(火) 17:55:42 ]
まあ、ファイルのクローズと、領域の解放を忘れなければどうでも良いんじゃね

435 名前:デフォルトの名無しさん mailto:sage [2007/10/16(火) 18:48:47 ]
若い人は記憶力まかせにしても破綻しにくいからのぉ。

わしも小学生の頃は、
恐ろしくスパゲッティなコードを書いていたが、
ちゃんと把握できていたので何ら問題なかったな。

いまではもう無理。

436 名前:デフォルトの名無しさん mailto:sage [2007/10/16(火) 18:51:02 ]
若いのにRAIIとかエディタの支援機能に頼りまくりで記憶力低下中だけど
元からそんなに記憶力良い方じゃないから問題ないか

437 名前:デフォルトの名無しさん mailto:sage [2007/10/16(火) 18:51:59 ]
ここは自分のダメな所を書くスレになりました

438 名前:デフォルトの名無しさん mailto:sage [2007/10/16(火) 18:57:10 ]
若くても、頭脳を有効に使うために、スマートなコードを書くべき。

439 名前:デフォルトの名無しさん mailto:sage [2007/10/16(火) 20:59:21 ]
Cの配列宣言って要素数に定数じゃなくて変数って使えないんじゃ?
動的な領域確保したい時はCはmallocに頼るしかないはずだと記憶していたのですが?
覚え間違いかな…?

># 但し、殊にCではアナクロ的に関数の先頭で全てのローカル変数を宣言しないと気が済まない人もいるから注意。

これはブロック({}で囲まれた部分のこと、正式な呼び方知らない)の先頭でしか変数の宣言を許さないCの制限のせいでしょう
C++ではこの制限がないからbetterCとしてC++を使っているなら関係ない話ですが



440 名前:デフォルトの名無しさん mailto:sage [2007/10/16(火) 21:47:30 ]
>>439
その制限は関係ないよ。

関数の先頭でしか変数宣言すべきではないという石頭の連中は、
制限がないC++においても、同様のルールを主張していたりするから。


441 名前:デフォルトの名無しさん mailto:sage [2007/10/16(火) 22:16:45 ]
>>439プ

442 名前:デフォルトの名無しさん mailto:sage [2007/10/16(火) 22:23:16 ]
>>439
>Cの配列宣言って要素数に定数じゃなくて変数って使えないんじゃ?
C99なら出来る。C89はムリ

443 名前:デフォルトの名無しさん mailto:sage [2007/10/17(水) 11:22:34 ]
C言語の入門書を読んでたら、getsやscanfは使うなとか、fgetsを使えとか
ややこしいですよね。デリミタで区切られたデータ列を読み込む必要がある
んですが、呼び側のコードをシンプルにするため、こんな関数を作ってみま
した。下記のように使うのですが、何かマズいところはないでしょうか?
今のところ一応動いているのですが・・・

 char s[128];
 FILE *p = fopen("hoge.txt", "rb");
 if (ReadData(p, s) == 0) break;

/*********************************************************************
 ☆ファイルから1単位読み込んで文字列として返す
  デリミタで挟まれた文字列を1単位とする。
  int IsDelimiter(int c)はデリミタなら1、そうでなければ0を返す
  空のフィールドは存在しないものとする。
*********************************************************************/


444 名前:デフォルトの名無しさん mailto:sage [2007/10/17(水) 11:23:47 ]
int ReadData(FILE *p, char *s)
{
int ex, c, ip;
/* 非デリミタ文字が現れるまで読み飛ばす */
ex = 0;
while (ex == 0){
c = fgetc(p); if (c == EOF) break;
if (IsDelimiter(c) == 0) ex = 1;
}
if (ex == 0) {
s[0] = '\0'; return 0;
}
else {
s[0] = (char) c;
}

/* デリミタが現れるまで,文字列を積み上げる */
ip = 1;
ex = 0;
while (ex == 0){
c = fgetc(p); if (c == EOF) break;
if (IsDelimiter(c) == 1) {
ex = 1;
}
else {
s[ip] = (char) c; ip++;
}
}
s[ip] = '\0';
return 1;
}


445 名前:デフォルトの名無しさん mailto:sage [2007/10/17(水) 12:31:33 ]
128文字以上を入力するとマズい

getsを使うなってのは、読み込む最大文字数を指定できないからで、入力ファイルに予想より長い文字列が現れたら致命的
代わりにfgetsを使えってのは、fgetsは最大文字数を指定できるので、どんな入力が来ても死ぬことはない
>>444 の関数はそれと同じ問題を孕んでいる

ユーザに127文字までしか入力してはいけないといくら言い聞かせてみたところで、禁止されるとやりたくなるのが人というものだし、
そうでなくてもついうっかり文字数制限を忘れてしまうこともあるだろうし、プログラムはどんな入力が来ても安全なように作っておくべき

446 名前:デフォルトの名無しさん mailto:sage [2007/10/17(水) 12:56:45 ]
>>444
ReadDataにsの要素を渡して文字数のチェックをちゃんとすればおk
てかex変数が無駄に見える……

447 名前:デフォルトの名無しさん mailto:sage [2007/10/17(水) 12:57:32 ]
間違えた、sの要素数を、ね

448 名前:デフォルトの名無しさん mailto:sage [2007/10/17(水) 13:52:11 ]
ofstreamはdeleteした際には自動的にcloseされるますか?

449 名前:デフォルトの名無しさん mailto:sage [2007/10/17(水) 16:56:00 ]
yes yes yes



450 名前:444 mailto:sage [2007/10/17(水) 21:22:36 ]
レスありがとうございます。

>>445
>128文字以上を入力するとマズい

実装時には、バッファ長を1kB位取ってごまかしちゃうつもりでしたが、
言われてみればその通りですね。変数ipをチェックすればいいので、
バッファがあふれたらエラーを返すコードを追加しようと思います。

>>446
>ex変数が無駄に見える……

やっぱり?
ループの脱出条件をコーディングしながら決められるので、ついつい
やっちゃいます。こんな場合は、

  while ( (c=fgetc(p) != EOF ) {

とか書くもんなんでしょうか?


451 名前:デフォルトの名無しさん mailto:sage [2007/10/17(水) 22:24:27 ]
>>450
exが無駄って言ったのは、
ループ中途脱出(break)を判別するためだけに使ってるように見えたから。
あれならwhileループ後のif文をそのままwhile内にぶちこめば、
ex使わないでいけそうだったし。
まあ、分かりやすく書けば良いと思うので、聞き流して結構です

do {
if( (c=fgetc(p)) == EOF ) {
s[0] = '\0';
return 0;
}
} while (IsDelimiter(c));
ループ終了条件を>>450みたくデリミタでなくEOFにすると、
この場合はreturnするために別にまたif文書かないといけないから、無駄そう

452 名前:デフォルトの名無しさん mailto:sage [2007/10/17(水) 22:50:46 ]
C言語なんだから、関数ばしばし作ろうよ。

・デリミタもしくはEOFまで読み飛ばし、最後に読み飛ばした文字を返す
・デミリタまで文字列を格納する
という2つの関数を作ればスッキリするよ。


453 名前:444 mailto:sage [2007/10/17(水) 22:59:06 ]
>>451
>whileループ後のif文をそのままwhile内に

む。なるほど。
こちらの方がシンプルですね。

プログラムをできるだけ愚直に書こうと努力しているつもりですが、
スマートな解を示されると感動しちゃいます。勉強になりました。

>>452
>関数ばしばし

実装フェーズでは、そうなっちゃうかもしれません。
ただ、データ読み出しの関数なので、恐らく何万回も呼ばれる
ことになると思います。
実のところ、こんな冗長な関数を作るべきか、まだ悩んで
いるんです・・・


454 名前:デフォルトの名無しさん mailto:sage [2007/10/17(水) 23:09:09 ]
何万回程度の関数呼び出しコストなんて屁でもないぞ


455 名前:デフォルトの名無しさん mailto:sage [2007/10/17(水) 23:15:46 ]
というかこれでいいと思う

int ReadData(FILE *p, char *s){
int c, ip=0;

while( (c=fgetc(c)) != EOF)
if (IsDelimiter(c))
s[ip++] = (char) c;

s[ip] = '\0';
return !!ip;
}

456 名前:デフォルトの名無しさん mailto:sage [2007/10/17(水) 23:21:41 ]
いいのか、ほんとに。

457 名前:デフォルトの名無しさん mailto:sage [2007/10/17(水) 23:29:45 ]
なんでいいのか判らん・・・


458 名前:455 mailto:sage [2007/10/17(水) 23:32:29 ]
あ、すまん、所々ミスってる上にそもそも動作が違うなw

これでどうだ

int ReadData(FILE *p, char *s){
int c , ip=0 , flag=0;

while( (c=fgetc(p)) != EOF ){
if (flag){
if (!IsDelimiter(c)) s[ip++] = (char) c;
else break;
} else if (IsDelimiter(c)) flag=1;
}

s[ip] = '\0';
return !!ip;
}

うーん、あんまりスマートじゃない……

459 名前:455 mailto:sage [2007/10/17(水) 23:34:58 ]
>>456-457
いや、IsDelimiterの戻り値を勘違いしてた上に、
そもそも動作を全く勘違いしてたw

これならわざわざ書き直す必要なかったですね……
偉そうにでしゃばってすみませんorz



460 名前:444 mailto:sage [2007/10/17(水) 23:44:46 ]
各位殿

色々ご指導ありがとうございました。
とりあえず仮決めですが、下記のようにすることにしました。
色々いじったら、仕様が変わっちゃった・・・

>>454
ちょっと安心しました。

>>455
読み込み長を返すアイデア頂きました。
ありがとうございました。


461 名前:444 mailto:sage [2007/10/17(水) 23:45:24 ]
int ReadData(FILE *p, char *s)
{
int c, ip;

/* 非デリミタ文字が現れるまで読み飛ばす */
do {
if ( (c = fgetc(p)) == EOF ) {
s[0] = '\0';
return 0;
}
} while (IsDelimiter(c) == 1);
s[0] = (char) c;

/* デリミタが現れるまで,文字列を積み上げる */
ip = 1;
while (1) {
if ( (c = fgetc(p)) == EOF ) break;
if ( IsDelimiter(c) == 1 ) break;

s[ip] = (char) c;
ip++;
if (ip >= MAXBUFSIZE) {
ip--;
s[ip] = '\0';
return -ip;
}
}
s[ip] = '\0';
return ip;
}


462 名前:デフォルトの名無しさん mailto:sage [2007/10/17(水) 23:58:02 ]
自分なら、↓こんな感じかなぁ。

int ReadData(FILE* pFileIn, char* strOut) {
*s = '\0' ;
int countDelimiter = 0 ;
int countOutput = 0 ;

while(1) {
int c ;

c = fgetc(pFileIn) ;
if (c == EOF) break ;

if (IsIsDelimiter(c)) {
++countDelimiter ;
if (countDelimiter ==2) break ;
} else if (countDelimiter == 1) {
*strOut = (char)c ;
++strOut ;
}
}

return countOutput ;
}


463 名前:462 mailto:sage [2007/10/17(水) 23:58:45 ]
おっと、間違った。

int ReadData(FILE* pFileIn, char* strOut) {
int countDelimiter = 0 ;
int countOutput = 0 ;

while(1) {
int c ;

c = fgetc(pFileIn) ;
if (c == EOF) break ;

if (IsIsDelimiter(c)) {
++countDelimiter ;
if (countDelimiter ==2) break ;
} else if (countDelimiter == 1) {
*strOut = (char)c ;
++strOut ;
}
}

*strOut = '\0' ;
return countOutput ;
}

464 名前:デフォルトの名無しさん mailto:sage [2007/10/18(木) 00:14:00 ]
countDelimiterで制御するのですね。
ちょっとトリッキーかな・・・


465 名前:462 mailto:sage [2007/10/18(木) 00:22:08 ]
やりたい処理を素直に書いただけなんだけどなぁ・・・。

466 名前:デフォルトの名無しさん mailto:sage [2007/10/18(木) 00:35:46 ]
文化が違うのがオモロイなぁ・・・

467 名前:デフォルトの名無しさん mailto:sage [2007/10/18(木) 01:16:12 ]
int ReadData(FILE *fp , char *out , int n){
int c , i=0;

while(i<n-1){
c = getchar(fp);
if (c == EOF || (IsDelimiter(c) && i != 0)) break;
if (!IsDelimiter(c)) out[i++] = c;
}
out[i] = '\0';
return i;
}

468 名前:デフォルトの名無しさん [2007/10/20(土) 22:47:48 ]
エラーメッセージを出力するところなんですが、

#define ABC "ABCの時のエラーメッセージ"

などと定義しておいて、エラーメッセージの出力関数には、
エラーコードの「ABC」のみを引数で渡すようになっています。
ただの文字列に変換する場合はこれでよかったんですが、
エラーの時に出た数字もエラーメッセージに含める場合も追加されました。
その数字は、書式指定(%dとか%lfとか)なので、同じようにマクロで
文字列を生成しようとして、つまづいてしまいました。

こんな感じで書いてみたんですが、当たり前だけどstrをどこで定義すれば
よいのかがわかりません。

#define ABC(gStr) sprintf( str, "ABCの時のメッセージ( %g ).", gStr )

引数なしの時と同じように、文字列(str)をそのまま生成するには
どう書いたらいいですか?

469 名前:デフォルトの名無しさん mailto:sage [2007/10/20(土) 23:28:42 ]
>>468
> エラーコードの「ABC」のみを引数で渡す

あなたは自分がやっていることを理解してない。
ABCはエラーコードなんてものではなく、文字列リテラルへのポインタ。
なお、複数の同じ内容の文字列リテラルが1つにまとめられることは保証されていない。

そして、マクロが何者なのか、理解していない。
いまのコンパイラはプリプロセッサが統合されているので、わかりにくいが、
ソースコードは、プリプロセッサによってマクロが展開された後に、コンパイルされる。
マクロは「定義」するものだが、その定義とは、日本語の定義とは意味が異なる。

> strをどこで定義すればよいのかがわかりません。

エラーはネストするの?
シングルスレッドとマルチスレッド、どっち?




470 名前:469 mailto:sage [2007/10/20(土) 23:35:01 ]
ああぁ

呼び出し側の関数にエラーコードとして返したりせず、
エラーメッセージを出力する関数にしか渡さないのなら、
適当に自動変数で持てばいいと思うよ。

CとC++どっち?

471 名前:デフォルトの名無しさん mailto:sage [2007/10/21(日) 00:00:21 ]
>>468
#define ABC(gStr) "ABCの時のメッセージ("#gStr")"

ってgStrが変数なのか
知らね

472 名前:デフォルトの名無しさん mailto:sage [2007/10/21(日) 00:21:50 ]
基本的なことが理解できてない人に、
場当たり的に教えるのは、
効率が悪すぎる。

473 名前:デフォルトの名無しさん [2007/10/21(日) 00:42:22 ]
468です。いくつかのご回答、ありがとうございました。
>>469
自分のしていることを、自分で理解していないのかもしれません。
> エラーコードの「ABC」のみを引数で渡す
は間違いで、エラー出力関数への引数には、文字列になります。
エラーはネストしません。また、シングルスレッドです。

>>470
C++です。
「適当に自動変数」というのは、文字列自動変数をエラーコード
毎にその場でベタにつくって、エラー出力関数に渡す、という感じでしょうか?

>>472
効率よく教わるためには、どの基本的なことを勉強すればよいでしょうか。




474 名前:デフォルトの名無しさん mailto:sage [2007/10/21(日) 00:56:30 ]
>>473
ネストせず、シングルスレッドなら、str をグローバル変数にしてしまうのも可能。
簡単だけど、あんまり良いやり方ではないが、とりあえず最小の変更で済むかな。
strなんて短くてどこにでもありそうな名前は、変えるべきだよ。

> 「適当に自動変数」というのは、文字列自動変数をエラーコード
> 毎にその場でベタにつくって、エラー出力関数に渡す、という感じでしょうか?

そう。


475 名前:wolf ◆8VH3XAqjlU mailto:sage [2007/10/21(日) 11:00:52 ]
>>468
>>473
C++なら普通polymorphismを使いますが兎も角動かすには
#define ABC(i_code) { char str[256]; sprintf(str, "ABCの時のメッセージ( %d ).", i_code); printf("%s\n",str); }
ブロックについては www.geocities.jp/ky_webid/c/022.html

476 名前:デフォルトの名無しさん [2007/10/21(日) 11:47:16 ]
>>475
ありがとうございます。
実環境で確認してみます。

477 名前:デフォルトの名無しさん mailto:sage [2007/10/21(日) 16:45:38 ]
おま・・・。
せめてdo-while

#define ABC(i_code) do{ char str[256]; sprintf(str, "ABCの時のメッセージ( %d ).", i_code); printf("%s\n",str); }while(0)

で、ソレは俺も質問見たとき考えたけど、マクロの意味というか役割というかが変わってるから、
「なんでエラーメッセージをマクロにしたいのか」が分からないと使えるかどうか分からなかった。

個人的には、ストリングテーブル的に↓とかで十分かな、と思う。

#define ABC "ABCの時のメッセージ( %s )."
(共通な文字列リテラルの切り出し。日本語版やら英語版やらを作るときに使う)

478 名前:デフォルトの名無しさん mailto:sage [2007/10/21(日) 16:56:29 ]
>>477
do whileハックを使わないといけないのは、古いコンパイラ。


479 名前:デフォルトの名無しさん mailto:sage [2007/10/21(日) 17:33:37 ]
>>478
それはすまない。俺の勉強不足のようだ。
ついては↓のコードがエラー無くコンパイル通るような
「新しいCコンパイラ」は何かを教えてくれないか?

#include <stdio.h>
#define macro(x) {puts(x);}

int main()
{
if(1) macro("str1");
else macro("str2");
return 0;
}




480 名前:デフォルトの名無しさん mailto:sage [2007/10/21(日) 17:56:42 ]
>>479
そういう{}のないif文は、コーディング規約で禁止。

481 名前:デフォルトの名無しさん mailto:sage [2007/10/21(日) 18:00:58 ]
マクロには;をつけないっていう選択肢はなし?

482 名前:デフォルトの名無しさん mailto:sage [2007/10/21(日) 18:32:53 ]
どう考えてもバグの原因になるだろ。

483 名前:デフォルトの名無しさん mailto:sage [2007/10/21(日) 18:58:42 ]
小細工禁止!

マクロによる関数もどきはダメ。
インライン関数やテンプレート関数を使うべし。

484 名前:デフォルトの名無しさん mailto:sage [2007/10/21(日) 19:06:06 ]
コンパイルに5分かかるプログラムを作ったら一人前ですか

485 名前:デフォルトの名無しさん mailto:sage [2007/10/21(日) 19:07:23 ]
そうだねえ。
再帰テンプレートとか作ると簡単に5分超えるね。
練習にはいいんじゃない?

486 名前:デフォルトの名無しさん mailto:sage [2007/10/21(日) 19:10:36 ]
で、規約やら小細工やら良いんだけど

>do whileハックを使わないといけないのは、古いコンパイラ。
誰かコレを解説して貰えんか?
コンパイラの新旧が、マクロを括るブロックにdo-whileを使うことと
どう関係してんだ?

487 名前:デフォルトの名無しさん mailto:sage [2007/10/21(日) 19:11:40 ]
勘弁してやれw 勘違いだろw

488 名前:デフォルトの名無しさん mailto:sage [2007/10/21(日) 19:42:09 ]
制御文なしに中括弧だけを書くとエラーになるような古いコンパイラがあったんじゃないか。

489 名前:デフォルトの名無しさん mailto:sage [2007/10/21(日) 20:31:08 ]
>>475
それだとABC(data);って書いたら駄目だわなw
#define ABC(i_code) do{ char str[256]; sprintf(str, "ABCの時のメッセージ( %d ).", i_code); printf("%s\n",str); }while(0)
こうだな
まあ受け売りだが

てか一回sprintf経由する必要はあるの?
#define ABC(i_code) printf("ABCの時のメッセージ( %d ).\n", i_code)
これじゃ駄目なんかいな



490 名前:489 mailto:sage [2007/10/21(日) 20:33:43 ]
やべ、俺リロードしなさすぎw
吊ってくるww

491 名前:デフォルトの名無しさん mailto:sage [2007/10/21(日) 20:34:54 ]
エラーメッセージを生成するのと、表示するのは、分離したほうがいいと思う。

492 名前:デフォルトの名無しさん mailto:sage [2007/10/22(月) 10:50:35 ]
つーか、元質はデバッグ出力関数に渡す引き数を生成したいんじゃないかな?
だとしたら、>475以下はダメだろう。

493 名前:デフォルトの名無しさん mailto:sage [2007/10/22(月) 19:39:51 ]
C言語に関して質問です。
構造体の各要素に添え字を使ってアクセスすることはできないのでしょうか?

例えば
struct OBJ{
int x;
int y;
char c;
char str[10];
};

main()
{
struct OBJ tmp;
tmp.[0] ← xのこと
tmp.[1] ← yのこと
tmp.[2] ← cのこと
tmp.[3] ← str[]のこと
}

といった感じのことがしたいのです。実現可能な方法があれば是非お願いします。

494 名前:デフォルトの名無しさん mailto:sage [2007/10/22(月) 19:43:42 ]
unionを使えば出来ないことはないけど、正直お勧めしない。

495 名前:デフォルトの名無しさん mailto:sage [2007/10/22(月) 19:44:02 ]
C++なら・・・無理か。
型もバラバラだしな。
添え字に変数を使って

tmp.[i]

ってしたとき、何型で扱うつもりなんだ

496 名前:デフォルトの名無しさん mailto:sage [2007/10/22(月) 19:44:13 ]
>>493
限定的にはunionを使えばできる。
ややこしくはなるがポインタをキャストしてもできる。
どちらにしろ、サイズの違う型を統一的には扱えない。

497 名前:デフォルトの名無しさん mailto:sage [2007/10/22(月) 20:19:14 ]
>>493
なんで、そんな変なことをしたいの?


498 名前:デフォルトの名無しさん mailto:sage [2007/10/22(月) 20:22:08 ]
テンプレートクラスでtemplate <Type T>のTにクラスを入れることが可能なのですか?
int型などを入れるメリットは分かるのですが具体的にどんなクラスを入れれば役に立つのか教えていただけないでしょうか?

499 名前:493 mailto:sage [2007/10/22(月) 20:29:47 ]
回答して下さった方々有難う御座います。
for文のインデックスを利用出来たらと思いました。
しかし型などが違うのでその都度場合わけをしないといけないので出来たとしても結局のところ手間は増えますね。



500 名前:デフォルトの名無しさん mailto:sage [2007/10/22(月) 20:33:51 ]
>>498
可能です。
STLのvector<T> はTの配列と置き換えられる動的な再配置も可能なクラスですが
当然組み込み型以外でもvectorを使うことが出来ます。

501 名前:デフォルトの名無しさん [2007/10/22(月) 21:15:25 ]
float a;
a=1;
print("%d",a);
を実行すると
1072693248っていう数がでてくる。
これってどういうこと?

502 名前:デフォルトの名無しさん mailto:sage [2007/10/22(月) 21:24:52 ]
>>501
言語およびコンパイラは何?
"%f" を使うべきである事は知っていて、なぜそうなるのかが知りたいということ?

503 名前:デフォルトの名無しさん mailto:sage [2007/10/22(月) 22:53:01 ]
>>501
printfの引数の2つ目以降の型って決まってないよね。
だから、printfにとっては、どんな型の値を引数に渡されたのか、わからない。
そのため、書式文字列に%dとあれば、intだと思って処理するわけ。

504 名前:デフォルトの名無しさん mailto:sage [2007/10/22(月) 22:54:09 ]
>>498
可能。

int型を入れるのと同じメリットが、stringクラスを入れるのにもあると思うのだが。
stringの配列なんて使う機会ないか? ないなら、まぁ仕方ない。

505 名前:デフォルトの名無しさん mailto:sage [2007/10/22(月) 22:58:36 ]
list<vector<string> >
とかな。

506 名前:デフォルトの名無しさん mailto:sage [2007/10/22(月) 23:28:17 ]
>>505
そんなこと、したことないぞ。

まず、stringのように重いものを、ポインタや参照ではなく値として持つvectorに格納するのが、乱暴だ。

次に、vector<string>を直にlistに格納するのも、乱暴だ。
vector<string>に何か意味があるのであれば、それなりのクラスにすべきだ。

507 名前:デフォルトの名無しさん mailto:sage [2007/10/22(月) 23:35:45 ]
乱暴ってのが何を意味してるかわからんが、
別にstringは重くないしvector<string>も十分に速いぞ


508 名前:デフォルトの名無しさん mailto:sage [2007/10/22(月) 23:36:17 ]
あほすぎる・・・

509 名前:デフォルトの名無しさん mailto:sage [2007/10/22(月) 23:46:20 ]
>>506が何を言いたいのかワカンネ
乱暴ってどういう意味?
vector<string>を使うなって言ってるの?



510 名前:デフォルトの名無しさん mailto:sage [2007/10/22(月) 23:57:05 ]
vector<string>を内包したオブジェクトつくって
インターフェースをきちんとしたオブジェクト指向な作り方しろってことか…。

C++だからって必ずオブジェクト指向で作らんでもいいだろ…

511 名前:デフォルトの名無しさん mailto:sage [2007/10/23(火) 00:00:22 ]
>>506は「そんなこと、したことないぞ」と言っている通り、思い込みで書き込んでいるんだよ。






[ 続きを読む ] / [ 携帯版 ]

前100 次100 最新50 [ このスレをブックマーク! 携帯に送る ] 2chのread.cgiへ
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧]( ´∀`)<260KB

read.cgi ver5.27 [feat.BBS2 +1.6] / e.0.2 (02/09/03) / eucaly.net products.
担当:undef