C言語を勉強したくて本を買ってテキストエディタに書いて練習してます。 コンパイラがあると便利なのですけど、無料のコンパイラとかあるのでしょうか。
Visual C++ 2008 Express Edition
>>6 ありがとうございます。
いろいろ検索して、LSI C-86 というものを今インストールしてみました。
まったくの初心者なのでこれで十分かと思ってます。
C言語のことほとんど知らないのですが、DOSプロンプトみたいな画面に
文字が出てくるのですね。びっくりしました。
3つの数 int i, j, kを 昇順にソートする一番早い方法はなんですか?
変数そのものをソートすることは不可能です
qsortは無駄ですかね?
配列にまず入れろって 話はそれからだ
13 :
デフォルトの名無しさん :2008/08/12(火) 20:42:36
プログラミング始めてみた、一つ疑問があるんだけど printf関数とかって どうやってディスプレイに文字を表示させてるんだ?
環境に依存した方法で書かれてます
>>12 そうしてます。質問の仕方が悪かったです。すいません
int data[3]に入れています。
>>7 LSI-C試食版は(スモールモデル限定だから)大きいプログラムには向かないかもしれません。
あと、フリーならば Borland C か cygwin の gcc があります。
>>11 generic なかきかたには負けてしまいますが、普通の c でかくなら最速だと思います。枯れているでしょうし。
int型の配列の比較に使える関数ってありますか? 全要素が同じかどうかわかるようなやつです。 strcmpみたいな
たった、三つくらいならどんなソート方法でも一緒だから 好きにやれば良いよね
モニタに表示するにはドライバというプログラムをあーしてこーするんだが OSがドライバとの間の仲介をしてくれる これがハードウェアを操作する手順 printf→OS→ドライバ
>>11 3件しかデータがないなら、オーバヘッドがある分確実にqsort()は無駄です。
>7
LSI-Cは整数型が16ビットしかないので、学習には全くお勧めできません。
>>18 memcmp()でできますが、自分でループを書いたほうがいいかも知れません。
>>21 自分でループを書いたほうがいい理由はなんですか?
>>22 自分でmemcmp()に辿り着けないレベルなら、勉強になるジャマイカ。
24 :
11 :2008/08/12(火) 21:05:43
char *buff1,*buff2;に strcat(buff1,buff2)ってできませんか?
buff1がbuff2をコピーしうるだけの十分なバッファを指してれば可能
実行したらエラーになりました・・・ 対策を教えてください
>>25 できますが、事前に充分な格納場所を割り当てることを忘れずに。
buff1に実体がないとエスパー
うまくできません・・・ buff1="abc"; buff2="testtest"; みたいに結合前に代入しているんですが・・・
>>31 だからbuff1に十分な場所がないとだめだとみんなが。
そもそもそれ以前の話だけどね
そのbuff1の領域をあらかじめ広げておく方法がわかりません。 それ以前の話とはchar buff1="abc"; この宣言がよくないですか?
広げるっていうのは char buff1[256]; とか[]の中の数字を大きくするか mallocで動的に確保するかしかないよ
たぶん色々わかってないから説明が必要なんだろうけど、 俺ツタヤ行くから誰かが教えてくれるはず
realloc()でもすれば?
>>36 質問内容から察するに
前提条件から書かないと
質問者には意味が分からないはず
realloc()があればmalloc()もfree()もいらない。
とりあえず、今日はみんな寝よう
char * foo = realloc(NULL, 100); // same as char * foo = malloc(100); realloc(foo, 0); // same as free(foo);
42 :
7 :2008/08/12(火) 22:39:30
>>16 >>21 65535までの数しか扱えないみたいですね。
でも、今週から本買って始めた超初心者ですので、とりあえずこれで頑張ってみます。
>>41 なるほど勉強になった。で、何の話だっけ?
>>42 別にMSの回し者じゃないが
個人的には
>>6 が良いと思うけどなぁ
rubyみたいに!?も関数名に使えたら便利なのに・・・
たとえばなにがどう便利になると言うのか
関数の外に影響する関数には最後に!つけたり、真偽を返す関数には?をつけたりして可読性をあげるんだよ。あれ便利じゃん?
そんなもん自分で勝手にサフィクスでもプレフィクスでもつければすむことだろう
!?がもっともシンプルでもっともわかりやすいんだよ
>>49 その代わりに否定の!と三項演算子がつかえなくなるのはいやなんですが。
lispみたいに関数名の最後にpをつければいいじゃん
>>51 ctype.h関数群の is〜、もありますね。
>>49 そんなものはただのお前の好みであって便利でもなんでもない
>>50 いや、使えるだろ・・・
くっつけて書かなければ
いちいち空白を入れるのはうざい・・・そう思っていた時期が俺にもありました
>>54 そう作ればそうでしょうけれども。
現在の仕様では識別子の文字セットと演算子として使用する文字とはまったくかぶらないのでひっつけてかいてもOKなのです。
!がどういう関数につくのかよくわからないが、?に関しては関数名で自明になるように作るでしょ。 Is〜 Has〜みたいにさ。 ?がついたからわかりやすいんだ!という向きにはひまわりでもやってなさい、といいたい。
まさか関数の命名規則に不満がある人がいるとは思わなかった
コンパイル前にsedで変換すりゃいいだけじゃん。 あ、ゴメン、そういうの出来ないのか、そりゃ〜悪かった。
>>59 IDE使っててそういう発想がなかったのだろうよ。或いはMakefileを書けないとか。
それはさておき。
今のところ$と@は使われていないけれど、変数名なんかに使えたっけ?
[a-zA-Z_][a-zA-Z0-9_]*
処理の進行状況を表示したいのですが、 1% 2% ・ ・ 100%みたいに表示するのではなく "1"% ""この数字だけ次々更新していく方法はないんですか?コンソールプログラムです
簡易的に、\nじゃなくて\r使うとか
>>62 標準関数では無理
対象となるコンソールのスペックによる
\rでできました。ありがとうございます
うわ、いくらこのスレでも>63と>65はものの見事に恥かきっ子w
68 :
65 :2008/08/13(水) 11:20:30
間違ってもいいから、とにかくいう
最後の行という限定条件があるけどね
71 :
デフォルトの名無しさん :2008/08/13(水) 11:36:11
柴田望洋の明解C言語って本を借りてきたんだけど エディタはどれを使えばいいの? visual C++ってのが無料の統合開発環境らしいんでそれを使おうと思ってるんだけど それでいいですか? CとC++の違いがオブジェクト指向どうこうかいてあったけど プログラムは初めてで何の事だか・・・
本が今ひとつであることと、VisualStudioでは標準でC++を作らせようとしていることを除けば特に問題ないかと。 取り敢えず、ソースファイルの拡張子はcppにしないように気をつけてね。 PC自体の知識と意欲があるならLinux使うなりCygwin入れるなりを薦めるけどね。
>>71 それでいいよ
ファイルの拡張子を .c にすればCとして処理される。
標準関数が安全じゃないと警告が出るときがあるけど
\r知らないくらい許してやって
75 :
71 :2008/08/13(水) 11:46:14
>>72 linuxとかが開発に向いてるってのは聞いたことあるけどプログラム初めてなんで
とりあえずお手軽なとこで・・・
>>73 初心者がちまちまやってる分には特に問題なさそうですね
どうもありがとうございました。さっそくインストールしてみます。
76 :
デフォルトの名無しさん :2008/08/13(水) 11:53:19
勝ち誇りage
VSEE入れてコマンドラインからcl叩く分にはlinuxでgcc使うのと大して変わらんと思うがなあ IDEを使うと便利なんだけど、IDEを使えるようになるまでの苦労というものが初心者にはあるから。。
私もVisual C++ 2008 Express Editionをインストールしてみました。 いろんなサイト見て、ひとつ練習にプログラムを作りました。 そのあと次に新しいものを作るとき、また最初からプロジェクトとか 作る必要があるのでしょうか。「新規作成→ファイル」で作れると思ったのですが… 新しいプログラムを作るやり方を教えてください。よろしくお願いします。
>>79 いえ、毎回プロジェクトから作っていく以外に方法があるのかと思った次第です。
例えば、同じプロジェクトの中に新しいファイルを作って保存したりできないかと…
毎回新しくプロジェクトを作るのが当然のことでしたらそれでやるしかありませんので。
特に問題ありません。
今、いつくかのサイトで調べてみましたら、
「作成される実行ファイルは、一つのプロジェクトにつき一つだけです。 」と書いてありました。
毎回プロジェクトから作る必要があるみたいですね。
>>80 > 例えば、同じプロジェクトの中に新しいファイルを作って保存したりできないかと…
それは可能ですよ。だけど、main関数のあるファイルは追加しない。
追加するとどうなるんだ?mainが2つあるというエラーメッセージが出るんじゃないかな?
VC++で拡張子が.cのものをコンパイルすると 1>cl : コマンド ライン error D8045 : C ファイル '.\Test.c' を /clr オプションと共にコンパイルできません とエラーになることがあるんですけど対処法を教えてください。
素人すぎるだろ プロジェクトとmain関数の意味ググってこいやボケ
Cを覚えるまえにベーシックをやっていたんですがベーシックの頃の癖が抜けません。やはりCから入ったほうがよかったのでしょうか?
ベーシックの頃の癖ってなんだ?
後藤とか?
グローバル変数じゃないか
たとえばPRINT""って書いてみたり
整数の変数をI%にしちゃうとか
for i=0 to 9 とか
どうせポインタがわからないとかそういうんじゃねーの? READ/DATAは当然ないし
>>84 1プロジェクト複数exeを期待したんだと思うよ
コマンドラインから入ったら結構そう期待してしまいそう
行の最初に 10 20 30 とか
言語の違いなんて気にスンナ ベーシックとFORTRANとC++とJavaとアセンブラの仕事を同時並行した俺がいる こつ、覚えすぎないことw
GOSUBとかON ERROR GOTO とかかな
行番号じゃないのか
99 :
sage :2008/08/14(木) 02:38:20
カンマ区切りのデータを配列に移すとき、 例)abc,def,ghi,jkl.... 皆ならどういう風にするのでしょうか? 条件) ・strtokはなし。 ・分かりやすさ重視。
そんなもん頭から解釈していく意外にやることなかろう
先頭から一文字ずつチェックしてカンマを検出したらその直前までの文字列を格納できる領域を割り付けてコピー以下繰り返し 以外にまっとうで安全な方法があるなら聞きたいわ
>>101 元データを丸ごと領域確保&コピーしてカンマを\0に置換していったほうがいいんじゃないか?
strtok使いたくない理由は引用符を特別扱いするからか? それとも多バイト文字を扱うからか? いずれにせよ状態を保持しながら先頭から手動で一文字ずつチェックする以外ないな
awkだと考えるまでも無いんだけどね... 1)複数の、文字列のポインタを格納できる領域を確保(固定サイズである程度大きいものor区切りの数を数える) 2)元の文字列のコピーを作成,区切りを'\0'に置き換えつつ、1)の領域へ区切りの先頭アドレスを格納していく って感じかな
#include <stdio.h> #include <string.h> #include <stdlib.h> int main() { int i, arrylength; char basestr[] = "abc,efg,hij,klm, , asjelrhaesh"; char **arry; char *temp; i = 1; temp = basestr; while (temp = strchr(temp, ',')) { temp++; i++; } arry = (char**)malloc(sizeof(char*) * i); arrylength = i; i = 1; temp = basestr; arry[0] = temp; while (temp = strchr(temp, ',')) { *temp = '\0'; temp++; arry[i] = temp; i++; } for (i = 0; i < arrylength; i++) puts(arry[i]); return 0; } 異論は認める
106 :
デフォルトの名無しさん :2008/08/14(木) 03:26:02
for(i=0;i<len;i++){ if(data[i]==','){ j++; continue; } strncat(array[j],data[i],1) }
カンマで区切るだけでいい(ダブルコーテーションを考慮しない)のなら、sscanf()で%[^,]するのが一番簡単だろ。 カラム数が固定じゃないなら、%[^,],%nで。
分かりやすさ重視(速度やメモリ効率は無視)なら考えるまでもない。 char** tokbycomma(const char* src) { char** result = NULL; char* tmp; while((tmp = cutbycomma(src)) != NULL){ result = pushback(result, tmp); src += strlen(tmp) + 1; free(tmp); } return result; } cutbycommaとpushbackをどう作ればいいかは自分で考えましょう。
typedef struct{ double a[10]={0.0} char *mozi; }HOGE; HOGE data[200]; これで宣言したらaは初期化されていますか?
コンパイルしてみればいい。 typedef struct{ double a[10]={0.0} char *mozi; }HOGE; この段階だと実態は無いのでできない?
そうですね。できませんねー
書くならこっちじゃね? HOGE data[200]; でも仮にかけたとしても200個とか手で書くのか? どうせchar*もNULLでないと困るんだしどこかで memset(data,0x00,sizeof(data)); としておけば全部0でクリアになるよ
char * cutbycomma(const char * src) { char * tmp = malloc(strlen(src) + 1); int pos; int rtn = sscanf(src, "%[^,\n]%n", tmp, & pos); if (rtn != 1) { /* 抽出不可 */ free(tmp); return NULL; } if (src[pos] != '\0') /* 継続あり */; return tmp; }
typedef struct{ double a; char *mozi; }HOGE; 構造体はこうでした・・・ for(i=0;i<200;i++){ data[i].a=0.0; } とするのではどっちが早いですか?
memset()でdoubleが0になることは規格では保証されていない。 それでもいいなら、自前で代入するよりも速いかもしれない。
116 :
112 :2008/08/14(木) 09:35:42
あ、そっかdoubleか、すまん0x00でうめるのはまずいな。
intとか整数型ならいいかもしれんが実数はやめたほうがいい。
よって
>>114 のループで
>>113 毎回使いもしない長さの領域を確保してるじゃん。10点。
皆さんのレベルに到達するのに何年ぐらい必要ですか???
>>118 ひとそれぞれですし、取り組んだ課題によりさまざまな指向性を示すと思いますが、そんなことより、とりあえずやってみましょうよ。
for(i=0;i<num;i++){ if(条件){ 処理 break; } } この場合のbreak;はif文から抜けるだけですか?それともfor文からも抜けますか?
for
break文はfor文やwhile文から抜けるための文です
まったくの初心者で変な質問してスイマセンが、 今、DOS画面のような画面に計算結果を出力するような練習をしています。 C言語はこういうものだという狭い認識しか無いのですが、 C言語でゲームを作るとかいう場合は、グラフィックで動くソフトか何かを使うのですか? 自分には、「C言語はDOS画面みたいなもので動かす」という固定観念があります。 今のところそれしか見たこと無いので。
>>123 いやそんなことはないけどね。
ゲーム機の非公式開発なんかもCとかC++でかかれてたりするけど
普通にグラフィック扱ってるし。
むしろフォントの関係上英字が扱えるくらいで日本語とかになると
それなりに苦労するくらい。
今は、そのDOS画面とやり取りする関数を使ってるだけだからそういういイメージになるんだよ。 まあ標準ライブラリだけだとそうなるけど。
>>123 あなたは幼稚園程度の英語の知識を身に着けたばかりのような状態です。
例えば不思議の国のアリスを楽しむには、イギリスの生活習慣から当時の政治情勢まで知る必要があるのです。
プログラミング言語も同じようなものです。
足し算と補数があれば引き算掛け算割り算を実装できるというのは理解したんですが そのおおもとの、足し算ってどうやって実装してるんでしょうか?
>>127 CPUにそういう命令があって内部で計算してるの
C言語なんかはコンパイルのときにCPUがわかるように変換してる。
じゃあそのCPUは・・・といわれるとトランジスタを使った足し算用回路が 組まれてて計算してる。
HOGE data[200]={0};
>>131 構造体だとそれなんか警告でるんだけど全部初期化されるのは保証されてるの?
>>132 それ以前にポインター抱えてる構造体でそんな初期化って
>>132 警告の意味くらい、理解しなさいよ。
HOGE data[200] = {{0}};
>>133 ゼロクリアではなく、きちんとヌルポインタで初期化されるよ。
137 :
1 :2008/08/14(木) 13:58:48
いやむしろ悪化してコンパイルすら通らなくなるんですがw 試してから言ってくださいよw
>>136 --
% cat foo.c
typedef struct{
double a;
char *mozi;
}HOGE;
HOGE data[200] = {0};
% gcc -c -Wall foo.c
foo.c:9: warning: missing braces around initializer
foo.c:9: warning: (near initialization for `data[0]')
% sed -e 's/{0}/{{0}}/' foo.c > fooz.c
% !g:s/foo/fooz
gcc -c -Wall fooz.c
% gcc --version
gcc (GCC) 3.4.4 (cygming special, gdc 0.12, using dmd 0.125)
Copyright (C) 2004 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
--
警告でなくなるけど。
あれだっけ 初期化の指定が少ない場合コンパイラが勝手にやるんだっけ?
-W とかつけてんじゃね?それでも警告ですむと思うんだけど
>>140 >138では-Wallで警告が消えているね。
>>139 コンパイラがっていうか、0で補うのが仕様ですが。
142 :
140 :2008/08/14(木) 14:53:48
>>132 されてるよ
全部のメンバに対して=0;と書いたように初期化されるから
浮動小数点数でもポインタでも正しく0.0やヌルポインタになる
C言語撃退講座 ~K&Rは置いて、俺の話を聞け この本ってどう?
linuxでwin用のアプリをコンパイルすることはできるの?
理屈の上では可能だが、現実問題としてありえない
いや、結構普通だろw
クロスプラットフォームだっけ? コンパイラがあればできるんじゃね? というかlinux上で動くwinコンパイラなんてあるの?
151 :
デフォルトの名無しさん :2008/08/15(金) 03:58:51
それは可能だろ 機械語を生成するだけだからな でも使った事はないし知らない 32bitPCで64bitや携帯の機械語が生成できるのと同じ
Cygwinターゲットのクロスgccはなんか聞いたことがある。
MinGW
>>147 とりあえず答えておくとmingwとか使えばできます
155 :
デフォルトの名無しさん :2008/08/15(金) 04:04:44
こういうケースだとJavaや.NETはいいな
typedef union _BYTE{ unsigned char byte; unsigned bit0:1; unsigned bit1:1; unsigned bit2:1; unsigned bit3:1; unsigned bit4:1; unsigned bit5:1; unsigned bit6:1; unsigned bit7:1; } BYTE; sizeof(BYTE)がどうしても1になってくれないんですけど、どうすりゃいいんでしょう?
忘れてたよ で、これ1byteにできないの?
あ、なんか自己解決したわ unsigned char bitn:1;にすればよかったのね
つーかそんなので悩むなら普通に byte に対してビット演算しろよ byte | 0x01 byte ^ 0x01 とかすればいいだけだろ?
共用体でビットフィールド使っても無意味じゃないの?
ビットフィールド操作は大抵のコンパイラで糞なコードに展開されるわー もうちっと最適化できないもんかね
糞だとおっしゃるだけの英知をお持ちならそのご自分の能力でなんとかなさっては?
そもそもワードを任意のビットで区切ろうという発想が糞 は言いすぎとしても処理効率なんぞ求めんな
英知というほどの物じゃないけど、アセンブラでビット操作を書いたら こういう風には書かないだろうなあというコードになる。 C言語の仕様なので我慢して使ってるけど。
そこまで文句を言うならなぜ自分でアセンブらないの?
で、それに対する答えがそのまま
>>162 への答えだよ
インラインアセンブラは時々使うけど可読性が・・・
宿題で世界のナベアツプログラムがでたんですが 3の倍数はいいとして 3のつく数の判定はどうすればいいんでしょう
非標準だがitoa()を使って文字列に変換しstrchr()で判定する
>>168 それ、私が新人研修で出した課題だw
sprintf()で文字列にしてから、strchr()で探すのが一番手っ取り早い。
真面目にやるなら、一桁ずつ10で割った余りをチェックすればいい。
171 :
168 :2008/08/15(金) 13:39:07
なるほど、ありがとうございます あまりを出して調べるやり方でやってみます。 ああ、でもそれだと32とか321は無理ですよね 一桁ずつというのは、 1、3を引く 2、10で割ってあまりが0か調べる 3、違うなら1へ って感じですかね ちなみに学校の宿題ですw
12345 12345%10 = 5 12345/10 = 1234 1234%10 = 4 1234/10 = 123 123%3 = さぇぁ〜ん!
%3じゃなくて%10ね
321と言う数字があったとする 321 ÷ 10 = 32 … 1 32 ÷ 10 = 3 … 2 3 ÷ 10 = 0 … 3 余りに3が出たのでこの数字は3が含まれていると言う事がわかる と言うこと
>>170 そのやり方だと3の時に3を足さないと結果変わるね。
170の最後の行は
1 0かどうかチェック
2 %3の結果が0かどうかチェック
3 10で割った商と余りを別々に保存
4 余りが3かどうか
5 違うなら商を使って3へ
てことだろうから32でも321でも対応できるよ。
ただsprintf使った方がラク。
C言語質問じゃなくてアルゴリズム質問だからスレ違い
cursesを使ってブロック崩しのプログラムを作っているんですが、 return関数やscanfなどの標準入力関数を使うと、 なぜかprintfやmvaddstr関数などを飛ばしてしまい、ハイスコアの名前入力が作れません。 名前入力はどのようにすればいいでしょう? メイン関数は下のようになってます int main(int argc, char **argv){ int score; char tmp[7]; initscr(); /* 画面の初期化 */ noecho(); /* エコーなし */ cbreak(); /* 一度に1文字入力をON */ keypad(stdscr,TRUE);; /* 矢印キーが使える */ if(LINES>MinY&&WCOLS>MinX){ window(); /* 画面描画 */ } else{ printf("Windou size is too small!!!"); // return 0; } score = go(); /* ゲームを実行 */ GameEnd(score); endwin(); /* ウィンドウ終了 */ return 0; } GameEnd関数では、mvaddstrで「GameOver」と出した後、 scoreの値とファイルの値を比較し、ハイスコアであれば mvaddstrで「HighScore!put your name」と書いた後に scanfで名前を受け取ろうとしたのですが、mvaddstrが抜かされてしまう感じです。
cursesを使ったこと無いから的外れのことを言うかも知れないが scanwを使っちゃ駄目なのか?
fflush(stdout)とか?
その肝心の部分を張らずに質問とはいい度胸だ
環境依存すぎる まずinitscrやらnoechoやらの仕様を詳細にチェックしなおすこと モードを変えた後で元に戻さないとならないとかないか?
# 抜粋/整形厳禁、コンパイラに渡したソースをそのまま貼ること # サイズが大きい場合は宿題スレのアップローダ等を利用してください
>>179 ぐぐってみますた。バッファフラッシュですね。ちょっとやってっます。
>>178 使ってみましたが無視されてしまいました。
GameEndのソースファイルは今こんな感じです(いろいろ注釈にして試したりしてるのでごちゃごちゃしてますが…
endwin()を実行後に、注釈部のscanfなどをやってみてもだめでした・・・
void GameEnd(int score)
{
int i,j,k;
char tmp[7]=" ",file[10][7];
FileRead(file);
mvaddstr(LINES/2-2,WCOLS/2-5," GameOver!! ");
for(i=0;i<5;i++){
if(score>=atoi(file[1+2*i])){
for(j=4;j>i;j--){
strcpy(file[j*2], file[2*(j-1)]);
strcpy(file[2*j+1],file[2*j-1]);
}
mvaddstr(LINES/2,COLS/2-22,"HighScore!!Put your name!!(Max 5 ch\
ars)");
mvscanw(LINES/2+1,COLS/2-15,tmp);
FileWrite(file);
break;
}
}
return;
}
本当にちゃんとハイスコア出してるか? あとbreakはそこ一箇所だけでいいのか?
>>180 ,182
すいません、ごちゃごちゃしてたので貼り忘れてました。
>>179 やってみましたがその部分になると凍結してしまいました…
mvaddstr(LINES/2,COLS/2-22,"HighScore!!Put your name!!(Max 5 ch\
ars)");
fflush(stdout);
fflush(stdin);
scanf("%s",tmp);
こういう順番でやってみたのですが
>>181 やはりそうですよね… 学校の夏休み課題なんですが、cursesについての詳しい内容をほとんど教えられず
書き方だけしか教わってなかったのでさっぱりでした。
最悪カーセスモードを終了してからのscanfでやろうかと思ってるんですが、モードの終了の仕方もわからないで苦戦してます
186 :
184 :2008/08/15(金) 15:37:54
あ、breakはいいのか 見間違えた
>fflush(stdout); cursesは標準出力じゃないから意味がない。 >fflush(stdin); 入力のフラッシュ動作は環境依存。 >scanf("%s",tmp); %6sにしてバッファオーバフローを避けよう。
>>185 fflush(stdin) は環境によっては segmentation fault になるんじゃなかったっけ?
curses で入力がある限り読み飛ばせば大丈夫そうな気はする
curses 使ったこと無いのでちゃんとかけないけど
こんな感じかと
while(キーボードバッファに何か残っている) 読み込む;
>>187 ,188
ふむふむ。勉強になります
こんな感じに書き換えてみましたがどうしてもここで凍結してしまいます。
scanfをなくすだけでちゃんとmvaddstrの文が表示されて正常終了するのですが…
mvaddstr(LINES/2,COLS/2-22,"HighScore!!Put your name!!(Max 5 ch\
ars)");
while(fgetc(stdin)!=EOF)
echo();
scanf("%6s",tmp);
>>189 それは駄目だ
fgetc(stdin)==EOF になった時点以降は stdin から入力することはできない
dos (conio.h) でいうところの
while(kbhit()) getch();
っていうのがあるはず
あーそうそう、curses使っているときに標準入力を使おうとすると、想定外の場所にカーソルが出たり 標準入力の端末動作で画面が崩れたりするからそもそも標準入力は使えないと思う。
・開発環境や動作環境も晒すと答えが早いかもしれません。 ・質問者は最初にその質問をした時のレス番号を名前欄に書いて下さい。
うおおおお、奥が深い getch()ですね、ラケット移動などのカーソル受付をそれでやってます。 ただ、kbhit()にあたる方が分かりません。 仕様では「ゲーム終了時にTOP5に入っていたら名前を入力してもらう」と書いてあったのであれなんですが 友達はウィンドウモードにする前に、一番最初に名前入れてもらってやったと言っていました。 最悪自分もそうしようかなと思っていますが、、何か腑に落ちない感じがします。
良く分からないけどバッファを読み飛ばすなら while(getch() != '\r') 的な感じでどうだろうか?
>>193 ググってみた
while(getch()!=ERR);
でよさげ
>>191 なんと。
授業では入力方法は標準入力しか習ってないので…やはり一番最初に聞くしかない感じですかね
>>193 すいません初心者で。以後気をつけます
環境は学校の端末(ice環境)を外部環境(PodeRosa)で動かしてます。
>>194 、195
行の左端に戻る…と。ERRも始めてみました。勉強になります
どちらも標準入力は受け付けなかったんですが、mvaddstrは表示されるようになりました!
mvaddstr(LINES/2,COLS/2-22,"HighScore!!Put your name!!(Max 5 ch\
ars)");
while(getch()!=ERR);
echo();
scanf("%6s",tmp);
今はこんな感じです
そこでscanfじゃなくてcursesでの入力受付使えばなんか出来るんじゃないかな?
おお、早速以下のコードでやってみました! …が、出ませんでしたorz mvaddstr(LINES/2,COLS/2-22,"HighScore!!Put your name!!(Max 5 ch\ ars)"); while(getch()!=ERR); echo(); mvscanw(LINES/2+2,COLS/2-22,tmp); +------------------------------------------------------+ | | | |Time 1 | #### #### #### #### #### #### #### |Level 1 | |Score 10 | GameOver!! |HighS | #### #### #### #### #### #### |Name | HighScore!!Put your name!!(Max 5 chars) | | | | | | | | | | | ssh{*********}262: |
すいません、大分レス引っ張ってしまって。 いろいろアドバイスくださってありがとうございます。勉強になりました。 とりあえずは期限もあとわずかなので仕様とは少しずれてしまいますが以下のソースで提出だけしておきます ただ、自己満足になりますが悔しいのでいちおう現段階のソースも残しておきたいと思います。 int main(int argc, char **argv){ int score; char tmp[7]; printf("Hello,put your Name!(Max 5 Chars)\n"); fgets(tmp,6,stdin); printf("Let's play!!\n"); sleep(1); initscr(); /* 画面の初期化 */ noecho(); /* エコーなし */ cbreak(); /* 一度に1文字入力をON */ keypad(stdscr,TRUE);; /* 矢印キーが使える */ if(LINES>MinY&&WCOLS>MinX){ window(); /* 画面描画 */ } else{ printf("Windou size is too small!!!"); // return 0; } score = go(); /* ゲームを実行 */ GameEnd(score); endwin(); /* ウィンドウ終了 */ return 0; }
fgets()の常道では、第2パラメータは第1パラメータのサイズだ。 つまり、fgets(tmp, sizeof(tmp), stdin)でいい。 それから、(文字数オーバーじゃない場合に)末尾に改行文字が残ることにも注意。
>>85 win32プロジェクトでやってもエラーが出ました。
ちなみに拡張子を.cppでやるとコンパイルできます。
Cなんですけど。
>>201 それが出るとき、プロジェクトのプロパティの全般の共通言語サポートはどうなってる?
>>201 共通言語ランタイム サポートのことですよね。
共通言語ランタイム サポートを使用しないになってました。
これ以上はVC++あたりかな。 /clr のオプションがつくとCとしてはコンパイルできなくなる。 /clrをつけるのが、共通言語ランタイムサポート。 つまり、キミの状態はあきらかにおかしい。 同じ症状を持った人じゃないとわからんな。
なにかオススメのコンパイラはありますか?
>>205 私はgcc(cygwin)を使っています。
ギャップバッファのサンプルコード等ありましたら教えて下さい
>>209 凄く・・・高いです。
どこかのサイトにCで書かれたサンプルコードは無いのでしょうか
>>211 すまん、それは昨日見たんだが、
C++はどうも・・・
ありがとうございます。
>>212 おいおい、100行ちょっとのソースも駄目なのかよw
本が高かったら図書館に行けばいいじゃない
>>216 書籍だが、C++使える事前提で解説されてるの?
100行くらいならCに書き直してやろうかと思って
>>211 見にいったら
死ぬほど丁寧に解説されててワロタ
あの解説文でわからないなら本読んでも無駄じゃない?
つーかギャップバッファの代替ロジックもおおよそ浮かんだけどなあ。 イメージはファイルシステムの情報管理の方法だよ
K&Rみたいな有名本ってほかになんかある?
>>218 死ぬほど、とかそんな次元じゃなくて、
STL?template?operator?T& x?ってなんぞ?ってな感じでして、
C言語スレでC++のソースコード見せられるとは予想外でした。
C++じゃ全く読めなくて、すみません
これってさ双方向リストとかやってればすぐに応用かけそうだよな。 ギャップって呼ばれるのは特に説明がかかれてなかったけど1ギャップ=1バイトではなく 1ギャップ=nバイトの塊だよな?
>>222 ソースは見ないで、下の解説文だけ読めばいいと思う
あれだけ丁寧に解説してあればサンプルソースなんかよりもずっと理解しやすいと思う
>>223 図をみたら、nバイトとしか解釈しようがないと思うけど。
テキストエディタで考えると1ギャップ=64バイトから128バイトくらい間が理想か。
ネタではなく。 かなり前にMicrosoft Visual C++ 2005 Express Editionってのを やってみたんだけど、何をどうやっていかわからずいくつかくだらない ソフトを作って終わってしまいました。 やってみたいことは、ブラウザなどの操作を自動でやらしたい。 メールを受信して、本文中にある一部が定型のアドレスを 抽出し指定時間ごとにブラウザで開きブラウザに定型の文が 表示されたらタブを閉じる。 アプリケーションを操作する。などです。 こんなことできますか?できるなら何の勉強が必要なのか または近道なのか詳細お願いします。
>>227 C#でやったほうがいいんじゃね?
ブラウザの操作は知らんけど、コンポーネントでIEの機能を使えるから、同様のことができると思う。
メールを受信してどうこうは、ググれば簡単に分かると思う。
230 :
デフォルトの名無しさん :2008/08/16(土) 22:32:48
スロットのプログラムみたいね〜
231 :
デフォルトの名無しさん :2008/08/16(土) 23:20:29
>>231 そのリンク先の内容が理解できるなら、
業務に問題ないレベルだろうと思う。
>数の受け渡しをトレース
ってのはよく解らんのだけど。
ぴんきり
>>231 > 単に数の受け渡しをトレースできれば
データフローのことだと思うよ
データフローはプログラミングの基本、いやシステム設計の基本でもある
C言語やっててトレースなんて単語言った時点でたぶん減点。 ollyでもやってんのか?
文字コードの相互変換をサポートする関数とかってありましたっけ? S-JIS->EUCとか
sjistoeuc関数 使っている環境にあればの話 なければ自作
241 :
デフォルトの名無しさん :2008/08/17(日) 07:36:51
本格的にC言語を学ぶのはよくないですよ。 本格的にアセンブラやっても利用されるのはほんの一部なのと同じような物です。 C言語は生産効率が良くありません。 C++言語からにして、それで不足分があればC言語を勉強したほうがいいですよ
そうなんですか 音楽でいうところのピアノやクラッシックと同じで 基本として完全に把握しておけばその分将来有利だと考えたのですが・・・・ そもそもflashうまくなればcはむしろ必要ない言語なのでしょうか? それでも基本は抑えておいた方が良いのかな? オブジェクト指向プログラムしか扱えない人間はなにかしら欠点抱えるようにおもって勉強しようかと思ったのですが・・・・ 苦しんで覚えるc言語でいうとどの程度までかじる価値があるのでしょうか? それともオブジェクト指向メインでやるなら完全に必要ないとか・・・・・
243 :
デフォルトの名無しさん :2008/08/17(日) 08:16:20
芸術ではないのでやりたい事が簡単に実現できれば良いんです。 ピアノは演奏自体が大事ですが、プログラムは生産物が大事です。 コードに芸術性を求めても良くないです。 生産性はC++の方が上です。 オブジェクト指向は、プログラムを簡単にするやり方なだけで C++だからといって必ずしも使う必要はありません。
244 :
デフォルトの名無しさん :2008/08/17(日) 08:23:01
245 :
デフォルトの名無しさん :2008/08/17(日) 08:23:46
いくらC言語を習得、熟練しようとも 基礎学力がないと、大作は作れないような気がするのですが どうでしょうか?
246 :
デフォルトの名無しさん :2008/08/17(日) 08:29:30
マシンに近いという意味で、基本といえるのはアセンブラと思います。 C言語も、C++言語も、結局はアセンブラに変換されるので、最も基本だと思います。
>>245 もし私への質問でしたら、大作をつくる気はないです。
素人はrubyでもやってろってこった
>>249 Ruby の方が100倍難しいぞ
環境設定とか
環境設定とか
環境設定とか
>>245 大作を作るためのノウハウを修得、熟練しましょう。
特に、C言語の取扱いだけに固執するのではなく、
上流工程と呼ばれるもの(要求分析と設計)も含めて学習を進めるといいでしょう。
ER図やDFDが書けるだけでも世界が変わってくるはずです。
>>250 環境設定でなんか難しいところがあったっけ?
253 :
デフォルトの名無しさん :2008/08/17(日) 12:55:04
>>252 素人はパス通す事も難しいんだ察してやれ
環境変数ってなに?パスって? ってことだろうなあ。
Linux、Windows 両刀なんだ まんどくさい
256 :
デフォルトの名無しさん :2008/08/17(日) 13:10:22
でもwindowsならrubyのインストーラでインストールしたら一発じゃないのかな? コンソールで対話的にどうとかいう辺りで挫折しそうだけど
うるせー オブジェクト指向なのか、構造体指向なのか ハッキリわかりにくいんだよ うんこRuby しかもスレ違いじゃちんこ
こりゃまたわかりやすいのが続いたな
頭悪い人はプログラム勉強するより、世渡りを勉強してプログラマを使う仕事に就いたほうがいいよ
ボインちゃんを集めてプロのグラマーたちを使うことにしますた!
261 :
デフォルトの名無しさん :2008/08/17(日) 16:28:12
初歩的な質問なんですが BMP画像を読み込む際に 画像にアルファチャンネルが含まれているかいないかの判断は どうやってやるのでしょうか? 現在の自分のやり方ははヘッダから画像サイズと深度を計算して ファイル総容量と比較しています。 あまりにもアレなやり方なので 他に方法があると思うのですが ヘッダにもそれらしい情報もなく 皆さんはどのように判別されているのでしょうか? よろしくお願いします。
>>261 ヘッダにカラーフォーマットの情報なかったっけ?
bmpにαチャンネルなんてあったっけ?
>>262 >>265 あ〜biBitCountって色深度じゃなくて1画素あたりの
RGBA総データサイズなんですね。
勘違いしてました。
ありがとうございますた!
おかげさまで
もう少しスマートにやれそうです。
char はどの環境でも1byteが保障されてるんですか?
>>267 Cの世界だと、常にcharは1バイト。
ただ、1バイトが8bitとは限らない。
1バイトを16ビットにしてlongを128ビットにすればよかったのに・・・
270 :
デフォルトの名無しさん :2008/08/17(日) 22:43:54
>>268 現在稼働中で 1byte≠8bitな環境ってどんぐらい残ってんだろ?
switch+caseを使って分岐させると、プログラム自体は遅くなってしまうのでしょうか? 言葉など間違ってたらすみません。
if else if else if else if ... で同じような分岐をするのと比べてならswitch caseが遅いということはないはず
符号有/無の変数同士の四則演算についての質問です。 long hoge1=-101; ulong hoge2=100; printf("%d",(hoge1+hoge2)); とすると、「-1」が、 if( (hoge1 + hoge2)>0){printf("和が0以上\n")} とすると、「和が0以上」と表示されました。 結果として、printfは正常、if文は異常な動作をしています。 if( (hoge1 + (long)hoge2)>0)・・・のように if文中で使用している変数を型を揃えた場合、if文も正常に動作しました。 おそらく、if文中では変数の型を揃えないといけないものと勝手に理解しましたが、 これはC言語の仕様によるものでしょうか?
符号付きと符号無しで演算すると有効範囲の絶対値が大きいほうが優先されるのか…知らんかった
>>275 printfでは実際の数値はわからない
フォーマット指定でいかようにも変わる
printf("%d",(hoge1+hoge2));
printf("%u",(hoge1+hoge2));
printf("%hu",(hoge1+hoge2));
>>271 switch case はgccとかなら最適化で速くなるぜ。
使用しているコンパイラで色々試してみるのも一興
>>271 入門レベルで気にするほどは変わりません。最適化で同じになる可能性もあることは既に指摘の通り。
添え字でアクセスできる多次元の配列の動的確保ってだいたい下みたいな感じでいいのか? もっとクールでスパーハッカー的なやりかたってある? a = (int **) malloc(sizeof(int *)*A); for(i = 0; i < A; i++) a[i] = (int *) malloc(sizeof(int)*B);
>>283 AもBもコンパイル時には確定しない値(変数)にしたいなら、簡便法はない。
>>284 C99に足をつっこむという簡単な方法が!
>>281 要求する領域全体が、メモリ上に連続で確保できる程度の大きさなら、
一遍に割り付けたほうがmallocのコストが低い。
a = (int **) malloc(sizeof(int *)*A);
a[0] = (int *) malloc(sizeof(int)*A*B);
for(i = 1; i < A; i++) a[i] = a[i-1] + B;
もちろんどっちがいいかは場合による。
>>286 志村、その論点ならmallocもう1個減らせるよ
質問者じゃないが、なるほど。
289 :
デフォルトの名無しさん :2008/08/18(月) 18:22:32
cygwin環境でgccを使っています。 <ncurses.h>のprintwを使って全角文字を表示しようと文字化けします。 同じ書式で標準出力でprintfを使った場合は、全角文字が表示されているので、 端末などの設定は正しいと思います。 リアルタイムでキー入力を受け付けるgetch()が使いたいので、ncursesは必要です。 解決方法ないでしょうか。
>>289 エディタぽいのつくってるのかな。
全角に半角上書き処理してるんじゃないかとエスパー。
291 :
289 :2008/08/18(月) 18:56:28
>>290 #include <ncurses.h>
#include <locale.h>
int main(void){
setlocale(LC_ALL,"");
initscr();
printw("ほげほげ");
refresh();
usleep(1000000);
endwin();
}
ここまで短くしても文字化けしてしまいます。
>>286 ,287
a = (int **) malloc(sizeof(int)*A*B);
for(i = 1; i < 20; i++) a[i] = a[i-1] + B;
つまりこういうこと?
こっちのほうがfreeも一回でいいから便利そうだねd!
よく分からんが malloc(sizeof(int)*A*B + sizeof(int*)*A); って事かな
無難に a = (int **)malloc(sizeof(int *)*A); for(int i = 0; i < A; i++) a[i] = (int *)malloc(sizeof(int)*A);
a = (int **)malloc(sizeof(int) * A * B + sizeof(int *) * A); for(i = 0; i < A; i++) a[i] = (int *)a + A + i * B; 〜 free(a); なんどもサーセン これで正解じゃなかったらあきらめる
おかしいです^q^
スレ違いだと思うんですが、system関数でぶち当たった問題なんで質問させてください。 現在、system関数で一行に複数のコマンドを打つ必要に迫られているのですが…ウィンドウズのプロンプトでの命令の区切文字ってあるのでしょうか? unix系だと「;」だったんですが、ウィンドウズの場合は一行一命令という絶望的な解説しか見当たりません。 一応「;」「,」「:」等を試してみましたがダメでした。 知っている方がいらしたら、よろしくお願いします。
スレ違いです。
スレ違いだと思うなら質問しないでください。
302 :
ym :2008/08/18(月) 22:02:21
チェック文字列で渡された文字列が全てアルファベットのA〜Zの文字で構成されているかをチェックして 正常終了値;0 異常終了値;−1で判定するプログラムを誰か教えてください。 お願いします。
303 :
デフォルトの名無しさん :2008/08/18(月) 22:05:12
>>296 だから無難に
a = (int **)malloc(sizeof(int *)*A);
for(int i = 0; i < A; i++)
a[i] = (int *)malloc(sizeof(int)*B);
てして
for(int i = 0; i < A; i++)
free(a[i]);
free(a);
ってすればいいじゃん
304 :
デフォルトの名無しさん :2008/08/18(月) 22:12:56
>>302 #include <ctype.h>
int CheckFunc(char *str)
{
int i;
int check;
for(i = 0; str[i]; i++){
if((check = isalpha(str[i])) == 0)
return -1;
}
return 0;
}
>>298 NT系限定だけどこれはだめか?
cmd.exe /c hoge & foo
>>302 static int
checkstrA_Z(const char *str);
int
main(int argc, char *argv[])
{
if ( argc < 1 ) {
return -1;
}
return checkstrA_Z(argv[1])
}
static int
checkstrA_Z(const char *str)
{
for ( ; *str; str++ ) {
if ( !(('A' <= *str) || (*str <= 'Z')) ) {
return -1;
}
}
return 0;
}
/* EOF */
適当に作った、遅かったか。しかも試してないのでサーセン。
307 :
304 :2008/08/18(月) 22:36:29
修正
>>302 #include <ctype.h>
int CheckFunc(char *str)
{
int i;
int check;
for(i = 0; str[i]; i++){
if((check = isupper(str[i])) == 0)
return -1;
}
return 0;
}
>>306 なんで素直に
{
while(*str++){
if (('A' > *str) || (*str > 'Z')) {
return -1;
}
return 0;
}
としない?
無意味に複雑にするから案の定、バグってるじゃん。
309 :
298 :2008/08/18(月) 22:40:55
>>305 できました!!
すれ違いな質問なのに、答えていただきありがとうございました!
他の皆さんにもご迷惑をお掛けしてすみませんでしたm(_ _)m
ほいでは。
310 :
308 :2008/08/18(月) 22:41:56
あー全然だめだ308もバグってる。突っ込み歓迎。寝る。
('A')
if文while文for文の条件の中に色々詰め込んでとにかくソース短くしようとする人って何なの?
while('A' <= *str && 'Z' >= *str) str++; return *str == '\0' ? 0 : -1;
>>312 一般的に言って、短いほうが間違いがおきにくい。
複数の処理を一箇所にまとめて書くことはソースを縦に縮める効果がある。
一方で大抵の場合は同時に横に広がることでもあるので、
どちらを選ぶかはバランス感覚と好みの問題。
どっちがいいとか悪いとかいうことは、ない。
画面は一般的に縦より横に長い、つまりはそう言うこと と、どこかで見た記憶があるけど忘れた
「短くしようとする時期がある」とかいう反応が返ってくると思ったのに
長く書いてバグを紛れ込ますには馬鹿と相場が決まっている
313 - 314 はその調子で何Step組んだことあるの?
そして
>>317 はたった1行の日本語ですら間違えてしまう。
文法ミスはコンパイラがエラーを出してくれるから許されるのさ
Step数(大爆笑
日立さん乙ですw
ステップ数ってあーた・・・・・ ロートルですか?
ごめん。たしかにロートルだ。 他にソースの長さを測る単位教えて若い人。
ソース長
自分で考えろジジイ
行数のことをステップ数いうのがアレなんだろ。
メインフレーム時代の名残だろうな
昔は、行数でプログラムの値段を算出していたんだろ。
ソースの長さを測る意味がわからん 同じ仕事をやる100行のソースAと1000行のソースBで偉いのはどっち?
>>331 ということは、長くだらだらと書く奴の方が簡潔に書く奴より高給を貰ってた訳か
狂ってるな
可読性の話をしてると思ってたのだが。
>>332 正直者はいつも馬鹿を見るのがこの世です
>>332 まー実際は予算も決まってるし、新規で行数書けばその分テスト件数も増やさないといけないとか
いろいろあるのよ>日立の場合。
>>302 n = strspn(s, "ABCDEF・・・XYZ");
if (s[n] == '\0') return 0;
else return -1;
とすれば、ループもなくなるなと一瞬思ったけど、やっぱ"ABCDEF・・・"と書くのがダサいな。
isupperでまわしたほうがいいか。
あと、正常が0で、異常終了で-1ってのも、出題者のセンスが・・・
>>332 つか、メインフレームの作業体制は極度に分業が進んでいて
コーダーという人は詳細フローを言語のコードに一行ずつ落とすだけ。
そういう環境だから、ステップ単価というのは有効だったんだよ
>>336 正常0は理にかなってるよ
正常は一通りしかないが、異常にはいろんなケースがある
だから正常は0を返し、エラー時はエラーコードを返すほうがいい
>>338 だからウゼーって
独り言はチラシの裏にでも書いてろ
>>338 この場合は、エラーは一通りしかないじゃん。
bool値のかわりで、0と0以外のほうがいい。
それに、そういう思想だったら、-1じゃなくて、0とマイナス値としておかないとダメ。
341 :
デフォルトの名無しさん :2008/08/18(月) 23:56:05
多分この問題の次ではアルファベットじゃなかった文字数を返すようにしましょうって続くんだよ きっとそうだよ
>>339 完全に反論の余地がない時は黙ってた方がいいですよ
どう見ても初学者用の問題なのにstrspnとかisupperつかってかえって混乱させようとしてるやつなんなの?
入力がヌル文字列の場合はどっち?
>>343 ああ、そういえば再帰とかつかって、面白い回答にするの忘れてたな。
今からでも遅くないからさっさとやれよ
>>343 標準ライブラリ関数を使うことの何が問題なんだかわからん
string.hに定義されてるような車輪の再発明をやらせる方がよっぽど問題だ
>>342 反論の余地とかそういう問題じゃなくてお前がうざいの
>>348 しーっ!これ以上書くと頭が悪いことがばれますよ!
Cだと文字列の理解はC言語自体の理解にも多少は 繋がる気がするから再発明も完全に無駄だとは思わない俺
文字列じゃなくて文字配列か
353 :
304 :2008/08/19(火) 00:22:21
>>302 じゃ初学者用に書くよ
int CheckFunc(char *str)
{
int i;
for(i = 0; str[i]; i++){
if ('A' > str[i] || str[i] > 'Z')
return -1;
}
return 0;
}
>>344 0が返る
>>353 ○strがNULLだと落ちる
○iは無くても書ける
文字列に大文字以外が含まれているかどうか調べる関数って、どういう関数名が適切だと思う?
>>352 しーっ!これ以上書くと頭が悪いことがばれますよ!
>>354 引数にNULLを渡してはいけないという仕様です。
>>357 君の世界ではそれでいいのかもしれないが、俺の世界では文字列のNULLチェックを怠ったばかりに
落ちてしまうソフトが後を絶たないんだなこれが
360 :
デフォルトの名無しさん :2008/08/19(火) 00:32:54
ポインタを渡す関数はnullかどうかひかくしなくてはいけないのですか?それが一般的ナのですか?
>>359 あなたの世界では、たとえばstrcat()にNULLを渡したときに、落ちずに正常に動作してますか?
strcat()がNULLを渡しても動作するとしたら、どう動作すればいいですか?
パルプンテ
363 :
デフォルトの名無しさん :2008/08/19(火) 01:14:15
そうだな、システムコールとかは異常が-1、正常がそれ以外だったりするしね。
>>364 しーっ!これ以上書くと頭が悪いことがばれますよ!
ってもう遅いけど
ポインタを渡された側がNULLかどうかをチェックしてもあまり役に立つとは思わないけど。
無効なポインタは別にNULLだけじゃないから、無効なポインタは渡す側の責任でしか回避できない。
もちろん渡された側でのNULLチェックで回避できる問題もある。
でも渡される側でNULLチェックを怠ったばかりにおちてしまうような関数の使い方をしているようなプロジェクトなら、
他にも無効なポインタを渡してしまうような潜在的な危険があったりするおそれも。
>>357 の人も引数に渡してはいけないのはNULLとせず、無効なポインタとすべきだったと思う。
NULLは呼んだほうの責任だからな。 まあassert入れといてもバチはあたらんと思うが。
368 :
デフォルトの名無しさん :2008/08/19(火) 11:44:22
Visual Studio 2005とかだと、sprintfの代わりにsprintf_sを使えと警告をされるのですが、いちいち書き換えたくありません。 sprintf_sは、Visual Studioの独自の関数で、2番目に、文字列のサイズを引数に取ります マクロとかで解決できないでしょうか
#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1
370 :
デフォルトの名無しさん :2008/08/19(火) 11:50:42
>>369 ありがとうございます。まさにそれを探してました。
371 :
デフォルトの名無しさん :2008/08/19(火) 12:30:24
#include <stdio.h> #ifdef _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES #undef _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES #endif #define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1 int main( void ) { char fname[256]; // this causes 4996 warning sprintf( fname, "%s", "hogehoge" ); // this is safe version // sprintf_s( fname, sizeof(fname), "%s", "hogehoge" ); return true; } こんなシンプルなものでもまだwarningでるんですが。。。
#define _CRT_NON_CONFORMING_SWPRINTFS というかMSDN嫁
373 :
デフォルトの名無しさん :2008/08/19(火) 12:32:37
すいません。 #include <stdio.h>を後にしたらできました。
あ。悪い
>>372 は関係ないわ
#pragma warning(disable : 4996)
375 :
デフォルトの名無しさん :2008/08/19(火) 12:35:56
>>372 どうもありがとうございます。
MSDNは嫁にしたんですが、気づきませんでした。
376 :
デフォルトの名無しさん :2008/08/19(火) 12:41:29
初心者の底辺なんですがおすすめの開発環境はありますか? それとNetbeansでCをやろうとするとコンパイラが見つからないとエラー吐くんですが、 コンパイラってどこからDLするんでしょうか? 両方ググってはみたものの分かりませんでしたのでお願いします。
378 :
デフォルトの名無しさん :2008/08/19(火) 12:56:19
やはり、
>>371 でうまくいかない理由がわかりません。
>>378 ヘッダの位置変えたらうまくいくんでしょ?
コンパイラだって機械だからねえ。
機械的、要するにソースの上から解釈するってことだけでしょ。
プロトタイプ宣言の意味とか、プロトタイプ宣言をしない場合はmainより中で使ってる 関数がソースに前に来るとか理解できてるんだろうか?
381 :
デフォルトの名無しさん :2008/08/19(火) 13:12:34
>>379 そのとおりです。ヘッダをトップに持ってきたらうまくいきました。
>>380 理解できているつもりが、宣言の順番を変えるとうまくいかなくなる説明が解釈できません。
383 :
デフォルトの名無しさん :2008/08/19(火) 13:25:32
>>382 的確なアドバイス、どうもありがとうございます。
不毛な気がしますが、VCのコンパイラがどのタイミングでCRTライブラリにしてくれるのか、調べてみます。
たぶんヘッダを解析した段階でコンパイラがリンクするライブラリを決定してしまってるのに 後でスイッチ置かれても切り替えができなってことかな?
_CRT_NON_CONFORMING_SWPRINTFS をgrepしてそのあたり見てみりゃわかる
コピペ元間違った _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES こっちな
あと、、defineはコンパイラ等に直接指示するわけじゃないから 切り替えたいときはincludeの前に置くのは常識なんだけどな。 コンパイラ等に指示出せるのはpragma
C言語の入門書を理解したレベルで取れそうな資格ってなにかありますか?
英検3級
>>388 「C言語プログラミング能力認定試験」という、クソの役にも立たない資格があるぞ。
3級とか、C言語をほとんど知らなくても取れる。2級はプログラムが組めなくても取れる。
が、入門レベルがわかるだけの資格持ってて何の役にたつと思う? やめとけ。
391 :
デフォルトの名無しさん :2008/08/19(火) 15:30:31
>>387 なるほど。みなさん、よくわかりました。
おそらく、
_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMESがデフォルトでゼロになっていて、その値をマクロの引数にとって何かを展開しているのでだめなんでしょうね。
先手を取って1で定義してあげればよい、と。
#undefの使い方の間違えの典型であることがわかりました。
以上踏まえて、既に定義されているマクロを再定義する場合は#undefを使わないで、そのマクロが定義されている#includeの前におけばよいってことですかね。
>>388 そこから頑張って2種とか取れば良い。
ていうか、会社に理解してもらえない資格は時間の無駄、金の無駄。
CG検定、シスアドとか取ったけど糞の役にもたたねぇ。
393 :
ym :2008/08/19(火) 16:06:37
#include <stdio.h> #include <ctype.h> #define RET_OK 0 #define RET_NG -1 int N60901D01(const char *psChkString { int i; for(i = 0;psChkString[i]!='\0';i++){ if(isupper(psChkString[i])!=0){ return RET_OK; } else{ return RET_NG; } } return RET_OK; } int main(void) { char str[256]; int chk; gets(str); chk = N60901D01(str); printf("\n戻り値は%dです\n",chk); } アルファベットをチェックするプログラムなんですけど、 コンパイルをしたら1文字分しかチェックされませんでした。 どこが間違っているか教えてください。 お願いします。
>>393 >if(isupper(psChkString[i])!=0){
の中で必ず一回目でreturnしてる。
>>393 for文の中で1文字目チェックした後、真でも偽でもreturnしてるだろう。
そこは最後まで回さないと。最後がRET_OKってことは、if文のRET_OKの行を消せばいいような気がする。
396 :
ym :2008/08/19(火) 16:11:55
必ず1回目でreturnしないためにはどうしたらいいですか?
>>396 >>395 の言うように、
if(isupper(psChkString[i])!=0){
の下の
return RET_OK;
を消してみ。
return文を消せばいいと思うよ
399 :
ym :2008/08/19(火) 16:26:09
if文のreturn RET_OKを消したらコンパイル成功しました。 ありがとうございました。
え、コンパイル失敗してたの?そういう話?
>>400 3つめのreturn文にいくことはありませんエラーか。
402 :
デフォルトの名無しさん :2008/08/19(火) 17:43:19
処理開始から処理終了まで何秒経過したかを調べる方法を探しているのですが、 #include <stdio.h> #import <time.h> #include <unistd.h> int main (int argc, const char * argv[]) { clock_t start, end; start = clock(); printf("start:%ld¥n",start); sleep(1); end = clock(); printf("end:%ld¥n",end); printf("CLOCKS_PER_SEC:%ld¥n",CLOCKS_PER_SEC); printf("%ld秒経過しました。¥n", (end - start) / CLOCKS_PER_SEC); return 0; } これを実行すると start:6464 end:6580 CLOCKS_PER_SEC:1000000 0秒経過しました。 こんな結果が帰ってきました。 CLOCKS_PER_SECは1秒あたりのクロック数では無いのでしょうか。
整数型で出力しちゃあ駄目だろ
printf("%f秒経過しました。\n", (float)(end - start) / CLOCKS_PER_SEC);
405 :
デフォルトの名無しさん :2008/08/19(火) 17:52:29
>>404 ありがとうございます。
start:6894
end:7011
CLOCKS_PER_SEC:1000000
0.000117秒経過しました。
こうなりました。sleep(1)が0.00017秒?なわけ無いんだが…
CLOCKS_PER_SECはあてにならないってことなのかな
TimeGetTimeか QueryPerformanceCounter使えよ 1秒単位とか精度が悪すぎる(この場合はな)
int a[4]; int b[4]; int c[4]; : : といった感じに、int型配列が大量に存在している場合に、配列内の数字でソートしたいのですが、 int型配列の数字の大小比較がうまくできません。どなたかご教授お願いします 単純に int(a[0] > b[0]){ってやっていくと死ねる・・・orz
qsort
409 :
デフォルトの名無しさん :2008/08/19(火) 18:01:15
>TimeGetTimeか QueryPerformanceCounter Winの独自実装ですか… 残念ながらWindowsでは無いです
それだけだとほとんど0になるはずだよね。 どんな環境でやってるの?
sleepかけてる間クロックとまってんじゃないの
sleepで0.00017秒も食ってるから、おかしいと思ってるんじゃないの?
>>411 だろーね
こういうやり方してもテストにならないってこった
415 :
402 :2008/08/19(火) 18:11:16
>>410 gcc 4.0.1
Mac OS 10.5.4
Intel Core Duo 2.4GHz
2GB 667MHz DDR2 SDRAM
です。
416 :
402 :2008/08/19(火) 18:13:05
>>411 ,413
sleepするとクロック止まるんですか…、ありがとうございます。
>>407 何がしたいのかよくわからないが、たぶん配列を大量に作るのがもうおかしいんだろう。
ソートしたいもの全部を一つの配列に入れましょう。
>>418 int a[4] ; a[0] =1 a[1]=2 a[2]= 3 a[3]= 4
int b[4] ; b[0] =2 b[1]=2 b[2]= 3 b[3]= 4
として、a自体を1234、bを2234と考えて、大小比較を行いたいわけなんです
この場合はb>aみたいな感じで・・・
memcmpとかでいいのとちがうん? 配列で連続してればcharで見てやって
>>419 if ((a[0] * 1000 + a[1] * 100 + a[2] * 10 + a[3]) < (b[0] * 1000 + b[1] * 100 + b[2] * 10 + b[3])) {
// bが大きい
} else {
// aが大きい
}
とかじゃ駄目なの?
>>420 今調べてみましたが
buf1 と buf2 を先頭から n バイト分比較します。比較はunsigned char として行われます
とあるのですが、int型でも関係なくできるものなんですか?
intとcharじゃバイト数が全然違うので、なんか変なことになりそうな気もするのですが・・・
>>421 配列が何個もあるんです・・・
んで、バブルソートみたいなことをやりたいので、そのように書くととんでもないことになるんですorz
関数として何か簡単に比較できるものがないかな〜という感じで探してたのですが、いいのがなくて('A`
>>422 同じCPU環境化でメモリに入れちゃえばcharだろうがなんだろうがw
長ささえ同じなら問題ないよ。
エンディアンの問題も関係ないし。
4桁固定?例えば0030とか0111とか。 それなら1桁目からソートしていけば良さそうだけど。
>>424 なるほど・・・。ためしにちょいと動かしてみます〜
int a[4]={1,2,3,6}, b[4]={1,2,3,5}; int i = 0,c = 0; while(!(b[i]-a[i]) && c < 3)i++, c++; if(b[i]-a[i]==0)puts("同じ"); else if(b[i]-a[i]>0) puts("bのがおおきい"); else puts("aのがおおきい");
>>419 のサンプルでいけば
ビッグエンディアン系だとメモリに格納された場合はこんな感じ
a 00000001 00000002 00000003 00000004
b 00000002 00000002 00000003 00000004
で格納する元も両方intで比べる際もcharでもいいしunsigned charでもいいし両者の条件さえ同じなら比較する桁もあうので問題ない
リトルエンディアン系でも同じ
ビッグエンディアン系だとメモリに格納された場合はこんな感じ
a 01000000 02000000 03000000 04000000
b 02000000 02000000 03000000 04000000
intをレジスタ上で扱う場合は@ABC(<-バイトの並びね)だったらメモリにはCBA@とアドレスの最初から格納されるけど
通信でほかに渡したしりなければ同じエンディアン系で処理されるので結果memcmpであろうが比較する桁はいっしょなので
問題ない
↑で書いた数字は全部16進数ね
ビッグエンディアン a 00000F01 00000002 00000003 00000004 b 00000002 00000002 00000003 00000004 (a > b) リトルエンディアン a 010F0000 02000000 03000000 04000000 b 02000000 02000000 03000000 04000000 (b < a)
例を見る限り、配列に入ってるのは一桁の10進数だろ
>>430 エンディアン系を意識すればいいだけだろw
memcmpの結果を意識しろよw 大きいか小さいかイコールでくれるんだろw そんなことも考えれないようなら素直にループで1つ1つやれw
>>434 こういうのは?
リトルエンディアン
a 01010000 02000000 03000000 04000000
b 00020000 02000000 03000000 04000000
memcmpの結果 (a > b)
リトルエンディアン
a 00010000 02000000 03000000 04000000
b 00020000 02000000 03000000 04000000
memcmpの結果 (b < a)
でも実際は、どちらも b > a にならなければおかしい
誰か、いまだにエンディアンについてよくわかってない俺に図解!マンガでわかるエンディアンを頼む
>>436 数字があるとするじゃん。
一番上の位から読む?(ビッグエンディアン)
それとも一番下の位から読む?(リトルエンディアン)
って話。
>>437 いやそれは違う・・・
メモリ上に複数バイトで構成される数字を格納した際の
格納のされ方の違いだよ。
エンディアン糞フカナイ
>>439 汚ぇなぁ、おい。
>>435 >431
>>416 unix系なら、gettimeofday()がそこそこ使える。こいつは実時間だ。
既に指摘の通り、clock()はCPU時間だから要注意だ。
>>423 比較する関数を作ればいいだけなんじゃないの?
エンディアンを意識してどうこうするよりよほど楽だと思うんだけど
>>423 こんなんとか
int cmp(int a[4], int b[4]){
int i, ret;
for(i=0;i<4;i++){
ret=a[i]-b[i];
if(ret) break;
}
return ret;
}
443 :
デフォルトの名無しさん :2008/08/19(火) 21:38:42
いつのことだったか、ガリバーという人が訪ねたある国の人々が、 卵を大きい方の端から割る派閥(ビッグエンディアン)と、 卵を小さい方の端から割る派閥(リトルエンディアン)とに分かれて 争っていたんだそうな(とある国の政治家の風刺でもあるんだが)。 それにちなんで、MSBから先に格納するのをビッグエンディアン、 LSBから先に格納するのをリトルエンディアンと呼ぶんじゃよ。
扱う数値の範囲によっては
>>442 だとオーバーフローして逆の符号を返す可能性もある
計算結果がオーバーフローorアンダーフローしてるかどうかを調べることってできる?
448 :
440 :2008/08/19(火) 22:38:10
ふつうに計算じゃなくてビット演算組み合わせればオーバーフローもチェックできるんじゃね?って思った
>>445 ,446,449
できるよ。
符号付きとなしとで微妙に変わるけど、加減算なら二つの数値の
最上位ビット見ればいい。
乗除算もちょっと手間かかるけどできなくはない。
具体的にどうやんの 加算でもいいから教えてくだちい
符号付での二つでの足し算で言うと 負と負なら答えは負なので最上位ビットは普通はずっと1、 オーバー フローすると0になる 負と正ならそもそもオーバーフローしない 正と正ならオーバーフローすると最上位は1になる そんな感じ
桁あふれか 加算なら結果からもう一回引いてみればいいんじゃね? 元の数字に復元できれば桁あふれ無し。 元の数字にもどら無ければ桁あふれあり
オーバーフローした結果から引いたらアンダーフローして元に戻ると思うよ ・・・アンダーフローって意味違うような気がした
半分のビット数ごとに分けて計算する
456 :
デフォルトの名無しさん :2008/08/19(火) 23:31:35
logで計算する
logで足し算できるものなら教えて欲しい。
指でも折って数えるんだ 足りなくなったら隣の人の借りろ マイナスなど知らん
>>445 そもそも、どんなデータなんだよ。
そのオーバーフローやアンダーフローを気にしなくてはいけないデータというのは。
int add(int a, int b, int *p_is_overflow){ int chk_type, result, is_over_flow=0; chk_type=(a<0)*2+(b<0); result=a+b; switch(chk_type){ case 0: if(result>0) is_over_flow=1; break; // a, b ともに 0 以上なので解も 0 以上になるべき case 3: if(result<0) is_over_flow=1; break; // a, b ともに 0 未満なので解も 0 未満になるべき } if(p_is_over_flow) *p_is_over_flow=is_over_flow; return result; }
>>460 ちょっとした計算を代わりにやってもらうのプログラムなんですが
計算過程を式としては理解しているのですが、
計算途中の値がどの程度の大きさになっているのは知りません
知らないうちにオーバーフローしてるんじゃないかと少し不安なんです
もちろん値が狂ったら答えも大抵はおかしくなるでしょうからそうそう困ることはないのですが
出た答えが正常かおかしいかは判断できるのか? 方程式の解とかで元の式に代入して検算とかできるのなら困らないけど
>>461 の修正版
int add(int a, int b, int *p_is_overflow){
int chk_type, result, is_overflow=0;
chk_type=(a<0)*2+(b<0);
result=a+b;
switch(chk_type){
case 0: if(result<0) is_overflow=1; break; // a, b ともに 0 以上なので解も 0 以上になるべき
case 3: if(result>=0) is_overflow=1; break; // a, b ともに 0 未満なので解も 0 未満になるべき
}
if(p_is_overflow) *p_is_overflow=is_overflow;
return result;
}
掛け算は a*b/b==a をチェックすればいい
整数同士の除算は一つの例外を除いてオーバーフローしない (0div はあるけど)
その例外は・・・?
ヒント・大抵正の最大値より負の最少値のほうが絶対値が大きい
951 名前:デフォルトの名無しさん[sage] 投稿日:2007/05/15(火) 14:28:25
これでダメな場合って lop==0 の時以外にあるかな?
result=lop*rop;
if(result/lop!=rop) オーバーフロー
952 名前:デフォルトの名無しさん[sage] 投稿日:2007/05/15(火) 14:54:12
>>951 っ lop=-1 rop=INT_MIN
470 :
402 :2008/08/20(水) 09:34:26
>>440 ありがとうございます。
今作っている物は1秒ごとの判断で良かったので最終的にtime()関数を使うことにしました。
gettymeofday();も今度試してみます。
このプログラムなら正常に動くんですが、main関数内のnibai関数を scanf("%d",&a); nibai(a); printf("二倍した数値は%d\n",a); と書くと2倍してくれないんですが、何故でしょうか? ----------------------------------------------------------- #include<stdio.h> int nibai(int x); int main(void){ int a; printf("数値を入力してください:"); scanf("%d",&a); printf("二倍した数値は%d\n",nibai(a)); return 0;} int nibai(int x){ int wk; wk=x*2; return wk;}
a = nibai(a);
あーなるほど!! ありがとうございます。
474 :
ym :2008/08/20(水) 13:43:00
受け渡された文字列が'0000'〜'2359'の時刻範囲内かをチェックする プログラムを教えてください。お願いします。 チェック内容は以下の通りです。 1. 受け渡された文字列が全て数値であること。 2. 受け渡された文字列の先頭2文字が'00'〜'23'の範囲であること。 3. 受け渡された文字列の3文字目〜4文字目が'00'〜'59'の範囲であること。 正常終了時:return 0 異常終了時:return -1(時刻範囲外)
教えて欲しいのではなく宿題を丸投げしたいだけなら 宿題スレへ行ってください。
なんか最近範囲内チェックの質問多いな。全部同じやつか?
477 :
ym :2008/08/20(水) 13:57:04
char hh[3]; char mm[3]; int h; int m; hh[0]=pstime[0]; hh[1]=pstime[1]; hh[2]='\0'; mm[0]=pstime[2]; mm[1]=pstime[3]; mm[2]='\0'; h=atoi(hh); m=atoi(mm); if((h >= 0 && h <= 23)&& (m >= 0 && m <= 59)){ return RET_OK; }else{ return RET_NG; } } int main(void) { char str[256]; int chk; gets(str); chk = N60901D04(str); printf("\nreturn=%d\n",chk); } 受け渡された文字列が'0000'〜'2359'の時刻範囲内かをチェックするプログラムなんですけど、コンパイルをしたら、 アルファベット4文字を入力してもreturn 0(正常)で判定されてしまったん ですけど、プログラムの中のどこが悪かったのか、教えてください。お願いします。
たぶん、数字以外で数値に変更できなかったから0になって0時0分は有効だから、じゃない? isdigit とかで先にチェックするとか。
>>474 int main(int argc, char *argv[])
{
char *p;
int n;
for(p=argv[1] ; *p ; p++)
switch(*p)
{
case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': break;
default: return -1;
}
switch(argv[1][0])
{
case '0': case '1': break;
case '2':
switch(argv[1][1])
{
case '0': case '1': case '2': case '3': break;
}
default: return -1;
}
switch(argv[1][2])
{
case '0': case '1': case '2': case '3': case '4': case '5': break;
default: return -1;
}
return 0;
}
480 :
デフォルトの名無しさん :2008/08/20(水) 14:01:42
>>477 atoiで変換は失敗すると0を返すからじゃね
あ、n消し忘れた
>>482 あーそうだね
switch(argv[1][2])
{
case '0': case '1': case '2': case '3': case '4': case '5': if(argv[1][3]) break;
default: return -1;
}
こうか
>>483 ある
[3]が\0のときも無視して通してしまう
2桁目も switch(argv[1][0]) { case '0': case '1': if(argv[1][1]) break; だな
int check_time(const char *hhss) { int i, hour, second; if (strlen(hhss) != 4) return -1; for (i = 0; i < 4; i++) if (!isdigit(hhss[i])) return -1; hour = (hhss[0] - '0') * 10 + (hhss[1] - '0'); second = (hhss[2] - '0') * 10 + (hhss[3] - '0'); return (0 <= hour && hour < 24 && 0 <= second && second < 60) ? 0 : -1; }
教えてください int型の2次元配列の先頭のポインターだけをもらってくる関数があります。 配列のサイズはわかっているんですが関数内で見る際にはどう記述すればいいでしょうか? これを関数内でいじりたい unsigned int hoge2div[100][200]; 関数を呼ぶ前に連絡用構造体の所定のエリアに2次元配列のポインターを格納してます。 (unsigned int* )hoge->ptr = hoge2div; 関数内の定義(ここを直したい。) unsigned int* 2div = (unsigned int* )2div->ptr;
>関数を呼ぶ前に連絡用構造体の所定のエリアに2次元配列のポインターを格納してます。 >(unsigned int* )hoge->ptr = hoge2div; こっちが正解です hoge->ptr = hoge2div;
unsigned int (*p)[DIV1_SIZE]=(unsigned int (*)[DIV1_SIZE])hoge->ptr;
なぜわざわざポインタの型を変える
>>491 変えたいから変えたんだよ
お前いちいちうるせえから
よくわかったな
ム板って煽ると必ずレスもらえるよね
それはム板だけの話ではない気もするけどな
>>474 int check(const char *str){
char buf[4+1];
int hour, minute, chk;
if(sscanf(str, "%4[0-9]%n", buf, &chk)!=1 || str[chk]!='\0') return -1; // 四桁の数値か?
if(sscanf(str, "%2d%2d", &hour, &minute)!=2) return -1; // 時分に分割する
if(hour<0 || hour>=24 || minute<0 || minute>=60) return -1; // 数値の範囲は適正か?
return 0;
}
499 :
デフォルトの名無しさん :2008/08/20(水) 21:25:16
初心者な質問ですいません キーボードからの入力で英語の入力をしたいんですけど do{ printf("入力1を入力してください\n"); fgets(buf1,LEN,stdin); printf("入力1\n"); printf("%s\n",buf1); printf("入力2を入力してください\n"); fgets(buf2,LEN,stdin); printf("入力2\n"); printf("%s\n",buf2); printf("これでよろしいですか? Yes:1 No:0\n"); scanf("%d",&n); }while(!n); これを実行すると入力2しか入力できなく 入力1がおかしいのかと思って入力1をなくすと入力2が入力できなくなってしまうのですが 何がおかしいのでしょうか?
>>499 エスパーフル活用
buf1 のサイズが足りていない または 有効な場所を指していない
buf2 のサイズも足りていない または 有効な場所を指していない
ポインタでよくある間違いと見た
どういう入力をしたらどういう結果を出したかを書くこと インプット/アウトプットはシステムの基本
>>498 if(sscanf(str, "%4[0-9]%n", buf, &chk)!=1 || str[chk]!='\0') return -1; // 四桁の数値か?
↓
if(sscanf(str, "%4[0-9]%n", buf, &chk)!=1 || chk!=4 || str[chk]!='\0') return -1; // 四桁の数値か?
503 :
499 :2008/08/20(水) 21:49:11
fgetsの前にscanfがあったのが原因でした すいませんの騒がせしました、解決しました 意見ありがとうございました
やられた 前入力の \n だったか オレのESPも錆付いたもんだな
エンディアンをチェックしたいんだが↓でおk? typedef unsigned char BYTE; int IsBigEndian(void){ int x = 1; //00 00 00 01ならBE if(*((BYTE *)&x + sizeof(int)) == 1) return 1; //末尾の1byteをチェック return 0; } int IsLittleEndian(void){ int x = 1; //01 00 00 00ならLE if(*(BYTE *)&x == 1) return 1; //先頭の1byteをチェック return 0; } あと、バイトオーダーとか色々と違う環境をエミュレートするにはどうすればいいんですかね? フリーでそういうアプリとかあります?VM使えばできるのかな?
あ、まちがった int IsBigEndian(void){ int x = 1; //00 00 00 01ならBE if(*((BYTE *)&x + sizeof(int) - 1) == 1) return 1; //末尾の1byteをチェック return 0; }
(BYTE *)&x + sizeof(int) 行き過ぎてない?
なぜかオーバーフローするであろう数値を入力しても、printf内の文章が表示されません。 どうしてでしょうか? #include<stdio.h> #include<limits.h> int main(void) { int idt; printf("数値を入力してください:"); scanf("%d",&idt); if(idt>INT_MAX){ printf("オーバーフローしました。 int型最大値は2147483647です\n"); }else if(idt<INT_MIN){ printf("オーバーフローしました。 int型最小値は-2147483647です\n"); }else if(idt !=INT_MAX,INT_MIN){ printf("数値入出力 %d\n",idt); } return 0; }
if(idt>INT_MAX){ printf("オーバーフローしました。 int型最大値は2147483647です\n"); これで検出できないからオーバーフロー そもそも、オーバーフローするような数字はscanfでidtに格納されない。
512 :
509 :2008/08/21(木) 03:58:03
なんとなくわかりました。 オーバーフローを根本的に理解してないみたいです。 ありがとうございました。
体重が100kまでしか量れない体重計に、150Kのお相撲さんが乗ったのと同じ。 針は50Kを指しているが、一周回っている。
国家予算は数十兆の単位だから、32ビット整数をかるくオーバーフローするんだよね あれはどうやって計算しているんだろうか? 64ビットを使っている?それとも万単位で計算? それとも特殊は数字変数を使っている?
国家予算の計算に何を使ってるかなんか全く知らんが 普通に多倍長整数じゃないのかと思うわけで
計算尺
多倍長整数を使うならC++のほうが便利だね Cでやるとコードが大変になりそう
#include<stdio.h> int main() { char *pt; pt = "text"; printf("%s",pt); return 0; } ポインタにはアドレスしか代入できないと聞いたのですが文字列ならできるのでしょうか
いれてどうするの?
>>518 メモリ上に配置した文字列のアドレスを入れてんねん
C言語での文字配列の仕様。 アドレスに文字列を入れたのではなく、アドレスの先頭を指すptに文字列を入れると。 コンパイラさんが自動的に配列作ってごにょんごにょしてくれる。
523 :
ym :2008/08/21(木) 10:49:04
受け渡された文字列が'0000'〜'2359'の時刻範囲内かをチェックして、 正常終了時は、return 0 異常終了時は、return-1(時刻範囲外)で判定するプログラムなんですけど、 本当は、数字5文字以上だったら、異常(return -1)にならないといけないはずが、 コンパイルをして、数字5文字で入力して確認してみたら正常(return 0)になってしまいました。 どうしたら、数字5文字以上だったら、異常(return -1)になるかを教えてください。 お願いします。
521の説明は正確とは思えないけど、 (配列変数を初期化するとき以外では)文字列が配列だってのは合っているだろ。
>>523 またあんたか。
つstrlen
時刻なら、4桁でも9999みたいなのも弾かないといけないんだろうけど名。
int istimeformatstr(const char *str){ char time[24*60][5]={ "0000", ・ ・ ・ "0059", "0100", ・ ・ ・ "2359" }; int i, ret = -1; for(i = 0; i < 24*60; i++){ if(!strcmp(str, time[i])){ ret = 0; break; } } return ret; }
その「・ ・ 」の部分がわかりません、全部書いてください。
>>528 全部は書ききれないのでこれを実行してください
int main()
{
int i, j;
puts("int istimeformatstr(const char *str){\n char time[24*60][5]={");
for (i = 0; i < 24; ++i) {
for (j = 0; j < 60; ++j) {
printf("%02d%02d,\n", i, j);
}
}
puts(" };\n int i, ret = -1;\n for(i = 0; i < 24*60; i++){\n"
" if(!strcmp(str, time[i])){\n ret = 0;\n break;\n"
" }\n }\n return ret;\n}\n");
return 0;
}
//これでどうよ? #include <stdio.h> #include <string.h> #define TIME H(00) H(01) H(02) H(03) H(04) H(05) H(06) H(07) H(08) H(09) H(10) H(11) H(12) H(13) H(14) H(15) H(16) H(17) H(18) H(19) H(20) H(21) H(22) H(23) #define H(x) M(x##0) M(x##1) M(x##2) M(x##3) M(x##4) M(x##5) #define M(x) Q(x##0) Q(x##1) Q(x##2) Q(x##3) Q(x##4) Q(x##5) Q(x##6) Q(x##7) Q(x##8) Q(x##9) #define Q(x) #x##, int istimeformatstr(const char *str){ char time[24*60+1][5] = {TIME NULL}; int i, ret = -1; for(i = 0; i < 24*60; i++){ if(!strcmp(str, time[i])){ ret = 0; break; } } return ret; } int main(int argc, char **argv){ if(argc != 2) return -1; if(!istimeformatstr(argv[1])) puts("good"); else puts("bad"); return 0; }
long aaa[10][10]; long bbb[10][10]; long * pcount[2] = {aaa,bbb}; って書いてコンパイルエラーになるんだけどなんで? error C2440: '初期化中' : 'long [10][10]' から 'long *' に変換できません。
long * pcount[2] = {&aaa,&bbb};
2次元配列の場合aaaってaaa[0][0]のアドレスじゃないの?
536 :
デフォルトの名無しさん :2008/08/21(木) 14:46:44
>>532 long aaa[10][10];
long bbb[10][10];
long (*pcount[2]) [10][10];
pcount[0] = &aaa;
pcount[0] = &bbb;
同じとこにいれちゃったw
穴兄弟w
>>535 aaaは先頭要素のアドレスじゃなかった?
キャストすればいいんですね。 long aaa[10][10]; long bbb[10][10]; long *pcount[2] = {(long*)aaa,(long*)bbb}; で通った。ってことはそもそもaaaの型ってintなのかな。
>>540 過去スレで盛り上がったポインターに成り下がるとかってやつじゃないの?
めんどくさければこれでもいいんじゃね?
void *pcount[2] = { aaa, bbb};
これでおk long (*pcount[2])[10][10]={&aaa, &bbb}; 要素にアクセスするときは (*pcount[0])[0][0] とか
>>542 初期化子の要素はロード時に計算され得ません
と警告がでるんですが、そもそもこれはどういう意味の警告なんでしょうか
コンピューターがメモリーアクセスするときはアドレスで計算する。 つまり、ポインターのほうがコンピューターにとっては自然な型なのだ。 配列は、それを人間が理解しやすいようにちょっと置き換えたもの。 同一のものではないが、実体はやはりポインターと同じようにアドレスで管理されている。 だから簡単にポインターに成り下がる(ことができる)。
つーか中身はポインターだろうけどね 1次元配列をアセンブラ展開した際の配列にアクセス処理部分の位置計算 ptr + n1 x n2 ptr ・・・・ 配列の先頭アドレス n1 ・・・・ 各型ごとのバイト数 n2 ・・・・ 配列のインデックス
547 :
デフォルトの名無しさん :2008/08/21(木) 17:27:32
受け渡された文字列の先頭3文字がアルファベットの場合に、 残りの文字列をゼロサプレスするプログラムを教えてください。 ゼロサプレスの処理例は以下の通りです。 'ABC001' → 'ABC1' 'ABC010' → 'ABC10' 文字列長が4でない場合、後ろを空白で埋める。 返却値は、0:正常 1:異常 です。 お願いします。
>>547 どの部分が分からないの?
1.先頭3文字がアルファベットの場合
2.残りの文字列をゼロサプレスする <- 意味が分からん
3.文字列長が4でない場合、後ろを空白で埋める。 <- 意味が分からん
4.返却値は、0:正常 1:異常 <- 正常の定義が分からん
>>547 char main = {0xf0,0x0f,0xc7,0xc8};
夏休みの宿題ぐらい自分でやりなさい 質問っていうか丸投げしすぎだろ
>>550 まー日本のIT業界は理系をいかにうまく使うかがのし上がって行く上で重要?
らしいので、そういう訓練をここでやってるのかもな〜〜w
なら将来を見越してここで潰しておくべきだな
文字列処理ばっかり秋田
素人はrubyでもやってろってこった
部分的なアドバイス求めるやつは実際にプログラム組んでるってわかるけど
>>547 のような冒頭読んだだけでスレ住人を使う気満々な丸投げは放置に限るなw
たまに課題らしき物の丸投げがあるけど あれって工業高校・大学・専門のどれかだよね 大学行ってまでじゃんけんゲームやら文字列操作なんかやりたくないなと思う@普通化高校生
>>556 何がやりたいんだよ
ちなみに文字列操作は色々と落とし穴があって面白いぞ
>>557 文字列は面倒だな。
特にネットが絡むとS-JISだとかEUCだとか・・・もうねw
まだグラフィック関連いじってるほうが楽だったりする。
フォーマット決まれば所詮は色情報を持った2次元配列。
「物事を厳密にとらえる」というのがどういうことかをたたきこむのが重要なんであって 実際に作るものは低レベルでいい
大学で勉強するべきは数学なんだよ
でも研究室4年時でもぐら叩き作ってたな、俺。
UI絡みは使いやすくするってのが難しいな
CPUとかコンパイラとかの環境によってバイトオーダーとかintのサイズとか微妙に違うじゃん? これって違う環境でコンパイルしたバイナリだと別の環境だとバグが出るかもってことだよね でも普通のインストーラってOS別とかはあるけど、エンディアン別のインストーラーとかint2byte環境用インストーラーとかは見たことがない これって環境別のバイナリを配布側がいちいち全部用意して、その環境にあってるバイナリを選んでコピーとかしてるんですかね? それともインストーラーはコンパイルとソースを積んでてクライアントのパソコンでコンパイルしてるの? 多分バイナリを用意してるんだと思うけど、色んな環境用のバイナリ用意するのって大変じゃないすか?
>>563 >これって違う環境でコンパイルしたバイナリだと別の環境だとバグが出るかもってことだよね
同じCPUでもOSがlinuxかwindowsかでバイナリが使えないとかありますが・・?
(linuxの一部のwinアプリ動かすの除く、windows上でも仮想環境のソフト下のぞく)
でもwindows環境だと32bit向けにコンパイルされてても64bitOS化で実行も可能ですが。
>>563 ターゲット以外の環境では動かないし、そもそもインストーラすら動作しない
色んな環境用のバイナリを用意するのは確かに大変
Java ならある程度複数の環境で動作するようだけどな
無知の考え休むに似たり まずはもう少しパソコンに慣れろ
MacOSXでは複数のCPU用のコードをひとつのバイナリに含めることができるけど 動かす環境によってバグが出るとかはあるかもね
>>563 CPUが違えば動かないのは当たり前だろ馬鹿
intのサイズはコンパイラ内で完結する問題でCPUやOSでintのサイズが決まってるわけではない
同じソースがコンパイラが違うと動かないというのならわかるが
intのサイズはコンパイラ内で完結する問題でCPUやOSでintのサイズが決まってるわけではない これはちょっと微妙に突っ込みを入れられそうだな。 確かに抽象レイヤーではそうだが。
charはどのコンパイラも固定だからだな
またまたご冗談を
sizeof(char) は固定だけどねぇ
組み込み用チップ…
一番変わらないのはアドレスを指すポインタすよ先輩www 多分恐らくなかなかどうして4byteっすよwwwwww
最近はポインタも8バイトだ 昔は2バイトだったし
DOSの時代は、ひとつのプログラムの中で、2バイトと4バイトのポインタが混在したりとかあったな。
そういうことに縛られないように書くというのがCの理想
理想と現実のギャップに苦しむわけですね、わかります
char型配列でもらってくるデータの中にintが埋もれています。 その読み出し位置は別途もらうindexでわかるんですが 取り出す場合どう記述すればスマートでしょうか?
>>579 そのchar配列がポインタなら素直に
*(int*)(charポインタ+index)とでもすればいいんじゃない?
1バイトづつ整数の変数に読み込んで、シフトして、ターゲットの変数のorでセット。
>>580 ありがとうございます。
>>581 現在がその状態なんですが、現在チューニングしてまして
あまり改造せずに速度をあげれないかなあと思いまして・・・
typedef struct{ unsigned short bfType; unsigned long bfSize; unsigned short bfReserved1; unsigned short bfReserved2; unsigned long bfOffBits; }BITMAPFILEHEADER; sizeof(BITMAPFILEHEADER)が16になってしまい fwrite((void*)&bmf,sizeof(BITMAPFILEHEADER),1,fp); などで読み書きすると、うまくいきません スマートに処理させるにはどうしたらいいでしょうか
>>583 コンパイラは何だよ
packのしかたはコンパイラで違う
#include <windows.h>いれとけば定義済みだよ
お、BITMAPFILEHEADERと同じ並び、同じ型(WORDとかで)で作った構造体でもサイズ変わるんだ。 定義済みのにsizeofすると14バイトだけど↑の条件で作ったのは16バイトになった。 なんで定義済みのはパディング入ってないんだろう。
>>584 #include <windows.h>
でうまくいきました。ありがとうございます。
>>585 >>584 みてわかるべ。
今のwindows.hは定義の直前に#include <pshpack2.h>
って入ってるね。pshpack2.hの中身は#pragma pack(push,2)か#pragma pack(2)
>>579 に便乗、丁度いい質問がでてた。
char配列のポインタをもらってくるのであれば
>>580 の方法でもよさそうですが
char配列そのものしかわからない場合はどう書けばいんでしょうかね?
配列のインデックの移動基準はcharベース。
でも場所が決まった場合はchar、short、intのそれぞれで
アクセス(読み書き)したい。
>>588 配列を貰うというのは要するにアドレスを貰うわけだからポインタで貰うのと変わらないよ。
複数の型でアクセスしたいなら char short int のポインタを含む共用体を用意して、
それに &char配列名[インデックス] でアドレス入れればいい。
while(*str){ str++; len++; } って書くのと while(*str) len++, str++; って書くのどっちがいい?
その程度ならどっちでも気にしない
>>591 個人的には{ }ではさむのは2つ以上の処理を書く場合かな。
1個だけなら1行にする
char x[]={0x12, 0x23, 0x34, 0x45, 0x56}; long *p; p=(long*)&x[0]; printf("%ld\n", *p); // これはOKになる可能性が高い p=(long*)&x[1]; printf("%ld\n", *p); // これはバスエラーになる環境もある
595 :
588 :2008/08/22(金) 20:49:42
>>594 なるほど〜
実は
>>588 で質問した内容は配列の中身はリトルエンディアンが保障されているんですが
ソースはビッグエンディアン環境下でもコンパイルできるようにマクロ内部で
char配列から1バイトごとに読み出しては型にあわせて任意ビットシフトした後格納を
やっています。
そのソースを使おうとしてる環境はリトルエンディアンなので本来はダイレクトにアクセス
したほうが速度があがるだろうと教えてもらったようにマクロを書き換えてコンパイルして
みたところ、フリーズというところではまってます。
マクロ化したエンディアン吸収部分はかなりいろんな箇所で使われてて手動で直すのは
大変なのでなんとかできれば・・と思ってたんですが・・・・
アライメントでググろうぜ
>>595 ボトルネックはそこなのか?
それが問題だ
>>596 あーそういのもありますね。
>>597 そうですね〜
かなりの頻度でそのchar配列に読み書きが行われるはずですので
(そういう性質の物ですし)
後出しで色々追加するからわけわからん
600 :
588 :2008/08/22(金) 21:57:38
そういう感じ。 また、できたとしても普通より遅くなるってCPUもある、x86とか。やっぱり避けるべき。
602 :
588 :2008/08/22(金) 22:19:40
>>601 x86が奇数アドレスなんかをまたぐとペナルティがある
(内部的に読みやすいアドレスで複数回読み込んで合成して処理するのでクロックを食うでしたっけ?)
のは知ってましたが駄目なCPUもあるんですねえ。
>>600 環境というかCPUだね。
x86は問題がないでしょ。だけど、ダメなCPUもある。
奇数のアドレスを整数でアクセスでバスエラーとか。
つーか、最近のx86なら仮令4バイトintでもどうせ64バイト読み込むから1バイトずれるくらいじゃ大差ないけどな。
605 :
588 :2008/08/22(金) 22:33:43
x86だとよかったんですが、実行環境はMIPS系リトルエンディアンなんですよね。 同じリトルエンディアンなんで期待したんですが・・・・
なにはともあれ、まずはプロファイラからだな
>>605 なんだって?・ちがうだろ。
どちらにしてもビットシフトなんてしないといけないか?
struct INT
{
unsigned char b[4];
};
swap(b[0], b[3]);
swap(b[1], b[2]);
くらいの程度ちゃうのか?わからんけど
608 :
588 :2008/08/23(土) 00:28:22
まー元のソースは公開されてるのでいいかな・・・
下記マクロをリトルエンディアンで最適にアクセスできるように直したいのですが
#define LOADINTELDWORD(a) (((UINT32)(a)[0]) | \
((UINT32)(a)[1] << 8) | \
((UINT32)(a)[2] << 16) | \
((UINT32)(a)[3] << 24))
#define LOADINTELWORD(a) (((UINT16)(a)[0]) | ((UINT16)(a)[1] << 8))
#define STOREINTELDWORD(a, b) *((a)+0) = (UINT8)((b)); \
*((a)+1) = (UINT8)((b)
>>8 ); \
*((a)+2) = (UINT8)((b)
>>16 ); \
*((a)+3) = (UINT8)((b)
>>24 )
#define STOREINTELWORD(a, b) *((a)+0) = (UINT8)((b)); \
*((a)+1) = (UINT8)((b)
>>8 )
609 :
588 :2008/08/23(土) 00:30:03
条件は先ほどと同じです。 MIPS系のCPUでリトルエンディアンで動いてます。 配列のアドレス決定はchar単位ですがアクセスはshort,intがあります。 intはそれほどアクセス頻度は無いので現在のロジックでもいいと思いますが shortが多発すると思われますので改善したいんです。
関係ないけどコンマ演算子つかったほうがいいんじゃないのか。
611 :
588 :2008/08/23(土) 00:36:22
すみません。 元のソースそのまんまなのであまり詳しくは把握できてないんです^^;
>>609 なにを改善したいんだよ。
方法としては、シフトして論理和とるか、
>>607 のように入れ替えるかの
二つしかないんだから、どっちが速いか実測しろよ。
それに、本当のボトルネックはもっと別にあって、 そっちをちょっと改善したほうがずっと速くなるなんてことも有り得る。
これってさあ・・・ 某エミュレーターの内部じゃねーの? LOADINTELなんちゃらってそれでみたぞ。 x86エミュだとやっぱりメモリアクセスの改善が一番じゃね?
データかコマンドか判らんが1個データ拾ってswitchかなんかで分岐して後続の不定数のデータを抜いてくるのを繰り返してるんでしょ多分。
charの配列からサイズの異なるデータを抜くのはやっぱりシフトして論理和ってのがよくある奴だし枯れてる書き方だし触らない方がいいと思う。
こんなところに労力をかけるより、ボトルネックが他にあるはずだ。
抜いてきたデータをそのまま使うんじゃなくて加工する箇所はあるでしょ、おそらく。
データを抜くコストより、加工のコストの方が高いはずだからそこの無駄を省く方がいいと思うけど。
関数コール1個減らすとかだけでもお釣りが来るよ。
シフトと論理和のコストの方が重い処理ってなんだよ、と、ソース見てない私はそう思う。
それでもこの部分を根本から変えたいなら、ターゲットとなるCPUを変更せよ(ぇ
まぁ、shortだけなら、
>>608 のマクロ変形して
#define LOADINTELWORD(a) (((unsigned long)(a) & 1) ? (((UINT16)(a)[0]) | ((UINT16)(a)[1] << 8)) : *((UINT16*)(a)))
ってやれば偶数アドレスのときだけならそのままshortで抜いてこれる。
といってもこの場合でも、偶数アドレスで始まるUINT16がある程度多くないと比較で増えた分のコストを吸収できない。
PSPのPC98エミュを最適化したいというわけですね
np2 for PSPかな static REG8 MEMCALL memmain_rd8(UINT32 address) { return(mem[address]); } こういった関数をなくすだけでも早くなるんじゃないかな
普通のコンパイラなら、インライン展開位するんじゃないの?
初心者ですがmalloc関数が難しくて困っています。 #include <stdio.h> #include <stdlib.h> int main(void) { char *str; str = malloc(1); if(str == NULL) { printf("メモリが確保できません\n"); exit(EXIT_FAILURE); } /* 文字列を入力 */ gets(str); /* 文字列の表示 */ puts(str); /* メモリの解放 */ free(str); return 0; } とあるんですがstr=malloc(1)とやって 3文字入力したら普通に出力できてしまいます 1とあるので1文字だけかと思ったら。 str=mallock(1);とは char st[1]="a";じゃないんですか? 何故、1文字以上出力できるかがわかりません。 詳しい方教えてください。
あんたにCは早すぎる。VBかJAVAやってなさい。
>>619 バッファオーバーフローしています
自分で範囲を超えないように管理しないといけません
>>617 これってさ、関数ポインタの配列で呼んでるっぽいな。
MEMCALL部分って配列化するときのインデックスか何かの関連だろ。
ようはmallocを使うことによって、scanfなどで文字をうけわたしたり できるってことですか? char *str; scanf("%s",str);ではできませんが char str[100]; scanf("%s",str);はできて str=malloc(100)ってことでstr[100]になるってことですよね? mallocを使うことによって配列みたいになるんですか?
>>619 正式に確保したのは1なんだが、それ以降もたまたま書き込める状態だったということ
>>623 書き込める場所を確保するという意味ではあってる
一応char * str=malloc(100) とchar str[100]でいくつか違いはあるので全く同じではないが
>>629 C言語の文字列って何かってところから勉強しよう。
mallocはまだ早い。
> str=mallock(1);とは char st[1]="a";じゃないんですか?
そういう使い方できるけどそれは1文字の文字列じゃない。
char st[1]だと0文字の文字列しか入れられない。
たぶん意味わかんないだろうけどどういう意味か勉強してください。
> 何故、1文字以上出力できるかがわかりません。
> 詳しい方教えてください。
詳しい方なら3文字入る環境があることはわかっているが、
「たまたま動いているだけだからそんな使い方しないでください」
というアドバイスの方がよさそうだな。
>>623 mallocで領域確保するしないの問題と
>char *str;
>scanf("%s",str);ではできませんが
>char str[100];
>scanf("%s",str);はできて
これは分けて考えないと。
mallocっていうのはアプリケーションとOSとの間のやり取りで見ると
その都度要求のあったメモリサイズをちまちまOSから借りてくるわけではなく
何らかのタイミング(アプリケーション起動時、もしくはアプリケーションが最初に発行するmalloc)
である程度の大きさのメモリを借りてきます。
たまたまあなたの作ったアプリケーションが借りてきたメモリが実は1バイト以上なので
malloc(1)で確保したエリアに3文字書いてもエラーにならかった分けです。
この辺はヒープという単語でググってください。
で、
>char *str;
>scanf("%s",str);ではできませんが
こっちはstrポインタだけで文字を収める先が用意されてないので駄目です。
>char str[100];
>scanf("%s",str);はできて
こちらはstrは100個の文字を収める場所がありますので当然OKです。
>>628 丁寧なお答えありがとうございます
ですがmalloc(1)の場合は1バイトではなく何バイトなんでしょうか?
>>629 いや、それは環境によっても違うし、設定によっても違うし。
1バイト以上ってことなんですが 正確にわかる方法はあるんですか?
だからそれを理解するにはヒープでぐぐって勉強してね 各環境ごとに初期割り当てサイズとかあるんで
>>632 ない。
4バイトごとに確保する領域を繰り上げる環境もあるし、本当に1バイトしか使えない環境もある。
それにそれが判ったからといって、指定した領域以上の領域を使うようなことをしてはいけない。
>>634 ほーこれがややこしくてわかりずらかったです
やっとわかりました
誠にありがとうございます
×わかりずらかった ○わかりづらかった
初心者に実装の詳細の話しをしても混乱するだけかと
くだらんウンチク垂れてないで「malloc(1)なんだから1バイトを超えて使うなぼけ」で充分だろ
>>638 1バイト超えて使えるのは何で?って聞いてるんだしいいだろうがw
でも、ある程度上の説明で収まったからいいけどもっと程度低い
やつだとまだ延々と説明論議して疲れて放置とかなんだろうな。
未定義動作だから、たまたま使えてるかもしれないし、他の変数の値をぶっこわしてるかもしれないし、 システムぶっ壊して起動できなくなるかもしれない、っていつも通り答えておくのが正しいんじゃない?
まあ実態は、いちいち1バイト取るなんてめんどくさいから xxバイトとっておいて1バイトとったことにしておこう、くらいだろう
ちなみにmallocって別に使わなくても平気ですか? メモリどうたらいってますが、配列とかポインタでやってればメモリどうたらでも 普通に軽くうごくんですが
要らないなら使わなきゃいいじゃん
素人はrubyでも使ってろってこった
str=(char *) malloc(sizeof(char)*10);は sizeof(char)は1ですけど 何故 sizeof(char)と書くんでしょうか? 本にそう書いてありますが。 char型は1バイトだから malloc(1*10)とmalloc(sizeof(char)*1) は同じなんでしょうか?
お前万が一charが2byteだったらどうするんだよ
Cはプロフェッショナル用の言語なんだよ。 初心者が言語仕様をちょろっと勉強した程度で使えるような甘っちょろい言語じゃない。 実際、学部とか修士とかで「Cをマスターしました」とかほざく新卒で、きちんとCプログラムを 書ける奴なんてほとんどいない。 最初はvb, java, python, ruby等々、お遊び言語でコンピュータに慣れとけ。
>malloc(1*10) これだと後でソース見た人が何のためにメモリをこれだけ確保したかわからないから? あとcharだとほぼ1バイト固定だと思うけど intあたりになると4バイトもあれば違うのもあったりするので できればmalloc(sizeof(char)*1)とするほうがいい
>>648 ほー じゃあ自分で書く分には
省略してmalloc(10)ってことでもいいんですよね?
他人が見てわかりずらいから キャストとかsizeofがあるのかぁ
参考になりました。
その「他人」には自分も入ってることにいつか気がつくw
素人はrubyでも使ってろってこった
その前に日本語を勉強しとけ
>>649 それは誤解
キャストするのはコンパイラに教えるため。
あれは人間のためじゃない。
sizeofもそういう意味じゃない。
今の例はおおよそバイトサイズがわかるcharとかintだからいいけど
構造体を使いだしたらその都度計算するのか?ということになる。
本に書かれてることは間違ってることもあるが、利にかなってることもある。
>>650 そうだなwww
自分で書いたソースも時間がたつと「これなんだっけ・・・?」で
悩むよな。
手を抜いて数字ばっかりでやりだすと糞ソース化する
まぁ、sizeof(char)なんて書くのはナンセンスだけどな。
>>642 使えないと恥ずかしいとは思うけど、職業プログラマの現場でも、malloc()禁止とかはざらにあるな。
素人はrubyでも使ってろってこった
まあchar程度のまとまったエリア取るなら #define hoge_char 0x1000 xxxx = malloc(hoge_char); とかかな・・・
うわ、きも
私が読んでるのは、独習C、やさしいCです
>>646 C言語である限り、charは1バイト。
万が一charが2バイトだったら、そのコンパイラはCコンパイラとは呼べない。
malloc時にsizeof(char)をかけるかどうかは宗教的な問題で、
どちらが正しいということは無い。
どちらにも言い分があり、どちらも正しい。
将来charが2バイトになる可能性だって否定はできないよ
それは無いなあ。
どのコードで書かれたかわからない文字列のバイト列を渡されてそれを適切に解釈することってできるの?
>>664 文字コードってどれほど種類あるか知ってるか?
漢字なんてなくなればいいのに
>>668 いやあっても問題ない。
コードに複数種類があるのが問題。
うにコードも統一されてそれだけが使われる世界なら良いのになぁ
なんだ昨晩の高速化の件はエミュなのか
みなさんこのC言語をくししてどんなアプリケーションをつくってきましたか? 実際に使えるものなどのコードをのせてみてください
>>672 夏休みの宿題が残ってるんですね、わかります
業務コードなので載せられません
3年位前にやったシステムはありえないくらいソースが酷かったんで、記念にとってあるんだけど、 ネタでさらすわけにもいけないし、活用方法がないな。
>>670 そんな世界ができたらまさに夢のようだな
678 :
側近中の側近 ◆0351148456 :2008/08/24(日) 08:51:53
(っ´▽`)っ 最近書き込んでなかったね。C言語スレに。 おひさ☆
#include <stdio.h> #include <conio.h> #define MAP_SIZE_Y 10 #define MAP_SIZE_X 10 int y=5; int x=5; int map[100][100]={ {1,1,1,1,1,1,1}, {1,0,0,3,0,0,1}, {1,0,0,0,0,0,1}, {1,0,2,0,2,0,1}, {1,0,0,0,0,0,1}, {1,1,1,1,1,1,1}, };
void drawmap(){ int j,i; for(j=0; j<MAP_SIZE_Y; j++) { for(i=0; i<MAP_SIZE_X; i++) { if(j==y && i== x) { printf("Y"); }else{ switch(map[j][i]){ default:printf(" "); break; case 1: printf("*"); break; case 2: printf("H"); break; case 3: printf("K"); break; } } } printf("\n"); } }
void getkey(){ switch(getch()){ case 'w': y--; break; case 's': y++; break; case 'a': x--; break; case 'd': x++; break; } } int main(void) { while(1){ system("clear"); drawmap(); getkey(); } return 0; } マップ作成で主人公を動けるようにしたんですが、障害物にあたった時に進めないようにしたり する方法がわかりません。
case 'w': if (map[y - 1][x] != ' ') --y; break;
>#define MAP_SIZE_X 10 10と定義して >int map[100][100]={ 100個確保して >{1,1,1,1,1,1,1}, 7個初期化・・・・ 迷惑だからプログラム作るな。エロゲーでもやってろ。
static void drawmap(int x, int y) { for (int j = 0; j < MAP_SIZE_Y; ++y) { for (int i == 0; i < MAP_SIZE_X; ++i) { putchar((j == y && i == x) ? 'Y' : map[j][i] >= 1 && map[j][i] <= 3 ? " *HK"[map[j][i]] : ' '); } putchar('\n'); } }
int map[][] = { {1,1,1,1,1,1,1}, {1,0,0,3,0,0,1}, {1,0,0,0,0,0,1}, {1,0,2,0,2,0,1}, {1,0,0,0,0,0,1}, {1,1,1,1,1,1,1}, }; #define MAP_SIZE_Y (sizeof(map) / sizeof(* map)) #define MAP_SIZE_X (sizeof(* map) / sizeof(** map))
>>670 うにコードはねぇ。当初はえらい騒ぎだったんですよ。sci.lang とかで。
今でも毛唐の陰謀だとおもっています。
>>679 移動しようとした先に障害物があったら動かないようにすればいいだけ。
ヒントはすでにもらってるんだから自分で書いてみな。
ゲームっぽい何かを作ろうとしてるんだろうけど次は「アイテム取ったときには・・・」とか言うつもりだろ。
移動しようとした先にアイテムがあったらアイテムを取る処理すればいいだけ。
移動しようとした先に人がいたら会話処理すればいいだけ。
移動しようとした先に敵がいたら戦闘処理すればいいだけ。
移動しようとした先に階段があればマップ変更と座標移動すればいいだけ。
中国あたりを滅ぼして文字を減らしてはどうか
#include <stdio.h> #include <stdlib.h> int main(void) { char *str; int i,num; scanf("%d",&num); str=(char *)malloc(sizeof(char *)*(num+1)); if(!str){ printf("memori kakuho huka\n"); return 1; } for(i=0; i<num; i++){ *(str+i)+='a'; } *(str+num)+='\0'; printf("%s\n",str); free(str); return 0; } これなんですが if(!str)のときメモリ確保できませんとありますが 0とうってもメモリ確保できないようですが このメモリ確保できませんは どんなときにでるのでしょうか? if(str)だと数字をいれれば エラーを表示できますが
-99とか入れてみたらエラーになるんじゃない
>0とうってもメモリ確保できないようですが そんなことはない
>どんなときにでるのでしょうか? !strが0でないときだ
-99でできました こういうのややこしいですね !str !っていうのは0だったらって習いましたが
>>689 まずそのソースはお前が自分で書いたのか他人が書いたのかはっきりしろ
>>689 > str=(char *)malloc(sizeof(char *)*(num+1));
これは
str=(char *)malloc(sizeof(char)*(num+1));
こうだろ。
突っ込みどころが多すぎる お前にmallocは1年早い
>>693 !条件 は 条件==0 と同じ意味で、条件を0と比較したときに等しいと判断されるとき1を返す
ただし、必ずしも条件そのものが0であるわけではない(ヌルポインタ定数の問題)
>>697 これは難しいですね
この場合 strが0じゃなくて strに何も入ってない strの[]が確保できなかったときに
エラー返すってことでいいんですか?
どう見ても釣りです 本当にありがとうございました
>ヌルポインタは内部表現がどうであろうと、Cの中では0だ ちがいます Cの中ではヌルポインタの値がなんであるかは規定されていません コンパイラが0をヌルポインタにするだけです
アンカーぐらい正しく打てよ
704 :
側近中の側近 ◆0351148456 :2008/08/24(日) 13:43:42
(っ´▽`)っ 確かにANSIではNULLを0とせよとの記述はないが、 NULLが0でないコンパイラってあるのかな?
NULLは0または(void *)0と規格で決まっている
706 :
側近中の側近 ◆0351148456 :2008/08/24(日) 13:46:17
(っ´▽`)っ そうだっけ?
NULL ≠ ヌルポインタ
>>702 だったらやっぱり普通にCで扱う限りはヌルポインタは0だろーが
709 :
側近中の側近 ◆0351148456 :2008/08/24(日) 13:49:35
(っ´▽`)っ まあ、こういう誤解を生むから if(条件文)では、ちゃんと論理式を書くべきだね。 何でもかんでも略すカーニハンの悪い癖だ。
!strとかわかりずらいです str==0でいいのに
>>708 「普通」ってなんのこと?
そういうのを放置するからmemsetでポインタにゼロを埋めるようなやつが出る。
712 :
側近中の側近 ◆0351148456 :2008/08/24(日) 13:54:26
(っ´▽`)っ 確かに、 memset(&p, NULL, sizeof(p)); とやってる奴には、 お前、NULLって何だかわかって使ってるんだろうな? と問い詰めたくなるね。 というか、警告レベルを上げれば警告が出るけどね。
>>705 いや、NULLは処理系定義の空ポインタ定数なので、_Nullptrでもかまわないよ
714 :
側近中の側近 ◆0351148456 :2008/08/24(日) 14:03:09
(っ´▽`)っ というか、mallocが失敗した時に返す値をstrに入れないとダメだろ。 NULLの実体が0か否かに関係なく。 と言ってみる。
715 :
側近中の側近 ◆0351148456 :2008/08/24(日) 14:11:57
(っ´▽`)っ? (っ´▽`)っは何を言ってるんだ?
int main(void)なんですが int main( int x , int y)とかってないんですか?
717 :
側近中の側近 ◆0351148456 :2008/08/24(日) 14:18:30
>>716 (っ´▽`)っ
int main(int argc, char *argv[])
で我慢しなさい。
int argc, char *argv[]これしってます -helpとかですよね 側近中の側近さんは日常で使えそうなプログラムとか作れるんですか?
どうでもいいけど、「使えそうなプログラム」って聞くと、実際には使えないんだっていうイメージが沸く
実際ここの人が作った、日常で使えそうなおもしろいプログラムみたことないんですよね ただどうたら どうたら 流して結局ソースコード見せてくれないのが落ちなんでそこまで期待してませんが。 その前で日本語を学べっていうやつって腹が立ちますね。だいたい伝わってるのに、日本語を学べとか喧嘩うってるんですか? 他のサイトみせて 夏休みの宿題が残ってるんですね、わかります とか適当に流して。 これくらいしってるならCO2削減の家計ソフトとか作ったりできそうですが。
夏休みの宿題に追われているのですね、わかります
>>721 日本語わかるんなら、面白そうな小説のひとつくらい出してみろよ。
宿題うんぬんじゃないですよ。 みなさんが、どれほどすごいのか知りたいだけです。 この高度なスキルをいかしてどのようなことをしてるのかなど。 敷居の高いことを語りあってるから、ATMなど作ったりできるのかな?って思ってるだけです それとC言語ではどういうものが作れるか知りたいです。 自動販売機などはC言語?よくわかりませんが、アセンブラでしょうか? これは釣りではありません。
>>725 べつにすごくないです。
ここの質問は、高度なスキルがなくても答えられるようなことばっかりだから。
銀行のATMって、なんで作ってるんだろうね。 ホストのほうはCOBOLとか?
>713 _Nullptrってなんずら? 少なくともCには存在しないよ
>>725 一番最近やったCの仕事は、医療関係の測定機器と通信してデータを管理するシステム。
ただ、ぜんぜん高度じゃなかったけど。
十数年前からあるシステムで当時は選択肢はCしかなかったのかもしれないけど、今となっては
スクリプト言語で作ったほうが楽なんじゃね? と思われるような感じだった。
730 :
デフォルトの名無しさん :2008/08/24(日) 15:14:34
>>729 あるある。一から作り直した方がいいんじゃね系。
>>729 初心者の私から見れば、十分高度だと思います。
通信ってソケットどうたらですよね
そういうC言語を熟知してる時点でうらやましいかぎりです
しかし一から作り直す金は出ない
>>721 ソースをみたければ宿題スレへどうぞ。
たまに神がソースをアップしています。
>>725 C言語はコンピュータ制御で動くものなら何でも作れる。
いまどき自販機にアセンブラ使うバカはいない。
>>727 少なくとも俺の知ってるとこはCOBOL。
そのうち携帯と通信できてその場でWEBのボーナスサイトにアクセスできて当たりが出た人はもう一缶貰えるとか PCも通信モジュールが手に入ってクラックする奴が出てきて全部の味を混ぜたり好きなだけ缶出したり出来るようになるんだろうなあ
>>728 架空のキーワード
処理系はそういうことをしてもいいよという例えだろ。
>>731 外野の想像だけど、その通信はCOMポートとか使ったもので、ソケット関係なくね?
740 :
質問です :2008/08/24(日) 17:11:15
カレントディレクトリに任意のディレクトリを作る関数はあるのでしょうか? winでvb++使ってます。Cの知識がわずかばかりあるくらいです。 お願いします
脳内言語か。
742 :
740 :2008/08/24(日) 17:14:33
すみません ×vb ○vc
たとえば「VC ディレクトリ 作成」とか、適当に思いつく言葉でググればすぐ見つかると思うけど。
744 :
740 :2008/08/24(日) 17:20:14
携帯は辛いです・・・
携帯上でVCで開発していると聞いて
746 :
740 :2008/08/24(日) 17:24:02
携帯は2ch専用です
つまりPC上でVCで開発してるけどネット環境がないということでいいですか?
たぶん学校のPCとかだろう ていうかCの質問?
749 :
740 :2008/08/24(日) 17:29:24
750 :
740 :2008/08/24(日) 17:30:45
#include <direct.h> して mkdir() とかがこのスレっぽい?
752 :
740 :2008/08/24(日) 17:34:57
>>751 おお!できました!
ありがとうございました!
#include <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc, char *argv[]){ char shiroutoharubydemotukatterottekotta[80]; if(argc != 2) return -1; strcpy(shiroutoharubydemotukatterottekotta, "ruby -e\"Dir.mkdir('"); strcat(shiroutoharubydemotukatterottekotta, argv[1]); strcat(shiroutoharubydemotukatterottekotta, "')\""); system(shiroutoharubydemotukatterottekotta); return 0; }
754 :
721 :2008/08/24(日) 19:28:38
C言語で本を読み、ポインタ、構造体を理解したら何を学べば良いでしょうか? ネットワーク系のソケットってやつを学ぶのかそれとも、時計など、3分タイマーなどそういうのをやったほうがいいんでしょうか? 偉大な皆さんがやってきた順序を参考にしたいと思います。 私は、webサイト、入門書って順番です 3分タイマーやいろいろな物を作ってみたいと思います。
リンクドリストを作成する課題を通してポインタや構造体への理解を深めましょう
リンクドはねえよw
そしてオブジェクト指向へ
ドラクエ3やりたくなったわ
759 :
デフォルトの名無しさん :2008/08/24(日) 19:59:28
じゃあハッシュリストだ
本当にポインタを理解しているのかどうか、それが問題だ
>>754 進路による。
組み込み系なら簡単なアセンブラとコンパイラの挙動の理解。
ウェブ系ならTCP/IPと、他の言語(perl,PHP,Java)、DBとの連携、
ゲームやビジネスアプリの制作ならC++を覚えるといい。
>>760 コンパイラの仕組みが理解できてないと、完全な理解は無理だよな。
>>739 機械側はシリアルで出力してたけど、途中でアダプタかまして、IPに変換しえた。
>>754 構造体とポインタを理解した?ご冗談を。
理解したつもりになってるだけだ。
ためしに、
「引数に構造体hogeのポインタを持ち、帰り値がintのポインタであるような関数へのポインタを
引数に持つ、char型16個の配列へのポインタを返す関数fooのプロトタイプ宣言」
を書いてみ。
なんで関数ポインタまで飛ぶんだよw
766 :
763 :2008/08/24(日) 22:23:04
ていうかここでふんぞり返ってる奴らのうち半数くらいも書けないと予想
答えマダー(・∀・ ) っ/凵⌒☆チンチン.
char (*foo(int *(*)(struct hoge *)))[16]; これであってる・・・はず まあそれよりもテキスト操作を徹底的にやったほうがいいと思うけど
関数ポインタ見るたびに、そんなことするくらいならC++使えよって思う。 、、、負け惜しみだけど。
>>769 C++の関数ポインタに変わる機能はよくしらないが
速度が同じくらい出て簡単に書けるならいいけどな・・・
なんと関数ポインタより速…いんだっけ忘れた
>>771 アセンブラレベルで関数ポインターを考えるとあんまり早くする方法がなさそうなんだけどな・・・
switchに切り替えて処理が多い部分を先頭にもってくるというのは無しで考えると。
>>770 受け渡したいメソッド(関数)を持ってるオブジェクト(のポインタ)を受け渡しするだけですよ。
速度面についてはコンパイラの最適化に期待。
>>770 仮想関数使えってことじゃね?
速くはならないけど。
>>772 分岐が数個程度なら、ifやらswitchのほうが速いかもしれない。
速くならないかもしれないけど。
みんなどれだけ時間にシビアなプログラム書いてるんだか。 TRONの開発でもしてるんだろか。
配列とポインタの関係でも述べさせればいいじゃない
何この知ったかばっかりのスレ!!!
>>776 最近ここで質問してたx86エミュなんかだとシビアそうだな。
MIPSっていってたのでたぶんPSPで動かすんだろうけど。
いや、なんか関数オブジェクトとかファンクタとかそんな話、詳しくは使ったことないから知らない
781 :
721 :2008/08/25(月) 00:03:59
#include <stdio.h> #include <stdlib.h> #include <string.h> void show(void); void show1(void); void show2(void); int main(void) { void (*p[3])(void); int num;
782 :
721 :2008/08/25(月) 00:05:44
p[0]=show; p[1]=show1; p[2]=show2; printf("0,1,2\n"); scanf("%d",&num); if(num>=0 && num<=2) { (*p[num])(); return 0; } } void show(void) { printf("kuruma\n"); } void show1(void) { printf("hune\n"); } void show2(void) { printf("hikouki\n"); } すみませんが関数ポインタはp[0]=show; p[1]=show1; p[2]=show2; をやらないと呼び出せないんですか? 自分で p[3]=(show,show1,show2);などとやってみたんですが うまくいきません もっと簡単にかけるやり方教えてください
void *p[3]= { show , show1 , show2 }
つーか関数ポインタなんて手を出すな
ググって一番上のページに載ってるやん
786 :
721 :2008/08/25(月) 00:15:57
>>783 ありがとうございます
>>784 やさしいCっていう入門書に関数ポインタがのってるので一応やってみたんですが
結構便利です
787 :
721 :2008/08/25(月) 00:22:16
あーーー void (*p[3])(void);なんですが void (*p[3]={show,show1,show2})(void); では文法ミスで、void *p[3]={show,show1,show2}(void);とうってもエラーがでます。 (*p[num])(); の行がエラーがでますが、ここも変えるべきですか?
void (*p[3]={show,show1,show2});
void (*p[3])(void) = {show1, show2, show3};
790 :
721 :2008/08/25(月) 00:34:07
>>789 やっとできました
(void) 引数を先にもってくるなんて思いつきませんでした。
(*関数ポインタ)(引数リスト);しか書いていなくて。
>788
788さんのやり方では、エラーがでました { }が色がつき文法エラーになりました
型 配列名 = {変数名, 変数名, ...}; の流れからすれば当然だろう
Cプログラマはどんな椅子つかってんの?
黒い椅子
hoge = MACRO(hogehoge); のような戻り値を返すマクロを書く際、 マクロの内部で演算式で直接置き換えができない場合は この戻り値を返すという直接的な指定は可能なんでしょうか?
>>794 カンマ演算子を使えば、何とかなることもある。
内容にもよるだろうけど、同じような仕様のプログラムを作ったときにCとC++ってどっちが早いの?
C++の方が手っ取り早いな。内容にも拠るけどCだと車輪の再開発から入ることに成りかねない。
>>796 ライブラリが揃ってれば開発速度はどっちでも変わらん。
動作速度は、C++で何度もコンストラクタを呼び出したりしてると遅くなるが、そんなことしないからたいして変わらん。
C++ならちょっと遅くても簡単に開発するか、ちょっと面倒でも性能のいいものを作るか選べる Cなら必然的に後者になる 気がする
ライブラリがあっても商用に使えないGPLになってるのもあったりと 面倒だしな>Cで開発する場合
801 :
側近中の側近 ◆0351148456 :2008/08/25(月) 20:59:44
(っ´▽`)っ 関数ポインタを使って、擬似的にオブジェクト指向☆
ちょいと気になったのですが コンパイラの中の一機能であるリンカが、リンケージしてる対象って何なのでしょうか? ソースコードと実行ファイルをリンケージする事に何か意味があるのでしょうか? それともまったく別のものms_dosとかとリンケージしているのでしょうか?
803 :
側近中の側近 ◆0351148456 :2008/08/25(月) 21:41:30
>>802 (っ´▽`)っ
リンケージしてる対象:.oファイル
*.c → コンパイラ → *.obj → リンカ → *.exe
805 :
側近中の側近 ◆0351148456 :2008/08/25(月) 21:43:26
(っ´▽`)っ .cファイル ↓コンパイル .oファイル ↓リンク 実行ファイル
*.c → コンパイラ → *.obj → リンカ → *.exe ← スタートアップモジュール、ライブラリ
807 :
側近中の側近 ◆0351148456 :2008/08/25(月) 21:45:29
(っ´▽`)っ unix派は少ないのか・・・。
>>802 ソースファイルをコンパイルすると
>>803 のいうように.oになるんだけど
ソースが複数存在する場合なんかは互いの関数のバイナリーレベルの
相対的な位置やexternなんかで参照してるエリアの位置も確定しないので
すべて.oにし終わった段階でリンクさせるのがリンカーのおしごと
別にソースでやってるわけじゃない
あれは単なる指示書だし
809 :
806 :2008/08/25(月) 21:52:57
コテ邪魔だからどっか行け
なるほどそうなのですか ありがとうございます。
>>807 どれがunixでどれがwin相当なのでしょうか?
812 :
側近中の側近 ◆0351148456 :2008/08/25(月) 22:25:02
>>811 (っ´▽`)っ
unix(gcc)が.o
Win(VC+)が.obj
>>811 どっちにしろオブジェクトの略称でoなだけかobjなだけかの違いだよ
win32APIを1から学ぶのにいい参考書ってありませんかね?
もし、リンケージが無かったら・・・ こりゃ大変だぞ Windowsのアプリを作るのに、APIのソースコードのコンパイルからしなくてはいけない
>>814 win32APIっていってもピンきりだけど・・・・
>>816 ピンキリってのが良く分からないレベルです
C言語で簡単なアプリケーションが作れるくらいになればいいなと思ってるんですが
APIの意味わかってる? win32APIっていったらwindows用に用意されてる機能でAPI公開してる 物は全部ってことだよ・・・?
APIで学ぶWindows徹底理解
WinMainから作るのと、特殊なケースでだけAPIを利用するのと両方の使い方があると思う。 いまどきWinMainから作っている人っているのかな?
>>820 そこからか… じゃあ
つ【win95APIバイブル1】
C#がいい
823 :
721 :2008/08/25(月) 23:02:14
for(i=0; ke[i]!='\0'; i++)これは ke[i]がNULLに達するまでであってますか? あとwhile(*str)です これはよく意味が分かりませんが これも NULLに達するまでですか? ke[i]!=ke[5];ってやってもなんかだめでしたけど ソース int kazoeru(char ke[]) { int i,c; c=0; for(i=0; ke[i]!='\0'; i++) { c++; } return c; } 演算子を詳しく教えてくださいお願いします。
>>823 null文字に達するまでであってます
ke[i]!=ke[5];がだめとかいわれてもkeの中身なんて知らないし
strはどこにある
827 :
721 :2008/08/25(月) 23:12:44
>>825 ありがとうございます
>>824 826
keは char str[100]; scanf("%s",str); kazoeru(str)です
#include <stdlib.h> /*--- 文字列sの長さを調べる ---*/ size_t strlen(const char *s) { size_t len = 0; while (*s++) len++; return (len); }
文字列の最後に\0がはいってて文字数知りたいだけなら strlenって関数あるけど・・・
830 :
721 :2008/08/25(月) 23:18:08
strlenは知っていますが 入門書でstrlenの関数を作れと書いてあって while(*str)などがでてきて 質問してみました。
strがポインタなら*strはstrの指しているもの strが配列ならstrの最初の要素 while(*str)は*strが0と等しくない間繰り返すという意味
文字列の終わりの'\0'をnull文字とか言う知ったか野郎は黙っていろ CではNULLはポインタにのみ使うべきものだ
Cに慣れてない人は while (*s++) これですでに混乱するだろうね。
834 :
721 :2008/08/25(月) 23:29:32
>>831 while(*str) は 0と等しくない間繰り返すんですが
この0はNULL('\0)ととらえていいんでしょうか?
while(*str)
{
str++;
}
だとstr[1]になって
繰り返しが 0ではなくなって1になるのでストップしてしまうとおもうんですが
>>832 はいはい半端な知識乙
せっかくNULLじゃそう噛み付く奴いるともってnull文字にしといたのに・・・
NULでいいだろ
そこまで目くじら立てることもないとは思うがまぎらわしいのも確かだからNUL文字にしとけ
ぬるぽ
840 :
まつせ :2008/08/25(月) 23:34:16
void original1(char jpn[][256], char eng[][256], int count) { int a; while(1){ printf("新しく日本語を追加してください\n"); printf("%s\n", jpn[1]); scanf("%s",jpn[count]); printf("新しく英語を追加してください\n"); scanf("%s",eng[count]); printf("1個追加かんりょー\n\n"); count++; printf("まだ追加しますか? (y / n) :"); a = getchar(); if(a == 'n'){ break; } } if(count == 20){ printf("腹いっぱい\n"); return 0; } return count; } getchar関数が機能しません 詳しく教えていただきたいです
>繰り返しが 0ではなくなって1になるのでストップしてしまうとおもうんですが お前は何を言っているんだ
scanfとget系関数を混ぜて使うとそういう問題がおきます 素直に一文字でもscanf+%sで取りましょう
843 :
721 :2008/08/25(月) 23:36:45
>>838 831
やっとわかりました
0='\0'ってことですか
while(*str)=for(i=0; str[i]='\0'; i++)
0ってstr[0]かとおもって混乱してしまいました。
>>840 改行文字がバッファが残っていると思われる
getchar();
printf("まだ追加しますか? (y / n) :");
a = getchar();
としてみたらどうかな
>>834 NULLはポインター関連で使ったほうがいいかな・・・
\0は文字の終わりを示す物で16進数だと0x00
strは文字列のさす位置を常に移動してて
while(*str)
の部分は
条件判断に分解すると
*str != 0x00 の間処理をしますってこと。
配列風に書くと場所を指すインデックス用のエリアが必要だけど
int index = 0;
while(str[index] != 0x00)
{
index++;
}
scanfみたいに使いにくくて危険なものをどうしていつまでも入門書で教えるのか疑問で仕方がない
>>840 直前の scanf("%s",eng[count]); でたとえば "fuck"+Enter と入れたとする
するとコンピューターには "fuck\n" というデータが送られて
eng[count] には "fuck" が入り、'\n' は残ったまま取り込まれるのを待つ状態になる
次の a = getchar(); はこの '\n' を読んでしまっている
fgets(s, sizeof s, stdin); とかで一行ずつとって、sscanf()とかatoi()で変換するようにしましょう。 scanf()はクセ強いだけで使えないから、学習しても時間のムダです。
絶対strtok+atoiを教えるべきだと思うのだが何故そうせずにいつまでもscanfにこだわるのか。 まあ、入門書を書くような落ちこぼれプログラマもどきには無理な話か。
>>849 むしろその方法はえらく半端な気が
バッファがのこらないことぐらいか?利点
>>840 scanf()の喰い残した改行文字をgetchar()が喰っている。
>>852 scanf()に比べたら、シンプルで移植性もあるよ。
855 :
721 :2008/08/25(月) 23:45:52
scanfがだめってどっかに書いてあったんですが。 皆さんscanfダメといっていますが。 なんか入門書かって後悔します。入門書以外でどうやって学んだら良いんですか?
まぁ、strtok()なんて使う方がどうかしていると思うがな。
入門からあれが駄目これが駄目とか気にすんな 「俺ってそろそろ上級者?」ってやつだけ移植性とか気にすればいい
まぁ普通の入門書の構成でやろうとしたら入力は極力簡単なものにすることになるだろそりゃ いきなり文字列の構造からはじめろと?w
859 :
まつせ :2008/08/25(月) 23:51:16
ありがとうございました。
まつせwww どこの誤爆こて版ww
入力なんて最初から教えるのが間違ってる。 入力は出力と比べてものすごく危険なんだよ。 メモリやアドレスの概念がしっかりしてないとひどいことになる。 そういうことも気にせずに、inとoutだから対にして教えとけ、 程度しか思いつかないからプログラマもどきなんだよ。
読者を飽きさせない手法なんだろ。 なんか反応があった方がくんでる実感あるだろうし。 まあ正直そのくらいで飽きるやつはやらなきゃいいと思うがな。
だって、初心者本書いているのは技術者じゃないもん。
入力と出力から学ばないと、まともなプログラムが組めないでしょ scanfは使えないなと、後でわかればいいだけの話
865 :
まつせ :2008/08/25(月) 23:59:09
int original2(char jpn[][256], char eng[][256], int count) { int i; char ans[100]; int tokuten=0; for(i=0;i<count;i++){ printf("%s を訳せ\n",jpn[i]); scanf("%s",ans); if(strcmp(ans,eng[i]) == 0){ printf("正解!\n\n"); tokuten++; } else{ printf("間違ってるよ\n"); printf("回答例 %s\n\n",eng[i]); } } printf("終了\n"); return tokuten; } void original3(int tokuten ,int count) { printf("%d門中、%d門正解です。\n",count,tokuten); printf("正解率%d%%\n\n",tokuten / count * 100); } 次の質問 上と下の関数で、引数のcountって一緒じゃないんですか?
866 :
まつせ :2008/08/26(火) 00:00:11
別物ですかね?
興味だか実用例だかのために入力が必要ならatoi(argv[n])とでもすりゃいいじゃん 危険なscanfをわざわざ教える意味がない
868 :
デフォルトの名無しさん :2008/08/26(火) 00:02:03
てゆーかこの話題何回目だよ・・・・・・・・・・・・・
>>866 別物です
869 :
まつせ :2008/08/26(火) 00:02:57
引き継がせるなら、returnが必要...?
>>868 そりゃ新しく学ぶ人がいればループもするさ
どこのスレでも「wikiよめ」「ぐぐれ」とかありきたりな質問者に対する対応が
絶えないのと同じ。
ループするネタといえば、配列がポインターに成り下がるという件
>>869 returnを明示する必要があるのはその関数などが
戻り値を返す場合。
void original3(int tokuten ,int count)
{
printf("%d門中、%d門正解です。\n",count,tokuten);
printf("正解率%d%%\n\n",tokuten / count * 100);
}
これは関数が戻り値を返さないvoid 型なんでreturnなくてもいい
数値を返したい場合は
int original3(int tokuten ,int count)
などに変更して
return 0;
とか書いてあげればOK
>>869 まだ質問の意図がよくつかめてないが
グローバルに宣言するとか
すいません。C言語とは離れた話になって恐縮ですが、 メモリ領域について、宣言した変数を格納するスタック領域とmallocなどでメモリを確保するヒープ領域なのですが、 この2つが確保しているメモリ領域で衝突しない方法ってご存知ですか? あとstatic変数って多く宣言するとプログラムサイズも大きくなりますかね? 誰か詳しい人がいましたらお教えください。
874 :
まつせ :2008/08/26(火) 00:11:59
とりあえずこのプログラムの説明 まず、txtファイルから単語を読み込む 単語の追加をする 単語テストをする 正解数、正解率をだす で、読み込むときに、main関数内でcountに単語数を代入しました が、、、追加しても単語数が増えないのはなぜですか?
>メモリ領域について、宣言した変数を格納するスタック領域とmallocなどでメモリを確保するヒープ領域なのですが、 >この2つが確保しているメモリ領域で衝突しない方法ってご存知ですか? 普通は衝突しないだろ。 staticをつけるとプログラム内部に固定で取られる。 staticなしだとスタックにとる。
877 :
721 :2008/08/26(火) 00:16:03
>>870 わかりますそれ、ぐぐれとか、これだから初心者はとか言われると初心者みたいな私はいらってきます。
ですが私は教えるといったら変数とかforとかだけですけど あははっははっは
これでもC言語の入門書4冊もってますが難しいです。
メモリの衝突がわからん。
低レベルなことわからないなら一回アセンブラやってみるとだいたいわかったりする。
>>873 > この2つが確保しているメモリ領域で衝突しない方法ってご存知ですか?
衝突はしない。
スタック領域もヒープ領域も無制限に取れるわけではなくて、領域の総サイズは決まっている。
> あとstatic変数って多く宣言するとプログラムサイズも大きくなりますかね?
ファイルサイズは大きくはならない。かな?
仮想メモリー上のサイズは当然大きくなる。
881 :
デフォルトの名無しさん :2008/08/26(火) 00:20:37
>>874 main関数にあるものとorigiなんとか関数でのcountは
変数は別物なので、変更は反映されないんです
中身の数値が代入されて扱えるだけなんです
なのでreturn使ってがんばってください
もしくはグローバル変数で
882 :
まつせ :2008/08/26(火) 00:20:55
#include<stdio.h> #include<string.h> #include<stdlib.h> #include"binary_node.h" int count; //単語数 int print_menu(void); int load_dicdata(char *filename,char eng[][256],char jpn[][256]); void print_array(char [][256],int); struct node make_leaf(char *eng, char *jpn); void print_leaf(struct node *leaf); void make_tree(struct node *root, struct node *node); void print_tree(struct node *root); int store_dicdata(char *filename, struct node *root); void original1(char [][256], char [][256], int *count); int original2(char [][256], char [][256], int *count); void original3(int tokuten, int *count); struct node; void main() { int menu_num; char eng[20][256]; //英単語を格納 char jpn[20][256]; //英単語の対訳(日本語)を格納 struct node root = make_leaf("", ""); struct node leaf[20]; int i; int data_num; int tokuten=0;
質問なのですが、8進数で書かれた数字を10進数に換算するコツみたいなのってありますでしょうか? 16進数を10進数に換算と違って計算しづらいです。 もしかすると早見表みたいなのが存在してたりします?
884 :
721 :2008/08/26(火) 00:24:25
早くファイルオープン学びたいな。 ファイルオープンは本の最後らへんにあるから、最後に学ぶ物だと思うんですが。 ポインタの方が大事ですか? 最後に載ってる物の方が難しいと感じるんですが。 この掲示板の方がとても親切で本当にありがたいです。
885 :
まつせ :2008/08/26(火) 00:24:46
while(1) { menu_num = print_menu(); switch(menu_num) { case 1: count = load_dicdata("dicdata.txt",eng,jpn); if(count == -1) //ファイルの読み込みに失敗した場合 { printf("読み込み失敗\n"); return; } printf("読み込み成功\n"); break; case 2: print_array(eng,count); print_array(jpn,count); break;
>>884 fopenはポインタの概念を理解してないとイミフだよ?
>>883 8進数も16進数も兄弟みたなものだろ
プログラムをやって16進数になれてるからそう思うだけだ
>>883 二進数にしてから直せばいいんじゃないか。
>>まつせ
うざいから長くなるなら、どっかロダにあげろ
#include<fuck.h> #include<penio.h> int fuckup(){ anal.fuck(&pennis); Destroy(anal); };
8進数の一桁=2進数の3bit 16進数の一桁=2進数の4bit あとはわかるな?
891 :
721 :2008/08/26(火) 00:32:16
>>886 たしか fopenって*がついてましたね。
time *とか難しそう。
>>887 プログラムで16進数とか使えるんですが、使う機会ってあるんですか?
10進数を16進数に変換するツールとかで使ってそうですが
省略することによってメモリどうたらとかなんかメリットありますか?
>>891 >プログラムで16進数とか使えるんですが、使う機会ってあるんですか?
>10進数を16進数に変換するツールとかで使ってそうですが
>省略することによってメモリどうたらとかなんかメリットありますか?
C言語やってる上ではプログラムの内容次第では16進数はあまり縁がないかもね〜
アセンブラ(つーかハンドアセンブル)やってると16進数と仲良くならないとやって
いけなかったので16進数で暗算できたりしたな〜
今は簡単な計算しかできない^^;
893 :
まつせ :2008/08/26(火) 00:35:32
894 :
まつせ :2008/08/26(火) 00:36:33
パス1289
>>883 キリのいい数字を覚える
10 8
100 64
1000 512
10000 4096
・・・・・
3571だと、3*512+64*5+8*7+1=913
896 :
721 :2008/08/26(火) 00:40:17
>>892 アセンブラは組み込みと聞きましたが、アセンブラとかやったことないし。
命令がなんかSQLみたいで難しそうです。
それとプログラマーに転職したいと思ってるんですが。
ここでは皆さんレベルが高いこといってて、入門書読んだくらいじゃプログラマーなんてできないでしょうか?
やっぱりそれぞれの作る場所によって、教えてくれるんですか?
プログラマーって内容がイマイチなので、入門書にでてくるようなことをやってソフトを作るのかそれとも、
社員の方と協力して作るんでしょうか? もしかしていきなり、医療の通信する物をつくってくださいとか
押し付けられて一人でつくるはめになったりするんでしょうか?もうさっぱりです。
ITドカタ
>>873 の者です。
>>875 さん
>>880 さん ご回答ありがとうございます。
スタック領域とヒープ領域に関しては衝突しないということだったのですが、私が参考にしていたサイトでは
>スタックは高位のメモリアドレスから、低位に向かって伸び、ヒープ領域は逆に、低位から高位に向かって伸びて行くことに、注意して下さい。
>スタックとヒープは衝突する事もあり得ます。この場合プログラムは破壊されます。エラーも警告もなくコンパイルできるが、実行時に異常がでる時があります。
とあったのでmallocでメモリを多く確保し過ぎるとスタック領域の所までメモリが来てしまい衝突してしまうのかと思っておりました。
http://www1.cts.ne.jp/~clab/hsample/Point/Point19.html ということはヒープ領域というのはどんだけ malloc でメモリを取ってもスタック領域分のメモリと衝突する事はないということでよろしいでしょうか?
>>880 >> あとstatic変数って多く宣言するとプログラムサイズも大きくなりますかね?
>ファイルサイズは大きくはならない。かな?
>仮想メモリー上のサイズは当然大きくなる。
static の取り方によるんじゃないかな。
static int i;
static int j = 0;
static int k[10];
とかC言語仕様上ゼロクリアされるstatic領域ならstatic initializerでゼロクリアする
"コード"になるけど、
static int i = 1;
static int j[10] = {0,1,2,3,4,5,6,7,8,9};
とかなら、データ領域に 1,0,1,2,3,4,5,6,7,8,9 を"持っておいて"、同じく
static initializer内でmemcpy するようなコードになると思われる。
static でゼロ以外の初期値盛りだくさんだとコード増えるかも。
>>898 そのメモリの概念はまさしく俺がハンドアセンブルしてたころの
PC9801とかだなあ・・・
あのころはスタックエリアはまさしくSSレジスタ(だっけ?)
がスタックの位置を管理しててpop push命令で位置が変わってた。
で、そのサイトのように確かにアドレスの上位から下位に向いて
使うんだわ。
で普通のヒープと呼ばれるアプリケーション用のメモリは下位のあいてる箇所から確保。
でもいまどきのwindowsとかのアプリであればそんなので衝突なんてありえないから
マイコンとかくらいじゃね?
static double d[10000000]; とかにするとEXEのサイズが 大きくなってワロス
実行時にゼロクリアするとか工夫を凝らした処理系ないのかな
>>899 >>900-
>>902 さん 回答ありがとうございます。
それでは static変数については 使い方次第でプログラムサイズは大きくなるということですね。
あとスタック領域とヒープ領域の衝突については昔のコンピュータであれば起こっていたが、windows のアプリであれば衝突は起こらないということですね。
ありがとうごいざいました。
おお〜 なるほど そういった便利な数の考え方があるんですね。 でも進数別早見表とか使ってる人もいるんじゃないかと思うのは邪推ですか?
つ windows の電卓を関数電卓モード あと8進数と16進数は基本的に2進数にすぐに置き換わるので ビットレベルで足し算すればすぐでしょ
一旦2進法を介さないと変換できない俺のような人間もいる。
でっていう
>>886 printf とか scanf はもっとイミフだよ
しょっぱなから出てくるけどw
>>901 >>902 なんで、領域分exeが大きくなるんですか?わけわかりません
ためしに、コンパイルしてみましたがそんなに増えないです
なにかおかしいのでしょうか
>>911 増えない処理系もあるよ
BSSを起動時にクリアする賢い処理系ならね
ただstatic領域と言っても初期化の値がゼロとは限らないから
大抵実行イメージ内にコピーを持ってて起動時に転送する
全部ゼロなら最適化してくれる処理系があるって事でしょ
関数ポインタのようにgotoのポインター配列のようなのって可能なんでしょか? switchだと内部的にはif {} else if {] ・・・の繰り返しだと聞きますが これだとムラがありますし、関数だと呼び出し戻りでコストがかかります。
switchも、内容によってはテーブルジャンプにするよ。もちろんコンパイラ次第だけど。 で、gotoのラベルは、テーブルに出来ない。 やるとしたらアセンブラレベルにするしかないね。 ところで、間接ジャンプは、分岐先が前回と同じでかつエントリに残っている、というケース以外 必ず分岐予測ミスになるって知ってた? まあ、Pen4を前提とするとかでない限り、そんなに気にするもんでもないかもだけど。
915 :
側近中の側近 ◆0351148456 :2008/08/26(火) 07:14:13
>>832 (っ´▽`)っ
じゃあ、'\0'をなんと読むんだよ。
「ぬるもじ」じゃないのか?
>>915 ナル文字。
>>912 static int foo[100]とstatic int foo[100] = {0}で違うセクションに配置されて違う初期化を行なわれる環境は多いね。
'\0' ヌル文字 NULL ヌルポインター /dev/null ヌルデバイス
>>915 「ぬるもじ」で構わないけど、「NUL」な。「NULL」じゃないぞ。
null ━━ a. 無効の; 重要でない, 無価値[無意味]な; 存在しない; 【数】ゼロの; 【コンピュータ】ヌル, 空の. null and void 【法】無効の. ━━ n. 【数】ゼロ. null character 【コンピュータ】空文字. null code 【コンピュータ】ヌル・コード. null cycle 【コンピュータ】ヌル・サイクル. nul・li・fy ━━ vt. 無効にする; 無価値にする; 取消す. nul・li・fi・ca・tion n. null instruction 【コンピュータ】空命令. nul・li・ty ━━ n. 無効; 【法】無効なこと[物]; 皆無; つまらない人[物]. nullity suit 婚姻無効訴訟. null list 【コンピュータ】空リスト. null method 【工】零位法. null modem (cable) 【コンピュータ】ヌルモデム(ケーブル). null operation 【コンピュータ】空操作. null set =empty set. null string 【コンピュータ】空文字列.
>>895 ありがとうございます。 一番しっくり来る考え方です。 HDDやメモリの計算でなれているからでしょうか?
>>906 >あと8進数と16進数は基本的に2進数にすぐに置き換わるので
ビットレベルで足し算すればすぐでしょ
すいませんできれば例題をお願いします。
俺の予想している計算法だとすると・俺の頭だとするとむしろ3bitと4bitを前提に計算すると余計計算が辛いのです。
8 64 512 を目安にした方が計算が楽なのは俺が10進法世界の住人属性を未だに強く持っているからでしょうか?
>>921 頭の柔らかさの有無だろ。
8進は16進に変換した方が私も楽だな。
色を扱っていると17の倍数も覚えちゃうしね。
# 0x11(=17)、0x22、0x33、……0xff
# htmlの216色で使うのは0、0x33(=51)、0x66、0x99、0xcc、0xffの6階調。
NULL文字をASCIIコードの略記法でNULと書くことはある。 SOH ACK CAN NAK とかと同様に
ポインタのNULLと混同するから'\0'をnullとかNULとか呼ぶべきでない。 一時期EOSという呼び方があって良かったのだが廃れてしまったな。 「エンゼロ」とでも呼ぶのが良さそうだ。
質問です。 複数個の文字列を渡して、渡した先では変更しない場合、 宣言側で「char *var[MAX];」とかやってvar[0], var[1], ... にポインタを格納し、 関数fooを「void foo(const char** arg);」とか宣言して、実行箇所で「foo(var);」として、 gcc -Wallでコンパイルすると passing argument 1 of 'foo' from incompatible pointer type とかいう警告が出ます。 constを省略して「void foo(char** arg);」 とすると警告は消えますが、foo内でargは壊さないので、constを省略したくありません。 たぶんconstの場所が間違ってるんだと思いますが、正しい場所を教えてください。
>>922 なるほど ただ8進数を16進数に変換ってどういう計算式になるんでしょう?
私にはどうも思いつかないです。
10進数から頭がはなられられないTT
>>921 >8 64 512 を目安にした方が計算が楽なのは俺が10進法世界の住人属性を未だに強く持っているからでしょうか?
いや別に方法は人それぞれでいい気がするけど。
別に数学とかの問題で答えを導きだすとかそんなんじゃないんだし^^;
16進数だって10進数に変換する際は
16x16xa + 16xb + c
となるし
掛け算が面倒ならビットに分解して
ビットに当てはまる10進を足していけばいいだけ
1 2 4 8 16 32 64 128 ・・・・ なだけだしね
2進数に変換すると16進数も8進数も共通になるし
ちょっと考えてみたけどn進数→m進数変換もやってることは10進数変換と同じっぽいね ただm進のmm掛け算のテーブル(九九みたいな)とn一桁の数字のn→m変換のテーブルがないと手計算しんどい たとえば8進03751→16進だったら 010^0 * 01 = 0x8^0 * 0x1 = 0x1 * 0x1 = 0x1 010^1 * 05 = 0x8^1 * 0x5 = 0x8 * 0x5 = 0x28 010^2 * 07 = 0x8^2 * 0x7 = 0x8 * 0x8 * 0x7 = 0x1C0 010^3 * 03 = 0x8^3 * 0x3 = 0x8 * 0x8 * 0x8 * 0x3 = 0x600 ぜんぶたして0x7E9みたいなかんじで
ビットに分解ってどういうことでしょう?
8,64,512 とか 16,256,4096 よりも 010^1 = 0x8 010^2 = 0x40 010^3 = 0x200 010^4 = 0x1000 0x10^1 = 020 0x10^2 = 0400 0x10^3 = 010000 の方が変換しやすいってことだな
>>928 一番左の式は 2進法の時の式ですか? 時々そんな式を見るのですが俺には良く分かりません
=が一回はさまれてから理解できます。
特にキャレット計算に挟む段階でちょっと基礎知識が足りないです。
>>928 Cだと8進数は0123のように先頭に0をつけてあらわす
933 :
925 :2008/08/26(火) 13:22:39
8進数だか16進数だかの話はもう済んだんでしょ。 925に答えてください。
>>925 話長引かせてすいません。
俺には全然回答できないレベルなので返答もできなくてすいません。
でもできたらこっちもビットに分解とかのレスも欲しいです。
foo((const char **) var); でいいんじゃね?
936 :
925 :2008/08/26(火) 13:42:32
>>935 すいませんが、よくわかってない人の答えは要りません。解決にならないので。
>>925 変数宣言を const char *var[MAX]; にする
char** → const char** の変換はできない
プリプロセッサについて教えてください。 下記はどちらが組み込まれますか? #if 1 <hoge_a> #else <hoge_b> #endif 下記は組み込まれますか? #if 0 <hoge_c> #endif
>>932 「Cだと」と言ってしまうと、キャレット(^)をべきじょうの意味で使えなくなると思うが?
XOR演算してるわけじゃないだろ。
941 :
938 :2008/08/26(火) 13:54:40
いやまじめな質問です^^;
942 :
925 :2008/08/26(火) 13:57:52
>>937 おお、できました!!ありがとうございます!
const char *var[MAX]; として、 var[n] = "ABC"; とかはOKなんですね〜。
きっとvar[n][0]++;とかやると怒られるんでしょうね。
勉強になりました。
質問じゃなくて宿題の丸投げって白状しちゃえよ
>>938 上はエラー
#includeがあれば<hoge_a>が組み込まれる
下は組み込まれない
>>928 俺が手でやれって言われたら2進を介するな。
03751 = 11,111,101,001(2進)
= 111,1110,1001(2進) = 0x7e9
>>945 俺はやっぱり現在得意な方法でやった方がよさそうですね;
とりあえずcやる上でそんなに上の方に行かない限り現在のやり方で十分対処できそうだし。
てっきりはやみ表とかツール使うのが主流なものかと思ってましたよ。
皆さんちゃんと自前の頭で計算されてるんですね。
俺はWindowsの電卓を使う 自分で計算できても電卓の方が速い
>>948 ポチポチいいね
使わせてもらうよ
アイコンがださくて、速攻変えたけどw
明らかにプログラマーのアイコン手抜きっぷりにwwww
>>948 ありがたくいただきました
正直コンピュータにやらせられる事はなるべくやらせるべきですよね そもそも
人間が計算に煩わされないように開発されたものですし。
行列計算のライブラリって何があるの? ぐぐると エクスカリバーとかでてくるけど。 逆行列を計算したいだけなんだけどね 20x20の
meschachとか?
インストールの仕方をぐぐると ubuntu,debianとかの方法がでてくるけども。 vineでもできるのかな?
普通にアーカイブで貰ってきてmakeすればいいだけじゃないの
うむ。 中見ると、Cray、GCC、Linux、Microsoft、OS2、RS6000、SGI、SPARC、ThinkC、TurboC、WatcomPC に対応してるようだw
使えた?
./configure して make basic して自分でコピーして使うようだ。
./configure が通らなくても、自分でMACHINES/GCC/makefile コピーしてくりゃなんとかなるし
質問です。 先のレスと似た質問になるのですが、 「変数宣言とmallocでのメモリ確保でスタック領域とヒープ領域がメモリ領域内で衝突しセグメントエラーにならないためには何に気をつけるべきか」 という課題を出されているのですが、コレって ローカル変数の宣言ではstaticで宣言して変数を静的領域したり、 mallocでメモリ確保した場合は 処理が終わったらすぐに free で 解放する ということでよろしいでしょうか? 他にもスタック領域とヒープ領域でメモリ領域を取り合いにならない方法はあるのでしょうか?
>>963 すいません、そもそもヒープとスタックが衝突する状態ってのが想像できません。
>>963 PCじゃなくて組み込みかなにかでしょうか?
そうなんですか
>>963 参照してるページが古すぎます。
仮想メモリの無い時代はそういう事もあったでしょうが、
現在では仮想メモリがハードでサポートされているため、
異なるセグメントが物理メモリ上で衝突することが無いように
OSによって管理されています。
衝突するとしても、衝突する前にスタック領域とヒープ領域の限界ってのは有るんじゃないの?
>>966 そんなことになる前にページ違反で落ちるから安心しろ
>>966 そのサイトにあるプログラム実行してみたらわかるよ
今のOSだとスタックアドレス<ヒープアドレスだから衝突しない
普通スタックが無くなってエラーで終了
巨大な領域をmallocしたらmallocでNULLがかえるだけ
Q 「変数宣言とmallocでのメモリ確保でスタック領域とヒープ領域がメモリ領域内で衝突しセグメントエラーにならないためには何に気をつけるべきか」 A スタック領域とヒープ領域は別になってるので衝突しません スタックやヒープが足りなくなることはあります
みなさんご意見ありがとうござます。 しかし、課題を与えている先輩に聞いた所、ヒープやスタックは同じメインメモリに格納されているので衝突するはずというお話なのですが、 今のOSって割り当てる領域は別になっているというコトでしょうか? (ちなみにそのサイト2005年ですが、当時のPCは割り当てないということですか?) ちなみに私、VCがないのでそのプログラム実行できません。すいません。
衝突してから言え
ハードウェアに依存する問題はそもそもCでは扱いきれない
・スタックを使いすぎない とか ・ヒープを使いすぎない とかでいいんじゃないの。
つ【全部グローバル変数にしろ】
というかCの規格的には衝突してはいけないんじゃないの(確保できないことはあっても
mainの中で書いてもstatic付いてないとスタックに一時エリアは取るんだっけ? 以前このスレでスタック食いつぶしてフリーズしてハマってる奴が来てたな。 そりゃスタックにdoublex10000超える配列入れれば・・・ そういうの以外まず衝突はありえんけどなあ。
そういうのも、実はヒープと衝突しているわけじゃないね。
>>973 そのサイトにのっている「セグメントエラー」は、スタック領域とヒープ領域の衝突でなくて
スタック領域をこえたことによるオーバーフローではないかと思う。
次スレそろそろいる?
>>983 いやセグメントの概念をやかましくいうのは8086モード下くらい。
それ以外のCPUってそんな面倒な概念あんまりないやろ。
特に最近のは・・・
>>984 よろしこ
>>985 そのセグメントでなくて、Segmentation Fault
987 :
984 :2008/08/26(火) 23:30:59
たてれんかった、だれかよろ
アクセス例外だな
989 :
デフォルトの名無しさん :2008/08/26(火) 23:35:44
例とかでは、次々に改行しているが やってみるとどぅ改行すればいぃかわからん。。。。 エンター押すとわけのわからないものが・・・・orz
ここはエディタの使い方のスレじゃないんだけど
セグメントレジスタ、huge ポインタ、far ポインタ懐かしい 今思えば無駄に大変だったな
>>994 今思うと、IntelとMSにいいように引っ掻き回されていたということだな。
ナルポ
クワッ
プリントエフ
はじめてのC ってどんな感じですか? うめ
1000
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。