立てた
乙
前スレの最後のほうのヤツら、プロプロってなんだよ?
プリプロだよ、馬鹿!
プロプロワロタ
プリプリのほうがいい
全部日本語にすると前処理指令だな。
Turbo C++ のヘルプにはプリプロセッサ指令と書いてあった気がする。
いつの間にか全部横文字にするのが広まったみたいだが、長過ぎて良くない。
プリプロ プロプラ ポリモル ポリゴン
ヒヤヒヤドキッチョの
C言語を覚えるにあたって
参考書を読破するのが先ですか
読みながらソース書くのがいいですか?
自分は後者なんですが、この調子だと、終わるのがいつになるのか・・・
最終的にはネットワークプログラミングをしたいです。
一応TCP(UDP)/IP、IPv6、VoIP関係の本は何冊か読破してパケットキャプチャ
やsyslogに出てくるログは理解できます。
WinXPとDebian使っています。
どなたかご教授を。
11 :
10:2007/03/08(木) 10:11:56
追記
Cにこだわらなくてもいいでしょうか?
>>10 最終的にはネットワークプログラミングをしたいなら
C にこだわらないほうが良い
ソケットとか文字列処理とかが楽な言語をオススメする
手順について
読破し終わってどっこいしょと手を動かし始めるよりは、動かして
引っかかりながら覚えた方がいいと思う。
言語について
どんな言語でプログラムを書くにせよ、TCP/IPはもちろん、
ファイルディスクリプタとかUNIXシステムコールの知識はあったほうがいい。
言語としてのCの知識もあることが前提になってるし。
難しくてもCを触っておいて損はしないと思うよ。
まさか、英語をマスターするまでは一言も喋りません、なんて阿呆はいないだろ。
英文法を覚えるよりも片言ででも喋った方が上達するのは蓋し当然だ。
makeでコンパイルしたときにコンパイルが通らなくて、
objファイルとか実行ファイルを削除した上でmakeしなおすと
うまくいくということを何度も経験するんですが、
これは何が原因でこういうことになっていますか?
>>16 makefile が正しく書かれていない可能性大
おそらくヘッダファイルの依存性が正しくない
PCのタイマーがくるってる場合も
20 :
デフォルトの名無しさん:2007/03/08(木) 16:54:53
int から int にマップするのに一番いい方法はなんでしょうか?
C++ならstd::map がありますが、こういうことをgccでやりたいのですが...
int map[MAX_MAP];
b = map[a];
だと早いのですがaの値が-32768〜32767の範囲で100個くらいの値をとるので
メモリ効率を考えるとムリポです。
>>20 100個程度なら配列の中身と逐次比較していけばおk
登録回数に比べて検索回数が多いならソートしてから bsearch でおk
一度ハッシュテーブルを自分で実装してみるのも勉強になるぞ。
>>21 >>22 うほ。さっそくdクスです。
ハッシュテーブルむずかしす(;´Д`)
bsearchでやってみます。
ありがとうございまぷ。
>>20 別にgccでもstd::mapを使えばよいのでは?
gccであってg++ではない(Cで書かなければならない)ということだろ。
>>23 std::mapはRed-Blackツリーとかの高度なアルゴリズムでマップを
作ってるはずなので、最初は見て理解しようとしなくていいからな。
スレ違いだが
Cとコマンドプロンプトどっちを先にやったらいいですかね?
28 :
20:2007/03/08(木) 18:05:28
>>25 そのとおりです。
g++が使えれば楽なのですがgccでC言語がりがり書いてます...
オープンソースとか、いまでもgccなものが多いですよね?
サーバソフトなどであまりg++が使われないのはパフォーマンスの問題でしょうか?
いやだから、gccはcコンパイラじゃなくてコンパイラコレクションなんだが。
>>29 コンパイラコレクションのことを指すときには
大文字でGCCと書いていることが多い気がする。
34 :
10:2007/03/08(木) 20:39:01
>>12-15さん
参考になりました。
まずCを参考書を読みながら勉強することにします。
それから違う言語に行きます。
>>15さんのアドバイス、理にかなっています。
そういわれると「なるほど」と(よい意味で)納得できます。
皆さんありがとうございました。
がんばれ超がんばれ
誰も言ってないようなんで、言っとくと
C言語の一番の上達は、「良い指導者を見つける事」だったりする
なかなか居ないけどね
36 :
デフォルトの名無しさん:2007/03/08(木) 20:43:00
#include <stdio.h>
#include <string.h>
struct seiseki {
char no[10];
char name[20];
};
void main(void){
struct seiseki seito[2];
seito[0].no = "111A001";
seito[0].name = "山田";
seito[1].no ="111A002";
seito[1].name = "鈴木";
printf("学籍番号|氏名");
printf("%s|",seito[0].no);
printf("%s|",seito[0].name);
}
コンパイルできません・・・。seito[0].no = "111A001";seito[0].name = "山田";
seito[1].no ="111A002";seito[1].name = "鈴木";のところで、左辺の値が必要
とでるのですが、どういうことでしょう?
"111A001"はポインタだから配列には代入できん。
strcpyを使いな。
39 :
10:2007/03/08(木) 20:51:16
間違い承知で言わせてください(すみません)
char は1バイトしか記憶できないのでは?
ごめんなさいごめんなさいごめんなさい
40 :
デフォルトの名無しさん:2007/03/08(木) 20:52:15
やっぱり違いましたか。
すみません
>>39 合ってます。大正解です。
おめでとうおめでとうおめでとう
42 :
10:2007/03/08(木) 21:03:56
え?
立て続けにもう一つだけお願いします
winXPとDebianでCの勉強はどちらが良いと思いますか?
43 :
デフォルトの名無しさん:2007/03/08(木) 21:11:16
36です。。
>>37 まだポインタまで勉強してないもので・・・。構造体配列の勉強の途中でした。
strcpyもまだ勉強してないっす・・・・・。ほんと初歩の初歩しかまだやって
いないので。。調べてやってみます。
貴重なアドバイスありがとうございました。
>>42 個人的な感想
WinXP ならコンパイラに bcc 使うとコンパイル時のエラーメッセージが分かりやすいと思う(但し、最初の設定でつまづく人が多い)
VisualC++Expressは使ったこと無いのでコメントできない
Debian だと OS のインストール時にコンパイラがインストールされてる(されてないかも知れない^^;)
ので、いきなり使えて余計なことを考えなくても済む
>>44 >但し、最初の設定でつまづく人が多い
決して難しい設定ではないんだけどねぇ。
でも、うっかり半角スペースを含むパスにインストールしちゃったら
プログラミング自体が初めてって人は問題の原因がわかんなくて
確実に挫折するだろうね。
46 :
デフォルトの名無しさん:2007/03/08(木) 21:24:27
C言語を習得することによって、どのような職業で有利になるのでしょうか?
というのは、最近、何気なくC言語に関するサイトを見ていたら面白そうに感じてしまい、
今実際に勉強している最中なのですが(と言ってもまだ2日目)
>43
普通文字列処理一通り済ませてから構造体に行かない?
>>46 職業の種類の割に役立つのはC言語よりもExcelVBAだと思う
C言語はたしかに面白いけど、職業のメインに据えるのは止めたほうがいい
簡単なツールを作るくらいはするが、ほとんど趣味でやってる
49 :
デフォルトの名無しさん:2007/03/09(金) 01:07:35
http://doiob.net/doiob/uploader/src/up0999.txt c:\source>buf
'buf' は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。
c:\source>bcc32 buf.c
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
buf.c:
警告 W8065 buf.c 32: プロトタイプ宣言のない関数 'openFile' の呼び出し(関数 main
)
警告 W8065 buf.c 33: プロトタイプ宣言のない関数 'saveFile' の呼び出し(関数 main
)
警告 W8065 buf.c 34: プロトタイプ宣言のない関数 'listLines' の呼び出し(関数 main
)
警告 W8065 buf.c 35: プロトタイプ宣言のない関数 'gotoLine' の呼び出し(関数 main
)
警告 W8065 buf.c 36: プロトタイプ宣言のない関数 'insertString' の呼び出し(関数 m
ain )
警告 W8065 buf.c 37: プロトタイプ宣言のない関数 'deleteString' の呼び出し(関数 m
ain )
警告 W8065 buf.c 38: プロトタイプ宣言のない関数 'showHelp' の呼び出し(関数 main
)
警告 W8065 buf.c 42: プロトタイプ宣言のない関数 'clearBuffer' の呼び出し(関数 ma
in )
警告 W8070 buf.c 43: 関数は値を返すべき(関数 main )
警告 W8065 buf.c 82: プロトタイプ宣言のない関数 'enterFileName' の呼び出し(関数
openFile )
50 :
49:2007/03/09(金) 01:08:20
警告 W8065 buf.c 84: プロトタイプ宣言のない関数 'countLines' の呼び出し(関数 ope
nFile )
警告 W8065 buf.c 92: プロトタイプ宣言のない関数 'clearBuffer' の呼び出し(関数 op
enFile )
警告 W8060 buf.c 109: おそらく不正な代入(関数 closeFile )
警告 W8065 buf.c 110: プロトタイプ宣言のない関数 'saveFile' の呼び出し(関数 clos
eFile )
警告 W8065 buf.c 111: プロトタイプ宣言のない関数 'clearBuffer' の呼び出し(関数 c
loseFile )
警告 W8065 buf.c 120: プロトタイプ宣言のない関数 'enterFileName' の呼び出し(関数
saveFile )
警告 W8065 buf.c 133: プロトタイプ宣言のない関数 'ptintf' の呼び出し(関数 listLi
nes )
警告 W8065 buf.c 142: プロトタイプ宣言のない関数 'ptintf' の呼び出し(関数 gotoLn
inss )
警告 W8019 buf.c 196: コードは効果を持たない(関数 deleteString )
警告 W8066 buf.c 199: 実行されないコード(関数 deleteString )
警告 W8066 buf.c 200: 実行されないコード(関数 deleteString )
Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland
Error: 外部シンボル '_gotoLine' が未解決(C:\SOURCE\BUF.OBJ が参照)
Error: 外部シンボル '_showHelp' が未解決(C:\SOURCE\BUF.OBJ が参照)
Error: 外部シンボル '_enterFileName' が未解決(C:\SOURCE\BUF.OBJ が参照)
Error: 外部シンボル '_ptintf' が未解決(C:\SOURCE\BUF.OBJ が参照)
ご指摘、宜しくお願い致します。
void openFile(); // 前方参照
void openFile(void); // プロトタイプ宣言
デバッグは自分でやれ
>>49 行数書いてあるんだから一つずつつぶして池よアホ
scanfでもなんでも入力はいいけど、
数字の入力を求めて、下3桁を取るにはどうしたら良いのでしょう?
%1000
%1000?
パーセン
剰余
なるほど、ありがとうございました
サーセンw
取るが取り出すなのか取り除くなのかわからん。
62 :
49:2007/03/09(金) 01:39:44
レス、ありがとうございます。
c:\source>bcc32 buf.c
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
buf.c:
警告 W8070 buf.c 43: 関数は値を返すべき(関数 main )
警告 W8060 buf.c 109: おそらく不正な代入(関数 closeFile )
警告 W8019 buf.c 196: コードは効果を持たない(関数 deleteString )
警告 W8066 buf.c 199: 実行されないコード(関数 deleteString )
警告 W8066 buf.c 200: 実行されないコード(関数 deleteString )
Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland
Error: 外部シンボル '_gotoLine' が未解決(C:\SOURCE\BUF.OBJ が参照)
Error: 外部シンボル '_showHelp' が未解決(C:\SOURCE\BUF.OBJ が参照)
Error: 外部シンボル '_enterFileName' が未解決(C:\SOURCE\BUF.OBJ が参照)
これらが、どうしてもわかりません・・・ので
ご指摘、お願い致します。
>62
エラーはプロトタイプ宣言の関数名と実際の関数名が違ってるんだろ。
>>62 何だこの変なインデントは
mainの}が見つからないかと思った。
> 警告 W8070 buf.c 43: 関数は値を返すべき(関数 main )
main()て書いたらとりあえず
int main()て思われてしまうので
return int型;
が必要でしょう。
というか省略しないようにしましょう。
>>62 >警告 W8060 buf.c 109: おそらく不正な代入(関数 closeFile )
どこが109行目かわからないので推測だ。
if(ans[0] = 'y')
比較する式じゃないからわろうな。
if(ans[0] == 'y')
のまちがえじゃないのか。
>>62 警告 W8019 buf.c 196: コードは効果を持たない(関数 deleteString )
警告 W8066 buf.c 199: 実行されないコード(関数 deleteString )
警告 W8066 buf.c 200: 実行されないコード(関数 deleteString )
実行しないから効果ないといっているのだろうか?
判りません。
Error: 外部シンボル '_gotoLine' が未解決(C:\SOURCE\BUF.OBJ が参照)
Error: 外部シンボル '_showHelp' が未解決(C:\SOURCE\BUF.OBJ が参照)
Error: 外部シンボル '_enterFileName' が未解決(C:\SOURCE\BUF.OBJ が参照)
gotoLineが宣言されているし使用しているが存在しない。
showHelpが宣言されているし使用しているが存在しない。
enterFileNameが宣言されているし使用しているが存在しない。
67 :
デフォルトの名無しさん:2007/03/09(金) 01:54:46
FILE *fpl,*fps
この*fplと*fpsってどのような命令なのでしょうか?
ググっても出てこなかったのでどなたか教えていただけると幸いです
68 :
49:2007/03/09(金) 01:55:39
皆さんのお陰で
警告 W8019 buf.c 197: コードは効果を持たない(関数 deleteString )
警告 W8066 buf.c 200: 実行されないコード(関数 deleteString )
警告 W8066 buf.c 201: 実行されないコード(関数 deleteString )
Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland
Error: 外部シンボル '_gotoLine' が未解決(C:\SOURCE\BUF.OBJ が参照)
Error: 外部シンボル '_showHelp' が未解決(C:\SOURCE\BUF.OBJ が参照)
Error: 外部シンボル '_enterFileName' が未解決(C:\SOURCE\BUF.OBJ が参照)
まで減らせましたが、
>>66さんの仰る通り、それが解決できませんので
どうすれば解決しますでしょうか?入門書の解説には
このサンプルソースしかありません・・・・・
>>68 お前が関数定義のところでtypoしてるんだって。
よく見直せよ
>>67 FILE * fpl;
FILE * fps;
両方ともFILE構造体へのポインタという変数ですね。
>>68 他人のプログラムの無い物までは私にはわかりません。
showHelpとShowHelpがあやしい。
72 :
デフォルトの名無しさん:2007/03/09(金) 02:11:02
>>70 回答ありがとうございます。
ファイルポインタは分かるんですが、lとsが付く事で何が変わるのでしょうか?
ド素人で申し訳ありません。
int il;
int is;
lとsが付く事で何が変わるのでしょうか?
75 :
デフォルトの名無しさん:2007/03/09(金) 02:14:34
>>73 なるほど。
回答本当にありがとうございます。感謝です。
>>73 lとsがつかなかったら
int i;
int i;
iが2つあるのでコンパイルエラーになる。
変数名の最後の文字lとsに特別な意味はないし、
変数名の最初の文字iにも特別な意味はない。
77 :
デフォルトの名無しさん:2007/03/09(金) 02:16:01
>>74 ありがとうございます。
参考にさせていただきます。
あはははh
>>73 i1もisも名前だからなんも変わらん。データを格納する箱を任意で付けてるだけだから。
>>70 今でもFILE*をfplとかfpsなんて変数名にしてる例があるのか。
算法の参考書では*fp *fp1 ...*fpnがスタンダードっしょ
82 :
49:2007/03/09(金) 02:22:15
http://doiob.net/doiob/uploader/src/up1002.txt c:\source>bcc32 buf.c
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
buf.c:
警告 W8019 buf.c 197: コードは効果を持たない(関数 deleteString )
警告 W8066 buf.c 200: 実行されないコード(関数 deleteString )
警告 W8066 buf.c 201: 実行されないコード(関数 deleteString )
Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland
Error: 外部シンボル '_gotoLine' が未解決(C:\SOURCE\BUF.OBJ が参照)
Error: 外部シンボル '_enterFileName' が未解決(C:\SOURCE\BUF.OBJ が参照)
格闘していますが、これが限界です。外部ソースなんてないし・・・・
あとは、翔泳社の参考書のなので、そこに問い合わせてみるべきですかね?
ありがとございました。。。あと、一歩なのに悔しいorz
>>82 だからお前がタイプミスしてんだと何度言えば分かるんだ
それじゃあ悪いハンガリアンと間違った変数名の付け方の例じゃないか。
アルゴリズムに夢中でそれ以外は手抜き。
俺は手抜きばかりなので判らなくもないけどね。
85 :
49:2007/03/09(金) 02:26:33
なんとか探してみます、サンクスでした
>>82 まあ、gotoLineがありませんとか、enterFileNameがありませんとかは、
他人のプログラムなので俺にはわからないよ。
enterFileNameとentrFilenameがよく似てるね。
197 のステートメントはなんだ?if文に処理が無いじゃないか。
何がうざいかって中途半端な気持ち悪いインデントがムカつくな。
mainのみとか、()として(void)ときちんと書かないのも許せないが。
197行目のif文の未解決>ステートメントが意味不明。
gotoLineとentertFilenameの関数を作ってないんじゃないの?
以上
gotoLninssって使ってないね。
今のままでもエラーじゃないのかもしれんけど
せめて
int main()
かな
void main にしとくとreturnとかexit(0)入れなくてもプログラムの実行処理後、コンパイラが自然に
コマンドプロントを閉じてくれる。
void mainは規格違反だろ…
94 :
デフォルトの名無しさん:2007/03/09(金) 02:42:02
とりあえず、gotoLineとenterFileNameの定義部分で関数名間違えてる。
あとは、意味を成さないコードがあるので優しいbccが警告してるだけ
ところで、こんな不思議な書き方始めて見た・・・関数の閉じ括弧にインテンドとか・・・
95 :
デフォルトの名無しさん:2007/03/09(金) 03:05:00
・∀・)っ-○◎● は x64でのデータ型の定義も知らずに何をほえているのか?
なんかVisualC++に挫折経験があるみたいだけどw
delphi 厨の典型だな
96 :
49:2007/03/09(金) 03:19:38
97 :
49:2007/03/09(金) 03:27:59
c:\source>buf
command:fopen
filename:test.txt
command入力でfopenし
test.txtを実行するとエラーで止まってしまいます
考えられる原因の助言、宜しくお願い致します。
デバッグは自分でやれ
>scanf("%s, fname");
新手法ですか?
100 :
デフォルトの名無しさん:2007/03/09(金) 04:23:48
exit(1)やexit(-1)というのは意味合いとしては変わらないですよね?
使い分ける意味はやはりソースを分かりやすくするためでしょうか?
UNIX等のシェルスクリプト環境で複数のツールをチェインしたりするときに使うことがある
関数の返値と同じように、プロセスのリターンコードも条件判断に使えるのさ
異常終了という点では同じだけど、返り値でエラーの種類を伝えたりする場合もあるはず。
例えばgzipが、成功 : 0,エラー : 1,警告 : 2 とやってるみたいに。
104 :
デフォルトの名無しさん:2007/03/09(金) 05:26:27
次スレ
デバッグなら俺を使え(ガチレス篇)Part10
107 :
質問:2007/03/09(金) 09:16:47
ヘッダー he.h
struct inu {
int ip;
int mac;
};
メイン she.c
#include <stdio.h>
#include "he.h"
int main(void) {
struct inu tao;
tao.ip = 123;
tao.mac = 456;
printf("%d\n",ip);
printf("%d\n",mac);
}
なにがいけないんでしょうか?
>107
>printf("%d\n",ip);
>printf("%d\n",mac);
109 :
質問:2007/03/09(金) 09:22:59
びっくりしました。
アハ体験できました。ありがとうw
アハ体験って・・・
アホ体験だろ
だれがうま
なみ
なのね
あなた
とっても
ラッキーマン
コーヒー
あなた
len = strlen(string) + 1;
p = malloc(len);
len = strlen(string);
p = malloc(len+1);
どう考えても後者だよな? 普通後者だよな?
p + len が末尾の\0を指すべき。
後者だな
俺こう言葉を使い分けている。
size = strlen(string) + 1;
p = malloc(size);
len = strlen(string);
p = malloc(len+1);
mallocで文字列領域確保するってどんな状況なんだ?
大量に文字列読むにしても効率悪くない?
データ長か文字長かなんて"len"の一言でわからないんだから
p = malloc( strlen(string) + 1 );でつ
っ strdup
標準関数じゃないやん
129 :
デフォルトの名無しさん:2007/03/09(金) 15:33:47
if(p==NULL || p -> data >= n)
をstrcmp()で表すことって可能ですか?
無茶を言うな。
意味が分かりませんまさお
>>126 char *string=NULL;
の時もがんばれ
この早さなら言えるぬるぽ
すいません初心者です。
関数宣言で、
static void myfunc(void);
と
void myfunc(void);
何が違ってくるのでしょうかわかりません><
134 :
デフォルトの名無しさん:2007/03/09(金) 16:57:18
#include <stdio.h>
#include <string.h>
struct seiseki {
char no[10];
char name[20];
};
void main(void) {
struct seiseki seito[2];
int i ;
printf("NoとNameの入力\n");
for( i = 0 ; i < 2 ; i ++) {
printf("No入力\n");
scanf("%s",seito[i].no);
printf("Name入力\n");
scanf("%s",seito[i].name);
}
for( i = 0 ; i < 2 ; i++) {
printf("%s",seito[i].no);
printf("%s",seito[i].name);
}
ファイルの扱い方かたがわかりません。scanfを使わずに
一気に読み込ませていくにはどうしたらいいのですか?
まだ、ポインタの勉強はしていなにので、ポインタを使って
のファイルの取り扱いもわかりません。
とにかく何か標準入出力のプログラムのコード書いてください!!
明日までであせっています。
>>133 staticつけるとファイル内のみしか参照できない。
ファイル内でしか使わない関数なら付けるといいお( ^ω^)
詳しくはGoogleで、static 静的 関数 でぐぐるとよろし
>>134 いちおー、scanf から移行するなら、fscanf や sscanf 使う手がある。
まあfscanfよりfreadのが扱いやすいが、まずはFILE* の使い方覚えとけ。
エクセルファイルからデータを読み込むプログラムをC言語でしたいのですが
どうすればいいでしょうか?
おそらくエクセルファイルをバイナリで読み込むことにはなると思うのですが…
具体的いうと、Sheet1のA1に書かれてる文字列又は数値を読み込むプログラムを
したいのですが、全く分かりませんでした。
エクセルファイルをバイナリエディタ等でみてもよく分かりませんでした。
きっとエクセルファイルがどういう形式(規格)で作られてるかが分からないと
できないと思うのですが、誰かそのあたり分かる方いらっしゃいますでしょうか?
長々と申し訳ございません(´・ω・`)
エクセルのファイルを読むライブラリがあるからそれ使え
>>138 ExcelそのものもExcelのファイルを読み書きするための
ライブラリ(というよりコンポーネント)として使える。
普段の1アプリケーションとしてのExcelは言わば表の顔。
Excelのファイル形式に拘る必要が無ければ、
ExcelでCSVやタブ区切りテキストで保存すればよい。
こうすると単なるテキストファイルになる。
Excelを扱うためのC言語のライブラリってどこにあるの?
for(pI = 0;pI < sD->pen;pI++) {
for(i = 0;i < 360;i++) {
//pX=0;pY=0;
pX = (int)(sin(i * (MPI / 180))*pI);
pY = (int)(cos(i * (MPI / 180))*pI);
//保存した
if(sD->hozonX == x+pX && sD->hozonY == x+pY) {}
else {
SetBPixel(sD,x,y,pX,pY,pI);
sD->xyYouso+=4;
}
sD->hozonX = x+pX;
sD->hozonY = x+pY;
}
}
sin、cosで円を描くコードなんですが、判定が二度ないようにしようと思っています。
しかし上記のコードでは何度かして同じ座標にくるみたいです。
何ででしょうか?頼みます。
>>142 強いて言うなら141のいうとおりExcelの中。
COMで公開されているので、まずはそれについて勉強するといい。
でもCOMはCよりもC++からのほうが扱いやすいので、(ry
更にCOMはMSの技術だからVisual C++の独自拡張を使ったほうが(ry
145 :
デフォルトの名無しさん:2007/03/09(金) 20:35:44
変数名をどうつけるか、その変数の効能を英語にしてもなんか味気無いのですが、
皆さんはどうやってるのですか?
>>145 味気なんか必要ない
それが嫌なら女の名前でも付けとけばいい
女の数が増えると修羅場になるけどなw
この女はいつもバグを起こすから嫌いだ
148 :
デフォルトの名無しさん:2007/03/09(金) 21:37:42
後置インクリメントで質問です。
aを前置インクリメントすると結果が1と出るのですが
後置にすると、bに値が入っていないとエラーが出ます。
ですが、やさしいC第2版のP86では結果は0となっています
WinXP,コンパイラはボーランドの無償版を使っています。
周りで教えてくれる人がいないので、ここでしばらくお願いします。
#include <stdio.h>
int main(void)
{
int a=0;
int b=0;
b = a++;
printf("%d",b);
return 0;
}
149 :
デフォルトの名無しさん:2007/03/09(金) 21:41:44
エラーになる理由が分からん
>>148 エラーなんか出ないだろ。
正確にメッセージを書いてくれ。
試してみたが警告は出るな。
警告 W8004 10: 'a' に代入した値は使われていない(関数 main )
警告 W8004 8: 'b' に代入した値は使われていない(関数 main )
>bに値が入っていないとエラーが出ます。
エラーメッセージ貼ってみて
152 :
デフォルトの名無しさん:2007/03/09(金) 21:50:21
printf ("%s %s\n", func(), func())
で、func()は
char *func()
{
static char buf[適当な長さ];
\\なにかbufに処理
return(buf)
}
とします。printfされる文字列は常に引数の左から順にfunc()を処理して得られる
結果でしょうか?それとも最適化、あるいはプロセッサアーキテクチャ依存でしょうか?
>>152 引数区切りの , の前後のどちらから評価されるかは実装依存。
154 :
148:2007/03/09(金) 21:53:37
エラーメッセージはります。
お願いします
------ コンパイル開始 ------
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
lesson25.c:
警告 W8004 lesson25.c 15: 'a' に代入した値は使われていない(関数 main )
Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland
>>152 関数の実引数が評価される順序は規定されていないので、コンパイラ依存。
順序が保証されているのは、&& || (演算子の), ?:
これらは必ず左から順に評価される。
158 :
デフォルトの名無しさん:2007/03/09(金) 21:58:23
>>157
つまり変数が代入されていないということですか?
後置だから、bにaを代入しプラス1?
b=++
と同じことなんでしょうか。
これならエラーの意味がわかります。
>>152 どっちにしたってその場合は同じ結果になりそうなもんだが。
160 :
デフォルトの名無しさん:2007/03/09(金) 21:58:45
>>153,155,156
おお。たいへんありがとうございます。非常に助かりましたです。
b=a+1;
にしてみるテスツ
「代入したはいいが使ってないみたいだけど、いいの?」と聞かれてる。
>>159 buf の最後の一文字を '\0' に置き換える処理とかあるじゃん
164 :
148=158:2007/03/09(金) 22:02:14
>>164 実行結果なんて話題にしてない
コンパイル結果はどうなんだ?
166 :
158:2007/03/09(金) 22:05:34
>>165 すみません
------ コンパイル開始 ------
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
lesson25.c:
Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland
------ コンパイル終了 ------
です
>>166 先ほどはコンパイル結果以上の考察である実行結果を述べたのに、今回は真実結果のみだけの報告?
質問内容はどうなったの?
169 :
163:2007/03/09(金) 22:12:49
>>167 間違えた
buf の最後の一文字じゃなくて
下みたいなこと
if(buf[0]!='\0') buf[strlen(buf)-1]='\0';
170 :
158:2007/03/09(金) 22:15:54
え、あの、意味がわかりません
148のコンパイルエラーメッセージが154で
161さんの結果が1、コンパイルめーセージが166なんですが
どうして b=a++ で0にならないんだろう?という質問です。
>>169 bufそのものの値を変えない限り同じになるって。
printf ("%s %s\n", buf, buf);
172 :
163:2007/03/09(金) 22:29:11
173 :
148:2007/03/09(金) 22:30:08
>>173 >>148のエラーですって話は
エラーじゃなかったんだから改めて判らないことを質問しなおして欲しいな。
175 :
148:2007/03/09(金) 22:38:10
申し訳ありませんm(_ _)m!
b=a++
コンパイルしてメッセージが出ましたが、実行できました。
結果は0と出ました。
自分が馬鹿だと気づきました。
本当にすみませんでした。
エラーと警告は違うと言ったら何度(ry
実行してなかったとは
こりゃ一本取られた
>>170 エラー(実際は警告)の質問なのか、前置/後置インクリメントの質問なのか、
複合的なのかそれ以外なのか分からなくなってきた
とりあえずどれに焦点当てているのか明確に述べなおしてちょ
ちなみに折れんところのgcc(cygwin)さんでコンパイルして実行したら
int main(void){
int a, b;
a=b=0;
b=a++;
printf("%d\n", b);
}
の実行結果が 0 って表示される(あたりまえだが)
180 :
148:2007/03/09(金) 22:48:35
>>174 自分の反省点です。
コンパイル時にメッセージが出ると実行できないと思っていました。
後置インクリメントなので、bにaを代入しそれからプラスするという
ところまではわかるんですが、何では1にならないのだろう
b=++
という理屈は通らないんでしょうか?
でもなぜか実行できる。
という新たな疑問が出てきました。
>>180 > b=++
>
> という理屈
人にこの3行を示して、理屈を理解してもらえると?
プラスするのはaであってbじゃないから。
>>180 b = a++; これは
b = a; が終わってから ++a; を行うという意味だ。
それが後置インクリメント
b = ++a; これは
++a; が終わってから b = a; を行うという意味だ。
それが前置インクリメント
185 :
デフォルトの名無しさん:2007/03/09(金) 23:02:35
皆さんから見て僕はアホですか?
前置と後置、本ではfor文で使うので、と書いてあるので
そこで、何で前置と後置があるのかがわかってくるんじゃないかと
>>182-183 意味はわかります。
ただ、概念というか何で前と後ろに?、それも後でわかると思います。
「実行する」ということを忘れていました。
実社会でもわかっていても「実行」してないことたくさんあります。
ありがとうございました。
無謀に見えるだけ
アホとはまた性質が違う
187 :
デフォルトの名無しさん:2007/03/09(金) 23:04:51
学ぼうとする意欲は感じる。ただちょっと空回りしているだけ。気にするな。
>185
意味わかってない。
わかってないことを素直に認められないと成長しないよ。
189 :
148:2007/03/09(金) 23:18:10
前置
b=++a
++aを処理してからbに代入する
後置
bにa代入してから++を処理する。
本当は後置で何で1にならないのかわかってないです。
でも結果として、前置が1、後置が0なんです。
ウザかったらスルーしてください。
>>189 hm…
本気ならば一度アセンブリ言語で出力させてみるといい
逆アセンブルしてもいいが
C言語の正体は誰が何と言おうと、高級アセンブラだ
良くも悪くも特定のコンピュータアーキテクチャのネイティブコードに依存する
逆に考えれば、Cのソースコード全体はあるネイティブコードに変換されているということだ
Cの背景を知るためにアセンブラを学べといわれる所以はここにある
>189
だから++で処理するのはaであってbじゃないからだって言ってんだろ。
前置は
a++;//aが1になる
b = a;//bに1が代入される
後置は
b = a;//bに0が代入される
a++;//aが1になる
って書き直せば理解できるか?
>本当は後置で何で1にならないのかわかってないです。
>でも結果として、前置が1、後置が0なんです。
>ウザかったらスルーしてください。
正直に感想を言うと
日本語にもやや難あり、ってとこか?
いや、
>>148は
1+1=2
これはわかってる。
でも、1と1をたすとなぜ2になるのかと考えるタイプだ。
数学の勉強ですらすら解けるけど、解に導くまでに疑問を持たない奴いるだろ?
これはこの方法だからこれでやれ、では納得できないんだよ。
まず、それが決まりだからそれでやって、使いこなせるようになったら
改めて考えてみるとよい。
つまり、常に書かれていること以上のことを考えながら勉強するタイプだ。
おそらく常識人ではないな。
>>195 >でも、1と1をたすとなぜ2になるのかと考えるタイプだ。
これって原理主義的な数学者の間で、いまだに解けてない問題のひとつだったっけ?
そこまでは知らない
1+1=2 は定義じゃないの?
原理主義的な数学者って何?だけど
近代数学ではなんかこう、ペアノの公理系で定義されてたはずだ。
ブルバキだったかラッセルだったが証明したんじゃなかった?1+1=2。
あーそういうことか、言いたかったのは。
悪かったな、きつい言い方して。
まず、Cがんばって覚えろ。
たたかうきみのうたを〜たたかわないやつらがわらうだろ〜
>>189 > 前置
>
> b=++a
>
> ++aを処理してからbに代入する
>
> 後置
>
> bにa代入してから++を処理する。
>
> 本当は後置で何で1にならないのかわかってないです。
> でも結果として、前置が1、後置が0なんです。
プログラムの意味がわかってほっとするのは人間、プログラムの意味を理解するのも人間
プログラムを読むのは誰?実行するのは誰?
プログラムを読むのはコンパイラ、実行するのはコンピュータ
コンパイラは意味をしらない、コンピュータは意味を知らないばかりかもっと大雑把
意味を理解して満足する人はコンピュータからもっとも遠いところにいる人
あなたはコンピュータを理解している人?それとも時代錯誤な言語学者?
えらい詩的な文章ですことw
詩人だな
こりゃもう日本語でおk
女にはわからんだろ?wwこのたぐいは
207 :
デフォルトの名無しさん:2007/03/09(金) 23:58:16
周りにC言語を教えてくれる人を探せ!
どうでもいいことだがC言語の関数において仮引数を
int f(int a,b,c){
・・・・・・・・・
}
みたいにできたら便利なんだが・・・
209 :
148:2007/03/10(土) 00:00:43
いろいろとレスありがとうございます。
そんな高尚な人間じゃないです。
次の代入演算子に進んでいました。
ありがとうございました。
またよろしくお願いします。
>>208 f(a,b,c)でもおk
それとも型:名前を1:Nにしたいのか?
新しい構文入れないと、結構バグの元なんだぜそれ
int f(a,b,c)
int a,b,c;
{
...
}
>>212 ただし
>>211の構文は型チェックというCコンパイラの
大変ありがたい機能を殺すことになるのでお勧めできない。
移植性の問題はもうほぼクリアになっているだろうから、
積極的にこの構文を使う理由はないと思う。
タイプ量を減らしたいという理由も弱いとは思う。
なんで?
int f(int, int, int);
でプロトタイプ宣言かいとけばええやん。
>>214 関数の定義とプロトタイプ宣言とで型が合ってるかチェックできないと無意味
となると後は一つ。
・構造体に押し込む
・なんか奇跡を起こす
自作プリプロセッサをコンパイル前に通すとか
それはそれで、
#define BEGIN {
#define END }
みたいでいやだなあw
なんで車輪を再発名するの?
protoizeすれば解決。
>214
int f(char,char,char);
int f(a,b,c)
int a,b,c;
{return printf("%d %d %d", a,b,c);}
まあだまされたと思って、コンパイルしてみてよ。
プロトタイプミスマッチの警告・エラーでるから。
間違えた。218宛だた
パスカルでもやってろ
227 :
デフォルトの名無しさん:2007/03/10(土) 04:39:13
#include <stdio.h>
#define PRIME_MAX 50 /*素数の最大値*/
main(){
char num[PRIME_MAX];
int j,i;
/*配列の初期化*/
for(i = 0; i <= PRIME_MAX; i++)
num[i] = 0;
/*素数かどうかを判定*/
for(i = 2; i <= PRIME_MAX; i++){
if(num[i] == 0){
printf("%d", i);
for(j = 2*i; j<= PRIME_MAX; j += i)
num[j] = 1;
}
}
printf("\n");
return 0;
}
for(j = 2*i; j<= PRIME_MAX; j += i) のj += iの
+= iはなんなのでしょうか?解説お願い致します。
j=j+i
+= は2項演算子。
C言語の本とか解説見たら結構頭の方に載っているはずだが?
多分、プログラムの内容に頭抱えてるんじゃないかな
関数fread, fwriteで読み/書きした場合、読み/書きしたデータサイズに応じて、
ファイル中の読み込み/書き込み位置がインクリメントされることは
保証されていますか。それとも、処理系や環境に依存しますか?
正常に読み書きされた場合は保証される
>>232 ありがとうございます。
某サイトには「ファイル位置表示子(定義されていれば)」とあって
C言語の仕様なのかどうか迷っていました。
234 :
デフォルトの名無しさん:2007/03/10(土) 08:20:56
いかにも、某サイトの書き方が悪いみたいな書き方だな。
そりゃそうだ、自分の頭の悪さに気付くほど頭があればこんな質問なんてするもんか。
>>235 隠そうとしても隠し切れない知性が溢れ出る深遠な書き込みだな。
237 :
デフォルトの名無しさん:2007/03/10(土) 09:32:59
はじめまして。
現在、ファイルの読み書きで苦戦しているものです。
今まではscanfを使って一々入力して実行していたのですが、非常に面倒です。
そこで、ファイルに一気に書き込みまた読み込むようにしたいのですが、ファイル
に書き込むときにもscanfを使わなければならないのでしょうか?fscanfがあること
は本で分かったのですが、これも結局一つ一つしかできないですよね?
void main(void){
int a[10];
int i;
printf("値の入力");
for(i=0;i<10;i++){
printf("%d番目の値入力:"&i);
scanf("%d",&i);
}
printf("終了");
}
例えば上のやつだとどんな方法がありますか?1文字だけとかをファイルに読み書き
できるようにするのではなく、文字列なども読み書きできるようにするには?
言いたいことがよくわからないが、とりあえず文字列の読み書きと言えばfgets/fputs
>>237 一つ一つ入力することには変わりないけど
繰り返し自体はコンピュータにやらせるから問題無い
#include<stdio.h>
int main(void){
char *filename=__FILE__;
char word[256];
FILE *fp;
fp=fopen(filename, "r");
if(fp==NULL) return 1;
while(!feof(fp)){
fscanf(fp, "%s", word);
fprintf(stdout, "%s\n", word);
}
fclose(fp);
return 0;
}
240 :
239:2007/03/10(土) 09:56:25
間違えた ^^;
while(fscanf(fp, "%s", word)==1)
fprintf(stdout, "%s\n", word);
>237
はじめましてじゃねーだろw
scanfもfscanfも一つ一つではなく、一度の複数の値を読める。
条件分岐で
ifのはしご使うのとブール関数の簡単化使うのとどちらが良いかな?
前者は追ってけば何やってるかはわかるんだけど、
後者はぱっと見じゃ論理演算の嵐で何やってるかわかんね
あと、これをさらにループでまわす時の事を考えて、どちらが速いかも知りたい
単純な比較ならifの方が速いらしいし
保守しやすいifにしとけ
ループで多少速くなったとしても
保守する人が替わった時解読するのに時間がかかったら意味がない
とは言え、これはこれで投げ捨てたくなる。
if (cond1 < 0) {
if (cond2 < 0) {
var1 = -para1;
var2 = -para2;
} else {
var1 = -para1;
var2 = para2;
}
} else {
if (cond2 < 0) {
var1 = para1;
var2 = -para2;
} else {
var1 = para1;
var2 = para2;
}
}
これ、実際のコードを模式化した一部だけど、この調子で5段も続かれるともうね(苦笑)。
abs
247 :
デフォルトの名無しさん:2007/03/10(土) 11:29:39
>>245 上のコードを見る限りは入れ子にする必要がないような。
何十秒もの間に数億回とか実行するなら速いほうにするだろうけど
最近の俺は
そうじゃないなら簡単なほうを選ぶ様に心がけるように意識している。
気分的な自故意満足であって
C言語では速さ重視でプログラムを書かなければいけない風潮は
役に立たないからな。
ブール関数の簡単化とか論理演算の嵐ってのが
どんなものなのか想像つかないけど。
>>248 自故意満足
間にi打ってしまったのか
あはははh
最近のコンパイラやプロセッサの最適化はすばらしいから、
人間の一番読みやすい方法で書けばいいよ。
どっちが速いかなんて対象のCPUでベンチとってみないとわからん。
多変数のオンオフの組み合わせで処理を分ける場合、ifだと何度もネストする羽目になるけど
判定式に論理演算式使えば上手く行けばネストなしで書けます(最初に知った時素で感動しました)
ただ判定式がぱっと見ただけじゃ慣れてない人には何やってるのかわからない
式を導出する過程を示した図を用意して、コメントに図へのURLでも添えとくようにする方向で行くことにします
まとめられるなら、判定部を意味のある名前の一関数にして
関数の冒頭コメントに解説を書こう。
253 :
245:2007/03/10(土) 13:05:15
>>246 残念ながら、絶対値ではない。
>>247 そそ、なんでネストにしているのか不思議でしょうがない。
というわけで、そのコードは5*32行の代入文が10行に収まったのでした。
#最終的には更に減ったけど。
>>251 具体的なサンプルが無いから何とも言えないけど、導出過程を絵にしないと理解できないような条件式は流石にやめた方がいい気もす。
ifにしてドキュメントを詳しくした方がいいんじゃね?
ifなら小学生プログラマでも理解できるし
>>245 適度に条件まとめた方がいいな。
コメントを付けながら。
if , 論理演算は、3重くらいを限度にして
それ以上複雑になりそうだったら関数を分けてみるというのも手だ。
意味が分かりやすく整理できたら不要な処理とかが見えてきたりもするし
後でマクロで書き直してもよい
質問です。
typedef struct particle{
float x;
float y;
float z;
}PARTICLE[1000000];
例えばこういう3次元座標をもったパーティクル群があったとして
ウニョンウニョン動いているのですが
1個のパーティクルから、その隣接する(距離1程度)のパーティクルを比較したいとき
どうやればスパッと見つけることができるでしょうか…
総当りで1000000×1000000回探すのはどうにも効率が悪くて…
>>257 適当な検索範囲に絞るくらいしかないよなぁ (つまり何らかのヒューリスティクス使う)
何が適当かは俺は知らん
>>257 総数 N = 1,000,000
として
自分と既に比較済みははずすから
N*Nじゃないでしょ。
for(i=0;i<N;++i) for(j=i+1;j<N;++j) iとjの比較
距離1だけなら単純にパーティクル毎に一つのセルに収まっているとして考えれば
1個のパーティクルが含まれるセルの隣接セルだけを比較してやるようにすればいいと思うけど・・・
それだとサイコロの上下左右前後の6回×パーティクル数ってのになるし
距離が増えても2や3ぐらいならそんなに計算量増えないと思うし
>>258 ヒューリスティクスという言葉を初めて知りました。
一度これをintに落として(小数点以下を切り捨てて)
例えば
grid[256][256][256]
に収まる程度であればgrid[x][y][z]として、グリッドに落とし込んで
隣接上下左右で比較をしようかとも思ったのですが
grid[256][256][256]を越えたときにもうダメなのと
それなら始めからgrid[x][y][z]に落とせばいいのではとも…
はじめは1次元で xyz xyz xyz… と座標を入れていたのですがこれだと総当り検索しかできないので
>>259 その通りですね。すみません、よく考えずに書き込んでしまいました。
>>260 仰るとおりです。ただ、空白セルが出来てしまうので
ループの際に空白部分も検討しなくてはならないので効率が出せなくて。。。
grid[x][y][z]にそこに存在する構造体へのアドレスを保存するのは無理かな
空間そのものをオブジェクトとして扱っちゃうという考えで
あー、精度落とすのは駄目なのかスマンコ
x座標だけ1000000匹のウニョンをスキャンして
-2000以下、-2000〜-1000、-1000〜0、略、2000以上ってグループ分けて
-2000以下と(-2000以下、-2000〜-1000)との比較をする。
こういうのはlogなんとか的に重くなるから
逆に比較する数を減らせれば
すごく軽くなることを期待してみたりする。
でもやっぱめんどくせ〜〜〜〜
>>265 数が少ないときヒャ
工夫せず比較したほうが速いかも知れないってのも
悩ましいな。
>>263 じつはポインタが苦手でアドレス関係から逃げていたのですが
なんとなく出てきたイメージでは
○=パーティクルありでアドレス ×=NULL
○×○○××
○を見たときに、左右のポインタのパーティクル距離が1なら比較 出なければ次のパーティクル
といったリストみたいなイメージが出てきました。
ただ上下・奥行きはどうしたらいいのか、疑問が出てきました。。。。もうちょっと頑張ればいけそうな気が。。。
>>265 空間を線的に分割するという感じですね
みなさん、色々アドバイスありがとうございます。本当にありがたいです
268 :
デフォルトの名無しさん:2007/03/10(土) 17:04:43
これなんですが、今までは
#include <stdio.h>
#include <string.h>
int main(void) { ←void main(void)と書いてきた
int c; ←文字を扱いたいのになぜintなの? char cとかじゃないの?
printf("入力");
while((c=getchar())!=EOF){
putchar(ch);
retrun 0; ←なんで必要??
}
}
これじゃいけないのですか?↓
void main(void) {
char c;
printf("入力");
while((c=getchar())!=EOF){
putchar(c);
}
}
ちゃんとした入門書を1冊読めよ。そうすりゃ疑問点はすべて説明されていると思うが。
>>268 > int main(void) { ←void main(void)と書いてきた
main() の型は int と規格で定められている
void にしてしまった場合は未定義動作
> int c; ←文字を扱いたいのになぜintなの? char cとかじゃないの?
getchar() が返す値が int 型だから
EOF の値は大抵の処理系で -1 だが char 型の変数で受けてしまうと 0xFF が
入力されたのか EOF なのかが区別できない
> retrun 0; ←なんで必要??
main() の型が int なので何か値を返さなくてはならないから
> これじゃいけないのですか?↓
char c; については前述の問題がある
あとは動けばそれでいいならにそれでいいし他の環境に互換性を持たせたい
なら規格に沿った記述をしなければならない
>>269 その「ちゃんとした入門書」を1つでもいいから挙げてもらいたい。
>270の内容を説明した入門書は見たことが無い
独習Cでは説明されてたと思うけど
あれって入門じゃなかったのか
やっぱり説明されてませんでしたすいません><
作ってわかるC(ry
> retrun 0;
return 0; だな
276 :
デフォルトの名無しさん:2007/03/10(土) 17:27:30
よほど酷い入門書しか読んだことがないんだな。
getchar()のリターン値を入れる変数がintの理由は、だいたい書いてあるんじゃないの?
手元に入門書がないからチェックできないけど。
あとmain()のreturn 0;は必ずしも必要でない。
現実的なCプログラミングには書いてあるな。
main()のリターン値がどういう意味かと、fgetc()のリターン値がintの理由。
>>277 getchar()のリターン値を入れる変数がintの理由は、>270の内容の一部であって
全部ではない
> あとmain()のreturn 0;は必ずしも必要でない。
これは失念してた
280 :
デフォルトの名無しさん:2007/03/10(土) 17:34:26
268です。
みなさんありがとうございます。とりあえずもう一度本を読んでみます。
ちなみに、自分の読んでいる本は「やさしいC」です。細かなところまでは
確かにのってないです。。
また疑問に思うことがあったら質問させて下さい。今、急いでCを勉強している
もので、変な質問することがあると思いますが、そのときはご勘弁を!!
281 :
デフォルトの名無しさん:2007/03/10(土) 17:42:03
急いで勉強する必要があるということは四月入社か・・・?
がくがくぶるぶる
283 :
デフォルトの名無しさん:2007/03/10(土) 17:56:58
280、280です。
>>281 もう入社前の研修を受けています。。やヴぁいです。。。
上司や同僚に当たった人はご愁傷様です
こんなレベルの奴をプログラマとして雇うところがあるのか。
将来に備えて一生懸命勉強している自分がアホらしくなってきた。
スキル持ってるヤツを採用すればいいのに・・・
大学まで行って何をみんな身につけてるんだろう・・・・・
マ板でやれ
288 :
デフォルトの名無しさん:2007/03/10(土) 18:02:31
国立大学とかじゃねーの?気を抜いているとあっという間に抜かれるぞ。
大学中退の俺でもマ(コーダー)には成れますから^^
>>286 休日の有効な使い方
マはそれができない
下手すると休日までぷr(ry
291 :
デフォルトの名無しさん:2007/03/10(土) 18:25:00
>>286 新卒でスキル持っている奴なんて少数だろ。
仕事でコード打ち
趣味で立案解析設計実装運用
これが正しきマ(コーダー)の姿
今このスレがアツいと聞いて飛んできました
(プログラマとしての)登大遊ぐらいのスキルがあれば十分です
登大遊がどれくらいのスキルなのか分からん
マ板でやれと言っておろうが
マ板のどこで?
キーワード【 main BUF buf プロトタイプ int 警告 Borland 】
299 :
デフォルトの名無しさん:2007/03/10(土) 18:59:23
コンパイルして実行してると「問題が発生したため、d.exe を終了します。 ご不便をおかけして申し訳ありません。」
とでて来てエラーを送信しますか?という画面がでてくるのですが・・・何で?
#include <stdio.h>
#include <string.h>
struct seiseki {
char no[10];
char name[20];};
void main(void) {
FILE *fp;
struct seiseki seito[2];
int i;
fp = fopen("test.txt","w");
if(fp == NULL) {
printf("erro\n");
}else{
printf("open\n");}
printf("NOとNAMEの入力\n");
for(i = 0 ; i < 2 ; i++) {
printf("NOの入力:");
scanf("%s",seito[i]);
printf("NAMEの入力:");
scanf("%s",seito[i]);}
for(i = 0 ; i < 2 ; i++) {
fprintf(fp , "%s\n", seito[i]);}
printf("ファイル書き込み終了\n");
fclose(fp);
printf("file colse\n");}
>scanf("%s",seito[i]);
>fprintf(fp , "%s\n", seito[i]);
こいつらがおかしい
scanf %sなんて使うなよ…
303 :
デフォルトの名無しさん:2007/03/10(土) 19:13:03
>>303 残念だけど構造体を自動的に解釈して
適切な変換を自動的にしてくれることはない。
いくらなんでも
printf("NOの入力:");
scanf("%s",seito[i]);
printf("NAMEの入力:");
scanf("%s",seito[i]);}
は無理でしょ。
両方同じ指定でscanfがnoとnameが区別出来ると思うのか。
それに
scanfはseiseki.noがchar [10]であることなんて知らない。
scanfはseiseki.nameがchar [10]であることなんて知らない。
だから入力した文字が長すぎるとメモリ破壊起こすぞ。
fprintfは、たとえば以下のようにしないといけない。
fprintf(fp , "%s,%s\n", seito[i].no, seito[i].name);
今の新入社員って
>>280みたいにすぐ逆ギレすんのか・・?
307 :
デフォルトの名無しさん:2007/03/10(土) 19:36:35
>>304 ありがとうございました。実行できました!!しかし、ファイルができていないのですが
何ででしょう?
>>302 scanfを使わないとしたらどのようにすれば・・・?
上の方にも書いてあったかもしれませんが、購入した入門書が
糞だったようです・・・・・。
入門書なんだから別にscanfでいいだろ
少しは考えろよ
いや、gets使ってるような入門書があれば投げ捨てるべきだろ。
std::cinを使うと良いよ^^
>>307 どうすりゃいいんだろ。
scanfで直読みはよくないって知っているけど
だからといってどうすればいいか考えてないや。
ファイルができていない理由はわかりません。
入門書のせいにして自分を棚に上げる
大馬鹿者のレスが最近多い気がする。
fgets()使えばいいじゃん。
配列の宣言で
i=100;
int num[i];
みたいな感じでやってエラーが出るのですが
原因がわからなくて困ってます。助けてください
>>315 変数に出来ない。
即値じゃないとだめなんだ。
#define MAXSIZE 100
int num[MAXSIZE];
C99のコンパイラに変えるとか。
>>316 ありがとうございます。
というか、マジですか
ファイルの行数数えて、その分の配列確保したかったのですが
これじゃ先に進むことが出来ない
おいおい
>>318 int * num = NULL;
num = (int*)malloc( i * sizeof(int) );
if(num == NULL)
{
めもりぶそくだよ〜ん
}
つかいおわったら
free(num);
num = NULL;
なお、動作確認するきはありません。
多少のミスがあるでしょうけどあしからず。
使い終わったポインタをクリアするのは間違ったお作法。
えぇ、マ、マジ
そんなことはない
324 :
デフォルトの名無しさん:2007/03/10(土) 20:34:40
構造体のメンバーの値をある関数からだけとってくるように
するにはどうすればいいですか?
>>324 言ってることがよく分からんが、
Cにメンバプロテクションの概念はない
こうだな。
if(num != NULL) free(num);
num = NULL;
>>324 C++のprotectみたいなことか。
小細工してやる価値があるかどうかだな。
>>328 free(NULL); は何もしないことになってるからそんなチェックは要らない。
そんな作法なんて何の役にも多々ねーだろ。
num = NULL;をしないことを守ることにより
バグが減るわけでも
プログラムがわかりやすくなるわけでもない。
>>332 バグも減るし、プログラムもわかりやすくなるよ。
num = NULL;をするとなんかバグが減ったりプログラムがわかりやすくなったりするの?
num = NULL;がないだけでプログラムがわかりやすくなるなんてよっぽど馬鹿なんじゃねーの
>>334 誰もnum = NULL;をするとプログラムがわかりやすくなったりするなんていってないだろ
メモリが割り当てられているときには何もしない
メモリが割り当てられていないときにはメモリを割り当てたい時ってどうすればいいの?
>>335 いや、めちゃくちゃ重要。
あるなしじゃ、だいぶ違う。
339 :
デフォルトの名無しさん:2007/03/10(土) 20:53:35
そうです。プロテクトみたいなことです。
ファイルを分割するとは具体的にはどのようにするのでしょうか?
num = NULLしとけば間違ってfree後にその領域を使ってしまった場合に素直にヌルポしてくれるが、
そうじゃない場合は何とか動いてしまうことが多いのでバグが発覚しにくいといったところかな。
341 :
デフォルトの名無しさん:2007/03/10(土) 20:56:33
入門書が糞だ?
そんな糞な入門書なんか買うお前の方が糞なんだよ!!!
ちゃんと、内容を確かめてから買うようにね。
>>334は、
>>332に対するレスか。
num = NULL;をしない作法がどう役に立つのかって話であって
num = NULL;をすることが役に立つと主張しているわけじゃない。
>>342 そこまでわかってるならもう一息だ。
なぜいけないか頑張って考えろ。
毎回freeしてmallocしないで
前回のサイズのままでよかったら前回mallocしたのを使いまわしたり
でもやっぱり毎回freeしてmallocしちゃおっかなって気が変わることもあるし。
プログラムが複雑になると『使い終わったとき解放する』が曖昧で
プログラムが終わる直前に解放することもあれば
途中でデータエラーとかになったら中断して早くfreeしたいって思ったりすると
if(num != NULL) free(num);
num = NULL;
ってするかな(本当は嘘です)。
どっちでもいいだろ
結局は主張してる奴らの会社のコーディング規約に従わなくちゃいけないわけだし
>>343 まったくわからん。
>>345 だとしたら無意味なコーディング規約あるいは間違ったコーディング規約だ。
ほっとけません。
>>343 わかった。
num = NULL;が書いてあるだけでプログラムがわからなくなってしまう人のために配慮する作法だ。
いずれ誰でもNULL埋めするようになるってw
>>348 で a.c からは構造体のメンバにアクセスできない
必ず関数を通してアクセスすることになる
利点
構造体内部の実装をまるまる隠蔽できる
>>349 いや、作法どうこう以前に、当たり前の話だから。
「バグがあった時にNULLアクセスしてキッチリ落ちる」
ってのは結構大事だと思うんだけどな
ヘタになんとなくメモリぶっ壊される方がやっかい
>>344 みたいな変数やバッファを使いまわすような組み方が常態化してるPGは、ちょっと考えたほうがいい。
デバッガ相手にのうのうと生きている俺はきっと神に違いない
使い終わったポインタをNULLにしない奴なんかいるんだ・・・
「俺は解放したポインタを使ってしまうような馬鹿じゃないから
NULLにしなくていい」って理論は通じない
コーディングスタイルの話になると必ず
>>356みたいなこと言い出す奴が現れるからいやだわ
/* ここまで俺の自作自演 */
359 :
デフォルトの名無しさん:2007/03/10(土) 21:45:59
>>347 >>348 >>351 ありがとうございます。
さっそく見てみます。
osの内部構造はそうなってんのかな?と思ったりしたんですが
そんなことやってんのかなできんのかなと思い質問しました。
みなさんありがとうございました。
>>356 Cが参照使えるような言語ならまだその概念は一部通用したかもしれないけど、
実体を委譲したりするのが常で、実体を運用してるのが一箇所でない場合がよくある(参照が散在してる)
確かに部分部分で、使い終わったらNULLに初期化するのも一つの手だが、まぁ力説するモンじゃないからいいや
(゚パ
ところでNULLで初期化すんとなんかいいことあるのか?
>>361 「不正なポインタ」であるかどうかが分かるようになる
解放したらNULLを即代入するようにすれば。
NULLか否かでヒープ使ってるかどうかの判定ができる。
別に変数を持つよりエレガント。
初期化した後すぐmalloc使ってたら意味ないけどね
freeしてすぐにスコープを抜けるようなときにはNULLの代入なんてやらないよ。
なんという詭弁
みんな、これで静まってくれ
#define free(ptr) (free(ptr),ptr=NULL)
MSのDirectXサンプルで同じようなことはやってたな
DELETE(p)とかってマクロだったが
SAFE_RELEASE
>>359 MS-Windows のいわゆるハンドルってやつがそう
何をするにも API がハンドルしかくれない
内部の実装は闇の中
>>363 使いまわしてる変数以外は意味ないですね。
free()したポインタは必ずNULLを入れようって薦めてる本とか、そういうスタイルのプロダクトって、どんなのがある?
>>368 まずDirectXね。
>>354 同じ処理するときいやでも使うだろ?
まったく同じ処理を2回するとき変数名とか関数名かえるのか?
同じ変数を別の目的に使うとかじゃないよ。
頻繁にメモリ確保と解放しないで
最初に一括して確保しておくとかあるだろ。
(速度重視のプログラムが多いのでよく言われる。
聞き流して俺は結局やらないけど。)
というより
むしろ間違って使わないようにNULLにするという
意味があるんだけど。
>>357 コーディングスタイルの話じゃない。
作法の話だ。
>>372 postgresは、してないね。
(生のfreeは使ってないけど)
本だと、プログラミング作法とコードコンプリートもそういうのはたしかそういうのは薦めてなかったと思う。
C++だとdeleteしたあとにNULLを入れようとかって話は聞かないような。
C++だとboost::shared_ptrやboost::scoped_ptr使ったりするから、
そもそもdelete自体お出ましにならない。
DirectXでもATLのスマートポインタ使ったソースでは原則必要ないな
>>376 スマートポインタが定着したから、delete後のnullクリアは必要ないって言われだしたってわけじゃないだろ。
やっぱauto_ptrじゃなくてスマートポインタだな。
なんでスマートポインタが標準装備じゃないんだか。
C言語カワイソ
言語思想にないから
ファイルポインタとかOSからもらった各種ハンドルを入れた変数とかも、使い終わったらクリアしましょうみたいな話は聞かないよな。
>>379 auto_ptrもスマートポインタであることに違いは無いぞ。
>>381 freeと同等程度には聞く気がする。
std::vector と boost::shared_ptr は俺の中の世界を変えたな
>>382 >freeと同等程度には聞く気がする。
どのあたりで?
fclose(fp);
fp = NULL;
みたいなソースは見た記憶がないけど。
>>381 OSからもらった各種ハンドルは
一度確保してプログラム最後まで持ってたりするからな。
boost::shared_ptr使いてーみたいな場面じゃないし。
ファイルポインタはわからん。
結局NULLしないにこと関してはメリットなんて誰も言ってないな。
ファイルと関連づけられてないofstreamオブジェクト対して書き込み
やっても安全(ただしどこのストリームにも書き込まれない)なのはかなり楽だな。
そのポインタやハンドルがクラスメンバのひとつだったらNULL入れるけど
if(fp != NULL) fclose(fp);
fp = NULL;
だな。
// fpって変数名がダサいけど。
>>386 いや、言ってるやつはいるぞ。
オレは教えてないけど。
起動されている特定のスレッドを停止する関数を作りたいんですが、
何のシステムコールを使えばいいんですかね?
pthread_join()は起動しているスレッドが自分で終了するまで待ってる関数だから
無限ループしているスレッドを終了できなし。
pthred_exit()はpthread_join()の戻り値を引数に使うからpthread_join()使わないと無理だし。
誰かお願いします。
永続性があるかどうかだな。
多スレッドで参照するようなのは特に気を遣う。
結局NULLしないにこと関してはメリットなんて誰も言ってないな。
>>391 pthredかあ
俺知らね。
それって便利?
397 :
391:2007/03/10(土) 23:23:54
>>392 停止するスレッドの順番が決まってるんで、
とくに他のスレッドで参照されているかとかは気にしなくていいみたいです。
起動されているスレッドは全て無限ループしているスレッドです。
単純に指定したスレッドを停止するようなシステムコールはなさそうですよね
399 :
391:2007/03/10(土) 23:25:22
>>395 Linuxでサーバプログラム作るときにはデフォみたいな感じです。
Win32のTerminateThread相当のもの作りたいんだろ。
リソースリークするから強制終了はお奨めしない。
スレッドから参照できるメモリ空間にフラグを外部から立てて、
スレッド自身で自分で終了させる設計にしたほうがいい。
排他制御したフラグを云々でいいんじゃね
スレ違いか
402 :
391:2007/03/10(土) 23:26:33
だんごって案外普通なんだな。
>>337 遅レスだけど
方法 1:
ポインタはあらかじめ NULL で初期化しておく。
メモリ確保時に if で NULL かどうか調べて、NULL だったら malloc() を呼ぶようにする。
char *p = NULL;
あんな事やこんな事など;
if(p == NULL)
p = (char *)malloc(256);
あんな事やこんな事など;
方法 2:
realloc() の第 1 引数に NULL を指定すると malloc() と同じ動作をする。
realloc() は呼ばれても指定するメモリサイズが変わらなければ何もしない。
この性質を利用して、あなたの望む通りの事ができる。
char *newbuf, *p = NULL;
for(; ; )
{
newbuf = (char *)realloc(p, 256);
if(newbuf == NULL)
{
perror("メモリ不足");
exit(1);
}
p = newbuf;
あんな事やこんな事など;
}
free(p);
方法 1 のほうが簡単だが方法 2 のほうが柔軟性は高い。
reallocとはReal Rockでありその生き様はお塩先生だぜファッキンライト
407 :
391:2007/03/10(土) 23:37:59
>>400 なるほど。
その方が簡単そうですね。
ありがとうございます。
スレッド処理作成側に言ってみます。
最近はselect()使わなくなったのか?
え?freeしたらその確保した所ってNULLに置き換えられるんじゃないの?
>>409 確保した所の意味が分からないが
freeに渡した引数ならならない
開放したメモリ領域もならない
知らなかった、、、
まだ始めて間もない者です。許してください
配列や構造体のテーブルの初期化なんですが、
int a[10] = { 1, 2, }
とした場合a[2]〜a[10]には0が設定されると考えていいですか?
同じように構造体では、
typedef struct seito
{
void* name,
int a,
int b
} seito;
seito seito_tbl[5] =
{
{ tanaka, 1, 1},
}
とした場合seito_tbl[1]〜seito_tbl[5]は0が設定されると考えていいでしょうか?
1) はい。
2) seito_tbl[1]からseito_tbl[5]は {0, 0, 0} に初期化される。
417 :
414:2007/03/11(日) 01:23:43
関数テーブルに登録されてる関数をループを
使ってコールしていく処理を作りたいんですが、
★の部分どうすればいいんでしょうか?どなたかお願いします。
#include <stdio.h>
void a_func(void)
{
printf("a_func\n");
}
void b_func(void)
{
printf("b_func\n");
}
void* func_tbl[2] =
{
a_func,
b_func
};
int main(void)
{
int i =0;
for(i=0;i<2;i++)
{
func_tbl[i](); ★
}
return 0;
}
void*の配列に関数ポインタを格納してるのが問題だと思うんだ。
typedef void(*func)(void);
int main(void){
int i;
func func_table[2]={a_func, b_func};
for(i=0;i<2;i++) (*func_table[i])();
}
で動いたら奇跡
そこはfunc_table[i]();で十分だろ
422 :
418:2007/03/11(日) 10:54:09
>>419,420,421
関数テーブルを
void (*func_tbl[2])(void) =
{
a_func,
b_func
};
に変えて、
int main(void)
{
int i =0;
for(i=0;i<2;i++)
{
(*func_tbl[i])();
}
return 0;
}
としたら動きました。
うーん、何でこうしたら動くようになったかいまいち理解できない・・・
みなさんありがとうございました。
>>421 文法的にはそう書くことが認められているが、
厳密には (* ... ) だな。
シンタックスシュガーってやつ?
厳密も糞もないだろ。
標準化以前の処理系との互換性を考慮しなければどっちでも構わん。
動的な構造体配列を作るにはどうやればいいのでしょうか
struct hoge{
int orz;
int or2;
} hogehoge;
こんな感じの構造体を入力した数にあわせて作るっていうのをしたいのですが
void main(){
値を入力してほしいお
scanf(%d,num)
int *p = malloc(??????)
}
どうもわからんのです。助けてください。。。動的なメモリ確保がさっぱりというのもありますが
hogehoge[入力分]
を作りたいだけなのです。
hogehoge *arr;
arr = malloc(sizeof(*arr)*num);
>>426 struct hoge* p = (struct hoge*)malloc(sizeof(struct hoge) * num);
これ以降、p[n].orz とか使える。 (p + n)->orz でもいい
>>427 みたいにしたけりゃ、 struct の前に typedef
>>425 hogehoge *arr はポインタで
arrにmallocでnum分作れるということですか?
この作った後のarrのorzにアクセスするにはどうやるのでしょうか?
numが3だったとき、1番目にアクセスしたいときは
arr[0].orz
という風にできるのでしょうか?
ああああ
読み込まずに書き込んでしまいました
>>427-429の皆さん、ありがとうございますだ
試してみますだ
|-`).。oO(・・・・何か、ポインタ論争見ててGoslingとHejlsbergの気持ちが分かったよ・・・・・)
431です。
出来ました!ありがとうございます!
もう一つ別件なのですが
数を指定して、その分確保するのはわかったのですが
継ぎ足して、順次値を挿入していくようなもののやり方も必要で。
1次元配列で
int hoge[値不明];
int input;
int i;
while(1){
printf("値を入力しる >> ");
scanf("%d",input);
for(i=0;i<hogeの大きさ;i++)
printf("%d\n",hoge[i]);
}
といったことをしたいのです。
順次入力に伴い配列が増えていくようなメモリの取り方がしたいのです
malloc allocの説明を見てもどうもわからず。何度も何度もすんません
realloc
reallocについても観ていたのですが
フラグメンテーションがひどいということで。。。上のような小さいのならよいのだけど
数が増えたときを基準に考えてやらないといかんのです
C++のvectorでは上のはあっさりやってくれたのだけど
Cじゃないといかんので
で
だったら始めに大きめに余裕を持ってメモリを確保しておけ。
足りなくなったらまた余裕を持って更に多くのメモリを確保しなおせ。
C++のstd::vectorもそういう戦略を取っている。
リンクトリスト使って自前でメモリ管理すればいいじゃん。
メモリの動的確保もろくにできないのに
フラグメンテーションなんか気にすんなよ・・・
float型とlong型の計算によって発生する誤差を確認するために、
次のプログラムを組みました。
#include <stdio.h>
int main(void)
{
long l;
float f;
long big = 1234567890;
float lten = 10.0f;
l = (big / lten) * lten;
f = (big / lten) * lten;
printf("l : %ld\n", l);
printf("f : %f\n", f);
return 0;
}
実行すると、
a : 1234567890
f : 1234567936.000000
となりました。
計算結果をlong型の変数aに代入した場合に誤差が発生しないのは、なぜでしょうか。
(big / lten) * lten
これが内部的にdouble型やそれ以上の精度で計算されている可能性がある。
例えばx86の浮動小数点数演算はみんな80bit拡張倍精度で行われ、
レジスタを使いまわすとそういうことになる。
すいません、質問させてください
#include <stdio.h>
#include <unistd.h>
int main(void)
{
fputs("World!!", stdout);
write(1, "Hello!", 6);
putchar(0x0a);
return 0;
}
これを実行するとHello!!World!!の順で出力されるのですが,何故なのでしょうか
Cのstdioでの入出力はバッファリングされているため
stdioがバッファリングするから。fflushしろ。
>>441 ありがとうございます。
ということは、float型に代入した値の誤差は、計算時ではなく代入時に
発生したということですか?
>>444 低水準と高水準をごっちゃに使うな、と言う方が良いと思う
433ですたびたびすんません。reallocでとりあえず作ってみたのですが
上手く値が入りません。観てやってもらえませんか
int main(void)
{
int *p1,*p2;
int i,count=0;
int input;
p1 = (int*)calloc(1 , sizeof(int)); /* int型で要素数1の配列 */
while(1){
p1 = (int*)realloc(p1,sizeof(int)); /* int型1つの領域を再取得 */
if( p1 == NULL ) /* 成功したかどうか調べる */
{
free( p1 ); /* 再取得に失敗した場合には、元の領域は有効なままなので、自分で解放する */
printf("memory error");
return 0;
}
printf("input some number >> ");
scanf("%d",&input);
p1[count]=input;
for(i=0;i<=count;i++)
printf("p[%d]=%d\n",i,p1[i]);
count++;
}
free( p1 );
return 0;
}
input some number >> 7
p[0]=3
p[1]=-33686019
p[2]=1
p[3]=5
p[4]=7
値を入力した5回目でこうなります。2のところがどうしても変な値が入ってしまって
int 1個分しか取ってないのに、何で添字は増えていくんだ?
>>447 長さ変わらないんだったらreallocする意味ないだろ。
if( p1 == NULL )
free( p1 ); /* p1はNULLだから元の領域を開放できてない */
reallocが追加で取得するとか勘違いしてんのかな。
sizeof(int) * (count + 1) だけ realloc しよう。
433です
>>451 >>reallocが追加で取得するとか勘違いしてんのかな。
勘違いしてました('A`)
>>450 p1が確保できていないときの処理だと思っていたのですが、違うのですか
>>449 すみません、意味が…理解できないです
で、お礼が遅れましたが
>>451でアドバイスいただいたとおりで出来ますた!
ありがとうございます、ほんとに
やりたかったのはファイルの数字を連続で可変長の配列に組み込むことだったんですが
これだと、メモリがばらばらになるというのを聞いて、まだ改善しないと…だと思うのですが
目星つけることが出来ました。
>>449 ○ | ○| ○| ○ ←p全体
p[0] p[1] p[2] p[3]
だと思っていて
reallocすると
○ | ○| ○| ○ | ● realloc分+
p[0] p[1] p[2] p[3]
だと考えてしまっているのですが…どういう勘違いをしているのでしょうか
>>452 reallocの戻り値は別の変数に確保して、NULLチェックをしてから元の変数に代入する。
tmp = realloc(size);
if(tmp == NULL ) {
free(p1);
return 0;
}
p1 = tmp;
reallocが追加だと思ってたってことは、そのメモリブロック単体でバラバラだと思ってたんだなw
reallocはその領域で拡張しきれないときは、別の場所に確保して元の内容をコピーしてくれるだけ
> ○ | ○| ○| ○ | ● realloc分+
# ● | ●| ●| ● | ● realloc分+
じゃないか?
457は忘れて
433です。
>>455 なるほど。理解が出来ました!
>>456 ためしにこうやってみました
p1 = (int*)calloc(1 , sizeof(int)); /* int型で要素数1の配列 */
for(i=0;i<150;i++){
p1[i]=i;
printf("p[%d]=%d\n",i,p1[i]);
}
出力---
p[0]=0
p[1]=1
…
p[150]=150
---
p1 = (int*)calloc(1 , sizeof(int))
この時点で、ものすっごい長い配列みたいなのが出来てるってことですか?
私がやっていたのは
○ | …まだまだ入る | callocで確保したp
p[0]
↓
realloc
○| ○|…まだまだ入る|← これを何回も整理整頓してる ということでしょうか…
p[0] p[1]
reallocしたアドレス表示させてみ。
あと、最初のallocの後に別のメモリをダミーでallocしたときと比べてみ
>>460 先ほどのソースでこうやってみました
callocでint型を一つとって 4つに値を入れたアドレス
p[0]=431ff0 値 0
p[1]=431ff4 値 1
p[2]=431ff8 値 2
p[3]=431ffc 値 3
以下 reallocで 値を1個ずつ入力して、再度reallocでやっていく
input some number >> 5
p[0]=431ff0 値 5
input some number >> 1
p[0]=431fb0 値 5
p[1]=431fb4 値 1
input some number >> 4
p[0]=431fb0 値 5
p[1]=431fb4 値 1
p[2]=431fb8 値 4
すんません…混乱してきました(ノ_・、)
>>461 だだっ広い新大陸に入植者が沢山やってきて、各々に土地を割り当てたとするだろ
土地を拡張するためにrealloc()を使って再登録するんだけど、管理者は
モウ秋田
その説明だとreallocした後の領域は前に指していた領域を伸ばしたものとは限らないから余計手間かかりそうな
実際reallocは前に指していた領域を伸ばしたものとは限らないのだが
開拓民が土地に納まらなかったら別の土地を探すんだよ
>>459 reallocは void *realloc(void *block, size_t size);
blockが元のメモリ、sizeが再割り当てするのメモリサイズ
reallocによる再割り当ては前のメモリに追加して割り当てるわけではなく
sizeで指定したサイズに拡張すると言うこと
たとえばcallocで40バイト分確保していたときに
realloc(p1,80); とした場合 メモリ全体のサイズは120バイトではなく
reallocで指定した80バイトにしかならない
std::vector使ってるから再配置とか全然気にしてない
スレタイも読めないアホ
>>469 いや、低水準と高水準とまぜて使うなよ。。
471 :
デフォルトの名無しさん:2007/03/11(日) 21:49:34
上の
>>127,128でstrdupは標準関数じゃないという話が出てますが、
標準関数以外は使わない方がいいですか?大抵使えると思って
strdupしまくりなんですがまずいでしょうか?
別にかまわんだろ。
無くたって簡単に用意できる。
473 :
デフォルトの名無しさん:2007/03/11(日) 21:54:12
使いまくれ
>>471 # strdup() は SVr4, 4.3BSD, POSIX.1-2001 準拠である。
らしい、VCにもあったよな?
476 :
デフォルトの名無しさん:2007/03/11(日) 23:01:45
>>472-475 ありがとうございます。安心しました。windowsにはないかもしれないんですね。
うーん。やっぱまずいかも。
VCの話してんのに何でWindowsには無いって結論になるんだ
そらMSVCRT依存だからだろ
MinGWにせよBorlandにせよ
昨日mallocについて質問したものです。レスありがとうございました。
一晩考えたのですが、どうにもなっとくが出来ず…再度質問させてください。
やりたいのは可変長に値を確保できる配列です。たとえば値を入力したら、それに合わせてピッタリと配列が大きくなるような
○|○|○ に ●を入れると ○|○|○|●となるような
mallocについて色々見ていたら、mallocでメモリ確保するのと、配列で初めに宣言するのとそれほど代わらないのではと思ってしまいました。
ptr = (int *)malloc( sizeof(int));
if(ptr == NULL){
perror("ptr");
exit(1);
}
for(i=0; i<15; i++)
ptr[i] = i ;
for(i=0; i<15; i++)
printf("ptr[%d] = %d\n", i, ptr[i]);
free(ptr);
これでループを15回やると、15個表示されますが、表示を16にするとエラーになりますよね
これだと初めに配列でptr[15]とするのと代わらないんじゃないかと…
それで足りなくなったらreallocするんですよね?
上のに16個目の入力する要素を加えるとなるとどうなるのでしょうか…
何度もすみませんが教えてください
すみません
ptr = (int *)malloc( 15*sizeof(int));
ですね。
>>479 > 配列でptr[15]とするのと代わらないんじゃないかと…
スタックとヒープの違いは知っている?ググってみて
> 上のに16個目の入力する要素を加えるとなるとどうなるのでしょうか…
未定義です(malloc()で確保した領域以外の領域に対する読み書きは未定義のはず)
鼻から悪魔が出てきても何らおかしくはないです
>>481 ありがとうございます
スタックとヒープの違いを、はじめて知りました
ただ、どうしてもstatic ptr[15]みたいなものとの違いが…
>> 16個目
16個目以降を、入力に合わせて順次領域と一緒に追加していくためには
どうやればいいのでしょうか…
>ptr = (int *)malloc( 15*sizeof(int));
これを例にすると、、
ptr2 = (int *)malloc( 16*sizeof(int));
memcpy(ptr2, ptr, 15*sizeof(int));
free(ptr);
ptr = ptr2;
これがreallocと同じ動作(の、一部)
ptr の後ろがまだ使えるなら後ろも使えるようにするだけで、コピーとかしないが
あと
>>482がやりたいのは、もしかしてリストじゃないの?
リストを自前で作るとヒープやらポインタの扱いはうまくなるよ
>>482 static の変数はプログラム実行開始から終了までの寿命がある。
auto の変数 (関数のブロックの始めなどで宣言する変数) は関数
開始から終了までの寿命がある。malloc() で確保した領域は
free() するまでの寿命がある。またこれは realloc() で長さを
変えられる。(更に OS のある環境で動かす場合は free() せずに
プログラムを終了してもその後全部開放されるのが普通)。
という風に覚えておけば良いんじゃないだろうか。
実際にどのメモリ領域に確保されるかは実装によって違う可能性がある。
486 :
デフォルトの名無しさん:2007/03/12(月) 16:06:08
fgets(buf, sizeof(buf), stdin);のsizeofというのはなんでしょう?
また、何のために書くのでしょうか?
sizeofは演算子なのでmanでは出てこない希ガス。
soreha
c++
Cでも演算子だぞ。
質問です
2つの数字の四則演算を行うというプログラムを授業で製作したのですが
次に128文字まで入力可能にして計算できるようにプログラムを変更しろと言われました。
100桁を超える数字の計算なんて普通しないだろ・・・とか愚痴りつつ
計算方法を考えていたのですが、全く分かりません。
どうすれば100桁を超える数字の計算が可能か教えてください
>>491 普通しないけど、お前できる?
できるならその通りに作ればいいし、出来ないなら脳ミソ疑え
>>491 宿題は宿題スレに行け。
てか小学校の時に習った筆算のアルゴリズムで解けるよ。
多倍長整数演算
496 :
491:2007/03/12(月) 17:13:52
何型に入れればちゃんと計算結果出してくれるんだろとか考えてました。
>>494 多倍長整数演算でぐぐってみたら色々出たのでがんばってみます
無理そうだったら宿題スレへ・・・
497 :
デフォルトの名無しさん:2007/03/12(月) 20:54:52
>>479 >これでループを15回やると、15個表示されますが、表示を16にするとエラーになりますよね
>これだと初めに配列でptr[15]とするのと代わらないんじゃないかと…
たしかに変わりません.ただ
>>481さんぎ言うように確保される領域が違う場合がありますから
>それで足りなくなったらreallocするんですよね?
そうです
>上のに16個目の入力する要素を加えるとなるとどうなるのでしょうか…
???
>>496 文字配列を使って筆算の要領で計算するとか
499 :
デフォルトの名無しさん:2007/03/12(月) 21:25:27
>>480 てめーこの野郎。レスポップアップで見てるこっちの身にもなれや。
亀乙
次のようなプログラムを作りたいです。
実行すると、コマンドプロンプトを開き、実行されたディレクトリまで移動し、特定のコマンドライン引数付きで
特定の実行ファイルを実行する、というものです。
この流れは自動で一瞬で終わるようにしたいです。
どのように組めば良いでしょうか?
>>501 ( ・ω・)やりたいことは分かってる
(・ω・ )やらなきゃいけないことも分かってる
( ・ω・ )なんでやらないの?
ディレクトリを知る → GetCurrentDirectory とか gwtcwd とか
プログラムを実行する → CreateProcess とか systemとか。
今勉強しないといけない言語って、
C,C++と、Javaと、Perlくらいですか?
JAVAScript。
【強迫観念にとらわれています】
>>501 コンソールアプリで別のプロセス起動させるってことか?
>コマンドプロンプトを開き、実行されたディレクトリまで移動し
意味が分からない
>特定のコマンドライン引数付きで特定の実行ファイルを実行する
exec群
479です。
色々回答ありがとうございます。返信遅れてすみませんでした。
回答いただいて、ようやく自分の中で噛み砕けました。
Cだと順次、値を入れて、次の領域を確保するような操作は難しいのですね
ありがとうございました。
それCじゃなくてバッチだよなあ
と思ってたら、
>>509がちゃんと書いてた。
きっと世界の救世主になったんだろ
彼が難しければ万人が難しいんだよ
おれは べっせかい の にんげん だから かんけい ないヨ \(^o^)/
彼はC++の世界に飛び立ったのさ・・・
こんな低レイヤ処理には見切りをつけてなぜかPythonへ・・・
>>510 とりあえずmalloc,realloc.freeあたりの仕様をよく読めよ
518 :
デフォルトの名無しさん:2007/03/13(火) 00:46:19
typedef struct _STRLIST{
char name[128];
struct _STRLIST *next;
} STRLIST;
STRLIST *listtop = NULL;
listtop = (STRLIST *)malloc(sizeof(STRLIST));
strcpy(listtop->name, "Ichiro");
listtop->next = NULL;
リンクリストについて質問なのですが
上のソースに於いて、
>>STRLIST *listtop = NULL; はname, "Ichiro"が入っている
構造体のnextメンバを、予め指しているのでしょうか?
何言ってんの
STRLIST *listtop = NULL; はリストの要素は何も無い状態だろう
指してないよ
見たまんま、NULL を指している
NULLで明示的に初期化してから、mallocで領域確保した後、nameとnextメンバに代入してる
522 :
518:2007/03/13(火) 00:55:00
>>519-
>>520 では、一番最初の要素(listtop)には、何も入っていないとの事でしょうか?
そしたら、要素1を指せないですよね???
ですが、解説の図には先ず最初の要素に要素1を指す物を入れるとか・・・
要素1ってなんだよ
>>522 listtop = (STRLIST *)malloc(sizeof(STRLIST));
ここで最初の要素が listtop に入る
LISTで詰まったら図を描くんだ
頭を整理しろ
526 :
518:2007/03/13(火) 01:10:11
本に依ると
listtopと言う箱があり、それが要素1と言うものをさしています
listtopは&(要素1)、要素1は&(&要素1)、要素2は&(要素3)・・・・・要素5は&(要素6)
要素6はNULL ってな感じです・・・
527 :
518:2007/03/13(火) 01:11:13
訂正
要素1は(&要素2)
>listtop = NULL;
listtop → (あさっての方向
>listtop = malloc(〜
listtop → [ ]
>strcpy
listtop → [ Ichiro ]
529 :
518:2007/03/13(火) 01:12:50
>>524 もし、このlisttopがNULLなら
最初の(&要素1)を指せませんよね
このlisttopが最初の要素1を指してる
>>529 listtop = NULL; の「時点では」 listtop は NULL だ
ずっと NULL ってわけじゃないだろ
listtop = malloc(〜) の時点で listtop は要素1を指す
プログラムを書くにあたって、頭が固いのは
物を知らない事より邪魔な要素
>>526 絶対何か勘違いしてるだろ。
要素1は listtop
要素2は listtop->next
要素3は listtop->next->next
それにしてもポインタを箱と言うか・・・俺のイメージはアドレスの書かれた矢印型看板なんだけどな
以前もいたよ。
a=1;
printf("%d",a);
a=2;
printf("%d",a);
これでどうして、2つの printf で違うものが出てくるのかが分からないって人。
プログラムは上から順に実行されるんだってことが分からないらしい。
536 :
518:2007/03/13(火) 01:20:50
>>528->>530-
>>531 listtopは最初は明後日の方向(何処も指していない)
でlisttop = malloc[ ]ができて、listtopに(&要素1)が入るのでしょうか?
listtop = malloc[ ]って打ち間違いだよな?
mallocで作った領域へのポインタ(mallocの戻り値)がlisttopに入る
入るとか言うからややこしいんだよ
listtop は要素1を指している、でいいんだよ
>>528 でわざわざ「矢印」を書いてくれてるだろ
俺のポインタのイメージは参照先へ線が付いてるタグ
プログラムは3Dマッピング
俺のポインタのイメージは
┌─┐
│ ┼→
└─┘
541 :
518:2007/03/13(火) 01:27:12
皆さん、ありがとうございます
listtop = malloc()でした
もうわけわかめなので、出直してきますが
では、"Ichiro"が要素2は listtop->next に
入ってる事になりますでしょうか?
要素1とか要素2とか言うからわけわからんようになるんだろうが。
もうちょっとちゃんと構造体を意識しろ。
>>541 >listtop = NULL;
listtop → (あさっての方向
>listtop = malloc(〜
listtop → [ ]
>strcpy
listtop → [ Ichiro ]
この図を見ても、「要素2」に「Ichiro」が入ってるように見えるか?
listtop → STRLIST構造体1
メンバ name = "Ichiro"
メンバ next → STRLIST構造体2(この時点ではまだNULL)
メンバ name = "Ichiro"
メンバ next → STRLIST構造体3
545 :
518:2007/03/13(火) 01:37:46
>>543 >>544 では、整理させてください。
最初はNULLで指している構造体ができてから
その前の所にできた構造体のアドレス(ポインタが入ると言うことでしょうか?)
546 :
518:2007/03/13(火) 01:41:34
使っている本は絵本シリーズです・・・
>>545 >最初は
「最初」というのはどこでしょう
>NULLで指している構造体
意味が分かりません
>その前の
どの?
548 :
518:2007/03/13(火) 01:47:32
自分でもよくわからなくなってしまっているので
最後に再度質問です
STRLIST *listtop = NULL;
が、いつ要素1にかわるのでしょうか?
>>548 531 名前:デフォルトの名無しさん[sage] 投稿日:2007/03/13(火) 01:16:05
>>529 listtop = NULL; の「時点では」 listtop は NULL だ
ずっと NULL ってわけじゃないだろ
listtop = malloc(〜) の時点で listtop は要素1を指す
550 :
518:2007/03/13(火) 01:49:57
ありがとうございました。
デバッグして動きを見てけば分かりやすい
百聞は一見に如かず
質問するのはいいことだけどさ、
返ってきたレス読んでないだろ?
たった10個前のレスコピペしただけでありがとうとか
つまりそのレスを読んでない証拠。
図を描けって言っても描かないし
要素1要素2ってやめろって言ってもやめないし
入るじゃなくて指すって言っても指すって言わないし
もっと頼れよ
何しに聞きにきてるんだよ
自分ひとりで解決しようとすんなよ
553 :
デフォルトの名無しさん:2007/03/13(火) 01:55:04
リバースエンジニアリングスレってどこだ?
ちょい報告しようかと思ったんだが。
2chブラウザには面白いもん内蔵されてんだよね。
ちょいビビった。
このスレの住人は知ってる人多そうな、既出ネタっぽいが…。
(こりゃ儲かるよなあ、内蔵されてれば、でもシークレット???)
554 :
デフォルトの名無しさん:2007/03/13(火) 02:04:12
ポインタはアドレスと言う概念で理解するより
唯単に指す物的なイメージで覚える方がいいでしょうか?
>>553 雑談スレとか
いや、他の板で扱うネタな気もする
>>554 抽象的に捉らえておいて、
実際に使いながら理解するって感じかなぁ
アドレスと覚えるとインクリメントとかでつまづくかも
>>534 おれのイメージは変数名が書いてある紙にひもがぶら下がっていて、
そのひもの先に何か括り付けられている感じ。
557 :
デフォルトの名無しさん:2007/03/13(火) 04:13:17
>>555 アドレス的概念だけでは理解しない方がいいみたいですね
>>556 やっぱし、皆イメージは付けてるのね
ポインタは型の情報のついたアドレスだと思ってる。
アドレスとして捉えないと、配列などで連続したメモリブロックにある場合のイメージが曖昧になる。
動的メモリ操作に関する質問です。
どんなときメモリ確保&解放するべきかよくわかりません。
例えば単に配列を読み込んで表示する場合と、メモリ確保してから
配列の読み込み&表示して解放するのではどう違ってくるのでしょう?
文字を逆に表示するプログラムを考えています
本来はファイルの内容を1行ずつ逆にするのですが
基本的なことからわかってないようなので
以下のプログラムのどこがいけないか教えていただきたいです
#include <stdio.h>
int main(void){
char str[]="abcdefg";
int i;
for(i=10;i>=0;i--){
if(str[i]!=0){
putchar(str[i]);
}
}
return 0;
}
実行結果は最初の数文字が文字化けで表れ
「g」は表示されず「fedcba」は表示されます
for文のiを文字数と同じ「7」にすると上手くいくのですが
文字数がわからない場合でも対応したいので「10」にしています
(本来は1024にするつもりですが、現段階では結果がものすごいことになるので減らしています)
>>560 10を((sizeof(str))/sizeof(str[0]))-1に置き換えてみたらうまくいくと思います。
固定配列とは限らないんだtったら
長さは strlen() で数えよう
>>559 長さが事前にわからない場合は動的にやるだろ
>>559 「配列を読み込む」とは具体的にどういう操作のことを言ってるの?
>>460 if(str[i]!=0){
putchar(str[i]);
}
これは、strが
0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0, 0, 0, 0
であることを前提にしている(ASCIIだったとして)。
でも実際には9番目と10番目と11番目は何が入ってるかわからない。ゼロであるとは限らない。
だから、putcharのループは、確実に終端文字'\0'の一つ手前から始まるようにしないといけない。
文字数が固定でないなら、最初に開始位置を確定する操作を置くべし。
565 :
560:2007/03/13(火) 05:37:40
質問に答えていただいてありがとうございます
stdio.hの標準ライブラリ関数だけでは
この内容のプログラムは不可能だったり、無駄に複雑になったりしますか?
できればstdio.hだけで処理したいんですが
566 :
デフォルトの名無しさん:2007/03/13(火) 05:38:45
エクセルやワードが使えないのにC言語やってます、皆から順序が変と
言われます…この前、エクセルの参考書を見たら関数や引数がCやってるせいか
理解しやすそうでした
567 :
560:2007/03/13(火) 05:42:06
>>564 なるほど、9番目以降はデータが入っていないのではなく
何が入ってるかわからない状態なんですね
ありがとうございます
う〜ん、文字数が固定でない状態で確実に終端文字の一つ手前から始まる操作。。。
今のところ思いつきませんが考えてみます
>>565 じゃあこれで(ファイルからの読み取りだと
>>561ってワケにはいかなそうだし)。
char *cp = str;
while(*cp)cp++;
while(cp != str)putchar(*--cp);
ポインタ地獄
これくらいは楽に読めるようになっては欲しいけど、まあ複雑だあねw
スキャナのヘッドを読み取りたい領域まで持っていってから
紙を物理的に逆さにするわけにはいかないから、反対側の紙の外まで持っていって
そこからまた紙の外に出るまで戻しながら読み取っていく
って感じか
演算子の優先順位とか調べながら変数に初期値与えて紙の上でこちゃこちゃしてたらなんとなくわかった
でもこういうの見た瞬間に理解できるようになりたいなぁ
>>564 説明が下手だな。コードで説明しなくても文字で説明すれば済むだろ。
>>565 string.hを使わない積極的な理由が無いなら、使うべき。
>>566 確かに順序が変だね。もっと日本語をやるべきだ。
576 :
560:2007/03/13(火) 07:52:23
正直言って、授業の課題をやってるわけですが
この授業ではstdio.hしかやっていないのです
ポインタも後回しで、「ファイル操作の時にはこうやるんだ」とだけ。
私は他の授業でstring.hもポインタも習っていますが
授業の進め方がこうである以上、ポインタを使わずかつstdio.hだけでやるやり方を探しています
今のところ思いつきませんが
string.hの関数を自分で実装すればいいじゃないか
ポインタ無しのstdioだけ?
int i=1;
fseek( fp, i, SEEK_END)
while( ftell(infp) != 0 ){
fputc( fgetc(infp), outfp);
i++;
fseek( fp, i, SEEK_END);
}
こんな感じ?
ざんねんながらfpはポインタだ
580 :
560:2007/03/13(火) 08:32:35
みなさんありがとうございました
自分で配列の長さを測る関数を作ってやりたいと思います
もう考えるのも面倒だし
582 :
デフォルトの名無しさん:2007/03/13(火) 08:40:06
趣味でネット麻雀代打プログラムを作っています。
思考ルーチンが走っている間であっても、ユーザ入力(一時停止や、思考ルーチンの強さ指定、
攻撃・守備モード切替等)を受け付けることができるようにしたいのですが、
マルチスレッドにする必要はあるのでしょうか?
そりゃぁ、論外だし。
>>580 #include <stdio.h>
int main(void)
{
char str[] = "abcdefg";
int i;
for (i=0; str[i] != '\0'; i++);
for (i-=1; i>=0; i--) putchar(str[i]);
return(0);
}
思考ルーチンの最中で、ときどきメッセージループをまわしてあげるのはどうだろ?
思考ルーチンからループアウトしてまわすのは大変だけど、
思考ルーチンの途中で呼び出すイメージ
// 思考ルーチン
while (〜){
// いろいろ考えて
CallMessageLoop();
// いろいろ考えて
CallMessageLoop();
}
>>584 ちょっとすっきり。
#include <stdio.h>
int main(void)
{
char s[] = "abcdefg";
int i;
for (i = 0; s[i]; ++i);
while (--i >= 0) putchar(s[i]);
return 0;
}
再帰版はこんな感じか。
#include <stdio.h>
void rev(char s[], int p)
{
if (s[p]) {
rev(s, p + 1);
putchar(s[p]);
}
}
int main(void)
{
rev("abcdefg", 0);
return 0;
}
ポインタアリなら再帰ですっきりだな。(無駄な感じするけど)
#include <stdio.h>
void rev(char *p)
{
if (*p) {
rev(p + 1);
putchar(*p);
}
}
int main(void)
{
rev("abcdefg");
}
588 :
501:2007/03/13(火) 10:38:54
>>503 >>508 ありがとうございます!
>>507 自作ソフトに付属するdllファイルをregsvr32で登録させるインストーラーを作りたいと思いまして。
>>511 あ、そうです!
バッチって言われてるような、一瞬プロンプトが出て消えるけど、作業がされてるみたいなのにしたかったんです。
>>509 誘導ありがとうございます!
>>580 ところで、もし大学ならば講義でやってないことを宿題に書いて出しても
普通は問題ないと思うよ。あえてそれをやるなと言われているのでなければね。
590 :
501:2007/03/13(火) 10:55:41
バッチファイルで、めちゃくちゃ簡単にできましたw
ありがとうございました。
void main()
{
void func(); ←ここの意味
i = func(a,b);
}
int func( a, b )
{
}
かなり省略形ですいません><
UNIXからの移植なんですが func() があるとVCじゃC2660出ちゃうし
安易に消していいものか?分からなくて
意味を教えてください、お願いします。
関数プロトタイプ
挨拶もせず、いきなり乗せて失礼しました。
3行目 int func(); でお願いします><
まだ省略してるだろ
int func(int a, int b) とかじゃないのか。
そしたらプロトタイプもああおれにあわせろ
分からないなら※アウトすればイイじゃない
っていうか、そこに書いてある理由が思いつかない
>>592 即レスありです。
関数プロトタイプっの引数無しって事ですか?
VCじゃ、ちゃんと宣言しとかないとC2660が出る気がして
宣言しなおしてるんで必要なしって事ですかね
もうちょっとゴソゴソしてみます、ありがとうございました。
C2660なんて書かれてもVCもってなければ意味が分からんわけだが。
ぐぐって調べたぜ。
mainの中のvoid func();は、funcという関数は引数を取らず、
値を返さない関数であるというプロトタイプ宣言。
関数呼び出し前にプロトタイプ宣言もしくは関数の定義そのものがないと、
その関数はintを返す引数のない関数であると仮定される。引数については、
Cでは引数の数はチェックされなくなり、C++では引数なしの関数であると
仮定される。
でもって実際にはfuncの定義を見ると引数が2つある。
あんぎゃー。CとC++の違いを書こうとして推敲せずに出したら間違えた。
2段落目の引数のとこは無視。3段落目の文が正しい。
そのコードでコンパイルエラーになるとしたら、
それはVCだからではなく、C++としてコンパイルしているからだと思う。
……慌てるとダメだな。
>>598のほうを無視だ。
2段落目はプロトタイプ宣言自体の説明で3段落目は省略時の話だわい。
落ち着けよわけわかんねーよ
訳もわからず消すのはやめてCのソースとしてコンパイルすべき。
プロトタイプを省略すると戻り値はintと仮定、引数についてはチェックしない
(Cの場合)
プロトタイプを書いた場合は、呼び出し形式や定義がその通りになっていないと
怒られる。
これでよいかな。
>>591は古いC言語なら正しいソースだよ。
普通にコンパイル通る。
便乗して質問おながいします。
b.h で定義してある
typedef struct {
:
} TYPEB;
というのがあるとき、b.hをincludeしてない別のヘッダファイル内で
TYPEBを引数に持つ関数の宣言はどうやるのが正しいのでしょうか?
/* in a.h */
struct TYPEB; /* プロトタイプ宣言 これがないと次の行でTYPEBが未定義と怒られる? */
struct TYPEB* func (struct TYPEB* arg);
これであってます?
>>605 b.h で
typedef struct typeB { } TYPEB;
/*
struct typeB { };
typedef struct typeB TYPEB;
*/
としているのならば、a.h では
struct typeB* func(struct typeB* arg);
という宣言が可能。
元記述だと名前なし構造体なので
b.h を include するなりして、TYPEB を確定させるしかない。
607 :
605:2007/03/13(火) 12:38:15
>>606 すばやいご回答ありがとうございます。
typedef struct name { } TYPEB;
のnameをつけるのとつけないのは何が違うのか良くわからなかったのですが
よくわかりました。ありがとうございます。
printf関数等で画面に文字を出力する時、最終的にはそのOSのAPI(WindowsならTextout関数等)を呼び出して表示してるわけですか?
はい。
610 :
608:2007/03/13(火) 13:53:35
>>609 すっきりしました、即レスありがとうございます
VC8SDKで現在開発しているのですが、APIをゴリゴリ書いていくのに
疲れてしまいました。そこでMFCかC++Builderか悩んでいます。
調べた感じC++Builderが開発効率が良さそうなのですが、実際のところはどうでしょう
みなさん、どのような環境で開発してるんですか?
abc,123,456
tako,23,134,2345,
hoge,344,11,
このようなカンマで区切られた、1行のデータ数が適当だったり
カンマの個数がまちまちだったりするデータを読み込んで
data[1].name data[1].score1
に入力していきたいのですが。
fscanfを使わないでやりたいのです
普通に切り分けていけばいいじゃないか。
何が知りたいの?
その組み方がわからなくて
fgets strtokあたりの使い方を
普通に切り分けるサンプルのようなものありませんか
>>612 %100[^,\n]
とかの書式指定はできるけど
fscanf がダメな理由はあるの?
>>617 fscanfだと
%s,%d,%d,%d, みたいに書式が分かっていないとだめですよね。
カンマと「 (スペース)」が混在したりもしているので。
カンマとスペースで区切って、任意の変数にファイルから読み込むというのを
最終的にやりたいのですが、カンマの時点で突っかかりました
普通に前から一文字ずつ読んでいって、カンマならそこまでコピーすればいいんでないの?
>>616 strtokでみてみて、いまいち意味がわからないのが
int main(void)
{
char str[] = "ABCD ef.1234.G";
char *tp;
/* スペース.を区切りに文字列を抽出 */
tp = strtok( str, " ." ); //←ここはなんのため?
puts( tp );
//strを分割するだけなら↓からだけで十分じゃないの?
while ( tp != NULL ) {
tp = strtok( NULL," ." );
if ( tp != NULL ) puts( tp );
}
return 0;
}
といった疑問が。あとfgetsの動きもよくわかりません
>>619 最終的に行数=人数も吐き出したいので、1文字ずつより1行ずついきたいのです
1行分をばっさり読み込む fgets → buf
top = tail = buf;
カンマ, スペースが来るまで tail を進める。 (*)
top から tail までがトークン 適当に切り出す。 strncpy(dst, top, tail-top);
top = tail+1;
(カンマ, スペースが続く間 top を進める)
* 最後まで繰り返し
strtokは自分専用の文字列ポインタを持ってて、NULLでない
引数がわたってきたときはそれで専用ポインタを初期化する。
NULLがきたら、既に覚えてるはずの専用ポインタの値を使う。
>>622 やってみます。というか似たようなことで詰まってる人他にもいるだろうに
>>623manページは伝えわるような文じゃないので、わかんないっす
>>612 読み込むデータをリダイレクトでこれに流し込んでみて
#include <stdio.h>
int main(void){
FILE *fp=stdin;
int row, line_count=1;
char buf[256];
while(!feof(fp)){
if(fscanf(fp, "%1[\n]", buf)==1)
line_count++;
row=0;
while(1){
fscanf(fp, "%*[ \t,]");
if(fscanf(fp, "%250[^ \t\n,]", buf)==1)
printf("Line:%d Row:%d %s\n", line_count, ++row, buf);
else
break;
}
}
return 0;
}
man読めないって重症だと思うんだが
>>626 理想どおりの動きをしました…ただ、自分の読解力の無さのためfscanfの項で何をしているのかがわからないです
ほんとすんません
コードを読めない
日本語を読めない
……どうするんだろう。
英語か何かなら読めるんだろう。
>>611 C++Builderは使ったこと無いのでわかりませんが
MFCはVC++との相性がよいので比較的ラクだと思います。
ただMFCには使ってはいけないといわれるクラス(CSocketとか)がいくつかあるので、
そういう地雷を踏まないように経験を積む必要はありますが。
TreeViewとかListViewとかWebBrowserとか、
Windowsのコンポーネントを使うにはMFCは便利なので、
MFCは使えるように初期化だけしておいて、必要なクラスだけ使う、
のがいいんじゃないでしょうか。
と言ってみるテスト
しかし scanf のマニュアルの読みにくさは最上位レベル
636 :
582:2007/03/13(火) 17:15:31
>>585 なるほど・・・ご回答ありがとうございます。
思考ルーチン部そのものがイベントドリブンな感じなので(自分のターンがきたときや、
ポン・チーの問い合わせ時のみ思考関数を呼び出しています)、
それ以外の暇なときに、ユーザ入力部に相当する、チェックボックスやラジオボタンの変更を
チェックする関数を呼び出す、みたいな感じでやってみようと思います。
manって何かと思い、リンク踏んだら
おもいっきり日本語解説文じゃねーか
てっきり「きっと、英語の難しい解説文なんだろうな」
と思って損した。
manを知らない人間がいるとは驚愕。
それを知ってて理解できるやつは入門を超えてるだろう
mankoマンド
int main(int argc,char *argv[]) とするのは、
何かコマンドを取るプログラムを作る時のみで構いませんよね?
はい。
fseek(fp, 10L, SEEK_SET); で
10Lの"L"とは一体何なんでしょうか?
ただの10でも動くのですが、必要なのでしょうか?
>>641 引数を必要としない、かつ呼び出し元に何も通知する必要が無ければ
void main(void)
でおk
>>643 Lがlongですよーって明示的に言ってる。必要か不要化?
最近のコンパイラは頭が良いので付けなくても良いけど、
自分や後からコードを見た人にとっては有った方が嬉しいね。
ご期待に応えて:
「main関数の返値をvoidにするのは規格違反」
>>646 把握した
>>645 コンパイラは頭が良いので
↓
プロトタイプ宣言があれば(この場合は関数呼び出しより前に #include<stdio.h> があれば、でも可)
昔は組込環境とかでエントリポイントがvoid main()固定というのがたまにあったが
ANSI準拠でないことは確かだな。
651 :
645:2007/03/13(火) 20:15:06
東ア+より食いつきが良いなー
高々数千回の比較分岐代入操作に、ちっちゃな構造体(数10bytes程度)を
関数にconst参照で渡す処理を行うんですが
値渡しでなく、const参照渡しを使うことによる目に見えるほどのデメリットが生じる可能性はあるでしょうか?
>>650 自立環境(フリースタンディング)では、
エントリポイントが処理系定義となっていたはず。
それならANSI準拠を名乗れる。
C言語を独学で勉強して一年以上経つし、その間わからないことは色々ググったりしたけど、
manなんてものは全然知らなかった。
>>638の驚愕に驚愕した。
文章は日本語だけど画面構成が見づらいね。
個人的にはMSDNの方が見やすい。
初期の頃"strlen"とか調べなかったの?
一番最初に出て来るジャマイカ
>>654 unix 系OSには man というコマンドがあって
man fopen
とかすると解説が出てくるんだ (マニュアルがインストールされていれば)
>>630 の URL は linux の man を翻訳したもの
なので ls (dir みたいなもの) のヘルプとかも調べられる
>>654 そりゃ、コンソール上に表示するための画面構成だから
linuxくらい経験しとけ
>645
はいはいクマクマ
もうcygwinでいいよー
/dev/dspつかえるし
661 :
654:2007/03/13(火) 22:16:47
そういうことか。
linuxな人ってああいうのが多いんだ?
おまえの世界観が狭いだけだよ
manをHTMLで見るのは本来想定されていた見方ではないがな。
>>652 そんな気にするような欠点は無いと思ってよい。
それよりもここはC++のスレでないから、
スレ違いであることを気にしろ。
>>654 MSDNライブラリはオフラインならいいけど、
オンラインはいいと思えない。その点manとどっちもどっち。
>>662 そりゃ独学で一年の奴の「世界観」とやらが広いわけはないが、
お前の性格が少々アレな感じなのはそれとは全く独立の事象だ。
匿名相手に性格云々ぬかすのはナンセンスだ
どっから性格の話が出てくるんだよ
これだからゆとりは…
>>654 Windowsプログラマの癖にMSDNを知らなかったらビックリするだろ? そんな感じ。
でも Linux/Unix を触ったことがないヤツなら別に知らなくてもフツー。
>>638 が驚愕してるのは
>>638 が偏見と先入観に満ちてる馬鹿だから。
どーでもいいよ
これだからすぐ「これだからゆとりは」っていう奴は・・・
>>666 世界観云々を言うのはナンセンスじゃないのか?
よく考えたら初心者向けのスレだから
別にman知らなくてもゆとりでもOKだな
むしろ UNIX 触ってなかったら、どこで man なんて存在を知るんだ
MSDNオフラインリファレンスくらいExpress Edition入れれば入るんだけどね。
MSDNライブラリはExpressとは関係なく単独でダウンロードできる
そもそもExpressに付いてくるMSDNライブラリはExpress仕様で、
CRT関数や.NET Frameworkのクラスライブラリのリファレンスなんかが
すっぽり抜け落ちていて使い物にならなかったはず。
include
>Express仕様
要するに_s付きの関数が標準で用意されてると思いこませる仕様ってことか。
理系の大学なら大抵ワークステーションがあって
Sun、Solarisあたり触ってると思うんだけど
man知らない人って文系でプログラミングやってるの?
おいら8年前大学生で理系だっったけど、NT4.0でVCとか動いてたよ。
LinuxOS入ったPCなら大量にあるけど、皆VMwareからWindows使ってます
>>678 いや、そういう関数リファレンスみたいなものは一切無かったはず。
コンパイラオプションとかチュートリアル程度だった気がする。
今はもうMSDN ライブラリExpressはインストールしていないから、詳しくは忘れたが。
もっとも、普通のMSDNライブラリでも_s付き関数は非標準だとどこにも書いていないが。
スレ違いですが教えて下さい
msdnライブラリのオフライン版には API のマニュアルもついているんでしょうか?
今2G超のイメージファイルをダウンロード中ですがあと7時間ほどかかりそうなので
もし API のマニュアルが含まれていないなら中断しようかと思っています
Windows APIのことなら当然入っている。
ただし英語で良いならPlatform SDK/Windows SDKのドキュメントにも同じものが入っている。
理系がみんなプログラミングやるわけじゃないだろ。
UNIXもそう。
在学中はプレゼン資料作成以外にコンピュータは使わず、
卒業後に趣味でプログラミング始めた俺みたいなのもいる。
>>684 ありがとうございます
粘ってダウンロードすることにします
>>682 ECMA規格化されたC++/CLIの規格に入ってるから
非標準というわけでもないんだよな。
それでなくともCRTのセキュア化は必要だし
俺、理系だったけど大学linux乗せているのはなかった
研究室にはあったかもしれないが
授業とかの環境もボーランドC++3だったし
689 :
デフォルトの名無しさん:2007/03/14(水) 03:44:51
#include <stdio.h>
void swap(int *, int *);
void printDate(int *);
main(){
int a[] = {2,4,3,5};
int n = 4;
int j, i;
printDate(a);
for(j=0; j <= n-2; j++){
for(i = j+1; i <= n-1; i++){
if(a[j] < a[i]){
swap(a+i, a+j);
printf("[%d]と[%d]を入れ替え\n",i, j);
printDate(a);
}
}
}
}
void swap(int *y, int *z){
int t;
t = *y;
*y = *z;
*z = t;
}
690 :
689:2007/03/14(水) 03:46:34
void printDate(int *a){
int i;
for(i = 0; i < 4; i++)
printf("%2d", a[i]);
printf("\n");
return 0;
}
このソースでわからない事があります
for(j=0; j <= n-2; j++){
for(i = j+1; i <= n-1; i++){
if(a[j] < a[i]){
swap(a+i, a+j);
これらを解説お願い致します。
691 :
689:2007/03/14(水) 03:52:54
n-2; と n-1が特にりかいできません
692 :
デフォルトの名無しさん:2007/03/14(水) 03:56:16
>>690 3 4 2 5 (はじめ)
4 3 2 5 j=0 i=1
4 3 2 5 j=0 i=2
5 3 2 4 j=0 i=3
5 3 2 4 j=1 i=0
5 3 2 4 j=1 i=2
5 4 2 3 j=1 i=3
5 4 3 2 j=2 i=3
693 :
689:2007/03/14(水) 03:58:34
n-1とはa[0]の事でしょうか?そしてn-2はa[1]の事でしょうか?
694 :
689:2007/03/14(水) 04:06:24
>>692 ありがとうございました、何となく理解できました
695 :
デフォルトの名無しさん:2007/03/14(水) 04:08:40
3 4 2 5 (はじめ) <−最初は2 3 4 5だったねスマン
4 3 2 5 j=0 i=1
4 3 2 5 j=0 i=2
5 3 2 4 j=0 i=3 ※i=3の3がn-1
5 3 2 4 j=1 i=0
5 3 2 4 j=1 i=2
5 4 2 3 j=1 i=3 ※i=3の3がn-1
5 4 3 2 j=2 i=3 ※j=2の2がn-2 ※i=3の3がn-1
696 :
689:2007/03/14(水) 04:11:14
>>695 実行すると始めは、2,4,3,5あのですが・・・・
697 :
689:2007/03/14(水) 04:27:17
ひ〜もうわけがわからんです。
{2,4,3,5};に於いて、nは2、n-1とは4でn-2は3、n-3が5なのでしょうか?
そして、jとは基準値との事ですが、j+1とは何なのでしょうか?
698 :
デフォルトの名無しさん:2007/03/14(水) 04:36:51
これだな!
2 4 3 5 (はじめ)
4 2 3 5 j=0 i=1
4 2 3 5 j=0 i=2
5 2 3 4 j=0 i=3 ※i=3の3がn-1
5 4 2 3 j=1 i=2
5 4 2 3 j=1 i=3 ※i=3の3がn-1
5 4 3 2 j=2 i=3 ※j=2の2がn-2 ※i=3の3がn-1
5 4 3 2 (結果)
699 :
デフォルトの名無しさん:2007/03/14(水) 04:56:23
>>697 > {2,4,3,5};に於いて、nは2、n-1とは4でn-2は3、n-3が5なのでしょうか?
nは配列aの大きさで4
n-1は4-1=3, n-2=4-2=2, n-3=4-3=1
ここではそれぞれ配列aのインデックスをしめしている
a[4]={2,4,3,5}だと;
a[n-1]=a[3]=5、a[n-2]=a[2]=3、a[n-3]=a[1]=4
> そして、jとは基準値との事ですが、j+1とは何なのでしょうか?
すべての配列要素a[j] j=0, 1, 2, 3=n-1と後ろの配列要素a[j] i=j+1, j+2, ・・・n-1
を比較しa[j] < a[i]なら、つまりa[i]がa[i]より大きければa[i]とa[j]えお入れ替えるという処理
をここでしているわけです
だから、j+1というのはjのつぎ、つまりうしろという意味です
わかった?
700 :
689:2007/03/14(水) 04:59:26
ありがとうございます、何とか理解できてはできてきましたが
nとは因みに、どの事をさすのでしょうか?要素が4つですよね?
701 :
689:2007/03/14(水) 05:03:51
>>699 あー!更にわかってきました!あとは深く考えてみて理解を深めます
皆さん、黎明までつきあって戴き、ありがとうございました。
702 :
デフォルトの名無しさん:2007/03/14(水) 05:05:38
>>700 ループを一回ずつ追って、配列の中身がどのように変わるか
それを机上でやってみてください
703 :
689:2007/03/14(水) 05:10:10
もう一つ確認の質問なのですが、
>>698さんの>>※i=3の3はnー1
とは、4ー1=3と考えて宜しいでしょうか?又、他のも然りですかね?
704 :
689:2007/03/14(水) 05:11:29
705 :
デフォルトの名無しさん:2007/03/14(水) 05:12:43
706 :
689:2007/03/14(水) 05:17:10
更にわかったのが、ー1とはインデクスと要素を合わせる為に必要だった
んですね
>>706 然り。
配列扱うとき個数がNなら、N-1 ってだいたい出てくる。そういう意味
(以下は余計なお節介かも試練が)
一見ややこしい i, j の範囲はこれが一番ムダがないから。
例えば 「5 と 5 を比べて、もし 5 が 5 より大きいなら……」 という無駄な処理はやりたくないっしょ?
for (j=0; j<=n-1; j++)
for (i=j; i<=n-1; i++)
if (a[j] < a[i]) swap... // i=j のとき無駄な処理
708 :
689:2007/03/14(水) 05:45:42
やはり、仕組みは理解できましたがソースで見ると、ややこしく
ちんぷんかんぷんで今一わからない…
709 :
689:2007/03/14(水) 05:47:07
710 :
デフォルトの名無しさん:2007/03/14(水) 05:58:01
float の有効数字を小さくすることはできますか?
例えば
float f = 0.123456;
float g = 0.987654
に対して、0.123と0.988を返して欲しいんですが。
浮動小数点と有効数字の違いが微妙なのですが、上記の例に追加すると、
float h = 98.7654;
については、98.8 にしたいです。
712 :
デフォルトの名無しさん:2007/03/14(水) 06:20:02
sprintfで有効桁数3桁の文字列に変換して
その文字列をatofでfloatにする
float f1, f2;
char s[128];
f1 = 98.7654;
sprintf(s, "%.3g\n" , f1); /* 98.7654は文字列の"98.8"になる */
f2 = atof(s);
713 :
710:2007/03/14(水) 06:58:27
>>712 ありがとうございました。
あやうくめんどくさい関数を自作するところでした。
ファイルの入出力のあたりを勉強したのでファイルに文字を書き込むプログラムを
作ってみた。以下のソースはその一部でとりあえずファイルをオープンしてNULL
チェックもして以下のように処理させた。
r:;
printf("何行入力しますか?:");
scanf("%d",&j);
printf("それでは文字を入力してください。\n");
for(i=0;i<=j;i++){
gets(a);
fputs(a,fp2);
fprintf(fp2,"\n");
if(i==j&&j!=0){
printf("\t終了しますか?\n");
printf("1.はい2.続行する\n");
printf("番号:");
scanf("%d",&q);
if(q==1){
break;
}
else{
goto r;
}
}
}
とりあえずコンパイルしてもエラーは見られなかったが、scanf関数に万が一でも文字を
いれると無限にこの関数が実行してしまう。このバグを回避する方法とかを何とか・・・。
gets!?goto!?
gotoは構わんだろ
getsは氏ね
fgets(buf, sizeof(buf), stdin)で文字列として受け取ってから整数に変換でおk
別にgoto使うなとまではいわないけど、714の使い方は死すべきレベル。
ただ死んで終わるものではなく、又吉イエスによって火の中に投げ込まれるレベル。
終了しますかの部分は、for 文から出すべきだろ
for の条件式が意味を成してない
scanf なんて使うのは、個人での練習段階だけだろうから
文字を入れられるとかは気にしなくていいんじゃない?
何故かFORTRANを思い出した。
gotoってネストしたループ&switchからの脱出以外で、必要性ってあったっけ?
delete やら fclose やらの終了処理を最後にまとめて、
エラーが出ればそこにすっとぶってやってる人もいるな
do{
if(A()) break;
if(B()) break;
// :
} while(0);
なんていう汚いプログラムを書かなくてすむようになる。
>>714 for(;;)
{
printf(("何行入力しますか?:");
fgets(buf, sizeof(buf), stdin);
j = atoi(buf);
if(j <= 0) break;
printf("それでは文字を入力してください。\n");
for(i=0;i<j;i++)
{
fgets(buf, sizeof(buf), stdin);
fputs(buf, fp2);
}
printf( "\t終了しますか?\n"
"1.はい\t2.続行する\n"
"番号:"
);
fgets(buf, sizeof(buf), stdin);
q = atoi(buf);
if(q != 2) break;
}
scanfは指定した書式以外の入力は、入力バッファそのままで返ってくる
その入力をクリアしないでまたscanf呼ぶと、また同じことになる
scanfの是非以前にこの挙動は把握するべき
725 :
714:2007/03/15(木) 00:15:43
いろいろとレスサンクス。俺がまだ未熟だったよ。
ところで俺はコマンドライン引数というのを最近勉強して知ったんだがそれを応用した実用性のあるソースをまだみたことがない。急にすまないがそのソースの例を示してくれないか?
linuxのコマンドのソースでもみとけ
dir c:\
shutdown -s -t 0
format c:
>>725 それよりもメモリと代入を応用したソースってあるの?
kill you
732 :
714:2007/03/15(木) 00:41:31
>>729 それ危険w
質問の意味を取り違えているような…。例えば
int main(int argc,char *argv[]){…}
みたいにコマンドライン引数を応用した実用性のある例を示してくれないだろうか。
#include <stdio.h>
int main(int argc, char **argc) {
for(;*argc;argc++) if(!remove(*argc)) return 1;
return 0;
}
>>732 たとえば、別のプロセスから起動させるときとか
実行ファイルのアイコンに処理するファイルをD&Dしたときとか
指定したスイッチによって処理方法変えたいときとか
>>732 いや、
>>729 とかがまさにそれじゃないのか?
format だってプログラムだ、
"fotmar c:" で、argc に 2 が、argv[1] には "c:" が入ってるだろう
737 :
714:2007/03/15(木) 01:12:34
なるほどw
じゃあ、bcc32_○○.cみたいにコンパイルするのもそれってことなのか?
気づかなかったのか・・・
これはなんというか・・・
可哀想に見えてくるのは禁じえない
740 :
デフォルトの名無しさん:2007/03/15(木) 03:30:53
include <stdio.h>
void printDate(int *);
main(){
int a = {9,6,5,1,2};
int n = 5;
int i,j,h,t;
printDate(a);
for(h = 1; h <= n; h = 3*h + 1)
;
h /= 3;
while(h >= 1){
for(i = h; i < n; i++){
t = a[i];
for(j = i-h; j >= 0; j-=h){
if(a[j] > t)
a[j+h] = a[j];
else
break;
}
741 :
デフォルトの名無しさん:2007/03/15(木) 03:32:52
a[j+h] = t;
if(j+h != i){
printf("[%d]の位置に[%d]を挿入\n", j+h, i);
printDate(a);
}
}
h /= 3;
}
}
void printDate(int *a){
int i;
for(i = 0; i < 5; i++)
printf("%2d", a[i]);
printf("\n");
}
742 :
デフォルトの名無しさん:2007/03/15(木) 03:33:59
エラー E2291 sehell.c 6: } が必要(関数 main )
エラー E2141 sehell.c 6: 宣言の構文エラー(関数 main )
エラー E2139 sehell.c 6: 宣言に ; がない(関数 main )
警告 W8070 sehell.c 6: 関数は値を返すべき(関数 main )
警告 W8004 sehell.c 6: 'a' に代入した値は使われていない(関数 main )
エラー E2190 sehell.c 6: 不要な }
エラー E2356 sehell.c 10: 'printDate' の再宣言で型が一致していない
エラー E2344 sehell.c 3: 一つ前の 'printDate' の定義位置
エラー E2258 sehell.c 10: ここには宣言が必要だが見つからない(関数 printDate )
エラー E2258 sehell.c 12: ここには宣言が必要だが見つからない(関数 printDate )
エラー E2258 sehell.c 12: ここには宣言が必要だが見つからない(関数 printDate )
エラー E2258 sehell.c 12: ここには宣言が必要だが見つからない(関数 printDate )
エラー E2258 sehell.c 14: ここには宣言が必要だが見つからない(関数 printDate )
エラー E2258 sehell.c 16: ここには宣言が必要だが見つからない(関数 printDate )
エラー E2342 sehell.c 16: パラメータ 'a' は int * 型として定義されているので und
efined は渡せない(関数 printDate )
エラー E2062 sehell.c 18: 無効な間接参照(関数 printDate )
エラー E2062 sehell.c 20: 無効な間接参照(関数 printDate )
エラー E2062 sehell.c 21: 無効な間接参照(関数 printDate )
エラー E2062 sehell.c 21: 無効な間接参照(関数 printDate )
エラー E2062 sehell.c 25: 無効な間接参照(関数 printDate )
エラー E2342 sehell.c 28: パラメータ 'a' は int * 型として定義されているので int
は渡せない(関数 printDate )
警告 W8070 sehell.c 32: 関数は値を返すべき(関数 printDate )
警告 W8057 sehell.c 32: パラメータ 'a' は一度も使用されない(関数 printDate )
エラー E2190 sehell.c 33: 不要な }
エラー E2238 sehell.c 35: 'printDate' の宣言が複数見つかった
エラー E2344 sehell.c 10: 一つ前の 'printDate' の定義位置
*** 22 errors in Compile ***
どうしても、参考書のソースと比較しても解決しませんので、ご指摘お願い致します。
>>740 >int a = {9,6,5,1,2};
>>742 >どうしても、参考書のソースと比較しても解決しませんので、ご指摘お願い致します。
新しい参考書かメガネ買ってこい。
744 :
デフォルトの名無しさん:2007/03/15(木) 03:45:29
>>743 できました!!サンkすです
あまり良いソースではないのでしょうか?
何コレ……
>int a = {9,6,5,1,2};
もし、↑以外が参考書の通りだっていうのなら
まずはその著者を教えてくれ。
746 :
デフォルトの名無しさん:2007/03/15(木) 04:27:47
高橋誠
747 :
デフォルトの名無しさん:2007/03/15(木) 04:29:19
あとは参考書通りだし実行できます、著者は3人です
一人が今挙げた人ともう一人が渡辺さんです
748 :
デフォルトの名無しさん:2007/03/15(木) 04:30:52
本のを描写してますし、初心者なので、こんな難しいソースは書けません
因みに解説もあまりなく全然わかりませんし…
ソートをしてるっぽいってのは分かるんだが…
for(h = 1; h <= n; h = 3*h + 1)
;
h /= 3;
この辺り高度すぎて俺には理解不能
750 :
748:2007/03/15(木) 04:40:21
僕にもさっぱりです
しかも途中に;が付くなんて初めて見ました
皆さんサンクスでしたノシ
>>750 参考書丸写しする前に、もっと簡単な本で文法の基礎から勉強しろ。
752 :
デフォルトの名無しさん:2007/03/15(木) 06:06:25
2次元配列についての質問です!
たくさんの2次元配列を使いたいときは、どうすればいいのでしょうか?
それとも、扱える配列の最大数は決まっているんでしょうか?
私の環境では、
double a[359][359];
までしか宣言できないんです。
もっと大きな配列、例えば、
a[0][0]〜a[1000][1000]
とかを使えるとうれしいのですが。
753 :
デフォルトの名無しさん:2007/03/15(木) 06:33:07
double** a = (double**)malloc(sizeof(double*) * 1000 );
for(int i = 0; i < 1000; i++ ) a[i] = (double*)malloc(sizeof(double) * 1000 );
// 配列を用いた処理
・・・
・・・
・・・
// 配列を使い終わったら、
for(int i = 0; i < 1000; i++ ) free(a[i]);
free(a);
754 :
752:2007/03/15(木) 06:54:16
>>753 うおっ!
それでできるんすかっ!
うはーやっぱ人に聞いてみるもんですねぇ。
まじで、まじで、ありがとうございました!
やめた方がいいけどね。
いまどき時代遅れのC言語なんてやっても意味ないの?
好きなのに・・・・
>>757 ぃゃ、Cはすべての基本です。
OSはもちろん、サーバなどのプログラムは今でもほとんどC(C++ではない)で書かれています。
なのでCができるならそれにこしたことはないでしょう。
CというのはアセンブラなみのCPU直接操作に近いことから、
高級言語並みの隠蔽処理までできますが、
その分プログラマーの力加減で完成度が激しく変わってくる難しい言語です。
あー、単純に1.3で割った余りを使うより効率がいいってことか、多分
商でしたorz
なぜ
>>752 が宣言できなくて
>>753 が宣言できるかわかりますか?
>>752 で宣言するとスタックエリアに配列領域を確保しようとするので、
スタックサイズを超える領域は確保できないのです。
スタックサイズはプロセス起動時にOSによって割り当てられますが
通常は1MB程度と考えたほうがよいでしょう。
WIN32の場合は1MBです(プロセス作成時にデフォルトスタックサイズを変更できますが)
この領域はさらに関数呼び出しなどで利用されるので、
ローカル変数で使える領域は更に狭く数10KB程度が上限と考えるべきです。
double変数が4バイトと仮定しても(正確には環境によって違う)
4 x 359 x 359 = 503KBとなり、スタックの約半分が消費されてしまいますから
致命的なメモリエラー(スタック不足)の元になります。
Linuxのスタックサイズってどの程度なんでしょ?
getrlimit
#include<stdio.h>
int main(void)
{
int no;
printf("正の整数を入力してください:");
scanf("%d", &no);
while(no>=0)
printf("%d", no--);
putchar('\n');
return(0);
}
これで改行が入らないのは何故でしょうか?
うんこな質問ですいません
>>766 改行をどこに入れたいの?
各数字ごとなら、
printf("%d\n", no--);
とするか、
while(no>=0)
{
printf("%d", no--);
putchar('\n');
}
で
>>766 while(no>=0)
{
printf("%d", no--);
putchar('\n');
}
>>766 >これで改行が入らないのは何故でしょうか?
while(no>=0)
printf("%d", no--);
putchar('\n');
が
while(no>=0)
{
printf("%d", no--);
}
putchar('\n');
と実行されてるからだよ
どうでもいいけどreturnは関数じゃないから ()はいらない。
付けてもいいけど、個人的には勧めない。
return にはつけないけど、sizeof はつけちゃうんだよなあ。
関数以外で () つける場合は、空白入れるようにしてるけど。
>>765 少なくともapache (httpサーバー) はC言語だね。
良く使われてるメールサーバも、データベースサーバもみんなC言語ですね。
過去の遺産を引き継いでいるから?それともC++に移行できない理由(パフォーマンス?)があるのでしょうか?
教えてエロイひと
apacheがCでできてるからってC憶えたらなにかできるの?
仕事できるんじゃない?
>>714 getsとgotoとscanfを窓から投げ捨てろ
ダンディー坂野
>>773 C覚えたら何かできるか、というよりも、
サーバーみたいなものを作っている人達と一緒に仕事をするなら
Cはできなきゃ話にならん、ということなんでしょうな。
普通にWEBプログラマーやってるだけならC言語知らなくても何とかなるけどね。
rubyとかphpの簡単さ加減を覚えるとCなんてマンドクセ、てなる。
今流行のオープンソースってことでapacheをカスタマイズするってことでしょうか
オプソ系の仕事はCのソースコード読めないとだめだろ。
C言語は組み込みマシン用プログラムとOSとかを作るためにしぶとく生き残ると思う。
しかしOS上で動くアプリとしては段々と使われなくなっていくと思う。
782 :
デフォルトの名無しさん:2007/03/15(木) 20:12:34
お勧めのサイトとか本とか教えてください。
まるでOSとはGUIであるかのようなすっとこどっこいなことを……
Cができるからって、10数年前からあるウンコプロダクトの保守要員にまわされてた。
去年一年間。
785 :
714:2007/03/15(木) 21:04:14
>>776 gotoやscanfなら捨てられそうだが、getsはすてられそうもない。とりあえずgetsがダメな理由を。
文字をキーボードから入力し、その文字列をファイルに出力できる方法が別にあるならそれでもいいが…。
>>785 バッファ長以上の長さの入力があったら死ぬから。
fgets(... stdin);を使う。
_____
/ミミ\\\\ \
/ミミミ\\\\\\\
/彡ミミミ\\\\\\\\
|彡ミミ/\\\\\\\\|
|彡 | \\\\\\\|
ヽ |へ、_ _,へ\\\\/
| __ __ | / ) ゲッツ!!
| |/ ノ
| ( / _ ) /
ヽ ヽ |
ヽ ヽー‐‐‐ァ /\
//ヽ ヽ-‐' / /\ \
/ / ヽ_ / / / \
/ \ |\ /| /\ \
(⌒\ / (⌒ヽ |二| | / \ \
__ゝ ヽ ___ ゝ \ \| / / |
( ヽ─ ( l ) ヽヽ / / / |
 ̄ ̄( ̄丿 |  ̄ ̄( ̄ ゝ \ / / |
( ̄ノ | ( ̄ ゝ | ̄ ̄ ̄ ̄ |
( ̄ノ | ( ̄ ゝ |
>>786 そういうのが標準ってあたりC言語って恐いな。
Trust the programmer.
790 :
デフォルトの名無しさん:2007/03/15(木) 21:39:52
レスに感謝する
>>786 getsってこわいな。とりあえずstdinでバッファオーバーランを避けられてよかったよ。
>>789 getsはプログラマではなくユーザの信頼性の問題だろうが。こいつらは絶対に信じられないが
>>791 C言語って怖いな、への(ネタ)レスであってgetsどうこう言いたいんじゃなかとです…
信頼したいけど信頼できないよね。
>>783 Cはアプリ作成用言語としては廃れて行ってるだろう。
UNIX系OSはかなり前からその傾向強かったしな。CGIが
Perlばかりだったのはそのせいでもある。ちょっとした
プログラムならわざわざCで作らずにシェルスクリプトや
sed, awk, perl などのスクリプトで作るというのがUNIX系
OSでは普通だった。Cで作るとしたら高速に動かしたい
とか効率良く動かしたい場合、あるいはソースを見せ
たくない場合だ。(GUIはスクリプトが対応していなくて
Cでしか作れないという場合もあったが)
なんか話しずれてね?
はなししどころか、認識もずれているようだ。
Unix系で「ソースを見せたくないからC」なんて有り得ない。
>>794 >GUIはスクリプトが対応していなくて
つ Tcl/Tk
昔もプロプリなUNIXでは結構あったんじゃないの。
今ではLinux界隈でもバイナリのみ配布とかあるし。
スクリプト言語でもソースを見せたくなければどうにでもなるのがUnix流。
>>794 むしろWinのほうがCの使用はすたれてるだろ。
sed、awkでは普通文字列処理しかできんし。
ていうかUN*Xのプログラムは今でもかなり多くがCだぞ
>GUIはスクリプトが対応していなくて
つ pygtk
とネタにマジレスてみるテスト
CのほうがJavaより使ってて面白いと思いませんか?
プログラミング暦が浅いんだけど、Cでろくに複雑なプログラムを書いたことがないまま
オブジェクト指向に慣れてコードの拡張性あげていくのが楽しくなってきたので
いまからC流でコードを書けといわれてもどうしていいかわからない
そりゃあろくにプログラム書いてないだけだよ
C++がある
girl?
VC++ & MFCで地獄めぐり!
BCCでbyte型を右シフトしたりすると
変換によって有効桁が失われるって警告出るんですが、
わざと消すためにやってるわけで
出ないようにする方法はありませんか?
>>807 #if defined(__BORLANDC__)
#pragma warn -????
#endif
BYTE hoge = ...
hoge >>= n;
#if defined(__BORLANDC__)
#pragma warn .????
#endif
????にはその警告とやらの番号を当てはめてくれ。
>>807 多分、その警告はシフト演算の際に byte 型とやらが int に昇格され、
演算後に再びその byte 型に代入される際に出ている警告。
明示的に
BYTE hoge = ...
hoge = (BYTE)(hoge >> n);
とかやってやると警告はでなくなると思う。
810 :
デフォルトの名無しさん:2007/03/16(金) 22:36:15
質問です。system()関数でcopy aaa.txt+bbb.txt sum.txtのような
もののファイル名の指定をchar配列で指定したいのですがいい方法は
ありませんでしょうか。例えばsystem("copy hairetu +sum.txt sum.txt");
みたいにしたいのですがやり方がわかりません。どなたかご教授ください。
っstrcat
>>810 ファイル名部分を可変にしたいってことならsprintf。
sprintfと言って欲しいのかコノヤロウ。
あいう<>ほげ<>123
というような、ありがちな<>で区切られたデータを
構造体に格納したいですが、どういう風にすればよいのか
いまいちよくわかりません。 教えてください
>>814 つ[sscanf(string, "%[^<]<>%[^<]<>%d", ...)]
左から順に読んでいって '<', '>' の並びを見つけたらそこまでをコピーする。
>>815-816 ありがとうございました。
また、sscanfの知らない使い方があったみたいなので
それについて調べてみます。
char d[3][256];
sscanf("1<2<>2<>3", "%[^<]<>%[^<]<>%s",d[0], d[1], d[2] );
printf("%s\n%s\n%s\n", d[0], d[1], d[2]);
$./a.out
1
$
char *gettok (char **line)
{
char *new;
if(s=strstr(*line,"<>")){
new = calloc(1, s-*line+2);
strncpy(new, *line, s-*line+1);
*line = s+2;
return new;
} else {
return NULL;
}
}
main()
{
//line に読みこむ
while (token = gettok(&line)){
//token をどうにかする
}
}
822 :
デフォルトの名無しさん:2007/03/17(土) 09:35:44
#include <stdio.h>
int main(void) {
int a[10] = {1,2,3,4,5,6,7,8,9};
int i;
FILE *fp;
fp = fopen("test2.txt","wb");
if(fp == NULL){
return 1;
}else{
printf("open\n");
}
for(i = 0; i < 10; i++){
fwrite(&a[i],sizeof(a[i]),1,fp);
}
fclose(fp);
return 0;
}
fwrite()の部分なのですが、a[i]とするとコンパイルエラーで、パーラメター'_ptr'
はconst void * 型として定義されているのでint型は渡せないと出ます。
配列の場合だと&を付けなくても、配列の先頭要素へのポインタとなるのになぜ
&をつけるのでしょうか?
なぜ
1 % 10が1になり2 % 10が2になり これをfor文で25になるまで繰り返すとすると
123456789012345678912345となるのでしょうか?
もしかして算数ですか?悔しい・・・
#include<stdio.h>
int main(void)
{
int no, i;
printf("整数を入力");
scanf("%d", &no);
for(i=1;i<=no;i++)
printf("%d", i%10);
putchar('\n');
return 0;
}
>>822 a ← アドレス
a[i] ← 値
&a[i] ← アドレス
>>823 なぜも何も、それが % 演算子だ
% って何か知ってる?
割った数の剰余を表示する
えっ、%って整数除算じゃないんですか?
除算は /
>>829 Cでは、整数を整数で割るだけで整数除算になるので専用の演算子はない。
ライブラリによく使われている
*dest *src はそれぞれ何の略なのか教えて欲しい
destination
source
*srcはsourceだったのか orz
ありがとうございました
勢いよく答えたのはいいが合ってんのかどうか自信ないや
あってるお。
間違ってないお
キャリア20年以上の人に同じような事聞かれてビビった記憶がある
mallocとcallocという関数があるが、
個人的にはcallocの0クリアがされてた方が
バグもあまり発生せず、なんだか扱いやすい気がするんだけど、
なんか考え方が間違ってます?
だれも人の心まで干渉することはできない
決まりごとでもない限りどーでもいい部分だな
ちゃんと設計していれば0クリアされていようがいまいが
バグにはならんような気がする。
0クリアされている必要なんて無い場合も多いし。
逆にいうと、callocを使わないとバグが発生し、
その原因となる箇所がよくわかってないってことだろ?
むしろそれが問題だ
ちなみにcallocは内部でmallocでメモリ確保したものをmemsetで
ゼロクリアしてから返してる。
メモリアロケーションの方法は1種類じゃないんだから、むしろゼロクリアが
必要なときに的確にする癖をつけたほうがいい。
わからないけどこうすればOK!で
オカルトな法則やルールができていくんだよなー
mallocとcallocで一方が0クリアとかが迷惑なんじゃね。
static変数とか
callocの0クリアとstatic変数の0が入っているのは全く意味が異なる。
847 :
810:2007/03/18(日) 11:14:08
ありがとございます!!
848 :
デフォルトの名無しさん:2007/03/18(日) 11:36:05
二次元配列の大きさを取得したいのですがどうしたらいいのでしょうか?
test[6][7] だったら、「7」を取得したいのですが、
int l
l=strlen(test[0])
printf("%d",l);
ではうまくいきません
>>848 それが本当に二次元配列なら、sizeof(test) / 6。
まぁ、定数か変数で覚えておけと。
sizeof test[0]
>>848 マジックナンバーであることが根本的に問題じゃないか?
852 :
デフォルトの名無しさん:2007/03/18(日) 11:45:55
>>849 sizeofで解決できました ありがとうございました
じゃあ別の解決も望めるわけだな
int a[6][7];
assert(sizeof a[0] / sizeof a[0][0] == 7);
assert(sizeof a / sizeof[0] == 6);
856 :
デフォルトの名無しさん:2007/03/18(日) 12:00:15
C言語でお勧め本ありますか?ポインタや構造体あたりを基礎からしっかりやりたいもので。
現在は、やさしいCを使ってるのですが、正直微妙ですね。ほとんど「おまじない」とかで
なんでこうなるかということが書かれていない。
独習Cが結構評判いいみたいなのですが、中身をみたら文字だらけでメモリのこと
など載っていないかんじでしたけど、どうですか?初心者にとっては理解しやすいものですかね??
なにかお勧めあったら教えて下さい。
アセンブラの勉強でもしとけ
oreillyにアセンブラの本なさそうだな
>>856 K&Rプログラミング言語C第2版
これ以外読まなくていい
ポインタや構造体の基礎って言っても、入門書に書いてある以上の基礎なんていらないだろ。
みなおしたら、へんなこと書いてた。
assert(sizeof a / sizeof[0] == 6); は
assert(sizeof a / sizeof a[0] == 6); の間違い。
#define numof(a) (sizeof(a) / sizeof((a)[0]))
...
l = numof(test[0]);
↑でもいいけど、↓こっちのほうがいいよな
#define WIDTH 7
#define HEIGHT 6
..
int test[HEIGHT][WIDTH];
..
l = WIDTH;
WIDTHって何て読むんですか?うぃどす?
widθ
俺は 0 が気持ち悪いから
#define numof(array) (sizeof (array) / sizeof *(array))
ってしてる。
>>862 > こっちのほうがいいよな
まあ、一長一短だな。
場合にもよるが、
#define lengthof(a) (sizeof (a) / sizeof *(a))
#define WIDTH 7
#define HEIGHT 6
int test[HEIGHT][WIDTH]; /* testはHEIGHTとWIDTHの2次元配列。*/
/* コードの意図がHEIGHTとWIDTH分表示なら */
for (i = 0; i < WIDTH; i++) {
for (j = 0; j < HEIGHT; j++) {
printf("%d\n", test[i][j]);
}
}
/* testの全要素表示という意図なら、*/
for (i = 0; i < lengthof(test); i++) {
for (j = 0; j < lengthof(test[i]); j++) {
printf("%d\n", test[i][j]);
}
}
設計意図をコードに直接反映させることが重要かと思う。
>>866 > testの全要素表示という意図なら
こんな状況、Cならありえないんじゃない?
コンパイル時にスコープの届かない範囲の配列はポインタと等値になるわけだから、要素長を伝えないといけない(=sizeof は使えない)
そうではなく、スコープの届く範囲の配列は WIDTH と HEIGHT が分かっているんだから sizeof を使う必要はない
やっぱり配列に対して sizeof するのは、コンパイル時に要素長が解決する場合かなと思う
上のコードだと、int test[WIDTH][HEIGHT]を見て初めて全部というのがわかる。
下のコードだと、見なくても全部ということがわかる。
なんていっても、結局はtestが2次元配列なのかどうかもtestの定義をみて
初めてわかるからどっちでもいいかといえば、どっちでもいいかもね。
問題は、固定長配列のまま使うケースが実務では少ないことだ。
870 :
デフォルトの名無しさん:2007/03/18(日) 16:37:07
void Function(unsigned char (*Layer)[20*20]);
int main(void)
{
unsigned char[10][20*20];
}
void Function(unsigned char (*Layer)[20*20])
{
Layer[0][5]=123;//値の代入が出来る
}
2次元配列の関数渡しはこれで出来るんですが疑問があります。
今、ここで2次元配列の大きさは[10][20*20]だったのですが、
この[20*20]をユーザーが入力した値で確保したいのですが
その場合の関数渡しはどうしたらよいのでしょうか?。
画像処理プログラミングで、縦と横の長さが20*20で表現しています。
固定されていれば[4167*4167]でもいいのですがここがユーザーの入力で
変わってしまうときどうやって関数で渡したらいいかということです。
871 :
デフォルトの名無しさん:2007/03/18(日) 16:38:34
void Function(unsigned char (*Layer)[20*20]);
int main(void)
{
unsigned char Layer[10][20*20];
}
void Function(unsigned char (*Layer)[20*20])
{
Layer[0][5]=123;//値の代入が出来る
}
すいません こうでした
void Function(unsigned char**);
>>872かもしくは自分で構造体とそれのアクセサを定義する
1次元配列にしてまうというのも無難。
C言語をある程度理解すれば、プログラマとしてそれなりにやっていけますか?
基本情報技術者合格すればまあまあですか?
>>874 それに賛成。
というかサイズが固定ではない場合それ以外の方法ある?
void Function(unsigned char * Layer, int width, int height);
1次元配列でも2次元配列でも
それは1つの連続したメモリであることを利用する。
>>875 > C言語をある程度理解すれば、プログラマとしてそれなりにやっていけますか?
NO
> 基本情報技術者合格すればまあまあですか?
NO
次の患者さんどうぞ〜
あれ、関係ないけど
int a[1][1]
の時のaって、int*だっけ?int**だっけ?
879 :
デフォルトの名無しさん:2007/03/18(日) 17:17:27
>>877 ソフトウェア開発技術者くらいになれば、プログラマとしてやっていけますか?
どれくらいできればやっていけるのでしょうか?
>>875 プログラマって職業あるのかな。
情報処理の試験と実際の仕事は違うしな。
いまどきC言語が少々程度判った程度ゴロゴロいるだろうし。
他人の作ったプログラムのバグ取したり
機能拡張したりしなければいけない。
その際元あるコードがスパゲッティーで納得いかなくても
自分の付け足したコードが悪いのか元あるコードが悪いのか示すため
元あるコードを消さずに残しておかなければいけないとか。
何かよくわからない説明でプログラムを作らなければいけないとか。
テストを数百件やったとか
バグ発見した件数を毎日数えて
日々少しずつバグが減っているグラフを見せて仕事していることを主張したり。
>>878 最外周の配列がポインタになる。
そう書けばわかりやすいが、Cの宣言の構文がアレなんで、int (*)[1]。
>>879 プログラマになってから日々勉強じゃないの。
今すぐプログラマになっていいよ。
ちなみに俺はソフトウェア開発技術者試験はまったくだめだ。
さっぱりわからん。
>>879 面倒だからといって変数名が全部
1文字で意味わかんないようなプログラムを書いちゃ駄目とかそういうことが大事だな。
int a,b,c,d,e,f;
経験積んでメモリ破壊や解放漏れを起こしにくいように心がけたり
テストやデバッグの効率を上げるとかだな。
じゃないとデスマーチで体壊すよ。
>>879 上司がまともならその人の能力に合わせた仕事をくれるよ
C言語以外にも言語ができる奴には、幅広い仕事くれるし
テストしかできないやつは一生テスト要員
当然評価=給料にも差がつくし、出世にも差がつく
早い話が毎日勉強
ちなみに新入社員をみてる感じこの業界に馴染めない奴は、
一年持たずに辞めていく。一年持てば大丈夫やっていけるよ
>>876 配列のポインタ配列という形なら、可能といえば可能。
887 :
デフォルトの名無しさん:2007/03/18(日) 18:02:27
>>883 >>884 >>885 なんていうか。丁寧にありがとうね。
試験と実際の仕事は違うってよく聞くけどさ。
じゃあ、アプリケーションエンジニアって資格を取ったら、それはどれくらいの価値あるの・
これくらいの資格だとやはり凄いの?
C言語の事を聞けよ
889 :
デフォルトの名無しさん:2007/03/18(日) 18:09:28
じゃ、C言語の質問です。
基本情報れべるの学習が終わったあとは
独習Cで勉強するか、共立出版から出てる聖書で勉強するか悩んでるんですが、
どっちで勉強するのがいいでしょうか?
正直いって、基本情報レベルのCって簡単ですね
神よ、この愚かなものをもお導きください
アーメン
>>889 どっちがいいかは個人の好みがあるからなんとも言えないね
2,3ページ読んで判りやすい方で勉強するのがいいよ
ちなみに自分だったら両方読むかな(良書だし)
892 :
デフォルトの名無しさん:2007/03/18(日) 18:16:00
C,Python,C++,C#,Java,Perl,JavaScript,JSP,EJP,サーブレット,Ruby,PHP,COBOL,アセンブラ,VB
こんなにたくさんの言語を勉強しないといけないのですか?この中から大事なのを選ぶとしたら何ですか?
>>892 LISPはどーした?
Prologは?
そんなに似通ったパラダイムの言語したって面白くないよ?