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

このエントリーをはてなブックマークに追加
1デフォルトの名無しさん
C言語の*入門者*向け解説スレッドです。
初心者、初級者の方は他の質問スレのほうが良いかもしれません。

教えて欲しいのではなく宿題を丸投げしたいだけなら
↓宿題スレ↓へ行ってください。
C/C++の宿題片付けます 126代目
http://pc12.2ch.net/test/read.cgi/tech/1242655611/


・C++言語はスレ違いですが、ある程度なら対応です。
・分からない事をなるべく詳しく書いて下さい。
・ソースコードを晒すと答えやすくなるかもしれません。
  # 抜粋/整形厳禁、コンパイラに渡したソースをそのまま貼ること
  # サイズが大きい場合は宿題スレのアップローダ等を利用してください
・開発環境や動作環境も晒すと答えが早いかもしれません。
・質問者は最初にその質問をした時のレス番号を名前欄に書いて下さい。

前スレ
C言語なら俺に聞け(入門篇) Part 48
http://pc12.2ch.net/test/read.cgi/tech/1242129892/

過去スレ
http://makimo.to:8000/cgi-bin/search/search.cgi?q=%82b%8C%BE%8C%EA%82%C8%82%E7%89%B4%82%C9%95%B7%82%AF&andor=AND&sf=0&H=&view=table&D=tech&shw=5000
2デフォルトの名無しさん:2009/06/06(土) 23:47:58
>>1
3デフォルトの名無しさん:2009/06/07(日) 09:49:49
早すぎ
4デフォルトの名無しさん:2009/06/08(月) 06:54:14
tureって常に1なのですか?それとも0以外なら何でも良いのでしょうか?
これに関する規格はどこかで読めないでしょうか?
5デフォルトの名無しさん:2009/06/08(月) 07:03:33
>>4
0(整数値)はfalseに変換される。
0以外の整数値はtrueに変換される。

trueは1に変換される。(他の値にはならない。)
false整数値は0に変換される。

これが規格のどこかに書いてあった。
忘れたけどね。
6デフォルトの名無しさん:2009/06/08(月) 07:36:26
>>5

ありがとう
7デフォルトの名無しさん:2009/06/08(月) 09:42:48
テキストIOでは改行が\nにおきかえられるとなってますが
これは単純に\rが無視されるだけなのかそれとも\r\nと続いたときのみ\rが無視しされるのどっちなんでしょう?
\r\r\nのような場合はどうなりますか?
8デフォルトの名無しさん:2009/06/08(月) 10:04:04
\r\n→\n
9デフォルトの名無しさん:2009/06/08(月) 11:33:39
>>7
\r\nの2バイトを\nに変換する
\r -> \r
\r\r\n -> \r\n
10デフォルトの名無しさん:2009/06/08(月) 13:14:14
登場した順に処理していくから \r\r\n -> \r\n
ってことなの?
11デフォルトの名無しさん:2009/06/08(月) 13:32:30
#define MAX_LEN 200020
int main(int argc, char **argv)
{
unsigned int from_len, to_len,mv_len;
char *p = NULL;
char in[MAX_LEN],from[MAX_LEN],to[MAX_LEN];

のというプログラムで、コマンドラインからの引数(文字列)をプログラム内の変数に代入したいです。
具体的にはfromにargv[1]の文字列を、toにargv[2]の文字列を入れたいのですが…。
from=argv[1]というようにやっても、
「型が合わない変数に代入しようとしています」というエラーが出てしまいます。
どうしたらいいのでしょうか?
12デフォルトの名無しさん:2009/06/08(月) 13:33:25
strncpy
13デフォルトの名無しさん:2009/06/08(月) 13:40:58
なるほど、それを忘れてました。
ありがとうございます!
14デフォルトの名無しさん:2009/06/08(月) 15:51:54
文字列コピーでそれを忘れてましたってw
15デフォルトの名無しさん:2009/06/08(月) 18:40:49
http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/9377.txt

これは、オペレーティングシステムのレポートに使うプログラムのサンプルなのですが、
コンパイル時にエラーが出ます。授業中スライドに表示されたのを打ち込んだのですが、
どこが悪いのか困っています。

os.c: In function ‘main’:
os.c:36: error: expected expression before ‘]’ token

となる原因を教えてください。
16デフォルトの名無しさん:2009/06/08(月) 18:54:26
>>15
文法的には、if(execv(argv[0],argv[])==(-1)){ の argv[] の部分がおかしい。

内容自体はC言語の話から外れるが、UNIX系OSのexecvのことであるのなら、
argv[] を argv とすればよかろう。
17デフォルトの名無しさん:2009/06/08(月) 18:56:22
あ、ごめん。execvは標準Cライブラリに入ってたか。
18>>15:2009/06/08(月) 20:29:14
Ubuntuで実行しています。どうしたらいいですか?
19デフォルトの名無しさん:2009/06/08(月) 21:06:37
>>17
入ってるの? POSIXじゃね?
20>>15:2009/06/08(月) 23:09:21
unistd.hをインクルードして、 argv[]をargvでコンパイル出来ました。

ありがとうございます。
21デフォルトの名無しさん:2009/06/08(月) 23:11:03
POSIXだね。exec*()シリーズは。
ISO/IEC 9899 : 1999 (E)には、載ってなかった。
最新のドラフトISO/IEC 9899:201xにもないな。
regexとか入ってくれないものかなぁ。
22デフォルトの名無しさん:2009/06/09(火) 12:17:01
学校のPCで授業をやっているのですが、自分のつかっているコンパイラの名前・バージョンなどがわかりません。
どこをみればわかるのでしょうか?OSはGNU Network Object Model Environmentです。
お願いします。
23デフォルトの名無しさん:2009/06/09(火) 12:21:18
大概はヘルプにバージョン情報があるもんだけどな?
なけりゃ知らん
24デフォルトの名無しさん:2009/06/09(火) 12:25:40
GNOMEはOSじゃないけどな。
コンパイルはどうやってんの?
コマンドラインなら、大抵は -v オプションで出るよ
gcc -v とか
25デフォルトの名無しさん:2009/06/09(火) 12:47:41
>>22
gccって打ち込んでるならコンパイラ名はgccで通じるよ
正式にはGNU Compiler Collectionだけど
26デフォルトの名無しさん:2009/06/09(火) 16:13:10
副作用完了点についてちょっと曖昧だったので確認させてください
arr[idx++] = data++;
idxとdataが別のものである場合、それぞれインクリメント前の値で処理が行われるのであってますよね?
27デフォルトの名無しさん:2009/06/09(火) 16:13:49
また燃料が・・・・
28デフォルトの名無しさん:2009/06/09(火) 16:16:02
>>26
参照後 セミコロンまでの間のどこかで インクリメントがなされる

idx は arr[ ] に値を積んだ後 ; までの間
data は 右辺値 として参照した後 ; までの間
2926:2009/06/09(火) 16:17:59
char *p, *q;
*p++ = *q++;
は完全に合法ですよね?

*(arr + idx++) = data++;
と展開するといかにも怪しい感じになるんですが、どうなんだろうと思いまして。。
30デフォルトの名無しさん:2009/06/09(火) 16:19:29
>>28
合法なはずだけどどうだったろうかと思って心配になってました。
ありがとうございました。
31デフォルトの名無しさん:2009/06/09(火) 16:30:24
>>30
hoge++ と書いた場所から 副作用完了点までのどこかで hoge のインクリメントが発生する
という仕様

hoge++ と書いた場所から 副作用完了点までの間に hoge(ポインタ使用のエイリアスも含む)
が登場しちゃうと仕様の立場としては

後のhoge参照前にインクリメントが発生するのか
後のhoge参照後にインクリメントが発生するのか
定まらない

(さらに C89なら このようなケースで鼻から悪魔出しても良いとなっている)
32デフォルトの名無しさん:2009/06/09(火) 16:32:05
副作用完了点 は インクリメントが終わっていると断言できる点 であって
何時インクリメントを発生させるかを規定しているわけではないのさー
33デフォルトの名無しさん:2009/06/09(火) 16:50:55
文系で専門学校入ってC言語とかも苦労してるんですが慣れますか?
34デフォルトの名無しさん:2009/06/09(火) 16:54:39
>>33
お前は何をやってもダメ
C言語どころか日本語も英語もダメ

とでも言えばいいのか?
35デフォルトの名無しさん:2009/06/09(火) 17:35:11
ついでの疑問
 a[i++] = i ;
こいつは即論外として

a[i @] = i ++ A;

 |i @参照
 |参照値により a[ ] を
 |i A参照
 |i インクリメント (A記述〜 ; までの間のにインクリメント操作挿入)
こう解釈できそうだけど
@での i参照と Aの i 参照の翻訳順(?)が @→A とは限らないから やっぱNG ってこと?
36デフォルトの名無しさん:2009/06/09(火) 17:38:37
どっちも即論外
37デフォルトの名無しさん:2009/06/09(火) 18:51:01
右辺確定の為 i A 参照
A
↓ 添え字確定の為 i @参照
↓ a[] に右辺値を代入
B

A〜B間ならどこでも i のインクリメントを発生させてよいことになる
ポストインクリメント演算子とその参照の共存は論外
38デフォルトの名無しさん:2009/06/09(火) 20:34:55
""文字列を連結するマクロってあります?
39デフォルトの名無しさん:2009/06/09(火) 20:39:07
>>38
strcat()でできることと比べて何がしたいのか分かりやすく言ってくれ
40デフォルトの名無しさん:2009/06/09(火) 20:43:43
>>38 こんなん?
#include<stdio.h>

int main(void){
const char *p="abcde" "12345";

puts(p);
return 0;
}
41デフォルトの名無しさん:2009/06/09(火) 21:16:48
c=getch();
とやると

error C3861: 'getch':識別子が見つかりませんでした
となってしまいます。
なにがいけないんでしょうか?
(コンパイラはVC++EEです
42デフォルトの名無しさん:2009/06/09(火) 21:18:20
#include <stdio.h>
がソースの頭にないとか
43デフォルトの名無しさん:2009/06/09(火) 21:42:38
getchだからconio.hかなー
44デフォルトの名無しさん:2009/06/09(火) 21:44:13
こにお?
45デフォルトの名無しさん:2009/06/09(火) 22:29:14
うん。こにお。
ではなくて、コンソールIO
46デフォルトの名無しさん:2009/06/10(水) 05:21:15
>>45
コンソールIOの略だったことを今更になって知った俺がいる。
47デフォルトの名無しさん:2009/06/10(水) 06:01:34
このスレに私の書いたプログラムを載せた場合、
ソースコードのここはこうしたほうがいい
等の助言を頂くことはできますか?
48デフォルトの名無しさん:2009/06/10(水) 06:16:40
助言できる場合もあるし、できない場合もある。

助言できない典型例は、「何がしたいのか分からないので改善方法も分からない」ってやつかなぁ。
まあ、気軽に書いてみたらいいよ。
49デフォルトの名無しさん:2009/06/10(水) 06:19:19
長いソースだったり、インデントの調整が面倒ならソースそのものを外部ロダに上げて
リンクを貼ってね
50デフォルトの名無しさん:2009/06/10(水) 19:00:44
>>47
codepad
ttp://codepad.org/
ここにソースを貼り付けるのがオススメだよ。

なお、2chに書いたソースの利権は2ch管理者の物になるので
根幹に関わる大事なところは伏せた方が絶対によい。
訴訟になったりした時のためにも。
51デフォルトの名無しさん:2009/06/10(水) 19:12:25
俺のコードなら2chに寄贈してやんよ
52デフォルトの名無しさん:2009/06/10(水) 19:23:48
>>50
そもそも、そんな大事なソースなら掲示板に晒してはいけない。
53デフォルトの名無しさん:2009/06/10(水) 19:37:29
すでにほかの人に権利があるコードを張ったら誰のものなの?
54デフォルトの名無しさん:2009/06/10(水) 20:12:16
>>53
書いた人の物だろ。
んで、もしその規定に反するようなソースを貼り付けたら
どうなるのかは・・・知らない。
55デフォルトの名無しさん:2009/06/10(水) 21:31:33
掲示板に貼り付ける程度の10〜20行程度のプログラムに著作権が
法廷で立証できるかは疑問だがな
56デフォルトの名無しさん:2009/06/10(水) 22:03:51
七行プログラミング
ttp://piza2.2ch.net/tech/kako/984/984182993.html
ここで出てきた
>海外のプログラマーが、たったの七行足らずで
>DVDのプロテクトを解除するプログラムを作成!
これくらいなら主張できるんじゃない?
偶然かぶったと言い切れないだろ、さすがにね。
5756:2009/06/10(水) 22:06:21
あとまあ、いかなるソースでも、

switch(掲示板に貼り付ける程度の10〜20行程度のプログラムに利権が
)
case 主張できない :自分の権利も認められない
case 主張できる :2ch運営の権利となる。

結局自分の権利は認められないことになるな。
58デフォルトの名無しさん:2009/06/10(水) 22:06:25
20行あれば割と重要な部分も書ける気がするが
59デフォルトの名無しさん:2009/06/10(水) 22:18:59
>>58
重要な部分とは、アルゴリズム=アイデアでしょ、アイデアは保護できない
60デフォルトの名無しさん:2009/06/10(水) 22:25:46
>>59
アルゴリズムは保護できるだろ?
61デフォルトの名無しさん:2009/06/10(水) 22:26:58
>>59
アルゴリズムもアイディアも保護できないなら、
何なら保護できるの?
62デフォルトの名無しさん:2009/06/10(水) 22:29:00
たとえば今では定番のリストに関連する関数なんて20行あまりで全部書けそうだしな

ああいうのは権利放棄されたのかね?それともそういう以前の問題かな?
63デフォルトの名無しさん:2009/06/10(水) 22:31:24
>>56
そういう詰め込み方がありなら
1レス2kBで相当書けそうな気はする
64デフォルトの名無しさん:2009/06/10(水) 22:48:25
>>62
広く一般に知れ渡っている知識やアルゴリズムは、著作権の対象とはならない。
これは一般的な考え方であって、実際には法廷で戦わないと結論はすべて出ない。
が、まず負けるだろう。
例えばだ、アルゴリズム辞典等で乗ってるアイデア等は、その後同じプログラムを
書いても、勝つことは難しい。では何が一番良いか、プログラムが同じでも、それに
長いコメントを書くことだ。コメントは明らかに著作物だと認められる。あと
大きなプログラムも著作権が認められやすい。
だが、実際は総て法廷で争う以外結論は出ない。
65デフォルトの名無しさん:2009/06/11(木) 01:18:36
そもそも、知識やアルゴリズムは著作権でもって保護されるものじゃないし。
66デフォルトの名無しさん:2009/06/11(木) 06:07:57
vc++環境下で組まれたソースをgcc向けに調整した際に警告がでたのですが
NULLって数字としても使えるものなんですかね?
gccだとNULLをポインタ変数以外で使うと警告がでます。
67デフォルトの名無しさん:2009/06/11(木) 06:28:54
関数のプロトタイプ宣言の際にstaticが付くのと付かないのでは何が変わるのでしょうか?
68デフォルトの名無しさん:2009/06/11(木) 07:09:28
>>65
アルゴリズムもアイディアも保護できないなら、
何なら保護できるの?
69デフォルトの名無しさん:2009/06/11(木) 07:10:40
>>67
staticキーワードでローカル(プライベート)にする - C言語とC++入門勉強ルーム
ttp://www.mapee.jp/cpp/static_2.html
70デフォルトの名無しさん:2009/06/11(木) 07:50:47
>>68
著作権で保護されるのは実装、つまりプログラマがプログラムを書くことに費やした努力。
アルゴリズムを考えるのに費やした努力を保護するのは特許権。
71デフォルトの名無しさん:2009/06/11(木) 08:23:12
>>69
ありがとうございます。

ではソースを分割した際にexternをつけて関数などを宣言するのは理解しているのですが
プロトタイプ宣言ではなく関数の実体のところにexternをつけると扱いは同じなのでしょうか?
72デフォルトの名無しさん:2009/06/11(木) 08:50:10
実体にはextern付けられないでしょ?
73デフォルトの名無しさん:2009/06/11(木) 09:31:54
デフォルトがexternなのでみんな省略しているだけ
74デフォルトの名無しさん:2009/06/11(木) 12:16:18
画像を1ピクセルずつ読み取って
その色データをエスケープシーケンスで文字”■”に色をつけて
コンソール上に画像みたいなものを表示させたいのですが
どうすればいいのでしょうか?
windows APIのDIBを使うのでしょうか?
75デフォルトの名無しさん:2009/06/11(木) 12:22:09
ファイル形式がわかってればそのファイルを直接読めばいいよ。
76デフォルトの名無しさん:2009/06/11(木) 12:57:39
俺は>>74と同じスレを見てるようだ
77デフォルトの名無しさん:2009/06/11(木) 13:29:47
78デフォルトの名無しさん:2009/06/11(木) 15:11:01
>>71
externは不要ですよ。

関数の場合
 extern char foo(int num);
 char foo(int num);
どっちでも同じ。

変数の場合はおっしゃるとおり
 extern long hoge;
 long hoge;
意味が違う。
79デフォルトの名無しさん:2009/06/11(木) 20:30:07
条件文AとBがあるとして
if(A){
 if(B){
・・・・・
 }
}
ってのと
if(A && B){
・・・・
}
って一般的には動作変わってしまうものでしょうか?
80デフォルトの名無しさん:2009/06/11(木) 20:32:29
場合によるかな
81デフォルトの名無しさん:2009/06/11(木) 20:43:50
>>79
Bに副作用があるなら変わるかな
82デフォルトの名無しさん:2009/06/11(木) 20:45:29
変わらないんじゃないかな
83デフォルトの名無しさん:2009/06/11(木) 20:50:43
変わらないでしょ。
どっちもAが偽だったらBは評価しないでしょ。
84デフォルトの名無しさん:2009/06/11(木) 20:56:27
>>79
全く同一で、変わらないよ。
C++で&&が変にオーバーロードされているとかじゃないかぎり。
85デフォルトの名無しさん:2009/06/11(木) 20:59:06
>>81
変わらない。短絡評価があるんだから。
8684:2009/06/11(木) 21:06:03
>>79
それから揚げ足をとるようだけど、
条件文じゃなくて条件式ね。
8781:2009/06/11(木) 21:12:24
思い違いをしてました。ごめん。
8879:2009/06/11(木) 21:35:37
様々な意見ありがとうございます
自身で実際書いたプログラムとしては、aを配列添字(別の関数から値を取得)、Bを配列として
 条件式A : a!=-1 // エラー値
 条件式B : b[a]==NULL
のように記述したのですが、>>79の前者だと・・・・・の部分が全く実行されず
疑問に感じたので質問させていただきました(自身はこの二つは同じものだと考えていたので)

ご指摘いただいた副作用や短絡評価について少し調べてみましたが、原因がよく分からなかったため
とりあえず後者の記述で統一しようかと思います
お騒がせしました。
89デフォルトの名無しさん:2009/06/11(木) 21:38:58
短絡評価なんかに頼っちゃいけません
90デフォルトの名無しさん:2009/06/11(木) 21:48:43
>>88
もし本当にそうだとしたら、原因は別のところにある。
使っているコンパイラの最適化のバグとか、メモリを破壊しているとかなど。
91デフォルトの名無しさん:2009/06/11(木) 22:18:28
>>89
いやいや、君C言語で仕事したことあるの??
92デフォルトの名無しさん:2009/06/11(木) 22:18:49
dllは異なるアプリでメモリを共有して使っている?とのことなんですが
グローバル変数やstatic変数を使わなければ危険はないんでしょうか?
93デフォルトの名無しさん:2009/06/11(木) 22:22:01
dragon=0;
printf("%x",dragon);
で16進数表示をさせると
0と表示されますが。
00や0aなどのように2桁で表示させるには
if文で一桁だった場合だけ0を付けるというやり方でよろしいでしょうか?
94デフォルトの名無しさん:2009/06/11(木) 22:25:40
printf("%02x",dragon);
95デフォルトの名無しさん:2009/06/11(木) 22:28:04
#include <stdio.h>
double angle;
main(void)
{
printf("角度を入力");
scanf("%f",&angle);
printf("%f",angle);
}
何がだめなんでしょう
96デフォルトの名無しさん:2009/06/11(木) 22:28:59
>>95
scanf("%lf", &angle);
97デフォルトの名無しさん:2009/06/11(木) 22:30:52
ありがとうございます
98デフォルトの名無しさん:2009/06/11(木) 22:44:44
>>91
あるよ?
短絡評価はいたずらにプログラムを複雑化し、可読性を下げる
さらには実行順序を強制することでコンパイラの最適化の機会さえ奪う
使うべきでない
99デフォルトの名無しさん:2009/06/11(木) 22:49:36
深刻かつ基礎的な話なので入門スレの話題としてはややスレ違いになって
いる件について
100デフォルトの名無しさん:2009/06/11(木) 22:52:47
短絡評価はわからないので禁止
101デフォルトの名無しさん:2009/06/11(木) 22:54:53
if (i >= 0 && a[i] == NULL)

これ自体はこれで問題ないし、可読性も悪いとは思わない。

if (i >= 0) {
if (a[i] == NULL) {
}
}

可読性なら、こっちのほうがよろしくないと思うぐらいだ。
102デフォルトの名無しさん:2009/06/11(木) 22:56:24
static変数をまとめて処理するのはどうするのでしょうか
structに入れようとしてもエラーが出てしまい、できません
103デフォルトの名無しさん:2009/06/11(木) 23:00:48
>>102
こんな風に書いたらエラーが出たって事?
typedef struct{
static int a;
static int b;
static char* c;
}ABC;
104デフォルトの名無しさん:2009/06/11(木) 23:02:35
構造体変数をstaticにする。
static struct ttt a;
10591:2009/06/11(木) 23:09:25
>>98
>さらには実行順序を強制することでコンパイラの最適化の機会さえ奪う
>101が言うような
if (i >= 0) {
if (a[i] == NULL) {
}
}
こんなif ifになっているコードと短絡評価は等価だよねぇ。
>短絡評価はいたずらにプログラムを複雑化し、可読性を下げる
可読性は水掛け論だから取り扱わないことにするとしても
>さらには実行順序を強制することでコンパイラの最適化の機会さえ奪う
こちらは全く当てはまらない指摘では?
106デフォルトの名無しさん:2009/06/11(木) 23:15:20
質問です
基本的な文体、構造体やポインタまでひととおり理解したら、次はライブラリの扱い方を勉強すべきと言われました

なのでライブラリを勉強しようと思うのですが・・・まず何をやればいいのかわかりません
最初に「Hello World」を表示したように、ライブラリの扱いを覚えるならまずこれをやれ、ってを教えてください
107デフォルトの名無しさん:2009/06/11(木) 23:16:34
クイックリファレンスでも買って眺める
108デフォルトの名無しさん:2009/06/11(木) 23:18:14
>>106 次はstrcpyだ。
109デフォルトの名無しさん:2009/06/11(木) 23:19:56
qsortを使ってみろw
110デフォルトの名無しさん:2009/06/11(木) 23:25:13
>>108
つまり
#include<math.h>
を読み込んで平方根とか累乗の値を求めるのもライブラリを扱ってるうちに入るんですか?

しかし、それで何かができるって気がしません
ライブラリを使いこなせばあれこれできるようになると聞きますが
111デフォルトの名無しさん:2009/06/11(木) 23:26:30
まず、目的がないとダメだな。
112デフォルトの名無しさん:2009/06/11(木) 23:26:45
>>110
じゃあ標準関数(ライブラリ)を使いそうなお題を自分で用意して
それに取り組め
113デフォルトの名無しさん:2009/06/11(木) 23:29:05
>>105
それは順序性のある条件だからそれでいい
(if二段構えの方がいいと思うが)
問題なのはこんなの
if(i >= 0 && j >= 0)
コンパイラはj >= 0を先にやりたくても出来ない
こんなのに短絡評価を使うのは馬鹿げているので、こう書くべきである

#define AND(A,B) (!!(A) & !!(B))
#define OR(A,B) (!!(A) | !!(B))

if(AND(i >= 1, j >= 0))
114デフォルトの名無しさん:2009/06/11(木) 23:31:01
>>110
C言語だけではたいしたことは事はできない(一部の天才を除く)。

これは別にC言語が悪いわけではないが、APIというものに頼らねばならない。
技術者ですらAPIや外部ライブラリに頼る形になる。

んでどうすりゃ良いかというと・・・
>基本的な文体、構造体やポインタ
これが「本当にしっかり理解出来ているなら」次にC++に進むのが個人的にはオススメ。
(理解出来てないと死ぬけど。)

そしてC++から利用できるライブラリがいっぱいあるから
それを使ってより色んな事が出来るようになれる。
115デフォルトの名無しさん:2009/06/11(木) 23:31:17
>>88の見てふと思いついたんだけど
a != -1 && b[a]==NULL
a != -1&&b[a]==NULL
この二つって、演算子の前後の空白の違いだけだから問題ないよね

でも、それってこう読まれたりしないの?
a != -1 & &b[a]==NULL
116デフォルトの名無しさん:2009/06/11(木) 23:31:46
>>113
コンパイラがそれを最適化できるの?
117デフォルトの名無しさん:2009/06/11(木) 23:33:07
&にしちゃうと先に評価も何も、両方評価してから演算してさらに評価ってなるんじゃ?
118デフォルトの名無しさん:2009/06/11(木) 23:34:21
>>113
それは逆にコンパイラの最適化機能に期待しすぎだ。
そっちのほうが必ず速いという保証が全然ない。
むしろ遅くなる可能性も大きい。

>>115
しない。
119デフォルトの名無しさん:2009/06/11(木) 23:34:29
>>111
>>112
画像や動画をいじるプログラムを作れるようになるのが目的です
たとえばjpgファイルを読み込んで、色を反転させて表示させたりとか、そういうの
しかし「どこの延長線上にそれができるようになるのか」という、スタートラインがわかりません・・・
例えば「画面に赤い点を表示する」ということすらどうやっていいかさっぱりわからない
>>114
ええ、もう別の言語ですか・・・
120105:2009/06/11(木) 23:35:19
>>113
君のレスの言いたいことを理解したわ。

#define AND(A,B) (!!(A) & !!(B))
これは無理矢理にbool型ないしint型にした上でビット演算を適用している訳か。
・・・これって短絡評価による最適化の邪魔が無くなるというメリットより
bool型ないしint型に変換する方が遅そうだけど、本当に速い?
121デフォルトの名無しさん:2009/06/11(木) 23:35:40
最適化のためにと思って変な書き方をすると、かえって遅くなるとか、ぜんぜんかわらないとか
ありがちだけどな。
122デフォルトの名無しさん:2009/06/11(木) 23:35:56
>>119
本当に基本はできた自信があるなら、
既存のプログラムのソース読んだら?
関係ありそうな本買ってきて、サンプルプログラム見るとか。
123デフォルトの名無しさん:2009/06/11(木) 23:36:07
>>115
maximal munchというルールがあってだな
&は後ろに&や=が来ないと確認してからトークン切られるようになってる
124デフォルトの名無しさん:2009/06/11(木) 23:37:06
>>118
&&と空白なしで記述された場合はそうとしか読まれないってことで大丈夫?


それと、短絡評価についてだけれど、
if (A && B)とあった場合に、コンパイラが気を利かせてBを先に評価するようなことはありえないの?
if (i >= 0 && 1==1) と書かれていた場合とかでも常に i>=0を評価する?
125デフォルトの名無しさん:2009/06/11(木) 23:37:21
>>119
画像は特定の圧縮フォーマットを使ってる場合はそれ相応のデコード処理をする必要があるけど
それをやってしまえば色深度に応じた2次元配列のデータに過ぎない。
126デフォルトの名無しさん:2009/06/11(木) 23:38:06
>>123
おお、ありがとうございます。すっきりしました
127デフォルトの名無しさん:2009/06/11(木) 23:38:13
画像いじるならバイナリファイルの操作できれば可能だよ
128114:2009/06/11(木) 23:38:36
>>119
>画像や動画をいじるプログラムを作れるようになるのが目的です
だからこそのC++なのだ。
C++はすんげー険しいけど、そういう事をしたいなら外部に転がっているライブラリを使うことになる。

>例えば「画面に赤い点を表示する」ということすらどうやっていいかさっぱりわからない
それは俺の言う、
>別にC言語が悪いわけではないが、APIというものに頼らねばならない。
>技術者ですらAPIや外部ライブラリに頼る形になる。
ってやつだ。つまりC言語の言語仕様にないから純粋なC言語ではできないんだ。

そして外部に転がっているライブラリはC++用のライブラリでクラス化されていたりする。
その方が使いやすいからね。
129デフォルトの名無しさん:2009/06/11(木) 23:38:51
>>124
短絡評価は必ず左からやることになってるけど、
1==1は、常に真だからコンパイル時に取り除かれちゃう可能性はある。
130124:2009/06/11(木) 23:39:23
ごめん。。&&を||に読み替えて。。

if (A || B)とあった場合に、コンパイラが気を利かせてBを先に評価するようなことはありえないの?
if (i >= 0 || 1==1) と書かれていた場合とかでも常に i>=0を評価する?
131デフォルトの名無しさん:2009/06/11(木) 23:40:27
>>106
>>111がボソッと言っているが、
もう目的としての勉強は要らない段階。
あとは、これ作りたい(作らないといけない)→それにはあれが必要
→「それ」を使えるようにする(or 挫折)、の繰り返しで。
132デフォルトの名無しさん:2009/06/11(木) 23:40:58
>>122
そういうものですか
なんかわかりやすい「次はこれをやれ」ってのは、文法を覚えるときとは違ってないんですね
>>125
とりあえずbmpファイルをtxtファイルに変換してみて読み込んでいじってみるとかそれくらいはできたんですけど
bmpファイルの読み方がいまいちわかんないんで思い通りに画像をいじるという段階には程遠いんです

1ピクセルごとの三原色とかわかりやすく順番に書いててくれたらいいのに、とか
いや圧縮してるわけだからそういうふうにはならないんだろうけど
133デフォルトの名無しさん:2009/06/11(木) 23:41:03
>>119
amazonあたりで「画像処理」とかで検索したらそういう書籍がいっぱいでてくるよ。

まあでも、その前に、標準関数でファイル入出力とか文字列操作とかは
できるようになってたほうがいいね。
134デフォルトの名無しさん:2009/06/11(木) 23:41:15
>>130
言語仕様上そうなんじゃない?
||がオーバーロードされていたらどうするんだ。
・・・と思いきやC言語スレだったか。
135デフォルトの名無しさん:2009/06/11(木) 23:43:16
>>132
BMPにも種類がいろいろあるとかはさておいても、
RGB値についてはわかりやすく順番に並んでない?
136128:2009/06/11(木) 23:43:17
>>132
だからこそクラス…(ry

まあ俺はC++大好き人間だから多少偏ったこと言ってるかも。
他の人の意見も合わせて総合的に自分で判断してくれ。

でも俺はC++に移るのがオススメ。
137デフォルトの名無しさん:2009/06/11(木) 23:45:37
>>134
||をオーバーロードするのとboolへのキャストを用意するのとどっちがいいんだろ
138デフォルトの名無しさん:2009/06/11(木) 23:46:17
画像ファイルはめんどいよ
何の形式だか忘れたけど、1ピクセル分のRGBを16ビットに詰め込んでて
Gだけ6ビット割り当ててるんだったかな?
人間の目はRやBよりGの変化に敏感だからって
139デフォルトの名無しさん:2009/06/11(木) 23:47:19
>>127
要するにjpgファイルやらbmpファイルやらが、どういうふうに処理されているのか理解できていれば、データをいじれるってことですよね?
>>128
やはりC++ですか
次はJavaに手を出してみようかなと思っていたのですが、そういうことなら考えてみます

とはいえ、そもそもCですらまともにちゃんとしたプログラムを何か作れてもいないわけだから、別の言語の習得なんてまだまだだと自分では思っていたのですが
>>135
とりあえず何枚かデタラメに白と黒だけのbmpファイル作ってtxtに変換して読み込んでみたんですけどよくわかんなかったです
140デフォルトの名無しさん:2009/06/11(木) 23:48:03
>>138
それは一般的な16bitのRGBフォーマットだ
141デフォルトの名無しさん:2009/06/11(木) 23:51:04
>>139
今mspaint.exeで白黒24bitBMPを作ってバイナリエディタで見てみたんだが、データ部は見事に
00 or FFで埋め尽くされていたよ。
142128:2009/06/11(木) 23:52:26
>>139
>次はJavaに手を出してみようかなと思っていたのですが、そういうことなら考えてみます
ああ、Javaを教えてくれる人がもし身近にいるとかだったらJavaでもいいかも。
でも所詮Java止まりだろう。

もっと高級言語(Pythonとか)でもいいだろうけど、
普遍的なのはやっぱC++だよ。
C++は難解さも一段と勝るけど。
143デフォルトの名無しさん:2009/06/11(木) 23:52:52
>>141
まずは

ファイルフォーマット 仕様
という単語にbmp jpeg pngといったキーワードとセットにしてぐぐるということを教えてあげないと
144デフォルトの名無しさん:2009/06/11(木) 23:53:08
>>141
txtで読み込んでました

あの超初心者っぽい質問なんで恥ずかしいんですが、そんなふうにファイルの内容を16進数表記で表示させるにはどうすればいいんでしょうか
145デフォルトの名無しさん:2009/06/11(木) 23:54:48
あ、バイナリエディタって書いてましたねごめんなさい
146デフォルトの名無しさん:2009/06/11(木) 23:55:24
>>143
ごもっとも。

>>144
ばいなりえd、、、
fgetcして、%Xで出力すればいい
147デフォルトの名無しさん:2009/06/11(木) 23:57:23
>>113
ひとつ確認
if(a && b)
if(a & b)
副作用が無くてこれらの意味が同じになる場合についてのみ話してるんだよね?
148デフォルトの名無しさん:2009/06/11(木) 23:58:43
>>146
例えばこれを読み込んでデータを二次元配列に展開して、FFを00に、00をFFに変えたのち出力すれば白と黒が反転したbmpファイルができるってことですよね?
画像をいじるプログラムを作れるようになるという、最初の一歩が踏み出せた気がします
149デフォルトの名無しさん:2009/06/11(木) 23:59:08
>>147
違うぽ
150デフォルトの名無しさん:2009/06/12(金) 00:00:27
画像処理をするには2つの道がある。

1、画像フォーマットを勉強して、1からエンコーダ・デコーダを書く。
2、ありもののライブラリの使い方を調べる。

初心者を脱したくらいのレベルだと1のほうに魅力を感じるかもしれない。
それは悪いことではないが、しばらくプログラマをやっていくと、2の方が重要なことに気づく。
30年かけて蓄積されたライブラリを最初から作ったら、作りたいものができるまでそれ以上の時間がかかるわけだし。

外部ライブラリを使うというのは独特、これはこれで高度な技術。
C言語の外部ライブラリを使いこなせるようになるには、C言語の知識だけじゃダメだったりする。
ライブラリとは何か、ってとこからOSや処理系の知識まで複数の分野をカバーする必要がある。

文法や標準ライブラリの勉強というのはいわば箱庭の中で遊んでいるようなもの。
その温室から外に出るには、自力で調べ自力で試行錯誤する力を身につけなければならない。

っつっても、いまやグーグル先生がいるから茨の道手ほどでもないんだけどけどね。
151デフォルトの名無しさん:2009/06/12(金) 00:00:43
FFと00ならそれでもいいけど
エンディアnゲフンゲフン
152デフォルトの名無しさん:2009/06/12(金) 00:00:44
>>148
全部反転したらだめだよ。
RGB値のとこだけ。
それがどこなのかはファイルフォーマットを調べてね。
一歩踏み出せてよかった
153デフォルトの名無しさん:2009/06/12(金) 00:03:27
考えてみればグーグル先生のいない時代に先輩達はどうやって勉強してきたんだろうな
参考書や規格書を毎回手でめくって調べてたんだろうか
想像も付かない
154デフォルトの名無しさん:2009/06/12(金) 00:04:50
>>149
違う?
意味が変わる場合は設計も変えろって事?
155デフォルトの名無しさん:2009/06/12(金) 00:05:19
>>153
yes
高い書籍買ったりしてたよ。
156デフォルトの名無しさん:2009/06/12(金) 00:09:08
>>154
a == 2
b == 1
であるとき
( a && b ) == 1
( a & b ) == 0
!!a == 1
!!b == 1
( !!a & !!b ) == 1
157デフォルトの名無しさん:2009/06/12(金) 00:10:10
>>153
でもある程度の時代からパソ通のフォーラムがこのスレのような専門的な質問とかも
できるようになってたので金持ってるやつはそういうところで情報交換してたみたい。

158デフォルトの名無しさん:2009/06/12(金) 00:12:41
C言語覚えるのに、LSI-C試食版のマニュアルにお世話になった。
プレーンテキストファイルだったけど、コンパクトにまとまってて重宝した。
アセンブラもついてたしな。
159デフォルトの名無しさん:2009/06/12(金) 00:14:14
副作用が発生しないこと前提で、短絡評価をさせないことによって
コンパイラが最適化しうる余地を作ったってことになるのかなぁ?
160デフォルトの名無しさん:2009/06/12(金) 00:15:14
>>155
バイブルには載ってないけどDLLのstrings見るとそれっぽい関数があるんだけど!
という時代?
161デフォルトの名無しさん:2009/06/12(金) 00:16:49
短絡評価自体が無駄な評価をしないという最適化の一種じゃないの
162デフォルトの名無しさん:2009/06/12(金) 00:17:42
>>158
あのマニュアルは良かった

Windows95 で使ってたから
DOSモードで直接RGBプレーンに書き込んで画面表示なんかも出来たな
A000:0000 〜 だっけか
163デフォルトの名無しさん:2009/06/12(金) 00:18:21
>>153
今でも参考書や規格書は買うが。
昔はネットニュースでFAQをはじめとするドキュメントを入手してたな。
あとはフリーソフトウエアのソース参考にしたりとか。
164デフォルトの名無しさん:2009/06/12(金) 00:19:18
DLLなんて無い時代

165デフォルトの名無しさん:2009/06/12(金) 00:20:07
>>162
それはテキストVRAMの位置じゃね?
というかDOS/VとPC98系ではその辺の仕様が違うはず
166デフォルトの名無しさん:2009/06/12(金) 00:20:16
>>161
if (複雑な条件 && i != 0)
と書かれていた場合に、 i != 0を先に評価することで処理が速くなることはあると思うよ
167デフォルトの名無しさん:2009/06/12(金) 00:21:28
副作用がないことを明示すれば最適化してくれるようなオプションとか属性とかないのかな
168デフォルトの名無しさん:2009/06/12(金) 00:27:11
&を使わせることで
・両辺の評価を行うことが強制されるのかどうか
・評価順を最適化することが許されているのかどうか
これがわからん
>>113はそうであるかのごとく書いているけれど
169デフォルトの名無しさん:2009/06/12(金) 00:29:10
>>168
両辺の評価は強制
最適化は実際やってるコンパイラがあるのかわからん
170デフォルトの名無しさん:2009/06/12(金) 00:30:29
>>168
&は+とかと同じだから
両辺とも評価されるし、評価順は不定(コンパイラが好きにしていい)
171デフォルトの名無しさん:2009/06/12(金) 00:31:33
>>74
ncursesライブラリでコンソール上に色付きで表示できるよ
画像データはBMPが単純だからBMPのフォーマットを調べてバイナリデータを解析すればいいよ
172デフォルトの名無しさん:2009/06/12(金) 00:35:27
>>74
SetConsoleTextAttribute
SetConsoleCursorPosition
173デフォルトの名無しさん:2009/06/12(金) 02:01:43
そうなの?
右辺なり左辺なりが0であることがわかれば、もう一辺の値がどうであれ0になることはわかるのにね
ああでも最適化できるかというと難しい気がしてきたわ。。
174デフォルトの名無しさん:2009/06/12(金) 02:21:47
>>173
副作用がなければそういう最適化もできるよ。

そもそも今時のコンパイラなら、短絡評価の違いが現れる場合以外、
&でも&&でも同じように最適化したコードを吐いても不思議ではないと思う。
175デフォルトの名無しさん:2009/06/12(金) 03:08:54
可読性と効率は相反する要求
平均実行速度の最適化なら見た目の記述云々より
必要な処理を最低限のリソースで実現するプログラムがいい
コンパイラの最適化なんかよりアセンブリか機械語レベルで人間が直した方がいい
176デフォルトの名無しさん:2009/06/12(金) 03:19:57
じゃあ最初からそっちで書けば?
177デフォルトの名無しさん:2009/06/12(金) 03:21:43
>>174
なるほど。。コンパイラさまさまだね

>>175
すごいですねー
実際どういうときに速くなりますか?
178デフォルトの名無しさん:2009/06/12(金) 04:30:19
>>113
>AND(A,B) (!!(A) & !!(B))
VC++2008だと最適化有り無し共に&&より遅かった
179デフォルトの名無しさん:2009/06/12(金) 04:33:33
>>66
NULLはCでは
#define NULL (void *)0
とかで定義されてる
C++では単純な0かもしれないし、何かのオブジェクトかもしれない

32ビット環境では、intといったら32ビットで、メモリアドレスも32ビットだが
64ビット環境では、intといったら32ビットで、メモリアドレスが64ビットになるかもしれない
アドレスと整数を暗黙のキャストで都合よく変換できてることに依存すると後々困ったことになる

型が異なる演算や代入なんかでNULLを使いたいならキャストすべし
180デフォルトの名無しさん:2009/06/12(金) 07:54:31
>>178
やっぱり遅そうだもんな。
どう考えても処理が増えてる。
181デフォルトの名無しさん:2009/06/12(金) 08:42:48
普通にメモリアクセス増えるし、真面目にbitandとるから、そりゃ遅いよ。
182デフォルトの名無しさん:2009/06/12(金) 10:13:51
最適化スレに行けって話になっているけれど、更にダメ出し。

!!A はコンパイラにとってはA ? 1 : 0 と同じこと。
つまり、条件分岐を行なうか条件セットを行なうコードになる。
従って、処理速度的にメリットはない。
尤も、マクロではAND(i >= 1, j >= 0)としているので
省略はされて、(i >= 1) & (j >= 0) と評価されるから関係ないといえば関係ない。

で、このコードは条件分岐を二回経てから&を行なうので、
単純に i >= 1 && j >= 0と書くより早くなる筈がない。

>>113
結論、せめて得意のCPU向けのアセンブリ出力くらい眺めてから書こう。

>>181
メモリアクセスは「全く」増えないと思うよ。
恐らくは最適化で全てレジスタに配置されている筈だから。
183デフォルトの名無しさん:2009/06/12(金) 14:17:27
POSIXの標準関数で ファイルがあるかないか調べる関数 ってなんだっけ?
関数名が思い出せない
184183:2009/06/12(金) 14:23:24
自己解決しました
185デフォルトの名無しさん:2009/06/12(金) 15:01:44
結論:>>113=アホ
186デフォルトの名無しさん:2009/06/12(金) 16:00:21
for(i=0;i<10;i++){ }

for(i=0;i<10;++i)
187186:2009/06/12(金) 16:01:05
ごめんなさい途中送信しました

for(i=0;i<10;i++){ }

for(i=0;i<10;++i){ }
ってどう違うのでしょうか?
188デフォルトの名無しさん:2009/06/12(金) 16:01:53
>>187
C言語では一緒
189デフォルトの名無しさん:2009/06/12(金) 16:09:23
>>187
原則同じ。C++流に慣れた人がしばしば後者を使いたがる。
# 私もだけど。
190デフォルトの名無しさん:2009/06/12(金) 16:53:43
C++なのに++Cにする不思議
191デフォルトの名無しさん:2009/06/12(金) 17:57:30
便乗質問。
C++だとどう違うの?


「コンパイラによる最適化は無効な条件下において」

C言語でもC++でも、
for(i=0;i<10;i++){ }
は後置増分演算子だからテンポラリオブジェクトを作る分だけ
for(i=0;i<10;++i){ }
の前置増分演算子版よりか遅くなりそうなイメージなのだが。
192デフォルトの名無しさん:2009/06/12(金) 18:01:55
C++だとiがイテレータの場合があって、
実体がクラスだと無駄なコピーコンストラクタ呼ばれたりするので大差が付くことがある
193デフォルトの名無しさん:2009/06/12(金) 18:09:52
Cでは++iもi++も値のコピーだけど、C++では++iは有効な左辺値を返す。
つまり、インクリメントされたiの参照が返る。
++iはコピーしない文、コストが安い…だったと思った。^^

イテレータの話が出たのでついでに。
STL愛用者は(そうできるケースでは)

for( i = 0 ; i != 10; ++i) { }

のように書いたりする。なぜなら、
!= をサポートするイテレータの方が < をサポートするイテレータよりも種類が多いから。
194191:2009/06/12(金) 18:13:26
>>192-193
ありがとう。
イテレータじゃなくて生のポインタだったとしても、
「コンパイラによる最適化は無効な条件下において」
は遅くんだよね?
実測は不可能な程度だとしても、理論値的な意味で。
195デフォルトの名無しさん:2009/06/12(金) 19:36:12
>>191
組込型なら違いはない。
その例では式の結果が使われていないから前置インクリメントと同じコードを吐けばいいし、
例えそうでなかったとしても、インクリメントする命令を後回しにすればいいだけ。
よほど複雑な式ならともかく、最適化なんて意識しなくても自然とそういうコードになると思う。
196デフォルトの名無しさん:2009/06/12(金) 19:45:52
色付文字ってエスケープシーケンスの8色だけなんでしょうか?
197194:2009/06/12(金) 19:47:09
>>195
そんなもんなのか。
ありがとう。
198デフォルトの名無しさん:2009/06/12(金) 19:56:32
>>196
Linuxとかだと、最近は256色端末も使えると思う。
どれくらい広まっているのか知らないけど。
199デフォルトの名無しさん:2009/06/12(金) 19:56:40
>>194
なまぽで for 文の条件式ならほぼ確実にコンパイラが最適化しちゃうけど
最適化がないなら、理論的にはPOD型でも遅くなる。

この件に関しては名著 C++ Coding Standardsでも
「時期尚早に最不適化してしまわない」や
「インクリメント演算子とデクリメント演算子の標準形式を使おう」
といった項で説明している。小さな習慣ですむなら守るべきだろう。
200194:2009/06/13(土) 08:30:22
>>199
やっぱりそうだよね。
俺は元々++i派だから大丈夫だ。
ありがとうございます。
201デフォルトの名無しさん:2009/06/13(土) 13:31:53
環境依存だから確認した方がいいよ
x86 + gcc の場合だけど、前置式も後置式もステップ数は変わらなかった
202デフォルトの名無しさん:2009/06/13(土) 15:30:50
>>201
最適化禁止で?
203デフォルトの名無しさん:2009/06/13(土) 15:31:43
メモリ上のデータは全部リトルエンディアンでいいんでしょうか?
204デフォルトの名無しさん:2009/06/13(土) 15:34:45
そんなこたない。
205デフォルトの名無しさん:2009/06/13(土) 15:35:30
>>203
いいえ
206デフォルトの名無しさん:2009/06/13(土) 15:42:21
でも、統一しておかないとシフト演算とかで困るような気がするんですけど
207デフォルトの名無しさん:2009/06/13(土) 15:45:34
シフト演算はレジスターで行われるからエンディアン関係なし。
208デフォルトの名無しさん:2009/06/13(土) 16:54:27
//構造体
typedef struct {
int NO;
char NAME[10];
} STD_t;

STD_t sample[2];
sample[0].NAME="長谷川";

こんな感じで構造体char型のNAMEに文字列を入れたら
「'const char [5]' から 'char [10]' に変換できません。」というエラーになりました。
constについて調べましたが、定数宣言?は行ってませんし、なぜこういうことになったのでしょうか?
209デフォルトの名無しさん:2009/06/13(土) 17:00:09
>>208
char nane[10];
name = "長谷川";
ができないのと同じ。
210デフォルトの名無しさん:2009/06/13(土) 17:00:14
>>208
char NAME[10];

char *NAME;
にするか、
sample[0].NAME="長谷川";
をstrcpyなんかを使って書き直せ
211デフォルトの名無しさん:2009/06/13(土) 17:09:16
なぜに長谷川さんw
212201:2009/06/13(土) 17:19:53
>>202
最適化しない場合で。

"i++"より"++i"が優れてるのは、演算結果を一時的に
覚えておく必要が無い点だけど、レジスタがたくさんある普通の
CPUで単純な演算なら、その辺の差は必ずしも出ない
213デフォルトの名無しさん:2009/06/13(土) 17:24:00
宗教家が出てきたw

Effective C++の第二版にも書いてあった気がする。
Google Coding Standardsにも確か書いてあったと思う。
いるんだよ、こういう人がw
214デフォルトの名無しさん:2009/06/13(土) 17:28:24
>>212
PowerPCターゲットにしたコンパイラで、最適化しても前置インクリメントの方が
速くて、そっち使ってたことがあったな。
215デフォルトの名無しさん:2009/06/13(土) 17:32:42
少なくとも後置きが前置きより早くなることは普通はありえないよな
やってることが少ないんだから
前置きを習慣づけて損することはないならそっちの方がいいと思う
216デフォルトの名無しさん:2009/06/13(土) 18:21:50
コンソールの文字表示ってすごい時間かかるみたいなんですけど
これを高速化するにはハードを変えるしかないんでしょうか?
217デフォルトの名無しさん:2009/06/13(土) 18:28:11
そうです。もしくはバッファにためにためまくって、
もうこれ以上無理っていうところで初めて実際に出力するようにすれば
だいぶ早くなります。
218デフォルトの名無しさん:2009/06/14(日) 01:34:59
構造体の隙間埋めの仕方は環境依存ですか?
ファイルI/Oで構造体を丸ごとバイナリread/writeするのは危険ってことでしょうか
219デフォルトの名無しさん:2009/06/14(日) 01:36:51
>>218
読み込みと書き込みを行うのが同じエンディアンでCPUのビット数が同じなら問題ないはず
220デフォルトの名無しさん:2009/06/14(日) 01:38:07
>>218
危険です
221デフォルトの名無しさん:2009/06/14(日) 01:38:53
>>219
にゃんでやねん!
222デフォルトの名無しさん:2009/06/14(日) 02:59:26
>>218
やるのなら、コンパイラに対してパディングするなっていう指示をした上でやるべき。
223デフォルトの名無しさん:2009/06/14(日) 08:50:25
>>218
同一OS環境で、コンパチCPUで 、同一アプリケーションで読み書きかなら問題ない。
ひとつでも違えば危険、
224デフォルトの名無しさん:2009/06/14(日) 08:51:56
↑アプリケーションのレビジョンも同一を追加してくれ
225デフォルトの名無しさん:2009/06/14(日) 09:41:10
構造体まるごとread/writeしてるコードって、なぜかその構造体を
コード全体で使いまわしてる例が多いな。
それをやられると、すごいコードに柔軟性がなくなる。
226デフォルトの名無しさん:2009/06/14(日) 12:03:25
Cなら構造体のパディングを前提にしたプログラミングは当たり前だけどね
というか、データ構造の仕様が先にあって
それに合わせて構造体を定義するものだろう
227デフォルトの名無しさん:2009/06/14(日) 12:55:21
構造体丸ごとリードライトしたのちバイナリファイルを見ると変なパディングがあったり
エンディアンの問題があったりすると思いますが、

完全に安全なプログラム(パディングなし、他の環境でコンパイルした
プログラムでも全く同じファイルを書き出す・読み出せる)
にするためにはどうするのが望ましいでしょうか。
(あるていど速度も犠牲にするということで)
228デフォルトの名無しさん:2009/06/14(日) 13:21:57
>>227
charで読み出して合成するしかないね
でも浮動小数点は・・・・
229デフォルトの名無しさん:2009/06/14(日) 13:22:38
構造体のメンバをぜんぶunsigned charにする。
230デフォルトの名無しさん:2009/06/14(日) 13:25:50
>>227

writeWord(FILE* fp, WORD w)
{
fputc(w & 0xff, fp);
fputc((w>>8) & 0xff, fp);
}

writeDWord(FILE* fp, DWORD w) ・・・

みたいな関数を作っておいて、項目ごとに書き出せばいいよ。
231デフォルトの名無しさん:2009/06/14(日) 13:26:03
一番安全なのは構造体を丸ごとリ−ドライトしないこと。
汎用的なデータ形式にエンコード/デコードするのが正攻法。
232デフォルトの名無しさん:2009/06/14(日) 13:31:24
エンディアンはビッグエンディアンにする事が多い
233デフォルトの名無しさん:2009/06/14(日) 13:31:26
スピードが問題じゃなかったら、テキストにするってのもあるな。
ファイルのヘッダは、構造体まるごとリードライトのバイナリなのに、
本体はテキストになってるって変態フォーマットも見たことある。
234デフォルトの名無しさん:2009/06/14(日) 13:36:18
今はPC性能も高いからXMLやjsonなんかでデータ保存や通信するのも十分ありだと思う。
むしろその方が他のアプリと連携しやすい。
235デフォルトの名無しさん:2009/06/14(日) 13:59:31
>>227
パディングがあっても無くても、環境ごとに構造体を
正しく定義すればOK

汎用性を求めるなら229の言うように全部
unsigned charにするのが確実
236デフォルトの名無しさん:2009/06/14(日) 16:25:41
>>231,234が神。「達人プログラマー」にもそう書いてある。
バイナリが将来にわたる保守性を破滅的状況に導く極端なケースについても紹介。
237デフォルトの名無しさん:2009/06/14(日) 16:46:06
か、かみ
238デフォルトの名無しさん:2009/06/14(日) 16:47:16
Boost.Serializationを使えば話が早いのでは?

・・・っとここはC言語スレだったか。
239デフォルトの名無しさん:2009/06/14(日) 17:02:41
>>227
それをやろうという概念が、シリアライズ(マーシャリング)。
ということで検索したらこんなのあった。別に推薦しないけど。
ttp://kmaebashi.com/programmer/serializer/index.html
240デフォルトの名無しさん:2009/06/14(日) 17:03:17
#pragma once
があるのに
#ifndef HOGE
#define HOGE
#endif
を使うのはどうして?
241デフォルトの名無しさん:2009/06/14(日) 17:05:40
>>240
pragma はコンパイラによって様々
once が使えないことがあるから
242デフォルトの名無しさん:2009/06/14(日) 17:07:05
#pragma once は VC++ 専用?
243デフォルトの名無しさん:2009/06/14(日) 17:19:20
>>242
そう。
だけどあまりに人気があるpragmaだから、他のコンパイラも採用していることがある。
244デフォルトの名無しさん:2009/06/14(日) 17:27:51
#pragma onceでは、実質同じファイルをインクルードしてしまうことがあるし、
コンパイル時間も多くかかるようになる(場合が多かったと記憶している)
245デフォルトの名無しさん:2009/06/14(日) 17:47:28
ファイルからchar[4]に読み込んでからuint32_tに変換するコードなんですが、これで正しいでしょうか?

#include <stdio.h>
#include <stdint.h>
enum Endian {
LITTLE_ENDIAN,
BIG_ENDIAN
};

uint32_t read_uint32(const char* data, Endian e) {
uint32_t ret = 0;
unsigned char* p = (unsigned char*)data;
int i;
switch(e) {
case LITTLE_ENDIAN: for(i = 0; i < 4; ++i) ret += p[i] << i * 8; break;
case BIG_ENDIAN: for(i = 0; i < 4; ++i) ret += p[3 - i] << i * 8; break;
}
return ret;
}

int main(void) {
char little[] = {0xDD, 0xCC, 0xBB, 0xAA}; // リトルエンディアンで保存された0xAABBCCDD
char big[] = {0xAA, 0xBB, 0xCC, 0xDD}; // ビッグエンディアンで保存された0xAABBCCDD
printf("%0X %0X\n", read_uint32(little, LITTLE_ENDIAN), read_uint32(big, BIG_ENDIAN)); // => 0xAABBCCDD 0xAABBCCDD
}
246デフォルトの名無しさん:2009/06/15(月) 01:44:43
>>245
正しい
けど実行環境のバイトオーダーが分かってるなら、
普通に4バイト読んで、必要に応じてhtonl()等を呼べばいい
247デフォルトの名無しさん:2009/06/15(月) 02:22:13
>>245
関係ないがLITTLE_ENDIANとBIG_ENDIANは記号定数としてstdio.hで定義されてる可能性がある
その書き方で変換できてるが、こういう場面では += を使わずに |= を使うべき
あるいは
uint8_t *p = (uint8_t*)&ret;
for(i=0; i<4; ++i, ++p) *p = data[i];
のようにも書ける
248デフォルトの名無しさん:2009/06/15(月) 07:57:44
ありがとうございます
もうすこし改良することにしました
249デフォルトの名無しさん:2009/06/15(月) 19:48:08
当方プログラミング経験がほとんどないのですが、仕事でC言語を使うことになってしまいましたorz
Cを演習しながら覚えられる良書はありませんか?
250デフォルトの名無しさん:2009/06/15(月) 19:56:50
>>249
書籍スレも見つけられないような盆暗には、どんな良書も焚き付け程度にも役に立たないと思いますが。
251デフォルトの名無しさん:2009/06/15(月) 19:59:29
それなりに経験あるプログラマが必死になって仕事探してもなかなかありつけないのに、
なんで>>249みたいなところに仕事が行くんだろう?
252デフォルトの名無しさん:2009/06/15(月) 20:00:53
>>249
代わりに見つけておいた。
まぁ、業務命令なら命令出した人間に聞くのが筋だろうけどね。

推薦図書/必読書のためのスレッド 49
http://pc12.2ch.net/test/read.cgi/tech/1244882261/
253デフォルトの名無しさん:2009/06/15(月) 20:01:15
経営者が無能、または、>>249を辞めさせるために
254デフォルトの名無しさん:2009/06/15(月) 20:02:13
>>251
>253か、或いは外注に出せる予算がなくなって内製せざるを得なくなったとか。
まぁ、ろくなもんじゃないよ。
255デフォルトの名無しさん:2009/06/15(月) 20:08:40
就活しにそうです
256デフォルトの名無しさん:2009/06/15(月) 20:21:38
外注しようとしたら高いな!
まあいっか。プログラマが世の中にたくさんいるってことは簡単にできんじゃね?
ちょっくらおぼえて作ってよ。C言語っての有名らしいしさ。

という発想なんじゃないのかなー
257デフォルトの名無しさん:2009/06/15(月) 21:30:41
どう考えても、パワハラ(漢字で書くと羽輪原)です。
プログラミング言語のない人が書いたCのプログラムなんて
やさしさの半分はメモリリークでできているでしょう。
258デフォルトの名無しさん:2009/06/15(月) 21:44:20
mallocの使い方がわからず、リークさせるものがない
259デフォルトの名無しさん:2009/06/15(月) 21:46:23
sinをx-x^3/3!+x^5/5!...で計算すると.-1.#IND00って
出るんですけどなぜ?
260デフォルトの名無しさん:2009/06/15(月) 21:48:21
>>259
x^n/n! が無限大というか double で扱える範囲外とか
261デフォルトの名無しさん:2009/06/15(月) 22:42:36
コンソール上にbitmap画像を表示したいのですが、
どうすればいいでしょうか?

一応エスケープシーケンスを使って8色の画像なら表示できました。
できれば256色表示したいのですが・・・
262デフォルトの名無しさん:2009/06/15(月) 22:43:40
タッチタイピングくらい出来ないとプログラマにはなれませんか?
263デフォルトの名無しさん:2009/06/15(月) 22:45:16
いいえなれます
264デフォルトの名無しさん:2009/06/15(月) 22:49:12
うん
265デフォルトの名無しさん:2009/06/15(月) 22:53:37
自称タッチタイプできるってやつの大半は我流だしな。

あと、テレビとかで、外人のジャーナリストとか学者がタイプするところを
みてると、けっこう一本指打法だったりする。
266デフォルトの名無しさん:2009/06/15(月) 23:01:43
タッチタイプできたところで、
ほとんどのプルグルマは思考速度の方がはるかに遅い^^

考えてる時間1000に対して打ち込む時間1。
他人のコードを読んでいる時間が1000000、
課長が俺好みの女で業務中にわざと足を広げて
俺にパイパンのあそこをちらちらと見せ付けてくるのが気になってる時間が1000000000000くらい。
267デフォルトの名無しさん:2009/06/15(月) 23:04:34
>>266
時間比率から考えると
女課長は脳内に1万人以上24時間待機してるな
268デフォルトの名無しさん:2009/06/15(月) 23:04:53
とうとう壊れたPGがでてきたか・・・

タイピング速度をもろ要求されるのはパンチャーくらいだろ
とにかく打つのが仕事なんだし
269デフォルトの名無しさん:2009/06/15(月) 23:08:36
>>261
256色表示可能な端末エミュレータの準備はできてる?
270デフォルトの名無しさん:2009/06/15(月) 23:08:48
私が壊れても大丈夫、控えとバックアップ含め30人いるから…
271デフォルトの名無しさん:2009/06/15(月) 23:10:40
タイピングが速いと客先とかでインパクトを与えることができるよ。
なるべく静かで、なるべく速い方がかっこいい。速いけどうるさいのははた迷惑
272デフォルトの名無しさん:2009/06/15(月) 23:30:52
タイプ速度と同じくらいスラスラコード考える脳があればさぞや楽しいだろうなぁ
273デフォルトの名無しさん:2009/06/15(月) 23:33:11
>>272
会社組織でやってるとバンバン仕事回ってきて死ぬよ
バグ鳥は他人がやってくれるならいいけど
274デフォルトの名無しさん:2009/06/15(月) 23:35:26
コードを量産するのが無能な働き者だったらいないほうがマシだな
275デフォルトの名無しさん:2009/06/15(月) 23:35:49
頭の中でコードが出来上がってる時は、めんどくせーと思いながら
ひたすらコーディングするだけ。
276デフォルトの名無しさん:2009/06/15(月) 23:41:24
>>273
タイピング速度を上げて生き残れ
277デフォルトの名無しさん:2009/06/15(月) 23:42:33
タイピング速度を上げると、万能プログラミングマシーンになれるのですね。理解できません。
278デフォルトの名無しさん:2009/06/15(月) 23:43:19
タイプに思考速度が追いつかないって、思考速度が遅すぎなんじゃね?
頭の中にコードができてるのに、タイプが追いつかないであせることがしばしばある。
279デフォルトの名無しさん:2009/06/15(月) 23:46:38
ああ読み間違えていた。
脳が追いつかないのかよ。ご愁傷様
280デフォルトの名無しさん:2009/06/15(月) 23:49:03
エディタ、IDEをうまく活用できてるかどうかも重要じゃね
281デフォルトの名無しさん:2009/06/15(月) 23:50:51
ちょっと前にどっかのスレで、一日にかける行数どのくらいって話になったときにも、
「パンチャーじゃねえし」とか言って、暴れてるやついたな。
コンプ強すぎ。
282デフォルトの名無しさん:2009/06/15(月) 23:55:00
ある程度書くと減り始めるから
行数カウントは難しいかも
トータルではあまり行数は増えないけど
書く量はそこそこ
283デフォルトの名無しさん:2009/06/15(月) 23:55:04
最終形がある程度見えてもりもり書ける人はいいなあと思う。
いつも書いてる途中でリファクタリングしまくってる
284デフォルトの名無しさん:2009/06/16(火) 00:40:58
int main(void)
{
int i,sum=0;
int num[3] = {10,20,30};

for(i=0; i<(sizeof(num)/sizeof(num[0])); i++)
sum += num[i];

printf("%d\n", sum); // @1

hoge(num);

return 0;
}

void hoge(int *num)
{
int i,sum=0;

for(i=0; i<(sizeof(num)/sizeof(num[0])); i++)
sum += num[i];

printf("test : %d\n", sum); // @2

}

hoge関数でsizeofを読んでしまうとポインタサイズの取得になってしまい困っていますs。
@1と@2の結果を同じにしたいのですが、何か良い方法がないでしょうか?
285デフォルトの名無しさん:2009/06/16(火) 00:46:28
Cでは無理

素直にmain()で求めたsizeof(num) / sizeof(num[0])を関数の
パラメータに持たせなせえ
286デフォルトの名無しさん:2009/06/16(火) 00:47:57
hoge(num);



hoge(num,(sizeof(num)/sizeof(num[0])));


void hoge(int *num)



void hoge(int *num,int size)


for(i=0; i<(sizeof(num)/sizeof(num[0])); i++)



for(i=0; i<size; i++)
287デフォルトの名無しさん:2009/06/16(火) 00:55:27
これはhoge関数の中のね

for(i=0; i<(sizeof(num)/sizeof(num[0])); i++)



for(i=0; i<size; i++)
288デフォルトの名無しさん:2009/06/16(火) 01:00:57
main 文の中の num は配列型(より詳しく言うなら int[3] 型)、
関数 hogeの中の num はポインタ型( int* 型)。
型が違うのだから、当然利用するメモリサイズも違う。
配列型は全体のサイズを1要素のサイズで割るとその要素数がわかるというだけの話で
ポインタ型にはそのような特性はない。
したがって、hoge を

void hoge( int (*num)[3] ) {
int i,sum=0;
for(i=0; i < sizeof *num / sizeof (*num)[0]; i++)
sum += (*num)[i];
printf("test : %d\n", sum); // @2
}

のように記述し、呼び出しでは

hoge( &num );

とすれば、意図したとおりの動作となる。
289デフォルトの名無しさん:2009/06/16(火) 03:10:04
>>288
このときのhogeの引数の型って何になるの?
290デフォルトの名無しさん:2009/06/16(火) 07:07:51
>>289
int(*)[3] (int3つの配列へのポインタ)
291デフォルトの名無しさん:2009/06/16(火) 07:37:31
>>288
サイズ固定で汎用性がないけどね
292デフォルトの名無しさん:2009/06/16(火) 13:08:09
配列について聞きたいんですけど
配列の要素数って最初に宣言しないといけないんですか?
たとえば

int a[];
って宣言しといて、aにどんどん要素を入れていってあとで要素数を決めるってことはできないんでしょうか
293デフォルトの名無しさん:2009/06/16(火) 13:09:04
>>292
途中で追加することはできません。頑張ってmalloc()/realloc()/free()の使い方を勉強してください。
294デフォルトの名無しさん:2009/06/16(火) 13:14:30
realloc()使え
295デフォルトの名無しさん:2009/06/16(火) 13:16:46
>>294
reloadしろ
296デフォルトの名無しさん:2009/06/16(火) 13:45:10
>>293
realloc()だけあれば他は要らないけどね。
# 初心者は使い分けた方が判り易いか……
297デフォルトの名無しさん:2009/06/16(火) 15:38:35
malloc(size) = realloc(NULL, size) も
free(ptr) = realloc(ptr, 0) も保証されてるの?
298デフォルトの名無しさん:2009/06/16(火) 15:40:12
後者はどうなんだろうねえ。
realloc(ptr,0)の戻り値はNULLもしくはfreeに渡すことができるポインタらしいんだけど。
299デフォルトの名無しさん:2009/06/16(火) 15:44:39
ほい。
--
realloc() は、ポインタ ptr が示すメモリブロックのサイズを変更して size バイトにする。
新旧のサイズのうち、小さいほうのブロックに含まれる内容は変更されない。
新しく割り当てられたメモリの内容は初期化されない。
size がどの値であっても、 ptr が NULL の場合には malloc(size) と等価である。
size が 0 で ptr が NULL でない場合には、 free(ptr) と等価である。
ptr が NULL 以外の場合、 ptr は以前に呼び出された malloc(), calloc(), realloc() のいずれかが返した値でなければならない。
ptr が指す領域が移動されていた場合は free(ptr) が実行される。
--
4行目と5行目に注目。
300デフォルトの名無しさん:2009/06/16(火) 15:52:39
あらほんと。man見てたのにそこ読めてないとか俺バカス
301デフォルトの名無しさん:2009/06/16(火) 16:07:24
302デフォルトの名無しさん:2009/06/16(火) 16:18:47
俺はmallocの代わりに使うことはあってもfreeの代わりには使わないな
303デフォルトの名無しさん:2009/06/16(火) 16:23:59
何をしようとしているのかを明示するためにも
使い分けた方がいいんじゃなかろか。
304デフォルトの名無しさん:2009/06/16(火) 16:43:47
上級者はその辺も意識して使い分けるって事か。
malloc free と等価であることが明らかな環境であれば、reallocで済ませると。
すごーい
305デフォルトの名無しさん:2009/06/16(火) 21:45:30
素直にfree使えば混乱が無くていいと思うアマグラマでした
306デフォルトの名無しさん:2009/06/16(火) 22:35:45
プロなら
#define FREE(p) realloc(p,0)
307デフォルトの名無しさん:2009/06/16(火) 22:37:32
>>306
そんなプロはおらんやろ〜
308デフォルトの名無しさん:2009/06/16(火) 23:36:45
realloc(ptr, 0)で得られたポインタって、もう一回reallocしても大丈夫なのかな?
そうであれば、二重freeの危険性があるfree使うより、reallocで解放した方が安全だったりする?
309デフォルトの名無しさん:2009/06/16(火) 23:38:42
例え出来てもfreeと等価になるかどうかは知らん。
310デフォルトの名無しさん:2009/06/16(火) 23:41:19
>>308
それなら
#define FREE(p) (free(p),(p)=NULL)
とか
311デフォルトの名無しさん:2009/06/16(火) 23:44:53
SAFEDELETEとか作ってたことを思い出す
312デフォルトの名無しさん:2009/06/16(火) 23:46:05
>>311
DirectX のサンプルには必ずあった気がする
313デフォルトの名無しさん:2009/06/17(水) 00:13:09
realloc(0, 0) って未定義?
314デフォルトの名無しさん:2009/06/17(水) 00:49:01
realloc(0,n)はmalloc(n)のように振る舞うと決められている
malloc(0)の挙動は処理系定義で、NULLを返すか、
1以上の何らかのサイズでmallocしたかのように振る舞うか(ただしその領域にアクセスしたらダメ)
どちらかを選ぶことになっている
315284:2009/06/17(水) 00:58:55
>285
了解です。
C++ならいい方法があるのでしょうか?

>288
ひとつの解決方法として参考にさせていただきます。
316デフォルトの名無しさん:2009/06/17(水) 01:07:38
C++ならvector辺り使うとか?
317デフォルトの名無しさん:2009/06/17(水) 01:08:50
またマネージドからCに来た人が沸いてるのか?
318デフォルトの名無しさん:2009/06/17(水) 02:42:17
C言語の入門者が、Cではそれできないよ、といわれて、C++ならできるの?という疑問を持つのはよくあること
319デフォルトの名無しさん:2009/06/17(水) 03:42:42
>>315
C++なら参照渡しだろ?
と元の話を読まずに書いてみるテスト
320デフォルトの名無しさん:2009/06/17(水) 07:27:07
配列が固定サイズならCでもなんとかなる
321デフォルトの名無しさん:2009/06/17(水) 12:17:40
異なるスレッドやDLLではある関数内のローカルstatic変数は共有されないんでしょうか?
322デフォルトの名無しさん:2009/06/17(水) 12:41:09
>>321
共有されるのでマルチスレッドでは問題になる
323デフォルトの名無しさん:2009/06/17(水) 13:11:31
>>320
>>288じゃなくて?
324デフォルトの名無しさん:2009/06/17(水) 22:55:21
あれ?共有されないのはグローバル変数でしたっけ?
スレッドやDLLの安全性がよくまとまってるサイトとかありますか?
325デフォルトの名無しさん:2009/06/17(水) 23:27:45
for文のカウンタ変数はintって、どこに書いてあるの
326デフォルトの名無しさん:2009/06/17(水) 23:30:17
だれがそんなこといったん?総力あげて戦うつもりもないけど。
327デフォルトの名無しさん:2009/06/17(水) 23:34:46
intじゃなくてもいいからどこにも書いてないよ
328デフォルトの名無しさん:2009/06/18(木) 00:56:27
そもそもfor文は、カウンタを使わなくても良いし...
329デフォルトの名無しさん:2009/06/18(木) 05:03:14
doubleでも動作保証されてる、int以外の例どこにあるの
330デフォルトの名無しさん:2009/06/18(木) 05:09:45
>>329
頭固すぎだろ

doubleをカウントアップ用変数に使った場合、==で判定するケースは足しこむ数字と==で比較する数字に
注意しないとだめかもな
331デフォルトの名無しさん:2009/06/18(木) 05:24:02
double == doubleて使いものになるの?
小数点数を駆使したコード書いた事無いからよくわからんけど
332デフォルトの名無しさん:2009/06/18(木) 05:28:16
ならないよ
333デフォルトの名無しさん:2009/06/18(木) 05:28:21
>>331
足しこむ数字にもよるし単なるカウントアップ/ダウンなら安全にするために

左側をカウンタ、右側を判定に使う数字とした場合

>= とか <= を考えた方がいいかもね
334デフォルトの名無しさん:2009/06/18(木) 06:14:06
無限ループ
#include <stdio.h>
int main(void)
{
double i;
for (i = 0.0; i != 1.0; i += 0.1)
{
printf("%f\n", i);
}
return 0;
}
335デフォルトの名無しさん:2009/06/18(木) 06:15:30
これはOK
for (i = 0.0; i != 1.0; i += 0.125)
{
printf("%f\n", i);
}
336デフォルトの名無しさん:2009/06/18(木) 06:16:24
for (i = 0.0; i != 1.0; i += 0.1)

for (i = 0.0; i <= 1.0; i += 0.1)
337デフォルトの名無しさん:2009/06/18(木) 07:28:54
doubleやfloatは使わないほうがいいことになってる。
使うときは条件判断で「<」か「>」を使い、値の範囲に注意する。

ループの判定で、「==」や「!=」がちゃんと動くか保証がない以外にも、
すごく大きな数だと、+1しても値が変わらないことがある。
338デフォルトの名無しさん:2009/06/18(木) 09:10:05
再帰関数が必要になるケースってどういう場合なんでしょうか?
簡単なケースだとfor文でもいけそうですし、多くなるとスタックの問題もありそうですし
339デフォルトの名無しさん:2009/06/18(木) 09:22:09
一番出番が多いのは、ツリー型のデータ構造を扱うとき。
340デフォルトの名無しさん:2009/06/18(木) 09:33:28
A(B){A(Bx(B));}な場合
ループで処理するとA(B)の停止条件が既知でないとBx(B)を遡れない
341デフォルトの名無しさん:2009/06/18(木) 11:49:24
昔の人が書いたソースコードを見ていたら

main(argc,argv)
int argc;
char**argv;
{
hogehoge;
}
っていうように書いてる人がいました、
これって文法違反じゃないの?
でも無事にコンパイルもできるし。
これってどういう意味ですか?
グローバル変数?
342デフォルトの名無しさん:2009/06/18(木) 11:51:33
>>341
K&Rでググるとか
343デフォルトの名無しさん:2009/06/18(木) 11:52:05
>>341
main(int argc, char **argv)
{
hogehoge;
}
の昔の書き方。
344デフォルトの名無しさん:2009/06/18(木) 11:58:17
昔のプロトタイプはパラメータの型チェックがなかったのさ。
っていうか、もしかしてCにオーバー道路がないのも、この古い遺産のせい?^^
345デフォルトの名無しさん:2009/06/18(木) 12:08:14
>>342, 343, 344
なるほど、ありがとうございます!
よくわかりました!
ちなみに、knuth先生がwc.wでこのように書いてました。
346デフォルトの名無しさん:2009/06/18(木) 12:08:31
おかげで
f(double a,double b){ }

f(a,b)double a,b;{}
とかけてショートコーディングでたまに使う
347デフォルトの名無しさん:2009/06/18(木) 12:13:54
K&Rの書き方って今のコンパイラでも通るんだ。
ANSI通さないコンパイラ使わないといけなくなって、K&R形式に書き直したことはあったけど。
348デフォルトの名無しさん:2009/06/18(木) 12:35:08
unprotoize使うといいよ
349デフォルトの名無しさん:2009/06/18(木) 17:42:01
1 #include<stdio.h>
2 #include<math.h>
3
4 // gcc ex3.c -lm
5
6 int main(){
7 int i;
8 float x1 = 0.0;
9 double x2 = 0.0;
10
11 for(i=1; i<20000000; i+=1000000){
12 x1 = 1.0/i;
13 printf("%20.18lf %20.18lf %20.18lf\n", x1,
14 ((float)sqrt(1+x1)) -1, x1 / (((float)sqrt(1+x1)) +1));
15 }
16
17 printf("--------------------------------------------------------------\n");
18
19 for(i=1; i<20000000; i+=1000000){
20 x2 = 1.0/i;
21 printf("%20.18lf %20.18lf %20.18lf\n",
x2, sqrt(1+x2) -1, x2 / (sqrt(1+x2) + 1));
22 }
23 }

このプログラムを実行すると x1 の方の ((float)sqrt(1+x1)) -1 の値が途中から0になるのはどうして?
350デフォルトの名無しさん:2009/06/18(木) 17:50:33
>>349
(float)1.0000001192 == 1.0
だからじゃないか?
351デフォルトの名無しさん:2009/06/18(木) 17:52:42
x1が0になっちゃうからじゃないか?
352デフォルトの名無しさん:2009/06/18(木) 18:13:07
無限大はすぐそこにあるってことですね
353デフォルトの名無しさん:2009/06/18(木) 19:43:11
再帰は漸化式が似合う。
n!=n*(n-1)!

int fact(int n) {
if(n==0) return 1;
else return n*fact(n-1);
}
354デフォルトの名無しさん:2009/06/18(木) 19:49:56
<=が保証されんのなら、forは結局intだね。
float なんかの、良例あるかな
355デフォルトの名無しさん:2009/06/18(木) 19:58:08
ループにループカウンタは必ずしも必須ではないし、カウンタがintである必要もないよと
さんざん言われているのに、forは結局intだね(キリッ といわれても困る
356デフォルトの名無しさん:2009/06/18(木) 20:03:16
>>354
ループ条件にポインタを使うことはあるね。
C++だと、イテレータとかも出てくる。
357デフォルトの名無しさん:2009/06/18(木) 20:07:51
>>354
無限ループの為の空っぽ指定

while (1) や while (true) とかと違ってマジックナンバー使わないし
lint なんかで警告されないし
358デフォルトの名無しさん:2009/06/18(木) 20:08:06
>>354
・されるのなら
・されないのなら
どっち?
されないと思ったから結局intにつながるのか、
されると思ったからfloatの良例を求めているのか
359デフォルトの名無しさん:2009/06/18(木) 20:08:47
>>357
その1は全然魔法じゃない
360デフォルトの名無しさん:2009/06/18(木) 20:11:42
>>359
まあね
非ゼロなら何でも良いけど代表で1が居るのが気持ち悪い ってのは教条主義すぎか…
361デフォルトの名無しさん:2009/06/18(木) 20:46:07
for(;;)
while(1)
while(!0)
while(0==0)
362デフォルトの名無しさん:2009/06/18(木) 21:06:36
enum {forever = 1};

while(forever) {
  programing();
  sleep(hour(3));
}
363デフォルトの名無しさん:2009/06/18(木) 21:09:28
>>362
foreverの値を1にするのが気持ち悪いそうです
364デフォルトの名無しさん:2009/06/18(木) 21:11:24
LOOP:
  programing();
  sleep(hour(3));
goto LOOP;

365デフォルトの名無しさん:2009/06/18(木) 21:25:06
>>338
たとえば代数式の評価など
366デフォルトの名無しさん:2009/06/18(木) 21:37:36
>>338
すべてのアルゴリズムは、再帰がなくても書くことができる。
367デフォルトの名無しさん:2009/06/18(木) 21:40:38
>>354
「<」を使えばいい。
for (double x = 0.0; x < 1.1; x += 0.1)
こういうふうに、値の範囲が分かった上で使うのはいいのだ。
入力された初期値や増分でやるのは、あまりよろしくない。
368デフォルトの名無しさん:2009/06/18(木) 21:46:06
>>366
そのかわり余分な空間計算量が必要になりませんか。2分木を非再帰でかくのは結構パワーが必要ですよ。
369デフォルトの名無しさん:2009/06/18(木) 21:49:53
まあ必要か必要じゃないかって話だから。
再帰のほうが分かりやすければ再帰を使えばいい。
370デフォルトの名無しさん:2009/06/18(木) 21:57:38
再帰って何回くらい保障されてるの?
371デフォルトの名無しさん:2009/06/18(木) 21:59:09
確かANSIで規定されてるのは13回くらいだったはず。
しかし実際には10000回くらいやってもぜんぜん平気。
372デフォルトの名無しさん:2009/06/18(木) 21:59:11
スタックの空き/再帰関数で使う量
373デフォルトの名無しさん:2009/06/18(木) 22:09:34
用語の質問です。

質問@「関数の引数に空の配列を入れて、関数の中でそこに値を代入すると、帰って来た配列も書き換えられている」
事をポインタと言うそうですが、単にポインタを使うと言うとアドレスの場所を指すポインタと勘違いされてしまいました。
実際「*」等も使用していませんし、この用語の使い方はあっているのでしょうか?

質問A#include<stdio.h>をヘッダファイルと言い、画像などのフォーマットもヘッダーファイルと言う名前が使われています。
これは同じ物を指しているのでしょうか。


両方とも名前が同じなので口頭で伝える際に上手く伝えられません。
まだ習ったばかりなので、細かい用語に勘違いがあったら申し訳ありません。
よければその勘違いも含めて答えて下さったら嬉しいです。よろしくお願い致します。
374デフォルトの名無しさん:2009/06/18(木) 22:11:58
>>373
「配列を渡して書き換える」ことをポインタとは言わんよ。
375デフォルトの名無しさん:2009/06/18(木) 22:16:52
>>373
両方とも間違ってるな。

修正は他の人だれかやってあげてくれ。
376デフォルトの名無しさん:2009/06/18(木) 22:18:34
>>373
引数に空の配列を
func(char a[])
このことだと思うけど
func(char *a)
と同じだよ。

画像などのフォーマットにはヘッダー部が含まれているだけじゃないかな。
それを定義したヘッダーファイルを見たのかもしれないけど。
377デフォルトの名無しさん:2009/06/18(木) 22:18:48
画像ファイルは、ファイルの先頭あたりに入ってる情報をヘッダーと言うことは
あるだろうけど、ヘッダーファイルと言うことはなさそう。
378デフォルトの名無しさん:2009/06/18(木) 22:22:02
>>373
質問2 ヘッダーという意味では先頭に付加されてますが「先頭に付加される物」という言葉が同じだけと思ったほうがいいでしょう。
C言語などでincludeするヘッダーはご存知のように構造体の定義などが別ファイルとして記述できたりします。

特定のファイルフォーマットで使われるヘッダーというのはファイルのサイズや構造を明記したエリアのことをいいます。
379デフォルトの名無しさん:2009/06/18(木) 22:27:09
char *shirokoro
shirokoro="horumon"

とやるとどんな文字の長さでもshirokoroの中にはいるんですか?
これは動的にちょうどいいメモリの量を確保してくれるんでしょうか?
380デフォルトの名無しさん:2009/06/18(木) 22:29:13
>>379
文字列の先頭のアドレスが変数にはいるだけ。
文字列は最初から、どこかに確保されている。
381デフォルトの名無しさん:2009/06/18(木) 22:31:20
>>373
ちゃんと授業聞いていたのかという疑問もあるなあ。
@Cでは関数の引数に配列を渡すと、実際にはポインタ(先頭アドレス)が渡される。
AC→「ヘッダファイル」と画像→「ファイルヘッダ」が混乱していると思われる。
「header」を英和辞典で引いて、その英単語の意味を理解せよ。
382デフォルトの名無しさん:2009/06/18(木) 22:42:09
>>379
"horumon"は文字列リテラルの先頭アドレスを返している。
それをchar*型のshirokoroで受け取っているだけ。

"horumon"自体はコンパイル時に定まっているためプログラム起動時に勝手に確保される。

意味分かる?
383デフォルトの名無しさん:2009/06/18(木) 23:16:52
@
「引数として配列を渡す実際にはポインタ(先頭アドレス)が入る。」
こういう意味だったのですね。

A
#include<stdio.h> はヘッダー「ファイル」である
画像などのヘッダー はヘッダー情報が格納された「エリア」である
前者はヘッダファイル、後者はファイルヘッダ


なるほど、わかりました!
レスありがとうございます。大変参考になりました!

本当は習ったというより独学で教科書を先読みしている段階です・・・
矢張り自分の認識の甘さを痛感しました。もう少し勉強しようと思います。
ありがとうございました!
384デフォルトの名無しさん:2009/06/18(木) 23:40:24
>>383
あたまいいな。
今後もがんばれ。応援してる
385デフォルトの名無しさん:2009/06/19(金) 00:04:27
>>368
超亀レスだが、最近と言うか数時間前に2分木を非再帰で書いた。
3日くらい前から、紙とペンで唸りながらようやく形になった。
単純なことなら再帰の方が速くできるが、通りがけ順でfor()+イテレータ(構造体に一工夫したモノ)のように各節を扱うことはできない。
非再帰(非スタック利用)で書くことで、これができるようになった。

再帰はとても便利だとは思っている。
クイックソートにしろツリーにしろ同じ処理、同じ構造に適用するにはとても優れている考え方。
実際のプログラミングで再帰を使ったのは、ポップアップメニューを動的に作る関数だったな、ああ、なつかしい。
386デフォルトの名無しさん:2009/06/19(金) 00:08:56
あのですねprintf関数とかscanf関数とかもC言語で作られた関数でそれを#include<stdio.h>で読み込んでるだけだと聞きましたが
例えばprintf関数がどういうコードかとか読むことってできるんでしょうか
特にsqrt関数とかどういうふうにやってんのか気になります
387デフォルトの名無しさん:2009/06/19(金) 00:10:43
読めるよ
388デフォルトの名無しさん:2009/06/19(金) 00:11:20
確かに質問の形態はイエスかノーかを聞いてるように思えるでしょうが実際はその方法を聞いているということをご理解いただきたい
389デフォルトの名無しさん:2009/06/19(金) 00:13:00
>>386
gccのソースコードでも眺めるといいよ
390デフォルトの名無しさん:2009/06/19(金) 00:16:43
>>388
読めるってわかったらとりあえず調べないか?
やり方を聞くまで動けない人間なんて要らないよ
391デフォルトの名無しさん:2009/06/19(金) 00:17:36
sqrt関数はコールバックを使ってる
392デフォルトの名無しさん:2009/06/19(金) 00:22:14
>>388
VC++も、ライブラリのソースがついてくるよ。
393デフォルトの名無しさん:2009/06/19(金) 00:23:57
stdio.hに書いてあるのは、printfのプロトタイプ宣言だけ。
コードは、コンパイルして機械語になって、ライブラリに入ってる。
ランタイムライブラリのソースコードをインストールすれば読める。
394デフォルトの名無しさん:2009/06/19(金) 00:31:56
395デフォルトの名無しさん:2009/06/19(金) 00:40:03
vfprintf()ならマジうけると思ったら、マジだった
ですよねぇ、普通そうですよねぇ
396デフォルトの名無しさん:2009/06/19(金) 01:16:47
>>386
sqrtなんかは、FPUの平方根求める命令使って求めてることが多いんじゃない?
397デフォルトの名無しさん:2009/06/19(金) 10:02:51
>>392
math 系はソース無しだよね
398デフォルトの名無しさん:2009/06/19(金) 10:23:01
>>386
>#include<stdio.h>で読み込んでるだけだと聞きましたが
いいえ。stdio.h にあるのは宣言だけです。
コンパイルされた現物はライブラリにあり、そのソースは
あったりなかったりです。
399デフォルトの名無しさん:2009/06/19(金) 13:15:10
FPU関係はアセンブラだろう
400デフォルトの名無しさん:2009/06/19(金) 15:14:54
ふつうにニュートン法でかいてた
401デフォルトの名無しさん:2009/06/19(金) 15:29:58
malloc とかは明らかにアセンブラですよね?って思ったら
K&R第2版に、mallocの生の版が出てきてちょっと驚いた。
システムコールを使うからUNIX限定だけど
環境依存のコードをどうやって関数内に閉じ込めるかについて
とても勉強になった。
402デフォルトの名無しさん:2009/06/19(金) 18:39:27
>>malloc とかは明らかにアセンブラですよね?
それは無い。明らかに無い
403デフォルトの名無しさん:2009/06/19(金) 19:31:03
取りあえず猫は勉強したんだが、レベルアップするためには次何やればいい?
404デフォルトの名無しさん:2009/06/19(金) 19:33:30
>>403
毎日腹筋100回
405デフォルトの名無しさん:2009/06/19(金) 19:52:08
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#define STDIN 0
#define STDOUT 1
#define STDERR 2
int main ( void )
{
char prompt [64] = "-> ";
char command [256];
int st;
int out; /* 出力ファイル用ファイル記述子 */
fprintf(stderr, "%s", prompt);
/* ファイルをオープン */
out = open ("outfile", O_CREAT | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR);
/* リダイレクション処理
* 標準出力 -> ファイル
*/
dup2(out, STDOUT);
while (gets(command) != NULL) {
if (fork () == 0) {
if (execl(command, command, (char *) 0) == (-1))
exit(1);}
else {
wait (&st);
fprintf(stderr, "%s", prompt);}}}
シェルを実現するプログラム。入力したコマンドの実行結果をoutfileに出力したいが、うまく行かない
どこを訂正すればいいか教えて下さい。
406デフォルトの名無しさん:2009/06/19(金) 21:38:40
関数f(x) = ((2*x*x*+25)/(1+x*x)の式のxに
aとbを代入したf(a),f(b)をS = (f(a) +f(b))/2 っていう形にして
Sを使いたいんですけど、どうしたらいいか教えてください。
407デフォルトの名無しさん:2009/06/19(金) 21:41:33
日本語でおk
408デフォルトの名無しさん:2009/06/19(金) 21:42:53
お願いします!!
409デフォルトの名無しさん:2009/06/19(金) 21:46:18
関数 f(x)を作って、S = (f(a) +f(b))/2って書けば普通に動くぞ。
例えばこうだ。

int f( int x ){ return x; }
int main() {
 int s = ( f( 10 ) + f( 6 ) ) / 2;
}

これで晴れて s は 8 だ。
410デフォルトの名無しさん:2009/06/19(金) 22:11:07
わ〜お!
感動です!!
本当にありがとうございます。

最近Cをはじめたばかりなのでやりたいことはいっぱいあるんですけど、
今みたいに思ったことがなかなかできないんですよね(笑)
411デフォルトの名無しさん:2009/06/19(金) 22:23:58
続けざまですいません・・・
((2*x*x*+25)/(1+x*x)の部分はどこにいれればいいんですか?
412デフォルトの名無しさん:2009/06/19(金) 22:46:53
>>411
関数fじゃないの
413デフォルトの名無しさん:2009/06/19(金) 23:52:19
int f(int x)
{
  return (2 * x * x + 25) / (1 + x * x);
}
414デフォルトの名無しさん:2009/06/20(土) 00:07:10
double f(double x) { double x2 = x*x; return (2*x2 + 25)/(1 + x2); }
f : R -> R, ∀x e R∃y e R[y = (2*x*x + 25)/(1 + x*x)]
415デフォルトの名無しさん:2009/06/20(土) 00:28:32
405も頼む
416デフォルトの名無しさん:2009/06/20(土) 05:05:34
ここに、役に立つ話は何も無い...侵入生の雑談だろ?
お遊戯とか、お歌とか...しばらく遊んでろ。
417デフォルトの名無しさん:2009/06/20(土) 08:57:47
>>415
どううまくいかないのか分からないが fflush
418デフォルトの名無しさん:2009/06/20(土) 09:42:34
初歩的な質問でごめんなさい。ポインタの中身の数値同士を足した数が必要なときはどうすればよいですか?
例えば、
st1->a=12 ,st2->b=13のときその中身同士を足した数を変数に代入して関数の引数に使おうと思ったのですが・・・
当たり前ですが
int wa=st1->a+st2->bとしてもだめですし・・・誰か教えて下さい。











419デフォルトの名無しさん:2009/06/20(土) 09:45:24
>>418
それがダメなら分からんね
ポインタの指してる先がおかしいんじゃね?
420デフォルトの名無しさん:2009/06/20(土) 09:47:21
int wa = st1->a + st2->b でいいのでは
421デフォルトの名無しさん:2009/06/20(土) 09:49:08
st1->a
st2->b

まず確認したいんだけどこの二つ型は?

422デフォルトの名無しさん:2009/06/20(土) 09:53:01
>>418
> int wa=st1->a+st2->bとしてもだめ
どう「だめ」なのかちゃんと日本語で説明してくれないと教えようが無い。
423デフォルトの名無しさん:2009/06/20(土) 09:53:47
型で警告でてるとかそんなんじゃないの?
424デフォルトの名無しさん:2009/06/20(土) 10:03:12
*pってやるとpの指してるものの中身を得られるよ
425デフォルトの名無しさん:2009/06/20(土) 14:00:49
>>418
それはポインタの中身じゃなくて構造体のメンバのようだけど
426デフォルトの名無しさん:2009/06/20(土) 14:07:21
なんてハイレベルなんだ!
エスパー的に
427デフォルトの名無しさん:2009/06/20(土) 14:08:31
>>426
いやすでに上で型は何?ってでてる。
構造体もいわゆる型だ
428デフォルトの名無しさん:2009/06/20(土) 14:10:15
質問

char str[80] = "これはファイルシステムのテストです\n";
FILE *fp;
char *p;
p = str;
while (*p) {
if (fputc(*p, fp) == EOF) {
printf("ファイル書き込みエラー\n");
exit(1);
}

本ではこうなってたんだけど、これってなんでpをインクリメントしなくてもいいの?
429デフォルトの名無しさん:2009/06/20(土) 14:15:31
>>428
さあ
430デフォルトの名無しさん:2009/06/20(土) 14:18:07
>>428
関数の仕様を調べる癖をつけたほうがいい
http://www9.plala.or.jp/sgwr-t/lib/fputc.html
ファイルfpへ1文字を、intからunsigned charに変換して書き出し、ファイル位置指示子を進めます。
431デフォルトの名無しさん:2009/06/20(土) 14:18:33
>>429
本に乗ってるソースコードが間違ってるのはよくあること。
432デフォルトの名無しさん:2009/06/20(土) 14:21:13
>>428
それちゃんとソース全部書いてる?
}が一つ足らないだろ
433デフォルトの名無しさん:2009/06/20(土) 14:22:35
次のページに
++p;
}
って書いてあったりして。
434デフォルトの名無しさん:2009/06/20(土) 14:44:24
fpも初期化してないし、ファイルシステム関係ないし
435デフォルトの名無しさん:2009/06/20(土) 14:46:07
>>428
その本の名前教えて
436デフォルトの名無しさん:2009/06/20(土) 14:46:36
>>422
segmentation faultになってしまいます。
437デフォルトの名無しさん:2009/06/20(土) 14:48:35
>>436
だから型を教えてくれと
構造体なのか、単なるint型なのかchar型なのか
構造体ならその中が何かと・・・
438デフォルトの名無しさん:2009/06/20(土) 14:57:15
構造体です。実際はipの構造体で、たしか

unsigned int ip_len
unsigned int ip_hdl
と宣言されていてip_lenとip_hdlの差が必要なのでその差を計算したいのですが…
セグメってしまいます。
439デフォルトの名無しさん:2009/06/20(土) 14:58:13
>>438
ptr->a.ip_len
とかしないとできないよ
440デフォルトの名無しさん:2009/06/20(土) 15:06:39
下記の表現の違いを述べよ.
char aa[]=”abc”;  …@
char bb[10]={‘a’,’b’,’c’,’\0’}; …A
char *cc = aa; …B
441デフォルトの名無しさん:2009/06/20(土) 15:11:28
@は4個のchar型の配列。Aは10個のchar型を持つ配列。Bはポインタ。
442デフォルトの名無しさん:2009/06/20(土) 15:43:48
Cコンパイラにエラーを吐かれると、自分が間違ってるんじゃないかと
気が滅入るものだがCコンパイラははっきし言ってある種の馬鹿なので
気にしないほうがいいw
C/C++は古参のプログラミング言語で、プログラミング言語理論の
発達の前に既にあったもの。その後の理論から見て修正したほうがいい
文法とか表現法とか多数あるんだが(どれとかいちいち指摘はしないが)
今更直せないというものが多い。
C/C++が絶対正しく自分が間違いなんだとは思い込まないことが肝要
質問する以前の問題としてこのことを踏まえるべき。

以上、適当に修正してテンプレに入れておくことを推奨
443デフォルトの名無しさん:2009/06/20(土) 15:50:55
>>442
断る
444デフォルトの名無しさん:2009/06/20(土) 15:57:59
>>442
分かった。
以下の様に修正して入れようか?

Cコンパイラにエラーを吐かれても、自分が間違ってないと
思う輩ははっきし言ってある種の馬鹿なので気にしないほうがいいw
C/C++は古参のプログラミング言語で、仕様書にあるとおりに書けないヤツを
駆逐する能力がある。
C/C++の仕様書が正しく自分が間違いなんだと心にたたき込むべし。
「プログラムはあなたの思うようには動かないが あなたの書いたようには動く」
質問する以前の問題としてこのことを踏まえるべき。
445デフォルトの名無しさん:2009/06/20(土) 16:00:59
>>444
良しとしよう。賛成の者、起立!
446デフォルトの名無しさん:2009/06/20(土) 16:02:08
ガタンッ
447デフォルトの名無しさん:2009/06/20(土) 16:06:35
パチ パチ パチ 。
448デフォルトの名無しさん:2009/06/20(土) 16:08:28
よって賛成多数と認め、次のスレで >>444 を反映するものとする。
449444:2009/06/20(土) 16:10:35
単に冗談だったのだが
今更そんなこと言えない空気になってしまった。
450デフォルトの名無しさん:2009/06/20(土) 16:11:46
適当に乗って遊んでるだけだからw
451デフォルトの名無しさん:2009/06/20(土) 16:26:26
規格からはみ出してもなんとなく動くからやっかいなんだよな
452デフォルトの名無しさん:2009/06/20(土) 16:32:50
>>451
そうそう。分かるわ。
453デフォルトの名無しさん:2009/06/20(土) 16:36:37
>>451
なんとなく動いてるということが 後から判明した時には…
454デフォルトの名無しさん:2009/06/20(土) 16:39:46
#include <stdio.h>
#include <assert.h>

struct ST {
int a;
int b;
};

int main( void ) {

struct ST st = { 12, 13 };
struct ST *st1 = &st;
struct ST *st2 = &st;

int wa = st1->a + st2->b;

assert( st1->a == 12 );
assert( st1->b == 13 );
assert( wa = 12 + 13 );
}

ちょー問題なく動く。
455デフォルトの名無しさん:2009/06/20(土) 16:41:01
はっ。19行目にエラーが。w
assert( wa == 12 + 13 );
456デフォルトの名無しさん:2009/06/20(土) 16:41:38
>>454
そういうのはやめてくれ
457デフォルトの名無しさん:2009/06/20(土) 16:43:51
何ゆえ?
458デフォルトの名無しさん:2009/06/20(土) 16:45:33
ポインタの使い方もわからない人に余計なこと教えるなってことだろw
459デフォルトの名無しさん:2009/06/20(土) 16:54:17
それは>>418の質問には答えるなって意味?
460デフォルトの名無しさん:2009/06/20(土) 16:55:25
いえす
461デフォルトの名無しさん:2009/06/20(土) 16:55:41
assertだよw

何がよくないか聞きだしたりして、ちゃんとわかる人を作らないと
社会に出てこられても大変なだけだw
462456:2009/06/20(土) 16:57:14
一見問題ないけど
実は >>455 みたいなの
463デフォルトの名無しさん:2009/06/20(土) 17:00:17
assertの何が悪いんだ
464デフォルトの名無しさん:2009/06/20(土) 17:01:26
#include <stdio.h>

struct ST {
int a;
int b;
};

int main( void ) {

struct ST st = { 12, 13 };
struct ST *st1 = &st;
struct ST *st2 = &st;

int wa = st1->a + st2->b;
}

assertなしのこれならOKってことね。
465デフォルトの名無しさん:2009/06/20(土) 17:01:43
>>463
基礎がわかってないのに応用とかもっと後のこと教えてどうすると
466デフォルトの名無しさん:2009/06/20(土) 17:02:29
>>464
お前わざとだろ
467デフォルトの名無しさん:2009/06/20(土) 17:04:05
>何がよくないか聞きだしたりして、ちゃんとわかる人を作らないと

なるほど。これは自分には無理そうです。
ほかの人、がんばって答えてあげてください。
468デフォルトの名無しさん:2009/06/20(土) 17:05:03
>>465
応…用……?
469デフォルトの名無しさん:2009/06/20(土) 17:05:35
でも、assert以外でちゃんとプログラムが動いていることを
確認する有効な方法って何?

もちろん、強力なIDEが値やアドレス監視機能を提供してくれるのがベストだけど。

まさか、printf で値を表示したりしないよね?
470デフォルトの名無しさん:2009/06/20(土) 17:06:14
>>418>>428 もオレには質問の内容が理解できない
471デフォルトの名無しさん:2009/06/20(土) 17:06:51
C言語でデザインパターン実装するにはどうすればいいの?
472デフォルトの名無しさん:2009/06/20(土) 17:07:30
>>470
そうそう
で質問の仕方もわかってないし、ソースも断片しか貼ってない(片方は閉じてさえいない)
初心者もいいところじゃん

assertなんてまだ先の先
473デフォルトの名無しさん:2009/06/20(土) 17:13:22
#inclede <stdio.h>
main(){
int a;
int b;
int n;
int i;

for(i=0;i<n;i++)
{
if(a==i)
{
a=a+b;
printf("%d\n",a);
}
else
{
a=a-b;
for(j=0;j<n+j++)
{
a=f(a);
}
}
}
474デフォルトの名無しさん:2009/06/20(土) 17:24:43
>>473
何が言いたいの?
475デフォルトの名無しさん:2009/06/20(土) 17:33:56
476デフォルトの名無しさん:2009/06/20(土) 17:45:37
質問の仕方が悪かったのでもう一度。
#include <stdio.h>
#include <stdlib.h>
#include <string.h> /* strcpy */
#include <netinet/in.h> /* ntoh hton */
#include <arpa/inet.h> /* sockaddr_in */
#include <net/ethernet.h> /* ether_header ETH_P_ALL */
#include <sys/socket.h> /* socket */
#include <netinet/ip.h>
#include </usr/include/netinet/udp.h>
#include </usr/include/netinet/tcp.h>
#include </usr/include/netinet/if_ether.h>
/** mac address "network to ascii" */


union {
unsigned int x;
unsigned char y[4];
} A;
477デフォルトの名無しさん:2009/06/20(土) 17:46:20
続き1

struct st1{
unsigned char a;
};
struct st2{
unsigned char a;
unsigned char b;
};


struct st4{
unsigned char a:1;
unsigned char b:1;
unsigned char c:1;
unsigned char d:1;
unsigned char e:1;
unsigned char f:1;
unsigned char g:1;
unsigned char h:1;
};

struct ipfrag{
unsigned char ip_fra1:1;
unsigned char ip_fra2:1;
unsigned char ip_fra3:1;
unsigned int ip_off:13;
};
478デフォルトの名無しさん:2009/06/20(土) 17:46:25
>>476
最初の質問の番号を名前欄に書いたほうがいいなw
479デフォルトの名無しさん:2009/06/20(土) 17:47:32
267 :('A`):2008/09/18(木) 21:51:43 0
部屋に湧いたゴキブリをガチャポンのカプセルに閉じ込めて
何匹も飼っている俺が断言する

ゴキブリが軟便を出すようになったら、死が近い証拠


268 :('A`):2008/09/18(木) 22:00:31 0
http://p.pic.to/zkvzp

現時点での長老

288 :286:2008/09/18(木) 23:05:57 0
ごめんコマンドーに釘付けだった
ちなみにゴキブリ共は走ってる所を
上からカプセルをかぶせるようにして捕まえた

http://c.pic.to/s8rjj
先代長老(故)
画質悪くてすまんね

376 :('A`):2008/09/24(水) 03:03:51 O
長老がなかなか死なん
なんかウンコ喰って生き延びてるぽい


414 :('A`):2008/09/27(土) 22:05:45 O

http://m.pic.to/xon6l
10匹目捕獲成功
480418です:2009/06/20(土) 17:48:25
続き2
char *mac_ntoa(unsigned char *d){
static char str[18];
sprintf(str,"%2x:%2x:%2x:%2x:%2x:%2x",d[0],d[1],d[2],d[3],d[4],d[5]);
return str;
}
void print_arp(struct ether_arp *arp){

printf("hardware address format %u\n",ntohs(arp->arp_hrd));
printf("protocol address format %u\n",ntohs(arp->arp_pro));
printf("hardware length %u\n",arp->arp_hln);
printf("protocol length %u\n",arp->arp_pln);
printf("operation %u\n",ntohs(arp->arp_op));


}
481418です:2009/06/20(土) 17:49:27
続き3
int main(int argc, char *argv[]){
int rsock,rsin_size;
struct sockaddr_in rsin;
struct ether_header *eth;
struct ip *ip;
struct tcphdr *tcp;
struct udphdr *udp;
struct ether_arp *arp;
char p0[1518], *p;
unsigned int data_length=ip->ip_len-ip->ip_hl;
482418です:2009/06/20(土) 17:50:27
続き4
if ((rsock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) < 0 ){
perror("socket");
return(0);
}
rsin_size = sizeof(rsin);
while(1){
if(recvfrom(rsock, &p0, sizeof(p0), 0,
(struct sockaddr *)&rsin, &rsin_size) < 0 ) {
perror("recvfrom");
}
p = (char *)p0;
eth = (struct ether_header *)p;
print_ether(eth);
if(ntohs(eth->ether_type) == ETHERTYPE_IP){

p=p0+sizeof(struct ether_header); //ehternetのヘッダが終わった先.同様にUDPのヘッダ分ずらす。
ip=(struct ip *)p;
print_ip(ip);

if (ip->ip_p==17){
p=p0+sizeof(struct ether_header)+sizeof(struct ip);
udp=(struct udphdr *)p;
print_udp(udp);
p=p+sizeof(struct udphdr);
print_data(p,15);

}
483418です:2009/06/20(土) 17:51:51
続き5
if(ip->ip_p==6){
p=p0+sizeof(struct ether_header)+sizeof(struct ip);
tcp=(struct tcphdr *)p;
print_tcp(tcp);

}

}
else if(ntohs(eth->ether_type) ==ETHERTYPE_ARP){
arp=(struct ether_arp *)p;
}
}
}
これでdata_lengthがセグめっちゃいます。
484418です:2009/06/20(土) 17:53:12
>>関数をいくつか省略しました。
485デフォルトの名無しさん:2009/06/20(土) 17:54:00
>>483
そこまで大きいのはtxtにしてロダ経由の方が・・
486デフォルトの名無しさん:2009/06/20(土) 17:57:38
codepad
ttp://codepad.org/
ここに貼れ。

つーかこれ
スレの点プレに入れないか?
余りに長いならcodepadに貼れ、と。
487デフォルトの名無しさん:2009/06/20(土) 17:58:16
なんでこのレベルのプログラム書いている人が
「ポインタの中身の数値同士を足した数」の得かたもわからないのん?^^

っていうか、肝心の struct ip がどんな構造体なのかどこにも書いてねーでやんの。
sturct ip *ip は初期化されてねーし。

わかるかボケ。w
488デフォルトの名無しさん:2009/06/20(土) 17:58:58
struct ip *ip;

このポインタは ipという構造体型のポインタ

unsigned int data_length=ip->ip_len-ip->ip_hl;

この行の前にipにstruct ipの実体を入れてない
489デフォルトの名無しさん:2009/06/20(土) 18:01:25
プ板はボケツッコミの様式美を確立してないのが弱いところだと思うね
490418です:2009/06/20(土) 18:04:41
>>488
ほんとだすみません。
struct ip{
unsigned int ip_hl:4;
unsigned int ip_v:4;
u_int8_t ip_tos;
u_short ip_len;
u_short ip_od;
u_short ip_off;
u_int8_t ip_ttl;
u_int8_t ip_p;
u_short ip_sum;
struct in_addr ip_src,ip_dst;
}


491デフォルトの名無しさん:2009/06/20(土) 18:05:02
標準のライブラリってあらかじめインクルードガードされてるの?
492デフォルトの名無しさん:2009/06/20(土) 18:07:47
>>490
それもないとわからないけど俺が言いたいのは

ip = malloc(sizeof(ip));

とかして実体を作る必要もあるし

長さを計算するってことはそもそも今回作ってるアプリで実態を用意しないで
どこかからもらってきた領域がその構造体ってことだよね。
その辺の関数は省略してるのかな?
493デフォルトの名無しさん:2009/06/20(土) 18:09:39
まあ業務に関するとあれなんでかけない関数は名称を

hoge();
とかしておけばいいよ

struct ip *ip;

ip = hoge(); //ipに入れるstruct ipサイズの領域のアドレスが渡される?

で今回の計算でいいのかな?
494デフォルトの名無しさん:2009/06/20(土) 18:12:18
>>491
Solaris だと、たぶん全部されてると思う。
495デフォルトの名無しさん:2009/06/20(土) 18:12:55
>>487
コピペだけでやりくりしてる文型プログラマなんだろう
こういうやつが後の悪夢を生むんだなー
496418です:2009/06/20(土) 18:14:10
実際はパケットをうけとるものなのでipは実行してほっとけば入ってきます。
それで問題の
unsigned int data_length=ip->ip_len-ip->ip_hl;
がなぜだめなのかがわかりません。

497デフォルトの名無しさん:2009/06/20(土) 18:14:51
>>494
Solarisでは、ということは基本的に保障は無いわけですね。thx
498デフォルトの名無しさん:2009/06/20(土) 18:15:03
>>495
まあここで散々言われてるがへこまずどう聞けば的確な答えがもらえるかとか
を学んで欲しいわ。

そうでないとこういうソースを後で見る側が死ぬww
499デフォルトの名無しさん:2009/06/20(土) 18:16:41
unsigned int data_length=(unsigned int)ip->ip_len-ip->ip_hl;
500デフォルトの名無しさん:2009/06/20(土) 18:20:37
>>491
C標準のライブラリなら何度includeしても問題は発生しないことになってる。
501デフォルトの名無しさん:2009/06/20(土) 18:35:55
>>499
セグメ(´・ω・`)
502デフォルトの名無しさん:2009/06/20(土) 18:38:45
>>496
ダメじゃないよ
503デフォルトの名無しさん:2009/06/20(土) 18:39:22
>>488の指摘にあるように

struct ip *ip;
を宣言してから

unsigned int data_length=ip->ip_len-ip->ip_hl;
を計算するまでの間にipには何か入れる関数を呼んでるんだよね?
504デフォルトの名無しさん:2009/06/20(土) 18:45:48
っていうか、もう答えでてるじゃん。
Segmentation Faultじゃろ?不正なメモリへのアクセス。
どう考えても ip の値がおかしい。
「ipは実行してほっとけば入ってきます」ってあるんだから
そのほっといて入ってくる処理のほうがおかしくなってる。

ほっとくと入ってくる処理を書いたやつのケツに
いますぐちんぽ突っ込んでデバッグしろって言って来い。

505デフォルトの名無しさん:2009/06/20(土) 18:49:01
ちなみに、たいがいのプログラマはバグを指摘されると
「はぁ、ふざけんな。てめぇの方のバグだろ?」
と逆ギレするので(特に理系プログラマに多い)、

バグを指摘するときはなるべく強硬な姿勢で、
有無を言わせず、怒りをあらかじめあらわにした上で
上から目線で、力強く、がなりたてるようにいうことが肝要。

これ間違えると逆襲されるから注意ね。
506デフォルトの名無しさん:2009/06/20(土) 18:50:26
>>503
いえ、このままです。実際に送られてくるパケットを解析するので。
507デフォルトの名無しさん:2009/06/20(土) 18:50:44
>>438
unsigned int ip_len
unsigned int ip_hdl
となってるが

>>490
は片方がshortになってねーか?

実行マシンはx86じゃなければ境界踏んでねえかな?

ipに何か入れるとか言ってる関数ってすでにプリコンパイル済みで
ip構造体の中身が変わってるのにリコンパイルしてないとかそんなことやらかしてねえ?
508デフォルトの名無しさん:2009/06/20(土) 18:51:41
それはプログラマではなくただのコーダ―
509デフォルトの名無しさん:2009/06/20(土) 18:51:54
>>506
それじゃあ受け取ってないってw
int main(int argc, char *argv[])
これに渡されるのか?
510デフォルトの名無しさん:2009/06/20(土) 18:54:51
>>508
愛のコーダ(大島渚)、怒りのプログラマ
511デフォルトの名無しさん:2009/06/20(土) 18:55:06
とりあえず、ソースをアップロードしろ。

多くの人が指摘しているとおり、ipに有効な値が入っていない。
(C90までの)C言語では、宣言とコードを混ぜることができない。
struct ip *ip;
unsigned int data_length = ip->ip_len - ip->ip_hl;
までに、ipに値を代入することはできないのだよ。
わかるか、規格書を読んでから出直してきてください。ありがとうございました。
512デフォルトの名無しさん:2009/06/20(土) 18:57:59
んー。

>(C90までの)C言語では、

原因はこれ、かな。w
data_lengthをip=(struct ip *)p;のすぐ後ろあたりに書き込んだものの
中途宣言のエラーが出たから先頭に移動したら…

っていうか、釣りだよね、これ?^^;;;

513デフォルトの名無しさん:2009/06/20(土) 19:03:47
>>504
その事を意識して見直したら解決しました(´・ω・`)ほんとみなさんすいません。
514デフォルトの名無しさん:2009/06/20(土) 19:07:57
>>511 自己レス
間違えました。
>(C90までの)C言語では、宣言とコードを混ぜることができない。
これは、正しかったが、
>ipに値を代入することはできないのだよ。
これは、間違っている。極めて特殊な方法で代入できる。混乱させてすみません。
515デフォルトの名無しさん:2009/06/20(土) 19:10:41
>>507の指摘したサイズの違いは大丈夫なのか?とどう解決したのか知りたいわww
516デフォルトの名無しさん:2009/06/20(土) 19:43:24
一言で言えば、バグで上司にしかられてもちんこはびんびんなわけです。
517デフォルトの名無しさん:2009/06/20(土) 19:50:50
data_length=ip->ip_len-ip->ip_hl*4;
?
518デフォルトの名無しさん:2009/06/20(土) 19:56:15
static char str[18+1];
?
519デフォルトの名無しさん:2009/06/21(日) 01:40:54
バイナリファイルの取扱いで質問です
バイナリファイルは基本的に16進数ですよね
だから16進数のまま扱いたいのですがどうすればいいでしょうか

どういうことかっていうと、たとえばバイナリファイルの「f」の部分のみを抽出して「0」に置き換えるとします
そうするとC言語の普通の文法だと10進法で処理されるからうまくいきません
たとえばa[10000]っていう配列に順番にバイナリファイルを読み込むと10進法で記録されちゃいますよね
そうじゃなくて配列の1番目から順番に、0〜fの16進法の数値を入れたいんです
どうすればいいでしょうか
520デフォルトの名無しさん:2009/06/21(日) 01:45:40
まず、C言語は10進法では有りません、どちらかと言うと16進法
char a[10000]っていう配列に順番にバイナリファイルを読み込むと160進法
で記録されます
521デフォルトの名無しさん:2009/06/21(日) 01:46:55
×160
○16
522デフォルトの名無しさん:2009/06/21(日) 01:52:32
charの配列に読み込むとして、
charが8ビットなら、1要素に十六進法で2桁分格納されるということに気付け。
523デフォルトの名無しさん:2009/06/21(日) 01:53:12
>>520
たとえば

0123456789abcdef

というバイナリファイルがあるとします
これを読み込んで、char a[15]という配列に順番に最初から格納していくと
a[0]=0
a[1]=1
a[2]=2



a[10]=a
a[11]=b
という具合になるんでしょうか?

なるとしてですね、たとえばこの場合、fの部分のみを0に変えたいとします
しかし
if(a[n]==f) a[n]=0
とやっても変わらないですよね?
だって演算の時はfじゃなくて15になってるから(実際できませんでした)
524デフォルトの名無しさん:2009/06/21(日) 02:01:43
入門編の質問はおもしろいなぁ。

16進数のfはC言語では0xfと書く。fとはかけない。
525デフォルトの名無しさん:2009/06/21(日) 02:08:39
>>522
16進数は2進数で言うところの4ビットを1文字にまとめたもので、charは8ビットだから、charの配列には1要素あたり16進数が2つ入るという認識でいいでしょうか?
>>524
書くとしてどこに書けばいいんでしょうか

今いろいろやってみたんですが
424d4605・・・で始まるバイナリファイルをchar型のa[10000]という配列に読み込んでみたところ

a[0]を%xで表示すると42となりました
これは>>522さんの言うとおり、16進数の文字列が1要素あたり2文字入るということだと思うんですが
それでですね
a[60]の場合、バイナリエディタで見たところ、この位置には「ff」があるんですね
だからa[60]を%xで表示すると、上の理屈だとffにならないとおかしいと思うんですが、なぜか「ffffffff」と8つも入っています
char型の配列には1要素あたり16進数の数が2つしか入らないはずなのに、なんで8つも入ってるんでしょうか?
あとこれを%dで表示すると-1になってしまいます、訳がわかんないです
526デフォルトの名無しさん:2009/06/21(日) 02:08:48
普通unsigned charの配列に入れるけどな。
527デフォルトの名無しさん:2009/06/21(日) 02:11:26
424dでビットマップファイルを読もうとしてると分かってしまう俺様
528デフォルトの名無しさん:2009/06/21(日) 02:12:05
>>526
おお、unsigned charにしてみたら、ちゃんとa[60]の要素がffになってくれました
しかしなんで charのままだとa[60]はffffffffになって、unsigned charだとffになってくれたんでしょうか・・・さっぱりわかりません
529デフォルトの名無しさん:2009/06/21(日) 02:20:21
530デフォルトの名無しさん:2009/06/21(日) 02:26:34
>>529
なるほど
charの場合は正負を表現する符号がついて、ffffffffのうち上位6つのfは負の数を表すもので、残りの2つのfがもともとのバイナリファイルにあったffってことですね
unsigned charは符号が付かないので最後の2つのffのみが残ると
531デフォルトの名無しさん:2009/06/21(日) 02:54:44
>>491
心配なら見ればいいのに
532デフォルトの名無しさん:2009/06/21(日) 10:04:27
ワロタ
533デフォルトの名無しさん:2009/06/21(日) 10:36:03
do〜while文についての質問です。
判定部分でインクリメントやディクリメントしたほうが良い理由はなんでしょうか?
534デフォルトの名無しさん:2009/06/21(日) 10:43:56
絶対にしたほうがいいということは無いです。場合によります
535デフォルトの名無しさん:2009/06/21(日) 11:48:24
>>533
別にそんなことないよ?
誰が言ってた?
536デフォルトの名無しさん:2009/06/21(日) 12:05:02
Cでプログラムつくったときに
何行くらいなら大規模っていう?

企業レベルで。
537デフォルトの名無しさん:2009/06/21(日) 12:27:51
100万越えぐらいから
538デフォルトの名無しさん:2009/06/21(日) 12:29:58
学生レベルでは?
539デフォルトの名無しさん:2009/06/21(日) 12:44:59
1人なら、1000行じゃない?
540デフォルトの名無しさん:2009/06/21(日) 12:49:29
1000なんてちょっと書けば余裕で超えると思うけど・・・
541デフォルトの名無しさん:2009/06/21(日) 12:55:51
1000行で大規模って言わないだろ。
むしろ普通にライブラリを書いたりしてあっという間に数千行だよ?
542デフォルトの名無しさん:2009/06/21(日) 13:24:02
学生で1000行書ければ上出来。
543デフォルトの名無しさん:2009/06/21(日) 13:26:53
最近の学生はその程度なのか
優秀な学生はここにはいないのか
544デフォルトの名無しさん:2009/06/21(日) 13:28:53
入門篇だしな、優秀な学生がいるわけない
545デフォルトの名無しさん:2009/06/21(日) 13:40:34
200行で一苦労だぜorz
546デフォルトの名無しさん:2009/06/21(日) 13:48:12
行数じゃない。密度だろ
547デフォルトの名無しさん:2009/06/21(日) 13:51:40
初めて1000行超えた時の感動を忘れた俺が居る。
今は全然そう思わない。
548デフォルトの名無しさん:2009/06/21(日) 13:53:23
俺も学生の頃1000行超えた時におお、と思ったなぁ。
あのころは行数が気になってちょくちょく見てたもんだ。
549547:2009/06/21(日) 14:00:33
>>548
だよね。
今はファイルを分割して記述してすら1ファイル1000行
行っちゃうこともあるから、もう全部合計しても鬱になるだけw
550デフォルトの名無しさん:2009/06/21(日) 14:10:50
肝になる部分以外の記述だらけで疲れてくる
551デフォルトの名無しさん:2009/06/21(日) 14:19:12
職業プログラマってひとつきに1万行くらいは書くものなのかな
552デフォルトの名無しさん:2009/06/21(日) 14:29:42
コンピュータ内に16進数など存在しない。
553デフォルトの名無しさん:2009/06/21(日) 14:31:16
何進数があると思って言っているんだ?
554デフォルトの名無しさん:2009/06/21(日) 14:32:17
で、でんあつ・・・?
555デフォルトの名無しさん:2009/06/21(日) 14:41:26
どうせ2進数なんだよとか言いたいんじゃない?
これだから**はw
556デフォルトの名無しさん:2009/06/21(日) 14:49:43
>>551
発注の場合、一ヶ月1000行ぐらいだと思うよ
テストとかドキュメントも含めて
557デフォルトの名無しさん:2009/06/21(日) 14:53:55
え?たったの1000行/月でいいの?
558デフォルトの名無しさん:2009/06/21(日) 14:59:39
デスマーチは嫌じゃ
559デフォルトの名無しさん:2009/06/21(日) 15:01:06
行数がお金になる時代でもないですし。
560デフォルトの名無しさん:2009/06/21(日) 15:04:39
>>557
機能次第じゃないの?
文字列操作とかやりだすとたいしたことしてないのにやたら行数食うけど
そういうのじゃなければ案外少ない行数であれこれできるしねえ
561デフォルトの名無しさん:2009/06/21(日) 19:56:07
案外昔書いたやつコピペして、仕様書に合わせて改変してるんじゃないのけ?
562デフォルトの名無しさん:2009/06/21(日) 22:14:05
>>533
continueしたときのカウンタの変更忘れを防ぐため。
563デフォルトの名無しさん:2009/06/21(日) 22:56:24
プロセッサの中は情報エンタルピーが詰まっているだけで何進数でもない
564デフォルトの名無しさん:2009/06/21(日) 23:08:09
エンタルピーと聞くとタルピーを思い出す
565デフォルトの名無しさん:2009/06/22(月) 00:03:52
明解C言語入門を買ってきて最初のところにテキストエディタに
例文を打ち込んでプログラムを実行しろって書いてあったんだがどうやって実行するの?
borland c++ compilerをダウンロードしてTerapadに打ち込んだんだがこのあとどうすればいいのかわからない。
566デフォルトの名無しさん:2009/06/22(月) 00:04:26
ちょっと質問です。2分木のノード削除がうまくいかない(NULL をのぞいて鼻から悪魔状態)ですが、打つ手が尽きて、もうデバッガで調査するしかないのでしょうか。
567デフォルトの名無しさん:2009/06/22(月) 00:08:43
>>566
ソースをプリンタに印刷してじっくりにらめっこした?
画面だけでは発見出来ないバグが印刷すると簡単に
発見できたりするよ
568デフォルトの名無しさん:2009/06/22(月) 00:09:46
>566
デバッガで走らせてもいいし、怪しそうなところにデバッグ用の出力入れるのもよいかも。
自分では、論理ミスはしてないと思っていても、実はある条件分岐がうまくいってないことはよくある。
ソースをどこかに上げて意見を聞いても良いかもしれないよ。
その時は、どのように実装したかを説明するようにしよう。そうすると、意外にも間違っている箇所に気がつくことがあるから。
569デフォルトの名無しさん:2009/06/22(月) 00:09:50
>>566
他から領域破壊されてるとかじゃない限り
二分木程度ならコード眺めてたら分かるんじゃない?
570デフォルトの名無しさん:2009/06/22(月) 00:10:13
NOT素子はエンタルピーが可逆だから発熱しないんだってな。
571デフォルトの名無しさん:2009/06/22(月) 00:10:28
そもそもデバッガ使ってないの?
デバッガ使わずにどうやってバグ見つけるの?
572デフォルトの名無しさん:2009/06/22(月) 00:11:50
>>571
おーいwww
573デフォルトの名無しさん:2009/06/22(月) 00:15:11
printfデバッグ
574デフォルトの名無しさん:2009/06/22(月) 00:15:57
俺もデバッガあんまり使わなくて、非効率的なことをやっているなあと言われ、自覚してる
日々勉強っすね
575デフォルトの名無しさん:2009/06/22(月) 00:54:42
環境:cygwin ,コンパイラ:gcc

hoge構造体へのポインタ変数hogeにmallocでリソースを割り付け、
使い終わった後に解放するというシンプルなプログラムです。

解放する際に、free関数の引数に構造体hogeの先頭のメンバ変数numを
アドレスとして渡しています。
hogeそのものと&(hoge->num)が一致するので、 &(hoge->num)で渡しても
問題がないか検討してみました。結果、エラーは表示されませんでした。
解放する際は hogeの代わりに&(hoge->num)でも構わないでしょうか。

struct imp{
int num;
char name[20];
};

void main(void){
struct imp *hoge;
hoge = malloc(sizeof(struct imp));

free(&(hoge->num));
}
576デフォルトの名無しさん:2009/06/22(月) 00:56:50
ほとんどの場合うまくいくだろうが、俺はそうやらない。
577デフォルトの名無しさん:2009/06/22(月) 00:57:43
構造体hogeじゃなくてimpでした。あと検討→検証
578デフォルトの名無しさん:2009/06/22(月) 00:59:51
うまくいくんでないの?
俺もやらないけど。
579デフォルトの名無しさん:2009/06/22(月) 00:59:51
>>575
そういうおかしな癖を付けるな
後から苦労するぞ
それも並大抵の苦労じゃない
580デフォルトの名無しさん:2009/06/22(月) 01:00:40
大丈夫。すぐプロジェクトから抜ければ
デバッグするのは俺じゃねぇ。
581デフォルトの名無しさん:2009/06/22(月) 01:01:41
>>575
そのソースを人に見せたら馬鹿にされる。されない場合は無能のレッテルが
582デフォルトの名無しさん:2009/06/22(月) 01:04:41
だな
>>575
そのソース持って上司に伺いを立てに行け
クビにならなきゃいいけどな
583デフォルトの名無しさん:2009/06/22(月) 01:09:14
>>575
保証はされていないはず。
いずれにせよ、そんなことをしないといけないのは、コーディングが下手な可能性が高い。
584デフォルトの名無しさん:2009/06/22(月) 01:10:10
>>575は、何らかの特殊な事情があって &(hoge->num) と書きたい状況にあるのか
もしくは言語仕様やコンパイラの実装への関心からそういう質問が出てきたのか
そのどっちかだろうな。本人は何とも言ってないが
585デフォルトの名無しさん:2009/06/22(月) 01:22:10
>>585
前者です。あるプロジェクトに対する品質検証で、
リソースリーク検出ツールを使ってソースを網羅的に検査します。
検査後、リソースリークの疑いのある指摘がリスト表示されます。
リストされた中には、ツールの誤指摘が含まれているので、
人手で精査して正常検出/誤検出か判断します。
その精査作業で>>575のようなケースにぶつかりました。
これがリークかそうでないのかで悩んでいたわけです。
586デフォルトの名無しさん:2009/06/22(月) 01:23:25
ほれを書いた人物を検出すべし
587デフォルトの名無しさん:2009/06/22(月) 01:25:24
えっと、既存のコードに free(&(hoge->num)); というのがあって、そこにリソースリーク検出ツールが反応したってことかな。
じゃあ、この「デバッグするのは俺じゃない」「馬鹿にされる」「クビにならなきゃいいけど」って
さんざん言われてるコードの面倒みなきゃいけないほうの立場か。そりゃ大変だな。
588デフォルトの名無しさん:2009/06/22(月) 01:33:14
>>575

そのコンパイラでは問題が無くても、別のコンパイラで
は問題になる可能性が高い。
構造体のアドレス値と先頭要素のアドレス値を一致させることを
コンパイラが守る義務は無いので、freeにmallocで得た
アドレス値以外を渡す可能性がある。そうなるとfree関数は
正常に動作しない。
589デフォルトの名無しさん:2009/06/22(月) 01:35:16
>>583
保証されている。
ISO/IEC 9899:1999 (E) 6.7.2.1 Structure and union specifiers Semantics 6, 7, 13訳すの面倒だから自分で読んでおいて。
C++は、保証されてないと昔聞いたことがある。今度確認しておきます。
ANSI Cも今度確認しておきます。n1336も今度確認しておきます。
590デフォルトの名無しさん:2009/06/22(月) 01:38:21
impの定義が変更されて、numの前にメンバが入るかもしれないわけで。
ソース修正に回す方がいいだろうね。
591デフォルトの名無しさん:2009/06/22(月) 01:41:27
まあ仕様がどうあれそんな普通やらない事をするのは止めたほうが皆幸せになれると思う
592デフォルトの名無しさん:2009/06/22(月) 01:41:53
保証されていたとしても、修正しておいた方がいいよ。
もちろん最新の注意を払って。
593デフォルトの名無しさん:2009/06/22(月) 01:42:36
ええと、細心、ね。。一応orz
594583:2009/06/22(月) 01:49:01
>>589
あぁ、先頭にパディングは入らないって決められてるのか。失礼した。
595デフォルトの名無しさん:2009/06/22(月) 01:49:56
>>590
俺も全く同じ事を思った
596デフォルトの名無しさん:2009/06/22(月) 01:50:23
>>592
いいかげんなことを言うな。

コードの著作権は会社なり団体にあり、それが固定された
コンパイラに解釈させて正しく動作する限り、
それが他のコンパイラに解釈させて異常動作することを
以て勝手に変更する行為は、会社に対する業務妨害罪に抵触する。

ある会社内部の業務約款が他の会社で通用しないという理由で
その会社の約款を修正することが認められるならば、社名の
変更だって可能になるだろう。

(以上縦読みプリズ)
597デフォルトの名無しさん:2009/06/22(月) 01:54:14
>>589
コンパイラ作成者はISOの規格を遵守する義務は法的には
全くないことには注意。強制力の無い紳士協定みたいな
もので結ばれているに過ぎない。
598デフォルトの名無しさん:2009/06/22(月) 01:57:32
た、たてよみできない。。。

だからこそ規格に準拠したコンパイルであることが明記されてたりするんですね
599デフォルトの名無しさん:2009/06/22(月) 01:58:35
コンパイラ。。。だめだねよう
600デフォルトの名無しさん:2009/06/22(月) 02:01:46
ねたらしぬ
601デフォルトの名無しさん:2009/06/22(月) 02:06:54
ああ。。実はデスマってて。。バグ埋めないように気をつけるわ
602デフォルトの名無しさん:2009/06/22(月) 02:38:20
>>596
そのCコードが、それを所有する会社なり団体の業務約款に
相当するものかどうかの判定は、日本語で書かれた会社登記
関係書類や近年の活動内容と照らし合わせた上で、最終的には
CPUアセンブリニモニックコードとCPU動作統計検査で
判定されることになるが、
こういうの訴訟にされてもまともに審議するヒマな裁判所
など無いから念のため。(訴訟自体認められないんで)
603デフォルトの名無しさん:2009/06/22(月) 13:00:03
学校のLinuXだと
int main(stdin)
でよかったのに、家のCygwinだとエラーが出ます。
どういう問題があるんでしょうか?
604デフォルトの名無しさん:2009/06/22(月) 13:07:26
>>603
もう少しマシな釣りを希望する
605デフォルトの名無しさん:2009/06/22(月) 13:07:34
>>603
そんな阿呆なコードの断片だけ引用しないで、きちんと全文貼り付けた上でエラーメッセージも貼りましょう。
606デフォルトの名無しさん:2009/06/22(月) 13:08:57
>>603
俺のマシンに入ってるcygwinでは問題ない。
バージョンが違うのではないだろうか。
607デフォルトの名無しさん:2009/06/22(月) 13:24:03
#include <stdio.h>
typedef struct{
int number;//学生番号
char name[20];//名前
char password[8];//パスワード
}student;

int main(stdin)
{
student *person1, *person2;
student class[2];
scanf("%d",&person1->number);
scanf("%s",person1->name);
scanf("%s",person1->password);
printf("%d,%s,$s,%s,%d",person1->number,person1->name,person1->password);
}

つりとかじゃなくて普通に分からない。
608デフォルトの名無しさん:2009/06/22(月) 13:27:01
どこで教わったか知らないが、main関数の書き方は
int main()
int main(int argc, char *argv[])
の2パターンだけ知っていればいい。
609デフォルトの名無しさん:2009/06/22(月) 13:28:14
>>607
先が長そうだ・・・
610デフォルトの名無しさん:2009/06/22(月) 13:29:15
>>608
この場合上でいいのかな?
俺的にはscanfのたびにコマンドラインから入力するシステムにしたいんだが。
611デフォルトの名無しさん:2009/06/22(月) 13:31:44
>>610
自分のアプリを起動するときにオプションとかを指定するタイプなら下
ただ単に起動してアプリ内で入力待ちをするのなら上でいい
612デフォルトの名無しさん:2009/06/22(月) 13:32:16
>>610
コマンドラインからはコマンドを実行することができるだけ。インタラクティブな操作はできない。
613デフォルトの名無しさん:2009/06/22(月) 13:32:39
Int main()にしたら行けた。
でも今度は一つScanfを入力したところで変なエラーが出た。

26454 [main] class 2432 _cygtls::handle_exceptions:Ellor while dumping state(probably corrupted stack)
Segmentation faulst (core dumped)
614デフォルトの名無しさん:2009/06/22(月) 13:33:37
>>613
person1に適切な値が代入されていないから。
615デフォルトの名無しさん:2009/06/22(月) 13:35:43
でも、ちゃんと数字で入力したんだぜ?
616デフォルトの名無しさん:2009/06/22(月) 13:36:31
「代入」と「入力」の言葉の違いに要注意。
617デフォルトの名無しさん:2009/06/22(月) 13:37:19
ポインタを使うのはまだ早い
618デフォルトの名無しさん:2009/06/22(月) 13:37:32
person1に何も代入されていないってことは、person1はどこを指していると思う?
619デフォルトの名無しさん:2009/06/22(月) 13:39:19
>>618
つまり、Numberに何も代入されてない=アドレスが決まってないのに、&でアドレスを指定したのがいけないってこと?
620デフォルトの名無しさん:2009/06/22(月) 13:41:28
>>619
student *person1, *person2;
これだと構造体をさすポインターだけしかない

person1 = (person1)malloc(sizeof(person1));

としないと実体ができない
621デフォルトの名無しさん:2009/06/22(月) 13:44:45
>>620
な、なんだそりゃあ
そんなの学校で習ってないです。
学校ではそういうの無しに出来たと思うのですが…。
622デフォルトの名無しさん:2009/06/22(月) 13:53:39
思ったんですけど、アドレスで指定するのが駄目なのなら

int main()
{
student person1, person2;
student class[2];
scanf("%d",&person1.number);
scanf("%s",&person1.name);
scanf("%s",&person1.password);
printf("%d,%s,%s",person1->number,&person1->name,&person1->password);
}

では駄目なのでしょうか?
623デフォルトの名無しさん:2009/06/22(月) 13:57:11
お、なんか上手くいったっぽいです。
しばらくこの方向でやってみます。
答えてくださった方ありがとうございました。
624デフォルトの名無しさん:2009/06/22(月) 13:57:33
>>622
やりかたはそういう方向性でもいいんだけど何の学習をやるのかにもよるよ

あと、その書き方だとポインタじゃなく構造体に直接入れるので&つけてるとエラーになると思うよ
625デフォルトの名無しさん:2009/06/22(月) 14:06:39
処で、そのclassという配列は一体何に使うの?
626デフォルトの名無しさん:2009/06/22(月) 14:26:59
>>622

int main()
{
student person1, person2;
student class[2];
scanf("%d",&person1.number);
scanf("%s",&person1.name);
scanf("%s",&person1.password);
printf("%d,%s,%s",person1->number,person1->name,person1->password);
}

正しくはこうな
それからclass[2]が全く使われてないんだけどこれから使うのか?
627デフォルトの名無しさん:2009/06/22(月) 14:28:29
マイクロソフトの有料の方(プロフェッショナル)じゃないと最適化できなくて困ってます
CPU別に最適化できるフリーのコンパイラってありませんか?
628デフォルトの名無しさん:2009/06/22(月) 14:28:42
>>626
最終の printf 部漏れてる漏れてる
629デフォルトの名無しさん:2009/06/22(月) 14:37:31
直ってないなw

どうでもいいが、8バイトのパスワードは8要素の配列には入らないと思うんだ。
630デフォルトの名無しさん:2009/06/22(月) 14:43:03
printf("%d,%s,%s",person1.number,person1.name,person1.password);

こうか失礼

汚れ仕事は(エラー発見)はコンパイラにさせる癖がついてしまってるんで
631デフォルトの名無しさん:2009/06/22(月) 15:10:55
char *を渡すべきところにchar (*)[20]を渡してるけど大丈夫?と心配された(大丈夫なんだけど)

>>630は汚れ仕事をコンパイラにさせた後でレスをすべきだと思う
632デフォルトの名無しさん:2009/06/22(月) 15:47:34
>>626,630
間違え教えるなよ
633デフォルトの名無しさん:2009/06/22(月) 15:59:31
s/間違え/間違い/g
634デフォルトの名無しさん:2009/06/22(月) 16:57:16
s/い/ったこと/
635デフォルトの名無しさん:2009/06/22(月) 16:58:55
s/char */パイパンまんこ/
636デフォルトの名無しさん:2009/06/22(月) 17:36:53
* そのままだとちゃんと動かない気が
637デフォルトの名無しさん:2009/06/22(月) 17:38:03
したけど気のせいだったとさ
638デフォルトの名無しさん:2009/06/22(月) 17:55:14
C++ Coding Standardsには
「PODは、Cと移植性のあるレイアウトを持つ:メンバー変数は、宣言順に格納される」
とあるし、Effective C++ではCスタイルのstructはFORTRANなどにも渡せるとあるので
structの最初のデータメンバがstructのアドレスと一致することがCで保証されているなら
C++でも(それがPODである限り)保証されていると見ていいんじゃないかなーとか思った。
思っただけ。
639デフォルトの名無しさん:2009/06/22(月) 18:03:38
アドレスが一致することが保障されてるとしても、そんなことをする意味があるのか
640デフォルトの名無しさん:2009/06/22(月) 18:06:08
いや、後ろの空白が巻き込まれる。
意図してるのかどうかはしらないが
641デフォルトの名無しさん:2009/06/22(月) 19:00:47
構造体の先頭メンバがポインタだったら・・?

struct imp{
int *num;
char name[20];
};

int main(void){
struct imp *hoge;
hoge = malloc(sizeof(struct imp));
hoge->num = malloc(sizeof(int));
*(hoge->num) = 10;
strcpy(hoge->name,"taro");
free(hoge->num);
}
構造体の宣言によるけどこんな荒業が使える。
642デフォルトの名無しさん:2009/06/22(月) 19:03:00
ちゃんとhoge開放しろよ
643デフォルトの名無しさん:2009/06/22(月) 19:05:00
使えますん
free(hoge) -> free(&(hoge->num)) -> free(&hoge->num)
free(hoge->num) -/-> free(hoge)
644デフォルトの名無しさん:2009/06/22(月) 19:18:16
>>641
どう荒技なのかよくわからんが、
free(hoge)とfree(&(hoge->num))が同じかどうかの話でしょ
645デフォルトの名無しさん:2009/06/22(月) 19:22:45
>>644
荒業はいいすぎた。ところで
free(&(hoge->num))をやった後にfree(hoge)をやると2重フリーになるのでfreeを
呼ぶのは一回でいいのかな。
646デフォルトの名無しさん:2009/06/22(月) 19:29:43
ごめん、>>641が何をいいたいのか分からん。どこさして技って言ってる?
647デフォルトの名無しさん:2009/06/22(月) 19:35:06
>>645
試してみたら、二重開放になっていた。
よって、呼ぶのは1回でよい。

cc (GCC) 4.1.2 20080704 (Red Hat 4.1.2-44)
CFLAG=-Wall -std=c89 -ansi -pedantic
規格通りということだな。

>>589
ANSI Cにも同じようなことが書いてあった。
n1336は、ISO/IEC 9899:1999 (E)と変わってない。ちなみに6, 7, 13ではなくて5, 13だった。
C++は、個人的に利用しないのでどうでもいい。
648644:2009/06/22(月) 19:36:01
>>645
free(hoge->num);をやった後に、
free(hoge);、もしくはfree(&hoge->num);をすればいいのでは?
649デフォルトの名無しさん:2009/06/22(月) 19:38:43
>>647
何自信満々に確保した領域をほったらかしにしてんの
650デフォルトの名無しさん:2009/06/22(月) 19:47:47
>>649
>>641の場合、
free(&hoge->num)とfree(hoge)は等価だと何度いえばわかるんだ。
だから、>>645の言うとおり、>free(&(hoge->num))をやった後にfree(hoge)をやると2重フリーになる
のよ。
651デフォルトの名無しさん:2009/06/22(月) 19:49:42
>>641はfree(&(hoge->num))じゃなくてfree(hoge->num)なことに突っ込まれてんだよ
652デフォルトの名無しさん:2009/06/22(月) 19:52:29
>>650
だから>>641はhogeをfreeしてないだろっての
653デフォルトの名無しさん:2009/06/22(月) 19:54:29
二回mallocしてるのに、一回しかfreeしてないのにはなんの違和感も覚えないのか?
654デフォルトの名無しさん:2009/06/22(月) 19:56:09
荒技w

なんか面白いこと思いついた気がしただけだろ
そっとしといてやれ
655デフォルトの名無しさん:2009/06/22(月) 19:58:29
>>652
そんなことは見ればわかるだろ。
ちなみに私のレスは、>642,643,647,650ね
何度も言っているが、>>645は、>free(&(hoge->num))をやった後にfree(hoge)をやると2重フリーになる
かと聞いているので、なると答えただけだよ。

まぁ、入門篇だからしかたないか。
656デフォルトの名無しさん:2009/06/22(月) 20:00:09
>>650
そりゃ同じものを指してるんだから2重フリーになるよ。

> よって、呼ぶのは1回でよい。
でもこうはならないだろ?っていうのをみんな言ってんだけど
657644:2009/06/22(月) 20:04:10
>>655
2重フリーになるのかどうかを聞いてるのではなく、
1度のfreeで両方とも解放されるのかどうかを聞いてるように見えないか?
流れ的に。
658デフォルトの名無しさん:2009/06/22(月) 20:05:03
641=645がアホで終了していいだろ
659デフォルトの名無しさん:2009/06/22(月) 20:07:29
それは勘違いだな。
free(hoge->num)しているのは、>>641があったので前提としていた。
そのあとで、>>645>ところで
>free(&(hoge->num))をやった後にfree(hoge)をやると2重フリーになるのでfreeを
>呼ぶのは一回でいいのかな。
は、free(&(hoge->num)とfree(hoge)のいずれかを1回呼ぶと解釈された。

その後は、ぐだぐだになっていったということかな。
私が読み取り間違えていたの?
660デフォルトの名無しさん:2009/06/22(月) 20:15:01
構造体ひとつ開放するだけなら「一回でいいのかな」なんてことはでてこない。
661デフォルトの名無しさん:2009/06/22(月) 20:21:30
理解できた。確かに、そうとれる。
わかったことは、641,645が、free(hoge->num)とfree(&(hoge->num))を等価と考えていたので、
free(&(hoge->num))とfree(hoge)が等価だと最近聞いて、混乱したと。
その結果、2重フリーを気にしたが、示したコード片は、まさに2重フリーをするコードであったので、
>>647(私だが)が641,645の知りたいこととは違ったことをいい始めたと。
662デフォルトの名無しさん:2009/06/22(月) 20:22:57
>>641
どう荒技なのかよくわからんが、
(話していた内容は)
free(hoge)とfree(&(hoge->num))が同じかどうかの話でしょ
(free(hoge->num)は話題に出ているもののどちらでもない、関係ないものだよ)
(なのでhoge自体が解放されてないよね)

で、やっぱり荒技の意味は相変わらずわからないが、
>>648に続く。

>>641
> 構造体の先頭メンバがポインタだったら・・?
と、荒技、ということを考えると
free(hoge->num)と記述することで、hoge->numの先が解放され、さらにhogeとhoge->numが
同じものを指している(もちろんダウト)から、hoge自体も解放される
ということを言いたかったのではないかなあと、今なら思える。
663デフォルトの名無しさん:2009/06/22(月) 20:25:51
641だが
hoge->numとhogeを%pで表示させると同じ値だったから一度のfreeで解放
させられないかと思ったんだ。でも駄目みたいですね。
あと645の&〜は記入ミスです。
664デフォルトの名無しさん:2009/06/22(月) 20:32:25
>>663
そんなばかな。
とりあえず、コンパイラとそのバージョン、実行環境を教えてくれ。
665デフォルトの名無しさん:2009/06/22(月) 20:39:23
>>645
コンパイラ:gcc version 3.4.4
実行環境:cygwin
666デフォルトの名無しさん:2009/06/22(月) 20:40:30
struct imp{
int *num;
char name[20];
};
int main(void){
struct imp *hoge;
hoge = malloc(sizeof(struct imp));
if(hoge == NULL){return 1;}
hoge->num = malloc(sizeof(int));
*(hoge->num) = 10;
strcpy(hoge->name,"taro");
printf("No :%d\n",*(hoge->num));
printf("Name :%s\n",hoge->name);
printf("hoge->num = %p\n",hoge->num);
printf("hoge = %p\n",hoge);
free(hoge->num);
free(hoge);
printf("%p\n",hoge->num);
printf("%p\n",hoge);
return 0;
}
667デフォルトの名無しさん:2009/06/22(月) 20:42:39
実行結果
--------------
hoge->num = 0x6b0188
hoge = 0x6b0168
--------------
ごめんなさい 6と8をごっちゃにしてました。
どうみても同じじゃないです。お騒がせしました
668デフォルトの名無しさん:2009/06/22(月) 20:44:50
かわいいやつめ
669デフォルトの名無しさん:2009/06/22(月) 21:06:20

      ∧___∧  
     / -     -  \  
     |    ▼    |
   /|  =(_人_)= | >>668
  / ((ヽ、__ ゚し-J゚__ノ)) もしゃ
  |    _____ ノ   もしゃ
  ∪⌒∪     ∪
670デフォルトの名無しさん:2009/06/22(月) 21:09:47
ひっ
671デフォルトの名無しさん:2009/06/23(火) 03:08:00
荒技というならfreeせずにプログラム終了して、
メモリ解放はOSのプロセス管理に任せるくらいのことはしないと。
672デフォルトの名無しさん:2009/06/23(火) 03:16:20
それ別に荒いとは思わんけどね。
よきに計らってくれるんだから任せた方がスムーズに決まってる。

他言語でガベージコレクタを手動でせっせと起動するかっていうと、たいていの場合は任せるっしょ。
673デフォルトの名無しさん:2009/06/23(火) 05:00:28
>>672
> 他言語でガベージコレクタを手動でせっせと起動するかっていうと、たいていの場合は任せるっしょ。
確かに「他言語で」GCが言語仕様上規定されているならそうするだろうが
GC機能がないC/C++では、それは全く当てはまらないと思うが。

>メモリ解放はOSのプロセス管理に任せる
これは単にうまく動いてくれちゃっているだけで
言語仕様上はメモリーリークするコードになっているわけじゃないか。
674デフォルトの名無しさん:2009/06/23(火) 06:04:31
いや、言語仕様上、正常終了したときはmallocで割り当てたメモリは解放されるよ。

今更free論争なんて蒸し返したくないんで、あんまり突っ込まないで欲しいけど。
675デフォルトの名無しさん:2009/06/23(火) 06:18:16
それ仕様のどこに書かれてる?
676デフォルトの名無しさん:2009/06/23(火) 07:25:58
言語仕様じゃなくてOSの仕様だろ
677デフォルトの名無しさん:2009/06/23(火) 07:44:33
さぁ盛り上がってまいりました
678デフォルトの名無しさん:2009/06/23(火) 09:09:09
free(&hoge[0])
679デフォルトの名無しさん:2009/06/23(火) 13:01:00
ホント規格厨は手に負えんな
680デフォルトの名無しさん:2009/06/23(火) 13:59:45
で、やっぱり>>674はでたらめ?
681デフォルトの名無しさん:2009/06/23(火) 14:01:03
>>680
環境によるんじゃない?
開放してくれるのもあればしないのもあるだろうし
組み込みレベルになるとしないのもあるんじゃないかな?
限定はよくない。
682デフォルトの名無しさん:2009/06/23(火) 14:03:38
>>680
言語仕様上のくだりはでたらめ
683デフォルトの名無しさん:2009/06/23(火) 14:09:11
「今更free論争なんて蒸し返したくない」のと
「あんまり突っ込まないで欲しい」のは本当らしい。
684デフォルトの名無しさん:2009/06/23(火) 14:10:18
まあ古くからある言語だからなあ。

685デフォルトの名無しさん:2009/06/23(火) 14:57:09
scanfでchar(文字でなく値)の読み取りをしたいんだけど
調べたら%hhdっぽいような事は書かれてたんだけどmsdnで調べても無くて
VCで実際にやってみても%dと指定したのと同じになってるんだけど
もしかして出来ないの?
ちなみにshort型は%hdで行けました
686デフォルトの名無しさん:2009/06/23(火) 15:02:42
"%hhd"はC99以降です。
687デフォルトの名無しさん:2009/06/23(火) 15:51:07
>>685
intで読んでcharに代入
688デフォルトの名無しさん:2009/06/23(火) 16:30:15

あ…ありのまま 今 起こった事を話すぜ!
「2chのプログラム板を眺めていたと思ったら
いつのまにか古のネットニュースになっていた」
な… 何を言ってるのか わからねーと思うが(ry
689デフォルトの名無しさん:2009/06/23(火) 16:38:50
板更新しろ
690デフォルトの名無しさん:2009/06/23(火) 16:43:51
691デフォルトの名無しさん:2009/06/23(火) 20:30:16
2重freeに引っかからないように自作してみた。これは有効ですか?
void vfree(void **p);
int main(void)
{
char *str;
str = (char*)malloc(10);
printf("str = %p\n",str);
vfree(((void**)&str));
printf("str = %p\n",str);
vfree(((void**)&str));
printf("str = %p\n",str);
return 0;
}
void vfree(void **p)
{
free(*p);
*p = NULL;
}
692デフォルトの名無しさん:2009/06/23(火) 20:38:31
#define vfree(p) {free(p);p=NULL;}
でいいんじゃない?
693デフォルトの名無しさん:2009/06/23(火) 20:39:32
そうね!
694デフォルトの名無しさん:2009/06/23(火) 20:40:49
>>688

熟語の意味を辞書で引いて揚げ足取るやつとか居ないから違うと思われ
695デフォルトの名無しさん:2009/06/23(火) 22:01:54
C言語で、別のソースファイルに書いたラベルにgotoするにはどうしたらいいですか?
696デフォルトの名無しさん:2009/06/23(火) 22:03:08
#include
が使えるかもしれない。
697デフォルトの名無しさん:2009/06/23(火) 22:03:27
>>695
むり。
関数の外にはgotoできない。
698デフォルトの名無しさん:2009/06/23(火) 22:13:31
>>695
どうしてもしたい場合は setjmp/longjmp
699デフォルトの名無しさん:2009/06/23(火) 22:21:02
SEH
700デフォルトの名無しさん:2009/06/23(火) 22:29:37
>>686
調べが足りませんでした
>>687氏の方法で実装してみようと思います。
ありがとうございました
701デフォルトの名無しさん:2009/06/23(火) 23:03:05
>>695
すんげークソ設計な予感がするけど
大丈夫か??
702デフォルトの名無しさん:2009/06/23(火) 23:06:00
>>700
やるのはいいけど、あとで後悔するぞ
703デフォルトの名無しさん:2009/06/23(火) 23:59:55
>>606>>607>>608
ありがとうございます。goto無しでやるように書き換えようと思います。

>>701
ミニゲームのゲームオーバー画面からタイトル画面に飛ばせたらと思って…


後、例えばとある関数があって、その関数は引数によって微妙に処理を変えたいのですがどうすればよろしいでしょうか?
例えるならCASLUの命令のように。

LD GR1,GR2  //これだったらGR2の中身をGR1にコピー
LD GR1,X    //これだったらX番地の内容をGR1にコピー
LD GR1,X,=2  //これだったらX番地+2番地の内容をGR1にコピー

といったような感じに、引数によって内容をが微妙に異なるようなことは出来るのでしょうか?
704デフォルトの名無しさん:2009/06/24(水) 00:08:40
>>703
> 引数によって内容をが微妙に異なるようなことは出来るのでしょうか?
できる。
705デフォルトの名無しさん:2009/06/24(水) 02:21:49
関数に複数の値を渡したいのですが、その数値の数を流動的に決めることはできないのでしょうか
たとえば複数の数を渡して、その中から一番大きい数を返すina maxという関数を作るとして
このint maxに渡す数が1と2の2つだけだったり、10と20と30と40と50の5つだったり、そういう複数のパターンに対応させるようにしたいのです
706デフォルトの名無しさん:2009/06/24(水) 02:23:31
...をつかう
707デフォルトの名無しさん:2009/06/24(水) 02:25:14
ごめんなさい、もうちょっと詳しくお願いします
708デフォルトの名無しさん:2009/06/24(水) 02:26:25
va_listをつかう
709デフォルトの名無しさん:2009/06/24(水) 02:27:58
http://www.linux.or.jp/JM/html/LDP_man-pages/man3/stdarg.3.html
ここを見るのがいいと思う。
引数なしは無理だけど要件を見る限り大丈夫だろ、と思う
710デフォルトの名無しさん:2009/06/24(水) 06:22:38
>>703
引数によってというのがわからん
引数が10以下なら〜20以下なら〜とかなら普通にできるがそういう意味じゃないよな
711デフォルトの名無しさん:2009/06/24(水) 07:06:08
>>703
引数の型によって変えるならC++使え
712デフォルトの名無しさん:2009/06/24(水) 07:13:05
>>703
そういうのはジャンプしないほうが
状態の遷移を考えて・・・
713デフォルトの名無しさん:2009/06/24(水) 07:20:15
絶望的に設計が下手糞だな・・・
714デフォルトの名無しさん:2009/06/24(水) 07:26:39
>>713
経験だからねえ
スクリプトがメインの時代だとこういうジャンプを考えるのはありえなくないんだわww
その昔N88BASICくらいしか学生が手に出来なかった時代は余裕でやらかしてたからww
715デフォルトの名無しさん:2009/06/24(水) 12:11:18
上のを見て思ったんですけど

void func(int *p,int num);
void func(int *p,int *p2);
void func(int *p,int *p2,int *p3);

みたいな3つの関数って宣言出来るんですか?
716デフォルトの名無しさん:2009/06/24(水) 12:13:23
その辺はC9xによって違うとかC/C++で違うとかあるような。

ここで規格を語ってる方ひとこと↓
717デフォルトの名無しさん:2009/06/24(水) 12:18:50
>>715
そういう機能はオーバーロードと呼ばれていて、Cではできません
718デフォルトの名無しさん:2009/06/24(水) 12:47:44
C/C++で書いてgcc/g++でコンパイルして実行するという前提で、
ある問題(例えば100万以下の素数を生成する)をコーディングしたとして、
そこで書いたアルゴリズム(プログラム)の実行時間を知りたい場合、
どのような方法で知るのが一般的なのでしょうか?

コマンドラインからコンパイルor実行時に何かコマンドを繋げる、
プログラム中に time.h sys/* などをインクルードしてプログラム実行開始からの時間を取得して計算する、
などが考えられるのですが、具体的にどのようなコードを追加したりするのか教えていただけると助かります。
719デフォルトの名無しさん:2009/06/24(水) 12:52:59
timeコマンド使えばいいんじゃね?
720デフォルトの名無しさん:2009/06/24(水) 12:54:17
C99のtgmath.hが引数の型によって呼び出す関数を振り分ける
特殊なマクロを提供しているのは知っていたので
早速、「tgmath.h 実装」でぐぐってみたら、gcc は独自拡張で実装してたり、
あるサイトでは厳密なCコードでは実装できないと書かれていたり、
どうなってんのって感じ。^^; Sun Studio 12 がC99完全合致らしいので
それのヘッダを見れば秘密がわかるのか?
721デフォルトの名無しさん:2009/06/24(水) 13:16:03
Crypt関数について質問です。

printf("%s\n", crypt("hogehoge","ab"));

例えばこの出力を100万回ループさせると
十数秒かかるのですが、Perlで同じことをすると1秒程度で処理を終えます。
調べたところPerlのCrypt関数は、CのCrypt関数を使っているそうなんですが
CとPerlではなぜ処理速度がこんなに変わるのでしょうか?
722デフォルトの名無しさん:2009/06/24(水) 13:28:00
perlでは画面出力してないとかいうオチじゃないだろうな
723721:2009/06/24(水) 13:34:07
>>722
Perlでは下のprint文を同じく100万回ループさせています。

print crypt("hogehuga","ab") . "\n";
724デフォルトの名無しさん:2009/06/24(水) 13:36:48
C言語の方を
puts(crypt("hogehoge", "ab"));
に変えてみろ
725デフォルトの名無しさん:2009/06/24(水) 13:38:46
>>721
>CのCrypt関数を使っているそうなんですが
C“には”「Crypt」なる関数は用意されていません。
>CとPerlではなぜ処理速度がこんなに変わるのでしょうか?
最軽量コンパイラとインタプリタの比較ですか?
726デフォルトの名無しさん:2009/06/24(水) 13:39:21
本当にそれが crypt 関数によるところであるかどうかは
ベースとなる処理速度の違いを差し引く必要があるので
crypt関数を取り除いて(pirnt文だけで)空回ししてみるとわかるかも。
(デバッグモードのcではprintfが異様に遅いとか…)
727721:2009/06/24(水) 13:49:24
>>724
putsで試してみたのですがprintfと変わりませんでした。
ちなみにcryptを使わずにprintfだけにすると速いです。

>>725
たまたまCとPerlの両方でプログラムを書いたら実行速度があまりに違ったので
その原因を知りたくなりました。

>>726
printfだけだと速いですがcryptが入ると遅くなりました。
728デフォルトの名無しさん:2009/06/24(水) 13:57:47
となるとやはり、Cの方のcrypt関数がヘボいアルゴリズム使ってるのかもね。
もう少しちゃんと動くライブラリを探すと良いかも。
729デフォルトの名無しさん:2009/06/24(水) 16:17:17
>>721
10万回ループで26秒かかった(cygwin)
2ちゃんのトリップ検索はアセンブラだったような
Bitslice DESアルゴリズムとかいうのを使ってるらしい
730デフォルトの名無しさん:2009/06/24(水) 16:19:53
>>721
結果をプールしているんじゃなかろうか
731デフォルトの名無しさん:2009/06/24(水) 16:22:46
>>730
perlって、そういう最適化がきくのかね。
Cryptが同じ引数なら、同じ結果になるって知っていれば、
最適化できるけど。
732デフォルトの名無しさん:2009/06/24(水) 16:30:37
100万行表示で1秒?
733デフォルトの名無しさん:2009/06/24(水) 17:26:48
そのPerlがたまたま前回の結果をキャッシュしていて
全く同じ引数が与えられたら計算せずに前の値を返して
いるだけなんじゃねーの?

いくらなんでも速度が違いすぎるぞ
734デフォルトの名無しさん:2009/06/24(水) 18:08:08
定義域より外の値を引数に入れたら
・中で定義域に収まるように(端点などに)修正する
・エラーを返す
どっちがいいかな。好みの問題?
735デフォルトの名無しさん:2009/06/24(水) 18:10:25
>>734
エラーを返すほうが好きだ
736デフォルトの名無しさん:2009/06/24(水) 18:13:22
>>734
エラーを返す
だな。
呼び出してる側が本来は修正をしないといけないのに勝手にエラーに
ならないようにされると後々困ることになる。
バグ取りにならない
737デフォルトの名無しさん:2009/06/24(水) 18:13:48
>>734
両方とも妥当な場合がある、結果仕様による
738デフォルトの名無しさん:2009/06/24(水) 18:18:10
じゃあ定義域に修正する関数を別に用意してそれを通して引数に渡す、とだったらどっち?
いちおうゲームに使う予定なんで、できるだけエラーでストップして欲しくないから修正を使いたいんだけど
あんまり嫌われるようだったら考え直したい
739デフォルトの名無しさん:2009/06/24(水) 18:19:32
だから仕様による、その場合強固なシステムがいい場合も有る
740デフォルトの名無しさん:2009/06/24(水) 18:20:40
>>738
それでいいかもな。
修正する関数は、デバッグモードのときにはエラーで止まるようにして
リリースのときには修正するようにするとか。
741デフォルトの名無しさん:2009/06/24(水) 18:21:54
>>740
あ、それいいですね。いただきます
ほかの方もあざっしたぁー
742デフォルトの名無しさん:2009/06/24(水) 18:24:59
>>740
それは無い
同名のものは、出来る限り同じ機能であるべきだ

>>738
命名規則を決めておいて自動修正有り無しの両方つくるとか
743デフォルトの名無しさん:2009/06/24(水) 18:29:33
流れをぶった切って質問。

math.hみたいな感じの統計版ってある?

大げさなものじゃなくて、中央値とか分散とか程度でいいんだけど・・・
744721:2009/06/24(水) 18:41:38
>>728
CとPerlでは同じライブラリを使ってるという情報がありました。
他のライブラリでも試してみたほうが良さそうですね。

>>729
トリップ検索で有名なフリーソフトはたくさんありますが
だいたい1秒間に〜100万トリップ程度は検索しているようです。
ということは100万回Cryptしているのだと思うのですが
ソースが手に入らないのでどういったプログラムを書かれているのかわからないです。

>>732
画面の描画ではなくてプログラムの実行が1秒で終わるということでした。

>>730 >>733
乱数を生成してループの度に結果を変えましたが
特にキャッシュしているわけではなさそうです。
745デフォルトの名無しさん:2009/06/24(水) 18:57:39
・ループ部分も含めてソースを示そう
・出力はどうしてんの?100万行をttyに垂れ流し?
・もし/dev/nullとかに捨ててるなら、
ちゃんと動いてるか確認しよう
746デフォルトの名無しさん:2009/06/24(水) 19:13:52
a.hがb.hをインクルードしていて、
b.hもa.hをインクルードしている場合

何が起こりますか?
747デフォルトの名無しさん:2009/06/24(水) 19:17:12
includeできる回数には上限があるのでそこで止まります。
748デフォルトの名無しさん:2009/06/24(水) 19:17:31
インクルードが深くなりすぎてコンパイルがとまります
749デフォルトの名無しさん:2009/06/24(水) 19:19:12
C++に対抗してプリプロセッサメタプログラミングとかできないの?
750デフォルトの名無しさん:2009/06/24(水) 19:25:40
ずっとやってきてるじゃないか。
751デフォルトの名無しさん:2009/06/24(水) 19:28:28
>>746
インクルードガードを書いておけば問題なし

>>749
CSTL でググれ
752デフォルトの名無しさん:2009/06/24(水) 19:29:57
つーかC++使ってCソース書けばいいだけだろ?
753デフォルトの名無しさん:2009/06/24(水) 20:36:20
>>717
ありがとうございます
754デフォルトの名無しさん:2009/06/24(水) 22:41:25
#include <math.h>
#include <stdio.h>
#define n 10
int kaijou( int x ),m;
double SIN=0,angle=1;
main(void)
{
printf("角度を入力");
scanf("%lf",&angle);
angle=atan(1)*4/180.0*angle;

printf("%frad",angle);
for(m=0;m<=n;m++)
{
SIN=SIN+(double)pow(-1,m)*(double)pow(angle,2*m+1)/kaijou(2*m+1);
}
printf("サインの値は%f",SIN);
}
int kaijou(int x)
{
int y=1,count;
for(count=1;count<=x;count++)
{
y=y*count;

}
return y;
}
テイラー展開を使ってsinを求めるんですけど角度が大きくなると
値がおかしくなります 項数を増やすと-1.#indo00って出ます なぜ?
755デフォルトの名無しさん:2009/06/24(水) 22:44:08
>>754
ソースはほとんど読んでないけどレスしてみる。

オーバーフローしてない?

756デフォルトの名無しさん:2009/06/24(水) 22:49:54
コンパイラができません
bcc32は内部コマンドまたは外部コマンド
操作可能なプログラムまたはバッチファイルとして認識していません。ってでます

↑環境変数の設定やbcc32.cfgとlink.cfgファイル作ってもできません
757デフォルトの名無しさん:2009/06/24(水) 22:54:11
pathを通しましょう
758デフォルトの名無しさん:2009/06/24(水) 22:54:46
どうやって通すのですか?
759デフォルトの名無しさん:2009/06/24(水) 22:55:51
set PATH=通したいパス;%PATH%
760デフォルトの名無しさん:2009/06/24(水) 22:56:11
>>756
bccじゃなくて、VisualStudioを使った方がいいよ。
761デフォルトの名無しさん:2009/06/24(水) 22:56:24
C言語でプログラミングを書くときに
-------------------------
前処理(変数初期化)

本体
(異常があったときに ラベルに飛ぶ)

return(OK)
:ラベル
例外処理
-------------------------

というようなスタイルで書いているのですが、
こういう構造が古いと書いてあったウエブがあったのですが、
どこが古いのかわかりますか?

そのウェブサイトを思い出せれば、いいのですが、
再度検索してもヒットしないので
もしウェブサイトにこころあたりがあれば
教えてください。


762デフォルトの名無しさん:2009/06/24(水) 22:57:24
>>761
>どこが古いのかわかりますか?

goto使ってるとこじゃない?
763デフォルトの名無しさん:2009/06/24(水) 23:01:11
チラシの裏で。

bccも悪くないよ。
「初心者のうちは。」
764デフォルトの名無しさん:2009/06/24(水) 23:03:16
>>761
linusの最近のコードでもそういう書き方してるし、いいんじゃないの?
765デフォルトの名無しさん:2009/06/24(水) 23:06:15
テイラー展開って面白そうだね。
sin cosを大量に使うゲームには有効そう

でも
http://letsphysics.blog17.fc2.com/blog-entry-90.html

f(x)=-1/5+(1+x2)log[5-x]Tan[x]/(5-x2)
これを

f5(x) = -0.2 + 0.33 x - 0.04 x2 + 0.49 x3 - 0.062 x4 + 0.24 x5
こうするとうのには後何の知識がいるんだ?
766デフォルトの名無しさん:2009/06/24(水) 23:09:28
テイラー展開するとなんかの近似値を求められるってことは
思い出せた
なんだっけ?
767デフォルトの名無しさん:2009/06/24(水) 23:10:25
VC++を使っているのですが、sinやcos等の三角関数の計算を行っている
ソースファイルはどこにあるのでしょうか?

また、ネットを漁っていて気になる発言があったのですが、
CPU(もしくはOS)に、三角関数の計算アルゴリズムが実装されているのでしょうか?

以上、よろしくお願い致します。
768デフォルトの名無しさん:2009/06/24(水) 23:13:00
>>766
なにかってのは元の数式の近似値だよね?

重い計算をしなくてもテイラー展開しておけば簡単な計算式でできると。
769デフォルトの名無しさん:2009/06/24(水) 23:13:13
math.h
770デフォルトの名無しさん:2009/06/24(水) 23:14:05
>>765
> テイラー展開って面白そうだね。
> sin cosを大量に使うゲームには有効そう
標準ライブラリのdouble sin(double x)やdouble cos(double x)の実装がどうなっているかは
しらないが、近似値を求めると言うことはテイラー展開(正確にはテイラーの定理)を使っている可能性はある。

>>766
いろいろ近似値を求められるよ。
πとかeとか。

数学オタクの俺が言うんだから間違いない。

ちなみにテイラー展開とテイラーの定理をごっちゃにしているやつが
多すぎるのでそういう輩の説明は信用しないように。
771デフォルトの名無しさん:2009/06/24(水) 23:14:19
>>765
テイラー展開は元々平均値の定理から導かれた物だ
微分を知っていれば事足りる
772デフォルトの名無しさん:2009/06/24(水) 23:15:33
テイラー展開つかうと
標準関数ライブラリのsinやcosよりどれぐらい高速なんですか?
773デフォルトの名無しさん:2009/06/24(水) 23:18:10
>>772
math系のソースの中身が見えない場合は実測してみなとなんとも
最近は環境によってはハードウェアレベルでsin計算しちゃうのもあるのでテイラー展開するまででないとかある
774デフォルトの名無しさん:2009/06/24(水) 23:18:15
遅 い で す

あくまでも勉強用と考えましょう
ライブラリは様々なテクニックを使って例えば0やπ/2に近い時は
最適化されていたりするので

もしくは数値演算コプロセッサを使う事を前提としていたりするので
775デフォルトの名無しさん:2009/06/24(水) 23:19:00
>>759
コンパイルできました
ありがとうございました
776デフォルトの名無しさん:2009/06/24(水) 23:20:04
>>772
三角関数の値なんてfpuの一命令で求められる時代なんだから、標準ライブラリより速くなることはない。
777770:2009/06/24(水) 23:23:00
ふーん、そうなのか。
やっぱ数学オタクの俺のいうプログラミングの話は信用しない方が良いかもね。

778デフォルトの名無しさん:2009/06/24(水) 23:23:06
>>776
漏れが愛用しているZ80にもそんな機能があるのだろうか。
779デフォルトの名無しさん:2009/06/24(水) 23:24:22
でもゲームによってはatan2とか必要になるだろうしさすがにatan系までハードウェアで計算はしないからいるんじゃない?>テイラー展開
780デフォルトの名無しさん:2009/06/24(水) 23:26:08
781デフォルトの名無しさん:2009/06/24(水) 23:26:39
テイラー展開は普通は大学1年で覚えるよ
782デフォルトの名無しさん:2009/06/24(水) 23:27:54
>>781
面白そうと言った者です。
高卒です、すみません
783デフォルトの名無しさん:2009/06/24(水) 23:28:35
>>781
俺が使うことは一生なさそうだ
784デフォルトの名無しさん:2009/06/24(水) 23:31:11
>>779
80387系にはある
FPATAN
785デフォルトの名無しさん:2009/06/24(水) 23:35:04
>>784
ほう
786デフォルトの名無しさん:2009/06/24(水) 23:42:09
D3DXライブラリ使えば
三角関数使わないっすよね?
787デフォルトの名無しさん:2009/06/24(水) 23:45:30
その代わりクォータニオン(四元数)を理解しないといけない

元々ジンバルロックというガウス座標特有の現象を避ける為に
考え出されたもので宇宙ステーションのアーム操作にも応用されている
788デフォルトの名無しさん:2009/06/24(水) 23:46:16
>>786
ゲームによってはいると思うよ。

モデルとモデルのアングル求めたりアングルからベクトルに直したりと・・・
789デフォルトの名無しさん:2009/06/24(水) 23:50:27
ごめん
×ガウス座標
○オイラー座標

物理と混同していた
790デフォルトの名無しさん:2009/06/25(木) 00:06:44
>>786
使うよ。
791デフォルトの名無しさん:2009/06/25(木) 00:08:31
>>763
初心者だからこそ、余計なところでつまずく環境はお勧めできないと思うんだ。
792721:2009/06/25(木) 03:06:14
>>745
出力は/dev/nullですが、プログラムは実際には動いています。

以下プログラムのコピペです。

for (i = 0; i < 10; i++) {
for(j = 0; j < 8; j++){
str[j] = rand() % 8 + 1;
}
printf("%s\n", crypt(str,"ab"));
}
793デフォルトの名無しさん:2009/06/25(木) 03:12:46
何が分からんのか分からん。
cryptの実装の違いだろ。
794721:2009/06/25(木) 03:29:18
色々調べたのですが、やはりcryptは遅いそうなので
他のライブラリを試してみることにします。
レスを下さった方ありがとうございました。
795デフォルトの名無しさん:2009/06/25(木) 04:44:23
はぁ?
796デフォルトの名無しさん:2009/06/25(木) 06:30:43
今更だけど……、
自分の必要なだけの精度しか求めないようにするとか、
入力に何らかの仮定ができて、もっと簡単な近似式を使えるとか、
大量のデータの計算でSIMD命令を活用するなど、
どうしてもという理由があって特定の目的に絞れば、汎用品である標準ライブラリよりは速くできるかもしれない。
797デフォルトの名無しさん:2009/06/25(木) 09:31:56
>>742
デバッグとリリースモードで動作の違うのは普通にあるよ。
798デフォルトの名無しさん:2009/06/25(木) 09:41:22
そりゃあ違うのは実在するが
>>740みたいにそんな気軽にやるもんじゃないだろw

799デフォルトの名無しさん:2009/06/25(木) 09:42:58
assert()とか普通に使ってる。
800デフォルトの名無しさん:2009/06/25(木) 09:51:07
デバッグモードとリリースモードで動作が同じなのが原則で
異なるのは例外とすべき
801デフォルトの名無しさん:2009/06/25(木) 10:06:24
デバッグのときにエラーチェックして止まるってのは、まあ、普通に行われてることですね。
達人プログラマー(うろ覚え)で、リリースビルドでもassertは無効にするなって書かれてたり
して、スキル高い人でも、そうじゃないって意見はあるけど、一般的にはassert()とか
assert()的な動作のコードはよく使われています。
802デフォルトの名無しさん:2009/06/25(木) 11:48:41
>>792
バカか。動作のおかしいperlの方出せよ

#!/usr/bin/perl
for($i=0; $i<10000; $i++)
{
for($j=0; $j<8; $j++){ $str .= int(rand(8)) + 1; }
print crypt($str, "ab"),"\n";
}

time ./cryptest.pl > /dev/null
real 0m3.636s
user 0m3.600s
sys 0m0.010s

main()
{
int i,j;
char str[10]={0};
for(i=0; i<10000; i++) {
for(j=0;j<8;j++) str[j]=rand() % 8 + 1;
printf("%s\n", crypt(str, "ab"));
}
}

time ./cryptest > /dev/null
real 0m3.431s
user 0m3.400s
sys 0m0.000s
803デフォルトの名無しさん:2009/06/25(木) 11:50:31
#include <stdio.h>

main()
{
int i,j=0,sum=0;
while(j<=0){
printf("aは? ");scanf("%d",&j);
}
sum=0;
for(i=0;i<=j;i++){
sum=sum+i;
}

printf("1から3までの和は %d\n",sum);
}

804:2009/06/25(木) 12:02:21
#include<stdio.h>
float fmin(float,float);

float main(void)
{
float a,b,min;
printf("aの値は?\n");
scanf("%f",&a);
printf("bの値は?\n");
scanf("%f",&b);
min=fmin(a,b);
printf("%fの方が小さい\n",min);
return 0;
}
float fmin(float x,float y)
{
float z;
if(x<y)
z=x;
else
z=y;
return z;
}
805デフォルトの名無しさん:2009/06/25(木) 13:48:13

ある設定NOが1-99まであって、そのNOに応じて
EEPROMから設定内容を読みだすのですが、
設定内容の読み出し関数が設定NOの数だけあり、戻り値がunsigned longだったり
charだったりばらばらです。
ifやswitch文で99も分岐させるのは嫌なのですが、関数ポインタに
しても型が違うのでうまくいきません。どういうやり方がすっきり作れる
でしょうか?
806デフォルトの名無しさん:2009/06/25(木) 13:53:16
switch
807デフォルトの名無しさん:2009/06/25(木) 14:10:15
>>805
読み出し関数が設定NOの数だけあり・・・
それならswitchでいいだろ
808デフォルトの名無しさん:2009/06/25(木) 14:12:39
戻り値は違うけど関数の引数は同じ?
809デフォルトの名無しさん:2009/06/25(木) 14:18:53
引数はvoidで共通です。
810デフォルトの名無しさん:2009/06/25(木) 15:10:58
typedef unsigned long (*proc)(void);
static const struct {
  proc func;
  int   ret_type;
} proc_table[] = {
  {(proc)func_1, 1}, /* char */
  {(proc)func_2, 1}, /* char */
  {(proc)func_3, 4}, /* int */
  {(proc)func_4, 2}, /* short */
     :
とかやっといて、
  unsigned long ret = proc_table[code].func();
してから proc_table[code].ret_type で switch 分岐、キャスト。
811デフォルトの名無しさん:2009/06/25(木) 15:11:43
× [code]
○ [設定No]
812デフォルトの名無しさん:2009/06/25(木) 15:18:51
>>810
キャストすんな。
813デフォルトの名無しさん:2009/06/25(木) 16:26:51
swicth 並べるなりしたほうが速いとは思うけど…

>>810 の亜種
共通の戻りの型を一まとめにテーブル化 要素に設定No をおいて
渡された設定No をキーに for でなめてく

typedef long (*l_proc)(void);
typedef char (*c_proc)(void);
static const struct { l_proc func, int NO } l_proc_table[] = {
 { func1, 0 },
 :
};
static const struct { c_proc func, int NO } c_proc_table[] = {
 { funcA, 10 },
 :
};

for (i=0;i<sizeof(l_proc_table)/sizeof(l_proc_table[0]); i++) {
 if (l_proc_table[i] == <渡された 設定No>) {
  l_proc_table[i].func(); /* 呼び出し: 被代入変数は ptr で受ける? */
  return;
 }
}
for (i=0;i<sizeof(c_proc_table)/sizeof(c_proc_table[0]); i++) {
 if (c_proc_table[i] == <渡された 設定No>) {
  c_proc_table[i].func(); /* 呼び出し: 被代入変数は ptr で受ける? */
  return;
 }
}
814デフォルトの名無しさん:2009/06/25(木) 16:31:11
何々?
Cで仮想関数モドキをやろうとしてるの?
815デフォルトの名無しさん:2009/06/25(木) 17:54:32
下の関数のコール元で「cTest」の値を取得するには、どうすればよいでしょう?


void addCopy(char *pData)
{
char cTest = 10;

pData = &cTest;
}
816デフォルトの名無しさん:2009/06/25(木) 17:57:50
関数を変えていいなら

char addCopy(char *pData)
{
char cTest = 10;

pData = &cTest;
return cTest;
}
817デフォルトの名無しさん:2009/06/25(木) 17:59:24
>>815
そのコードでは無理
 void addCopy(char *pData)
 {
  char cTest = 10;
  *pData = cTest;
 }
ならば可。

呼び出し元は受け用の実体変数を用意して
 char c;
 addCopy(&c);
と呼び出せば良い
818デフォルトの名無しさん:2009/06/25(木) 18:00:42
>>813
戻り値の型の数だけテーブル化はいいですね。
どうも1つのテーブルにこだわりすぎて思いつかなかったです。
設定NOは2つのテーブルで同じものは絶対ないので、
おかしなことにもならないですし。
819デフォルトの名無しさん:2009/06/25(木) 18:01:47
>>817

やはりこれでは無理ですか。
ありがとうございました。
820デフォルトの名無しさん:2009/06/25(木) 18:04:19
>>818
1つのテーブルだと テーブルのindex == 設定NO とすることができるので
呼び出しにかかる時間コストはゴミという利点はあるけどね。

for でなめて引っ掛ける という性質上
時間コストは1つのテーブルの時より悪くなるのは仕方ないな
821デフォルトの名無しさん:2009/06/25(木) 19:16:52
複数テーブルでも、呼び出されないはずのエントリにダミーの関数登録しておくとかで
O(1)にできそうだけどね。
822デフォルトの名無しさん:2009/06/25(木) 19:24:27
で、結局テーブルの実体の記述はその数だけ並べなきゃいけないから
switch でも良いじゃん とループ

マクロである程度の簡略化はできるだろうけど、エントリの数だけ並ぶのは同じだし

#define IMP(no, func) case no: result = func (); break;

unsigned long result; /* 最も大きいサイズの型で受ける予定で */
switch (NO) {
IMP(1, funcA)
IMP(2, funcB)
 :
}

#undef IMP
823デフォルトの名無しさん:2009/06/25(木) 19:35:09
呼び出し側で場合分けすれば
824デフォルトの名無しさん:2009/06/26(金) 14:15:37
ランダム関数を用いたCPUとのじゃんけんを作ろうとしたけど、うまく作るのって難しいのね。
単純そうだが、上手なアルゴリズムは難しいな。
825デフォルトの名無しさん:2009/06/26(金) 14:20:11
>>824
何が難しいと感じたのか詳しく。
826デフォルトの名無しさん:2009/06/26(金) 15:23:55
昔、雑誌に相手の癖をみてジャンケンするコードが載ってたんで、
対戦してみたら、ほんとうに勝てなかったな。
827デフォルトの名無しさん:2009/06/26(金) 15:31:47
>>826
すげーな、それ。
ベイズ推定とかしていたのだろうか。
828デフォルトの名無しさん:2009/06/26(金) 15:33:01
>>824
乱数を用いた初心者向けのプログラムの中でも
もっとも簡単な基礎プログラムな気がするが。
829デフォルトの名無しさん:2009/06/26(金) 19:17:31
なぜC言語にはPerlのようなパターンマッチングという概念がないのでしょうか。
system関数で外部コマンド使うとか、自作するしかないのでしょうか。
自作を試みても100行超えてしまいます。Perlではたった1行で済むのに・・。何この差・・
830デフォルトの名無しさん:2009/06/26(金) 19:21:40
そういう人は、Perlの巣に帰っていいから、二度とこないでいいよ
831デフォルトの名無しさん:2009/06/26(金) 19:21:48
>>829
Perlでやればいいよ
regex?
832デフォルトの名無しさん:2009/06/26(金) 19:22:42
>>829
言語の目的が違うから?
perlは元からテキストなどを扱いやすいようにしてある言語だと聞いてるけど。
Cは元はそういう趣旨じゃないし。
それに一行で済むって、それはインタプリタ内で命令にあった処理を行ってるだけで
早い話あなたが実装した100行超のようなのが見えないところに実装されてるだけですよ
833デフォルトの名無しさん:2009/06/26(金) 19:24:41
regex.h
834デフォルトの名無しさん:2009/06/26(金) 19:25:11
>>829
scanf 系のマッチングでなんとかなるかもしれないし、ならないかもしれない
835デフォルトの名無しさん:2009/06/26(金) 19:27:52
ほんとにスクリプトとマネージドからくる奴はうざいのが多いな
836デフォルトの名無しさん:2009/06/26(金) 19:36:02
パターンマッチと言ったら普通 Prolog とか Haskell のものを指すだろ
一体 >>829 は何を指して「パターンマッチ」と言っているんだ?
837デフォルトの名無しさん:2009/06/26(金) 19:42:26
>>836
お前の「普通」はよく分からない
838デフォルトの名無しさん:2009/06/26(金) 20:26:54
正規表現のマッチングを100行かそこらで作ってしまうのはすごいな。
839デフォルトの名無しさん:2009/06/26(金) 20:42:49
>>829
適当なライブラリ探してきて使えばいい。
printfもscanfも、ライブラリ関数だ。
840デフォルトの名無しさん:2009/06/26(金) 21:10:19
一番シンプルで使いやすい正規表現ライブラリは何なの?
このさいc++でもいい
841デフォルトの名無しさん:2009/06/26(金) 21:21:37
>>840
Boost.Xpressiveは?
842デフォルトの名無しさん:2009/06/26(金) 22:45:24
正規表現ってなんですか?
843デフォルトの名無しさん:2009/06/26(金) 22:46:32
ぐぐってください
844デフォルトの名無しさん:2009/06/26(金) 22:55:30
a=(b=b+1)を簡潔にするとa=++bになるらしいんだがどうして?
a=b++じゃだめなのかな

845デフォルトの名無しさん:2009/06/26(金) 22:57:12
俺のせいきを見ろっていう芸術表現のこと
846デフォルトの名無しさん:2009/06/26(金) 22:57:24
>>844
自分で実行しろ。

>>842
お前もググれ。


ちょっといい加減にバカが多すぎる。
847デフォルトの名無しさん:2009/06/26(金) 23:00:35
>>844

a=++bの動き:bを1加算してからaに代入する
a=b++の動き:aにbを代入してからbに1を加算する

明らかにa=(b=b+1)は上の動き
848デフォルトの名無しさん:2009/06/26(金) 23:00:35
>>844
前置インクリメント、後置インクリメントでググると良いよ
849デフォルトの名無しさん:2009/06/26(金) 23:11:47
正規表現についてしらべました。
なんとなくわかりました。

でもこんなのコンパイラを作る人とかにしか関係ないと思うのですが
なんで必要なんですか?
850デフォルトの名無しさん:2009/06/26(金) 23:15:18
え?
851デフォルトの名無しさん:2009/06/26(金) 23:26:27
>>849
テキスト処理に使うだろ
852デフォルトの名無しさん:2009/06/26(金) 23:32:54
>>849
何も分かっていないwwww

もういいよ、じゃあコンパイラでも作ってろ
853デフォルトの名無しさん:2009/06/26(金) 23:45:12
>>851
少しわかりました

>>852
わかってたら質問しません。
854デフォルトの名無しさん:2009/06/26(金) 23:45:52
>>853
なかなか見込みのある男だ
ガンバレ
855デフォルトの名無しさん:2009/06/26(金) 23:51:46
そのレベルじゃ必要ないから忘れていいよ。
856デフォルトの名無しさん:2009/06/27(土) 00:03:34
俺も特に使わないな。大抵は普通の文字列検索で事足りる
857デフォルトの名無しさん:2009/06/27(土) 00:09:15
>>838
俺も真っ先にそう思った
858デフォルトの名無しさん:2009/06/27(土) 00:13:29
つまり、正規表現機能つきのマクロがほしい、と。
859デフォルトの名無しさん:2009/06/27(土) 00:14:06
strstr 相当のBM法かと思ってた
860デフォルトの名無しさん:2009/06/27(土) 00:15:22
>>853
お前「なんとなくわかりました。」
俺「何も分かっていないwwww」
お前「わかってたら質問しません。」

だから俺がさっきから「何も」分かっていないと
言ってるじゃないか。

部分否定じゃなくて完全否定だよ?
頭おかしいのかな?
861デフォルトの名無しさん:2009/06/27(土) 00:33:14
829です。
C言語でCGIプログラムをつくりたいのでパターンマッチングがないと不便です。
Perlでやれというのはなしで。
862デフォルトの名無しさん:2009/06/27(土) 00:34:24
ライブラリ探すか、無ければ作る
それがC/C++の世界
863デフォルトの名無しさん:2009/06/27(土) 00:36:18
>>861
パターンの種類を列挙できるならやってみて
864デフォルトの名無しさん:2009/06/27(土) 01:01:20
なんでPerlは無しなの?ひどくね?
Webサーバは何使うの?
865デフォルトの名無しさん:2009/06/27(土) 01:15:34
どうせCのほうが速いからとか、くだらない理由。
866デフォルトの名無しさん:2009/06/27(土) 02:06:51
CGIは別プロセス起動のオーバーヘッドがある
ApacheモジュールのPHPのほうがCのCGIより速いんじゃない
867デフォルトの名無しさん:2009/06/27(土) 02:20:37
Perlを使える環境構築に頓挫したからだよ多分
868デフォルトの名無しさん:2009/06/27(土) 04:17:37
#include <stdio.h>

int main(void)
{
int a,b;
char d;

printf("aha");
scanf_s("%d",&a);
printf("bha");
scanf_s("%d",&b);
printf("dha");
scanf_s("%c",&d);

printf(" %d ",a);
printf(" %d ",b);
printf(" %c ",d);

return 0;
}

dの入力ができません。
どなたか試してくれませんか。
869デフォルトの名無しさん:2009/06/27(土) 05:29:32
" %c"
870デフォルトの名無しさん:2009/06/27(土) 19:03:45
構造体の中に関数ポインタを持たせたい場合はどのように書けばいいのでしょうか?

あとその構造体の中の関数ポインタに登録されている関数を実行するコードはどのように書けばいいでしょうか?
871デフォルトの名無しさん:2009/06/27(土) 19:15:55
>>870
#include<stdio.h>

struct foo{
int a, b;
void (*bar)(struct foo *);
};

void prt_a(struct foo *p){
printf("a=%d\n", p->a);
}

void prt_b(struct foo *p){
printf("b=%d\n", p->b);
}

void prt_ab(struct foo *p){
printf("a=%d b=%d\n", p->a, p->b);
}

#define CALL_BAR(x) (x)->bar(x)

int main(void){
struct foo hoge={1,2,prt_a}, huga={3,4,prt_b}, haga={5,6,prt_ab};

CALL_BAR(&hoge);
CALL_BAR(&huga);
CALL_BAR(&haga);
hoge.bar(&hoge);

return 0;
}
872870:2009/06/27(土) 19:23:31
>>871
ありがとうございます
873デフォルトの名無しさん:2009/06/27(土) 20:44:46
ポインタ配列と二次元配列は状況によって使い分けろと教わりました。
ポインタ配列のほうが効率良くメモリを使用できると思うのですが、
二次元配列でないと駄目な状況とはどのような場合なのでしょうか?
874デフォルトの名無しさん:2009/06/27(土) 20:52:52
2次元配列の方が効率いいだろ
1回のmallocで済む
875デフォルトの名無しさん:2009/06/27(土) 20:58:20
文字に限ってはこんな感じかな?
http://ysserve.int-univ.com/Lecture/c2/e_04-03.html

876デフォルトの名無しさん:2009/06/27(土) 21:00:10
メモリー使用効率はポインタ配列の方がいいだろ。
使わない所はNULLで開放してればいいわけだし
877デフォルトの名無しさん:2009/06/27(土) 21:03:21
>>876
かならずってわけじゃないでしょ
878デフォルトの名無しさん:2009/06/27(土) 21:06:52
データの構造によるんでしょ
879デフォルトの名無しさん:2009/06/27(土) 21:08:07
配列の中で色々やる場合は
連続してる方がキャッシュ効率が良くなって速くなりそうな気はする
880デフォルトの名無しさん:2009/06/27(土) 21:08:46
構造体のソートの時は構造体を指すポインタ配列を持っていれば
ソートは速いね。

構造体が大きければ大きいほど。
881デフォルトの名無しさん:2009/06/27(土) 21:09:53
.>>875のような小さいエリアなら2次元配列を大きめに確保しておけばいいしね
882デフォルトの名無しさん:2009/06/27(土) 21:34:48
構造体Aに構造体Bが含まれているのですが構造体Bの中で構造体Aのポインタをもつ場合は
どのように宣言すればいいのでしょうか?
883デフォルトの名無しさん:2009/06/27(土) 21:43:53
>>882
>883
struct A;
struct B {
struct A *a;
};
struct A {
struct B b;
};
884デフォルトの名無しさん:2009/06/27(土) 21:50:46
>>883
ありがとうございます
885デフォルトの名無しさん:2009/06/28(日) 00:17:42
typedef を解除する方法はないの?
886デフォルトの名無しさん:2009/06/28(日) 00:28:44
untypedef
887デフォルトの名無しさん:2009/06/28(日) 00:41:31
>>885
typedefは#defineのようなプリプロセッサーに対する指令でないから
untypedefはない。
888デフォルトの名無しさん:2009/06/28(日) 02:20:07
スコープでどんこらする事のような
889デフォルトの名無しさん:2009/06/28(日) 09:45:15
int hoge;

//hogeになにか入れたりします。


if(hoge % 1 == 0)
{
//処理
}

こういうロジックがあるのですが
hoge % 1 って常に0ですよね・・・?
890デフォルトの名無しさん:2009/06/28(日) 09:47:32
配列HOGE[5]に"abcd"という文字列が入っています
これを使って、全く別のint型の変数abcdにアクセスしたいのですが、どのような方法がありますか?
891デフォルトの名無しさん:2009/06/28(日) 09:53:22
リフレクション
892デフォルトの名無しさん:2009/06/28(日) 09:59:02
>>890
むり。
893デフォルトの名無しさん:2009/06/28(日) 10:23:31
デバッグシンボルを元にリフレクションを行うという手法は存在する。
894890:2009/06/28(日) 10:28:38
回答ありがとうございます
なんとできないのですか・・・

抽象的な質問になって申し訳ないのですが
こういう場合、普通どういう方法を使うのでしょうか?
自分だと、単純にif文かswich文で
文字列abcdが入っていたら、変数abcdをうんたら〜しか思いつきません
895デフォルトの名無しさん:2009/06/28(日) 10:32:38
ああchar型配列に入ってる文字列と同じ名称の変数にってことか・・・

まあ仕組みを組めばできなくはないけどな・・・・
896デフォルトの名無しさん:2009/06/28(日) 10:40:42
変数名というのは人間界のものなんだよ。
Cにもハッシュテーブルがあれば、やりたいことが簡単にできそうだけどね。

解決策としては、全部番号にする手がある。
文字列をデータベースみたいに配列に格納して、変数も配列にする。
で、1番の文字列が見つかったら、1番の変数を操作するようにする。
変数名じゃなくて、文字列表の中の番号を使う。
897デフォルトの名無しさん:2009/06/28(日) 11:51:37
>>894
>>自分だと、単純にif文かswich文で
>>文字列abcdが入っていたら、変数abcdをうんたら〜しか思いつきません

それでいいんじゃない?
対象の変数が少なければ、それが普通かと
898デフォルトの名無しさん:2009/06/28(日) 13:56:43
int main(int argc,char *argv[])
{
Person dmy={"",0,NULL};
Person *start=&dmy;
Person *wkdtp;
Person *ip;
char name[30],age_ss[10];

while(1){

printf("名前="); gets(name);
if(strcmp(name,"")==0) break;
printf("年齢="); gets(age_ss);

wkdtp=(Person *)malloc(sizeof(Person));
if(wkdtp==NULL){
printf("メモリを確保できません\n");
exit(1);
}
899898:2009/06/28(日) 13:57:29
898続き

strcpy(wkdtp->name,name);
wkdtp->age=atoi(age_ss);

for(ip=start;ip->next!=NULL;ip=ip->next){
if(wkdtp->age < ip->next->age){
wkdtp->next = ip->next;
ip->next = wkdtp;
break;
}

一番下のfor文で、
ip=startでip->nextの値はNULLになるのではないでしょうか?
後まだ存在しないip->next->ageにアクセスしようとしていいのでしょうか?
900898:2009/06/28(日) 14:04:02
自己解決しました。
スレ汚し申し訳ありませんでした。
901デフォルトの名無しさん:2009/06/28(日) 15:24:58
execv*()の引数用の配列をmalloc()で確保したいのですが、
exec*()前にmalloc()したメモリはfree()しなくても大丈夫ですか?
902デフォルトの名無しさん:2009/06/28(日) 15:41:39
execvから返ってきた場合(エラーの場合)は freeする。
エラーが起きなければ返ってこないので freeしようがない。
903デフォルトの名無しさん:2009/06/28(日) 17:47:24
>>889
処理のところにちょこちょこbreakが入ってたりしない?
なんかのなごりというのが有力な気もするけど。
904デフォルトの名無しさん:2009/06/28(日) 18:47:57
INT_MIN % 1 とか変な結果になりうることがなかったっけ?
905デフォルトの名無しさん:2009/06/28(日) 19:00:31
>>904
うはっマジだ。ぐぐったら1じゃなくて-1だな。

#include <limits.h>
volatile int m = INT_MIN;
volatile int n = -1;
void main() { int i = m % n; }

VC落ちたw
906デフォルトの名無しさん:2009/06/28(日) 19:02:03
>>889
元々二回に一回等の処理したくて %2だったのが %1に変更されたんじゃないかと推測
907デフォルトの名無しさん:2009/06/28(日) 19:22:36
二回に一回の処理したくて
hoge &1 == 0
と勘違いしたんじゃないかな。
908デフォルトの名無しさん:2009/06/28(日) 21:15:54
typedef int num;
って書けば、変数宣言するときに
num i ; で
int i ;
と同じ意味になる(numはintの別名になる。)というのはわかってるんだけど


typedef struct tagDATEDATA
{
  int     Year ;  // 年
  int     Mon ;  // 月
  int     Day ;  // 日
  int     Hour ;  // 時間
  int     Min ;  // 分
  int     Sec ;  // 秒
} DATEDATA, *LPDATEDATA ;


って書いた場合はなにがどうなるの?
909デフォルトの名無しさん:2009/06/28(日) 21:19:35
DATEDATAがstruct tagDATEDATAの別名で
LPDATEDATAがstruct tagDATEDATA*の別名になる
910デフォルトの名無しさん:2009/06/28(日) 21:33:44
…ありがとう。
理解は出来たが、いややっぱり複雑で…微妙に理解出来てないかも。

LPDATEDATAって入力したらこの構造体へのポインタになる・・・の?
911デフォルトの名無しさん:2009/06/28(日) 22:16:34
そのとおり。
DATEDATA date;
LPDATEDATA pDate = &date;
pDate->Year = 2009;
912デフォルトの名無しさん:2009/06/28(日) 22:22:16
そんなtypedefは、まねる必要は無い。
とつくづく思うが、そんなリスト見かけるよな。
913デフォルトの名無しさん:2009/06/28(日) 23:15:08
C言語ではなくLinuxのシステムコールなのでスレ違いかもしれませんが
適切なスレが見つからないため質問させてください。
sample.txtの変更を監視するプログラムです。
epollの練習に書いてみたのですが、epoll_ctlがエラーを返します。


fd = open("sample.txt", O_RDONLY|O_NONBLOCK);
epfd = epoll_create(1);

memset(&ev, 0, sizeof(ev));
ev.events = EPOLLIN|EPOLLET;
ev.data.fd = 0;

epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev);
for(;;) {
epoll_wait(epfd, &ev, 1, -1);
printf("sample.txt is changed.\n");
}


このコードが期待通りに動きません。
調べてみるとepoll_ctl(2)が-1を返しており、errnoにEPERMが入っています。
また、fdを通常ファイルではなく、標準入力(1)にすると正常に動作します。
sample.txtの権限は644としており、読み書きが可能な状態としています。

どこが間違っているのでしょうか?
914デフォルトの名無しさん:2009/06/29(月) 00:08:10
epollって、対象fdがソケットやパイプじゃないと使えないんじゃないの?
915デフォルトの名無しさん:2009/06/29(月) 00:43:05
? :

これってどういう意味でしたっけ
ググってもヒットしてくれなくて・・・
916デフォルトの名無しさん:2009/06/29(月) 00:45:14
条件演算子でぐぐれ
917デフォルトの名無しさん:2009/06/29(月) 00:51:54
ありがとうございました
918デフォルトの名無しさん:2009/06/29(月) 05:30:31
スーパープログラマーの俺様が答えてやるぜ
こっちで頼むわ
http://nanajigen.blog74.fc2.com/
919デフォルトの名無しさん:2009/06/29(月) 20:08:33
携帯からで失礼します

'0'<=c && c<='9'
'a'<=c && c<='z' || 'A'<=c && c<='Z'
(*p>='a' && *p<='z')
(*p>='a' && *p<='z')&&(*p>='A' && *p>='Z')

上の5つの条件式なんですがなぜ上のように記述するのかいまいちわかりません
良かったら解説というか考え方をお願いします
920デフォルトの名無しさん:2009/06/29(月) 20:09:43
>>919
4つでしたねすいません
921デフォルトの名無しさん:2009/06/29(月) 20:11:46
>>919
半角文字の範囲をチェックしてます。
http://e-words.jp/p/r-ascii.html
この場合は数字の0-9とアルファベットの小文字a-zと大文字A-Zの範囲の文字かどうか

なぜこういうことでOKなのかといえば文字コードが連続してるから
922デフォルトの名無しさん:2009/06/29(月) 20:12:14
>>919
四つ目の条件はおかしい気がするぞ
923>>921:2009/06/29(月) 20:12:59
>>922
そういう式だけを抽出してきたのではと思ったのだが・・・
924デフォルトの名無しさん:2009/06/29(月) 20:14:09
不等号の向きが・・・まぁ単なる書き写し間違いかと
925922:2009/06/29(月) 20:15:37
携帯だから打ち間違えたのか
本当にその式でいいのか分からない
真ん中の && と一番最後の >=
926デフォルトの名無しさん:2009/06/29(月) 20:27:59
>>922
>>923
>>924
>>925
4つ目は打ち間違いでした
*p<='z'ですね

>>925
一応プログラムはちゃんと動いてたのであってるとは思います
ちなみに3つ目は英文字列を全て大文字に変換するプログラム
4つ目は英文字以外を全て空白に変換するプログラムで使用した条件式です

どうも理解できないですね(馬鹿なだけ)
文字コードで連続しているのはわかりました
927デフォルトの名無しさん:2009/06/29(月) 20:30:35
>>926
'0'<=c && c<='9'
この部分は

0x30 <=c && c<= 0x39
としてるのと同じ
928デフォルトの名無しさん:2009/06/29(月) 20:30:58
>>926
4つ目間違えました
すいません
この条件だとこうなるのかな(!(*p>='a' && *p<='z')&&!(*p>='A' && *p>='Z'))
929デフォルトの名無しさん:2009/06/29(月) 20:41:29
>>927
cの値が0x30以上かつcの値がcの値が0x39以下ってことでいいんですかね?
930デフォルトの名無しさん:2009/06/29(月) 20:42:26
>>929
そうですね
a-z A-Zも同じようにそれぞれの文字コードの範囲としても置きかえれます
931デフォルトの名無しさん:2009/06/29(月) 20:48:06
よくある入力された文字が数字もしくはアルファベットかどうかチェックするロジックでしょ?

*pの方は文字列チェックでcだけの方は1文字だけ?
932デフォルトの名無しさん:2009/06/29(月) 20:53:47
>>930
なるほどなるほど
ちなみに'0'<=c && c<='9'とc>='0' && c<='9'は同じ意味になりますよね?

>>931
1文字だけって訳じゃないです
933デフォルトの名無しさん:2009/06/29(月) 21:56:24
なるべくctype.hを使うべき。どうしようもないとき以外は。
934デフォルトの名無しさん:2009/06/29(月) 22:08:26
isdigit()とisalpha()もしくはisalnum()使え
935デフォルトの名無しさん:2009/06/29(月) 22:24:11
BohYoh.com【C言語講座】標準ライブラリ関数
ttp://www.bohyoh.com/CandCPP/C/Library/
ここ便利かもね。
936デフォルトの名無しさん:2009/06/29(月) 23:26:26
スレ違いだと思うのですが教えて下さい。。。

プログラムで出力したファイルを
バッチファイルで日付を入れてリネームしたいのですが
ワイルドカードの使い方がわかりません。

例えば
test.txt ->test_090629.txt

としたいのですが、
拡張子を除いた部分の「test」をどうやったら抜き出せるのかわからないのです。

OSはWindows vistaです。
よろしくお願いします。

937デフォルトの名無しさん:2009/06/29(月) 23:27:55
c>='0' && c<='9'
じゃなくて
'0'<=c && c<='9'
の方が数直線的に見やすくてよくね?って言ったらハァ?って顔された俺は異端なのかね
938デフォルトの名無しさん:2009/06/29(月) 23:30:10
まあどっちかに定数を持っていく方がいいと思うよ
右なら右とか
939デフォルトの名無しさん:2009/06/29(月) 23:34:07
cが'0'以上で'9'以下
というように、cを主語にして考えるので、前者の方が見やすい。
940デフォルトの名無しさん:2009/06/29(月) 23:35:26
c>='0' &&
c<='9'

嫌ならこう書いてもいいしな
941デフォルトの名無しさん:2009/06/29(月) 23:37:02
>>937
おれもその表記のほうが好きだ。数学的思考。
942デフォルトの名無しさん:2009/06/29(月) 23:37:44
やっぱり異端なのかorz
c < '0' || '9' < c
とかもわかりやすいと思ってたのにな。。
100 <= i && i < 1000 とかさ。。。
943デフォルトの名無しさん:2009/06/29(月) 23:39:06
>>939
「cは、'0'と'9'の間にある」っていう
ひとつのパターンで見る考え方もあるが?
世の中のコードを検索して比率を調べてみたら面白いかもしれない。
944デフォルトの名無しさん:2009/06/29(月) 23:39:38
>>937
数学的な値域の表現 0 ≦ c ≦ 9 の形に近い というやつね

>>939
たまたま 1回 c の評価をしてるだけ って立ち場だね
 c が '0' 以上で' d が '9' 以下 なら
 c <= '0' && d <= '9'
って書くし と。

どちらの主張も理解できるだけに悩ましい。 おれは上段のほうが好み
945デフォルトの名無しさん:2009/06/29(月) 23:55:09
符号の向きが揃ってる方が個人的には見やすい
946939:2009/06/29(月) 23:59:36
>>943
主語は左に無いと読みにくくて・・・。
あと&&が左右を完全に分断しているように見えるので、
おっしゃるような一つのパターンとして見ることができません。
数式なら断然「0 ≦ c ≦ 9」が見やすいんだけどね。
947デフォルトの名無しさん:2009/06/30(火) 00:01:56
>>944
うん。
大小比較は大抵 < か <= にそろえてる
948デフォルトの名無しさん:2009/06/30(火) 00:02:19
>>946
その辺は数学の数式に慣れろというのと同じでc言語のお作法になれろというか
バグを出しにくい書き方を覚えろとしかいえない
949939:2009/06/30(火) 00:10:09
>>948
C言語としても、どちらの作法もありだと思います。
私の場合、長年慣れ親しんだ前者が見やすいのでバグを出しにくいですね。
950デフォルトの名無しさん:2009/06/30(火) 00:12:15
>>948
この件で、C言語のお作法ってあるのかな?
とおもって、K&Rパラパラめくったら、同じようなコードを発見!
表紙の白いバージョン53ページ

if ( c >= 'A' && c < 'Z')

って書いてあるぞ。28〜29ページにも同じようなコード。
ということです。

でも、個人的には 'A' <= c && c <= 'Z' のほうが好きだけど。
951デフォルトの名無しさん:2009/06/30(火) 00:13:23
気持ち悪いのがすきなんだな
952デフォルトの名無しさん:2009/06/30(火) 00:14:23
>>950
K&Rの書き方は他の部分でも必ずしもスマートなわけではないと記憶してる
953デフォルトの名無しさん:2009/06/30(火) 00:14:35
お作法というのは先輩お作法だな

たぶん
'A' <= c && c <= 'Z'
これは嫌いなグラマー多いと思う
954デフォルトの名無しさん:2009/06/30(火) 00:16:53
確かに、ぐぐったらc >= '0' && c <= '9'の方が多かった
955デフォルトの名無しさん:2009/06/30(火) 00:17:35
{ } の付け方みたいな話だな。
まさかGNUコーディングスタイルとかで決まってないか?
956デフォルトの名無しさん:2009/06/30(火) 00:18:41
条件式で主語が左とかいう思考が理解できないのだが。
もしかして世の中ではソース読むときにいちいち日本語に直して理解するのが多数派なのか?
957デフォルトの名無しさん:2009/06/30(火) 00:18:53
文字だと気持ち悪いが、 0.0 <= x && x <= 1.0 は許容。
958デフォルトの名無しさん:2009/06/30(火) 00:21:31
>>956
そんな難しく考えてなくて

c <= 'Z'

1つだとこう書く

たまたま文字の範囲チェックなので挟む
でも
c >= 'A'
c <= 'Z'
の間なので

&&で繋げる

それだけ
959デフォルトの名無しさん:2009/06/30(火) 00:22:16
※このスレはあくまで個人的な感想です。コードの書き方・読み方には個人差があります。
960デフォルトの名無しさん:2009/06/30(火) 00:45:13
C言語を勉強し始めて3週間目の初心者です。
今「*」で図を書くプログラムに挑戦しているのですが平行四辺形・菱型・星型・渦巻き・ハートができません。
基礎であろう四角形と三角形(逆三角形と旗型)は作成できました。

作成する際の条件なのですが、
@2〜9を入力すると入力した行分の高さの図ができる。
A繰り返しをしようする。

です。
どうか皆さんの知識を分けていただけないでしょうか?お願いします。
961デフォルトの名無しさん:2009/06/30(火) 00:56:27
平行四辺形は▲▼
菱形は


星はええと、*なのか☆なのかによる
渦巻きハートは努力次第
962デフォルトの名無しさん:2009/06/30(火) 00:57:25
つか宿題じゃないのソレ。
挑戦するだけなら自分にわざわざそんな条件つけないしょ
963デフォルトの名無しさん:2009/06/30(火) 00:59:30
このスレの範囲じゃないね
宿題スレへどうぞ
964デフォルトの名無しさん:2009/06/30(火) 00:59:32
☆なのはたん、ハァハァ
965デフォルトの名無しさん:2009/06/30(火) 01:00:53
渦巻きは、四角い渦だと楽かな。
ハートは半円二つ+三角形で。
966デフォルトの名無しさん:2009/06/30(火) 01:08:37
>>961
星型は*です。

>>962
宿題ではありません。三角形と四角形が@Aの指定があったのでそのままの条件で作れないかと思い
そのようにしました。
967デフォルトの名無しさん:2009/06/30(火) 01:10:10
2行とかありえないだろ
968デフォルトの名無しさん:2009/06/30(火) 09:59:23
*****
*****
*****
*****
*****
--
これだって立派に菱形でもあり平行四辺形でもある。
969デフォルトの名無しさん:2009/06/30(火) 10:09:26
と、私が小学生のときに発表して、先生を困らせたんだよなぁ。
970デフォルトの名無しさん:2009/06/30(火) 10:25:54
>>967
理解力なさす
971デフォルトの名無しさん:2009/06/30(火) 10:26:57
困る先生にも困ったもんだ。

今回の「◆」と「▲▼」にしたって、単に「対角線が水平と垂直になる四角形」と
「二辺が水平で残りの二辺が傾斜した平行四辺形」とするだけでいいのに。
972デフォルトの名無しさん:2009/06/30(火) 10:29:47
>>966
「*」と言われても、フォントによって五傍星も六傍星も八傍星もあるのだが。
973デフォルトの名無しさん:2009/06/30(火) 10:37:23
あらかじめテキストファイルに出力したい絵を描いておいて、
入力に応じてファイルを選択して表示すればいいんじゃないの?
ファイルを1行ずつ読むところで繰り返しを使用するし
974デフォルトの名無しさん:2009/06/30(火) 10:43:33
それやるなら、配列でデータ持たせとく。
975デフォルトの名無しさん:2009/06/30(火) 11:00:47
さてと、そろそろヒントを書いておくかね。

・平行四辺形(▲▼)
三角形(▲)を作れればその応用。行内の開始点は▲と同じで、長さ一定とするだけ。

・菱形(◆)
これも三角形(▲)と逆三角形(▼)の応用。▲を出力したら、続けて▼を(1行減らして)出力すればいい。
後は高さに注意。三角形の行数の2倍-1行必要だから、2行では菱形に見えない。

・星型
これはややこしいな。出力したい形をエディタで書いておいて、規則性を探してみればいいよ。
順番としては、後回しにすることお勧め。場合によっては、>973-974のようにデータ構造を考えた方がいいかも。

・渦巻き
四角い渦巻きならそれほど難しくない。これもエディタで書いてみてから
上半分と下半分に分けて規則性を探せばいい。
但し、9行使っても目立った渦巻きにならないのに2行では渦どころか一巻きもできない。
そこはどう解釈する? 規則性を見つけやすいだけ星型よりはましかな。

・ハート
>965にもあるけど、上半分の半円を工夫すれば後は菱形の応用かな。これも行数に注意。
976デフォルトの名無しさん:2009/06/30(火) 11:31:14
試しにうずまき作ってみた。MAXを9にすれば9行になるけど
ぎりぎり一巻きぐらい。
#include <math.h>
#define MAX 60
main()
{
int i,t;
double v,w,x,y;
char table[MAX][MAX+1];

memset(table, ' ', sizeof(table));

w = 3.0/180;/* radian */
v = 0.03;
for(t=0; t<1000; t++) {
x = t*v*sin(w*t*M_PI);
y = t*v*cos(w*t*M_PI);

x += MAX/2;
y += MAX/2;
if(x < 0 || x >= MAX || y < 0 || y >= MAX) continue;
table[(int)y][(int)x]='*';
}

for(i=0; i<MAX; i++) {
table[i][MAX]=0; printf("%s\n", table[i]);
}
}
977デフォルトの名無しさん:2009/06/30(火) 12:13:41
>>976
table[MAX][MAX]にしておいて、printf("%.*s", MAX, table[i])とした方がいいと思うの。
978デフォルトの名無しさん:2009/06/30(火) 12:28:46
二次元文字配列みたいなことをしたいのですがうまくいきません。
↓だと大量に警告が出てコンパイルは通るのですが、実行するとcore dump吐いて落ちてしまいます。
これの正しい書き方が分かる人がいましたらご教示ください。
#include <stdio.h>
int main()
{
char ***pppChar = {
{"abc", "def", "ghi", NULL},
{"jkl", "mno", NULL},
NULL
};
char **ppChar, *pChar;
for(ppChar = *pppChar; ppChar != NULL; ppChar++){
for(pChar = *ppChar; pChar != NULL; pChar++){
printf("%s ", pChar);
}
printf("\n");
}
return 0;
}
979デフォルトの名無しさん:2009/06/30(火) 12:51:13
>>970
は?
指摘してる人もいるが2行だと要求してる図形にならないのもあるだろ
980デフォルトの名無しさん:2009/06/30(火) 12:52:37
>>978
// 二つ問題がある。一つは可変長配列の初期化、もう一つはポインタの型
#include <stdio.h>
int main()
{
char * firstStrings[] = {"abc", "def", "ghi", NULL};
char * secondStrings[] = {"jkl", "mno", NULL};
char ** stringArrays[] = {firstStrings, secondStrings, NULL};
for (int i = 0; stringArrays[i] != NULL; ++i) {
for (int j = 0; stringArrays[i][j] != NULL; ++j) {
for (int k = 0; stringArrays[i][j][k] != '\0'; ++k) {
putchar(stringArrays[i][j][k]);
}}}
for (char *** p = stringArrays; * p != NULL; ++p) {
for (char ** q = * p; * q != NULL; ++q) {
for (char * r = * q; * r != '\0'; ++r) {
putchar(* r);
}}}
return 0;
}
981デフォルトの名無しさん:2009/06/30(火) 12:55:17
>>978
いっぺんにchar型へのポインタ配列のポインタ配列は初期化無理みたいね

#include <stdio.h>

int main(void)
{
char *ppChar1[] = {"abc", "def", "ghi", NULL};
char *ppChar2[] = {"jkl", "mno", NULL};
char *ppChar3[] = {NULL};

char **ppChar[3], ***pppChar;
char **ppCharx;

ppChar[0] = ppChar1;
ppChar[1] = ppChar2;
ppChar[2] = ppChar3;

for (pppChar = ppChar; *pppChar != NULL; pppChar++) {
for (ppCharx = *pppChar; *ppCharx != NULL; ppCharx++)
printf("%s ", *ppCharx);
printf("\n");
}

return 0;
}
982デフォルトの名無しさん:2009/06/30(火) 13:00:13
警告をつぶすのが先か 考え方を整理するのが先か 迷いどころだな

●一番外の配列の要素数宣言は省略できるけど、内側は無理(固定量ならOK)
●内側がポインタになってて そこに配列の先頭を渡す宣言で、なおかつ その配列が個別に実体の大きさが違う

int で似たようなのを考えると こんな感じかねぇ…

int pData1[] = { 1, 2, 3, 0 };
int pData2[] = { 4, 5, 0 };
int pData3[] = { 6, 0 };
int *ppData[] = { pData1, pData2, pData3, NULL, };

int i;
for (i=0; ppData[i] != NULL; i++) {
 int *pData;
 for (pData = ppData[i]; *pData; pData++) printf("(%d)", *pData);
 printf("\n");
}
983デフォルトの名無しさん:2009/06/30(火) 13:03:58
>>977
1行に2個'*'がでることもあるし。。
984デフォルトの名無しさん:2009/06/30(火) 13:04:52
>>983
は?
985デフォルトの名無しさん:2009/06/30(火) 13:15:37
これがエラーになっちゃうんですよ
何とかなりませんかね

char **ppChar[] = { ppChar1, ppChar2, ppChar3 };
986デフォルトの名無しさん:2009/06/30(火) 13:17:04
エラーメッセージに従えばいいと思います。
987デフォルトの名無しさん:2009/06/30(火) 13:19:06
>>985
エラーメッセージも貼るといいよ
988デフォルトの名無しさん:2009/06/30(火) 13:29:26
>>983
%.<数値>s というフォーマット知らない?
フォーマット文字列内の数値部を引数からもってくる って仕様の
%.*s という指示があるわけで 決して * を表示しようとしているのではないぞ
989デフォルトの名無しさん:2009/06/30(火) 13:40:20
ああ、すごく、すごく見間違えていたよ。
990デフォルトの名無しさん:2009/06/30(火) 13:43:05
>>987
エラー E2063 strstr1.c 16: 不正な初期化(関数 main )

どうもポインタ配列で他のポインタ配列を初期化しようとすると
だめみたいだ
991デフォルトの名無しさん:2009/06/30(火) 13:47:12
配列のサイズが決まってないからじゃないの?
関数ポインタの配列だと同じようにポインタで初期化できてるし(ポインタ配列じゃなく関数だけどさ)
992デフォルトの名無しさん:2009/06/30(火) 13:48:12
ついでにgcc4.4.0のエラーも貼っておく
strstr1.c: In function 'main':
strstr1.c:19: error: incompatible types when assigning to type 'char **[3]' from type 'char **'
993デフォルトの名無しさん:2009/06/30(火) 13:49:57
>>992
char **ppChar = { ppChar1, ppChar2, ppChar3 };
こう書いてるだろ?

char **ppChar[] = { ppChar1, ppChar2, ppChar3 };
とは全然意味が違うんだぜ
994デフォルトの名無しさん:2009/06/30(火) 13:51:24
>>993
>>985

ちゃんと書いてます
995デフォルトの名無しさん:2009/06/30(火) 14:55:00
次はppcharがconstじゃないと言う落ちだな。
996デフォルトの名無しさん:2009/06/30(火) 14:55:20
ppChar1〜3 が char** になってない、以外に想像がつかんのだが。
997デフォルトの名無しさん:2009/06/30(火) 15:00:46
こういうソースです

#include <stdio.h>

int main(void)
{
char *ppChar1[] = {"abc", "def", "ghi", NULL};
char *ppChar2[] = {"jkl", "mno", NULL};
char *ppChar3[] = {NULL};

char **ppChar[3], ***pppChar;
char **ppCharx;

char **ppCharx[] = {ppChar1, ppChar2, ppChar3};

for (pppChar = ppChar; *pppChar != NULL; pppChar++) {
for (ppCharx = *pppChar; *ppCharx != NULL; ppCharx++)
printf("%s ", *ppCharx);
printf("\n");
}

return 0;
}
998デフォルトの名無しさん:2009/06/30(火) 15:06:31
そもそも
>char **ppCharx;
>char **ppCharx[] = {ppChar1, ppChar2, ppChar3};
なんだコレ。
999デフォルトの名無しさん:2009/06/30(火) 15:11:20
char **ppCharx;←無視して下さい 書いてありません
1000デフォルトの名無しさん:2009/06/30(火) 15:17:35
char **ppCharx[] = {ppChar1, ppChar2, ppChar3};

char **ppCharx[3] = {ppChar1, ppChar2, ppChar3};
これでだめなの?
10011001
このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。