,.―――‐ 、 / ,.―`.ヽ / | /:/: :ィ: : : : :\ / .f⌒h/`:/l:/^\:/l:/: :|` ゲ な 〈 _! l /ムl: :/ _ '^jノ| ソ .ん _| 人_|: l ,, ̄ =l: |,_ ?. で {:::_~,.:::}」: |. 「 7 '''}!::::|__ / /.,.=、|:!:.ト . l_/ ,.ィ_└┐:|__ ( └勹ノl:| |\、 // '|!V〉\;/
すみません前スレのスタックフレームの者ですが、 局所変数は関数呼び出し時に、スタック領域に確保されるということでおkですよね。 局所変数の大きさはソース見ればわかる、という回答者の方もいますが 実行時にソースを読んでいるわけではないですよね。 そうするとコンパイル時に大きさを求めて、そんで実行時、スタック領域に 局所変数に必要な大きさのフレームを確保する必要があると思うのですが その大きさは、、、やはりどこから求めているのかわかりません。
>>3 コンパイル時に変数の個数はわかってるだろ。
>>3 局所変数は関数内で有限個だから、コンパイル時に種類と個数を(どうにかして)数え上げれば、スタック上に準備すべきサイズもわかります。
実行時に求めるわけではありません。コンパイル時に判明することです。
どうにかして数え上げればっていうか、どの型の変数が何個使われてるとか ばっちりわかってないと、コンパイルできないだろ。 C99は実行時に配列の長さを指定できるけど、べつにそういうの気にしてるわけじゃないよな。 質問者は。
>>5 > スタック上に準備すべきサイズもわかります。
それはコンパイル時に判明したサイズですよね。
実行時もそのサイズを知る必要があると思うのですが、どこにあるのですか。
実行バイナリファイルにあるのでしょうか。
プロセスの仮想空間にロードされた後もわかるのでしょうか。
>>3 スタックの大きさは決めうち
コンパイルオプションで変えられる
実行時に呼ばれた関数が必要としている分だけ
スタック領域を準備しようとするけど実行時に不足していればスタックオーバーフローで止まる
再帰関数で油断してたり、巨大な配列を自動変数で確保しようとしたりするとよく起こること
9 :
5 :2010/03/05(金) 23:56:51
>>6 んー、確かにC99可変長配列の扱いはありましたね。
>>7 コンパイル時に自動変数に必要なサイズが判明しておれば、それにしたがってスタックポインタを変化させるコードをコンパイル時に生成すればいいのでは。
実行時にあらためて自動変数のサイズを求める必要はないはずです。仮想メモリの話は関係ないと思います。
>>10 つまり、局所変数のサイズが300バイトだとしたら
スタックポインタ = (現在の)スタックポインタ + 300バイト + その他情報の大きさ
みたいな命令を、関数呼び出し毎にしているってことなのでしょうか。
質問ばかりですみません。
>>11 まちがえた。add sp, -12 だな。
>>11 なるほど。少し納得しました。
これで寝られそうです。みなさん、ありがとう。
15 :
デフォルトの名無しさん :2010/03/06(土) 00:34:25
17 :
デフォルトの名無しさん :2010/03/06(土) 00:39:17
こんな板でも貼る奴いるんだな
寝る前に見てしまった...orz
>>15 とにかくグロ注意
みゃくらくは不明だが...
(誰か削除依頼したほうが良さげ)
20 :
デフォルトの名無しさん :2010/03/06(土) 01:34:21
そんなもんどうでもいい
21 :
デフォルトの名無しさん :2010/03/06(土) 01:36:47
コラなんか要らんわぼけ
アセンブラを勉強すれば関数呼び出し時のスタック操作とか自分でやるから理解が深まるけどな。 しかし、なんでここまで気にするんだろ?
24 :
デフォルトの名無しさん :2010/03/06(土) 12:13:05
たぶん自分独自のコンパイラ開発しようとしてるんだろ。ううんきっとそう
エラー時にスタックトレースを出力したいとか
>>23 ここまで気にする人だから、Cを学ぼうとしているんだろう。
低レベルに興味ない奴はVBとかJavaに行くだろ。
知らなくても察しが付くことだけどな
そうか?それって天才じゃね?
問題: 配列a[10]に対して、以下のコードと同等の結果になるコードを、gcc c言語のインラインアセンブラによるSSE3を駆使したコードで書け なお、long long型のサイズは8バイト。 4 long long a[10] = { 0x1234L, 0x5678L, 0x9012L, 0x3456L, 0x7890L, 0x1234L, 0 x5678L, 0x9012L, 0x3456L, 0x7890L }; 5 6 int i=5; 7 do{ 8 *(a+i+0) *= 0x3L; *(a+i+1) *= 0x3L; 9 i--; 10 }while( i > 0 ); という問題があったとして、答え合わせの解答集を無くしてしまったとして、答え合わせにこまってます。 ここの住人の方々は、みんな超スーパーハカーぞろいだという噂を聞きました。 どうか皆様がたのウルトラハイパー知識をくしして、この超難問の答えを導き出していただけませんでしょうか…! よろしくおねがいします。
4 long long a[10] = { 0x1234L, 0x5678L, 0x9012L, 0x3456L, 0x7890L, 0x1234L, 0 x5678L, 0x9012L, 0x3456L, 0x7890L }; 5 6 int i=10; 7 do{ 8 *(a+i-0) *= 0x3L; *(a+i-1) *= 0x3L; 9 i--; i--; 10 }while( i > 0 ); すみません、こうでしたw
>>29 なんでお前に命令されなきゃいけないわけ?
33 :
デフォルトの名無しさん :2010/03/06(土) 17:23:15
その前にいくらよいしょしてもここにそんなに知識のある奴はいないと思うが。
おれ
>>32 だけど、ちょっと頭がおかしくなってた。
ごめんな。
> 問題があったとして、 解答集を無くしてしまったとして そもそも仮定からしておかしい
つーか >インラインアセンブラによるSSE3を駆使したコード どういう頭の構造だと、これが C の質問だと思えるのかと。
/* sayHello() 関数へのポインタ */ void (*func)(void) = sayHello; このとき、'func()' と '(*func)()' の違いって何ですか? 結果は同じなのですが...
281 名前:デフォルトの名無しさん[sage] 投稿日:2007/11/08(木) 00:27:05 関数ポインタって代入時の&と実行時の*ってなくても動作変わらないよね? もともとはどっちが正しいの? 282 名前:デフォルトの名無しさん[sage] 投稿日:2007/11/08(木) 01:06:42 元々必要だったらしいが、gccがなんか理論武装して独自拡張として省略しても良くしたら、 世間に受け入れられたなんて話を聞いたことがある。
↑ ありがとう.
#include <stdio.h> int main () { unsigned long long a[10]={ 0x1234111111111111L, 0x5678000000000000L, 0x9012000000000000L, 0x3456000000000000L, 0x7890000000000000L, 0x1234000000000000L, 0x5678000000000000L, 0x9012000000000000L, 0x3456000000000000L, 0x7890000000000000L }; unsigned long long b[2]={3,3}; printf("3a={%llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx}\n", a[0]*3,a[1]*3,a[2]*3,a[3]*3,a[4]*3,a[5]*3,a[6]*3,a[7]*3,a[8]*3,a[9]*3 ); unsigned long long* ap = a; unsigned long long* bp = b; int i=5; while(i-->0){ asm volatile ("\ movdqa (%0),%%xmm0;\ movdqa (%0),%%xmm1;\ paddq %%xmm1, %%xmm0;\ paddq %%xmm1, %%xmm0;\ movdqa %%xmm0,(%0);\ " : "+r" (ap) : "r" (bp)); ap++; ap++; } printf ("3a={%llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx}\n", a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9]); return(0); }
41 :
40 :2010/03/06(土) 21:57:23
を実行したら 3a={369c333333333333,368000000000000,b036000000000000,9d02000000000000,69b0000000000000,369c000000000000,368000000000000,b036000000000000,9d02000000000000,69b0000000000000} 3a={369c333333333333,368000000000000,b036000000000000,9d02000000000000,69b0000000000000,369c000000000000,368000000000000,b036000000000000,9d02000000000000,69b0000000000000} ってなりました… 意味が分かりません… 動くはずないのに… なんで動いてるんですか…(orz
42 :
デフォルトの名無しさん :2010/03/06(土) 22:57:36
WindowsNT系のコマンドをC言語で呼び出す方法を教えてください。 dirなどのコマンドを呼び出す方法を教えて欲しいです。 仮に代替できるWin32APIやC言語の関数があったとしても、dirを直接呼び出す方法を教えてください。 よろしくお願いします。(dir以外の他のコマンドも将来的に呼び出したいため) 環境はWindowsNTだけサポートしてれば大丈夫です。
systemとか winexeとか dirだけでいいならopendirとか
_poepn
CreateProcessだろ DOS画面出さず出力をメモリに入れられる
const と define の違いが今ひとつわからない どっちも定数を定義するんだよね?
C言語でrailsのActiverecord 作ってくださいお願いします
自分でやれよ
51 :
デフォルトの名無しさん :2010/03/07(日) 10:37:04
>>47 define ・・・最も古くから使われている
enum ・・・ヒゲさん曰く見えない圧力に押されて追加、いまいちらしい
const ・・・禿と共同開発
定数を返す関数という手もあり
これが実は最も融通が利く
defineはコンパイル時に置き換えてくれるだけ だからマクロとして使えるし、関数丸ごとdefineしてみるとか変なこともできる __LINE___や__TIME___みたいなコンパイル時に決まるやつもある 事項時はもうすでに置き換わっているのでaaaaとかって名前でdfineしてデバッカでaaaa探してもない constはメモリ上に固定でそいつがずっといるだけ つまりデバッカで値も見れる
おれ52だけど なんでアンダーバーが3っつなんだろ??
コンパイル時というかプリプロセス時
キーリピート間隔を短く設定していたんじゃないのか
57 :
デフォルトの名無しさん :2010/03/07(日) 11:12:23
8bitのデータで、 6ビット目が1になったら他のビットが1でも0でも関係なく特定の処理をする動作はどのようにすればよいでしょうか。
& (1 << 5)
if(data&0x20){ 特定の処理 }
ループを使わずに配列の順序を逆にせよ。 という問題は、ループ制御構造(whileやfor)を使わずに、という意味でいいのかな? 関数の再帰呼び出しでもできそうだけど、goto文使ったらだめ?
>>60 それはCの問題ではなく日本語の問題じゃね?
どういう意図で書いたのかを書いた人に聞けよ
>>61 このホワイトボードプログラミングのところ:
http://japan.zdnet.com/sp/feature/07tenthings/story/0,3800082984,20409456-2,00.htm
一応、こんな感じで(^^
int *
reverse(int ary[])
{
int i = 0;
int j = SIZE - 1;
int tmp;
loop:
if (i >= j) goto end;
tmp = ary[i];
ary[i++] = ary[j];
ary[j--] = tmp;
goto loop;
end:
return ary;
}
gotoつかってもループだろ
goto文はループ制御構造ではないんですよね。 だったら「ループを使わずに」じゃなくて「再帰を使って」、と書けばいいのに。。
たぶん出題意図としては、再帰を使ってほしいんじゃないかね Cというよりは関数型言語でやらせるような問題
>>62 答え出てるぞ
* ループを使わずに配列の順序を逆にする。
答え:順次、配列を画面に表示して行ってオペレーターにメモさせておき、
メモした値を逆順に入力するよう促すダイアログを出す。
画像の範囲内をマウスのクリックで判定させるにはどのような考え方をすればよいのでしょうか? 参考サイトがあれば紹介して頂きたいです。
UNIX環境でVCの代わりになるような物ってないですかねぇ
69 :
デフォルトの名無しさん :2010/03/07(日) 13:34:37
VC のどんな特徴の「代わり」ができればいいんだ? VC そのものなら Xen という手もある
>67 その画像が矩形なのか矩形以外の多角形なのかで変わる >68 Anjuta, Emacs, Geany
>>71 ドラッグして範囲選択みたいな感じ?
考え方っていうか、サンプルコード見たほうが早いんじゃない?
マウスダウンのイベントでマウスカーソルをキャプチャして、マウスの
ボタンが離されたれらそこまでが選択範囲だけど。
単にヒットした座標か画素が欲しいだけだろ
範囲選択ではなく、画像のスイッチのような感じです。 一定の矩形の範囲内をクリックすることで、処理が行われるようにしたいと 思っています。
ゲームでも作りたいんじゃないの 確かやねうさんはビット演算でやっていたな 自分で紙に矩形とポイントを描いて条件を考えてみれば自ずと答えが見えてくるよ
マウスの位置と矩形の位置を取得しておいて 矩形の上境界線と下境界線の間にマウスの縦座標があって 左境界線と右境界線の間にマウスの横座標があればいいだけじゃないの?
left <= x && x <= rignt && bottom <= y && y <= top
>>67 むかしBMPファイル(って予備領域とか拡張可能になってるから)に勝手にホットスポットっていうか
クリック可能位置を付け足してクリックすると話が進む紙芝居、見たいなの作った
言語も環境も書いてないからあれだけど
クリッカブルマップ、とかでググってみるとなんとかくやり方わかると思うよ
あとは環境しだいで同じ様な事を違うやり方でやれば
様々なご回答ありがとうございます。 全て参考にさせて頂きます。
>>68 : kdevelop (書こうとしてる字を予測して、自動補完してくれるからラクちんです)
>>71 : 三角形がいっぱいあるとおもってやるほうほうもあるみたいですよ。
double OuterProduct(
double ax, double ay, double az,
double bx, double by, double bz,
double cx, double cy, double cz
) {
double Ax=bx-ax; double Ay=by-ay; double Az=bz-az;
double Bx=cx-bx; double By=cy-by; double Bz=cz-bz;
double opx = (Ay*Bz-Az*By); double opy = (Az*Bx-Ax*Bz); double opz = (Ax*By-Ay*Bx);
return opz;
}
B
A △ C
3角形ABC の中に、点P が「中かな?外かな?」ってのを知りたいときは、
「AB と P」、「BC と P」、「CA と P」 の3つについて、この関数で調べてみて、戻り値が3つとも全部プラス、または3つとも全部マイナスなら
点Pは 3角形ABCの内側ってことらしいです。 なんでか理由はよくわかりませんがw
符号1 = OutarProduct( Aのx座標、Aのy座標, 0、 Bのx座標、Bのy座標、0、 Pのx座標、Pのy座標、0 );
符号2 = OutarProduct( Bのx座標、Bのy座標, 0、 Cのx座標、Cのy座標、0、 Pのx座標、Pのy座標、0 );
符号3 = OutarProduct( Cのx座標、Cのy座標, 0、 Aのx座標、Aのy座標、0、 Pのx座標、Pのy座標、0 );
if( 符号1と符号2と符号3が、3つともプラス。 または3つともマイナスなら){ 点Pは、さんかっけいABCのうちがわ♪ }
ってなるみたいです。 なんでか理由はよくわかりませんがw こんど算数の先生に聞いてみまーす。
外積で左右判定してるんでしょ
>>67 三角形の内部の点かどうか判定するプログラム
#include<stdio.h>
#include<math.h>
int is_inner(double ax, double ay, double bx, double by, double cx, double cy, double px, double py)
{
double Ax, Ay, Bx, By, Px, Py, alpha, beta, divisor;
Ax=ax-cx;
Ay=ay-cy;
Bx=bx-cx;
By=by-cy;
Px=px-cx;
Py=py-cy;
divisor=Ax*By-Bx*Ay;
if(fabs(divisor)<1.0e-6) return 0;
alpha=(By*Px-Bx*Py)/divisor;
beta=(-Ay*Px+Ax*Py)/divisor;
if(0.0<alpha && alpha<1.0 && 0.0<beta && beta<(1.0-alpha)) return 1;
return 0;
}
int main(void)
{
printf("%d\n", is_inner(1.0, 2.0, 2.0, 1.0, 1.0, 1.0, 0.5, 0.499));
return 0;
}
83 :
デフォルトの名無しさん :2010/03/07(日) 21:51:15
再帰的アルゴリズムの利便性がわかりません。 下手をすればスタック領域が蓄積されていってメモリ不足に陥りますよね。 再帰を使わなくても他に解決できる手段があればみなさんはどちらを選択しますか
ほらループなしで処理が書けたよ!と頭よさげにアピールできる 問題領域そのものが再帰的なら可読性と保守性があがる C言語ではあまり利点がないので他の手段で頑張る 関数型言語とかだとまた別の話しになる
>>83 利便性っていうか、再帰的な処理は再帰で書いた方がわかりやすいな。
関数に状態を持たせるのがどうじゃこうじゃ 逆に再帰で書いているのを繰り返し制御などで書き直す方が頭良さげ 最近再帰使ったのはビット単位でファイルに書き込む関数の下請け関数だわ
本物のプログラマは自己書き換えプログラミング・コードを記述する。 そのことにより再帰アルゴリズムを使うのに比べて20ナノ秒も実行時間が改善される どうしても再帰なんつう場面は数年に一度 それ以外は、再帰アルゴリズムがぱっとわからないと馬鹿にされるという理由だけで使用する プログラマってそんなもん
89 :
デフォルトの名無しさん :2010/03/07(日) 22:52:19
再帰は、数学の階乗を求めるプログラムをかじった程度です。 可読・保守性があがるという利点は納得です。 逆にプログラマが再帰プログラムを創り出すほうが大変そう。 階乗求める以外に再帰を使ったほうがいいケースは思いつきにくいですね
階乗こそ単純ループで十分で再帰にする必要なんてないんだが。
無向グラフの経路探索とか再帰使わないと面倒でやってられんけど
>>89 ディレクトリをおりていく処理とか、ループで書くとめんどくさいだろ。
教材としてあげるにしても、せめてユークリッドの互除法とか、フェボナチ数列(など漸化式)とかが出てこないものか
再帰関数の教材ならハノイの塔の問題を解く奴が好き
他人のコードで見つけるとループに書き換えられないかと難癖付けてみたくなる要素 自コードと同じスタックでライブラリ的利用させてもらう場合特に
組み込み系だと、変数を取れるキャパが決まってたりして 「お、スタックが空いてる再帰でなんとかしろ」とかあるよ
>>89 再帰だとシンプルに書けるものはたくさんある。
もちろんスタックオーバーフローには注意が必要だけど、
プログラマの差ってのはこういうところから来るんだと思う。
例えば、テキストファイルの行を逆順に出力する(いわゆるtacコマンド)
を作ろうとすると、再帰だとこんなにシンプル
#include <stdio.h>
void rev()
{
char buf[1000];
if(fgets(buf, 1000, stdin) != 0) {
rev();
fputs(buf,stdout);
}
}
main() {
rev();
}
>>99 再帰関数で大きな自動変数の配列を使うのはナシだろ
なにこの制限だらけのtac
>99 これは再帰の悪い例としていつか使わせてもらう
>>再帰 文字列の中から、正規表現によって単語検索をする場合、正規表現の文字列の並びを、配列から、一旦、順序木の構造に変換してしまって、 木のノードを順番に辿りながら、文字列を検索していくと、一連の検索を、共通の操作であつかえて簡単だとおもいます。 たとえば括弧で囲まれて1まとめになった複数条件も、あるノードの子としてまとめて、”あるノードの子というひとまとまりの単位”であつかえるので、 たとえば単純な ”A" という条件も、複雑な ”[AかBかC]”みたいな括弧で囲まれた条件も、どちらも同一の「”このノード”を使って検索する」という操作で扱えます。 これが再帰を使って得られる簡単さという恩恵だと思います。 簡単に素直にするために再帰を使うんだと思います。 たとえば括弧に囲まれた複数文字も、囲まれてない単一文字も、どちらも同じように考えて検索できるのだから、 木がどんなに複雑な形をしてても、逆にどんなに単純な形だとしても、 どちらも同じ要領で「”このノード”を使って検索する」という共通の操作だけで最後まで処理できます。 この順序木を巡っていくという操作を、単一のループだけでやろうとすると、 「さまざまな形の木を想定」して、それぞれに専用の動作を書いたりするケースが出てきやすいと思います。 (たとえば "A"の場合と "[AかBかCか]"の場合とでの動作の違いを、「わざわざ専用に用意」しないといけいない。などのメンドクササ。 これがループだけでやる場合のメンドクササだと思います。) だけど、純粋に繰り返しの処理速度だけでみれば、やっぱり for ループみたいなモノの方が優れてるような気がします。よく知りませんが。 普通はループで十分事足りるので、たとえば「シンプルな int[1000] の配列全部に0を代入する」だけのことに、わざわざ再帰を使う必要は無いと思うし、 無理やり再帰なんか使ったら、逆に、わかりづらくなるだけだろうし、わかり辛いとミスも増えますし。 あたりまえですけど、「より簡単に、より素直に書ける方」を選んで使えばいいだけのことかとおもいます。どっちも便利だとおもいます。
Cの場合、非再帰で記述(スタックを自前で構築ってのは この場合反則になるんで)できる位の力量が無いのに 再帰(間接再帰を含む)を使いまくったコードを書くと 後で地獄を見る可能性も視野に...
>>104 よく分からん縛りだけど
人に強要するのは勘弁してね
ライブラリ、長く使うものに再帰はないな。 どこがスタック積まれるか判らないし、スタックオーバーフローもいつ起こるか特定できない。
108 :
107 :2010/03/08(月) 18:48:09
失礼、行を単位に逆になるという意味だったんですね。ちゃんとうごきました。
1行毎に1000バイトずつスタックに積むとか使えない。 手元にあるテキストは、1行当たり数キロバイトとか逆に数十万行とか普通にあるんだが。 まぁ発想方法としては、悪くないんだけどね。
一行読んで、それを連結リストで繋いでおく方がいいな。 それでもファイルサイズが大きすぎると面倒だけど。 tacコマンドは、ファイルの末尾にseekしてから表示しているな。 seekできないストリームに対しては、テンポラリファイルにコピーしてから。 まあちゃんと読んだわけではないから詳しくは知らないけど。
111 :
デフォルトの名無しさん :2010/03/08(月) 20:21:44
Cと直接関係してる質問じゃないけど ソースを見れる形でファイルを上げれるcodepadのようなアップローダって他にある? なんか似たような感じで見やすいところがもう一つあった気がするんだけど
113 :
デフォルトの名無しさん :2010/03/08(月) 20:32:06
いや、もっと企業がやってるようなオシャレな感じで掲示板では無かったんだけど。 codepadみたいにソースが表示されてdownloadボタンが付いてる感じで
おおそれだ、探しても見つかんなかったんだありがとう。
言われてから探して見つけてきたけど
アップローダとか無駄なキーワード入れてたのが駄目っだのかな・・
codepadの類似サービスだから一緒くたに紹介されてると思って、はてブでcodepadと検索したら出てきた
#include <stdio.h> void rev(void) { char *buf; if ((buf = malloc(sizeof(char) * 1000)) == NULL) { fputs("memory allocate error.", stderr); exit(1); } if (fgets(buf, 1000, stdin) != 0) { rev(); fputs(buf,stdout); } free(buf); } int main(void) { rev(); return 0; } これでいいですか?
malloc()で動的に確保しても、領域計算量が大きければ意味なし。
最近も再起なんて使う?みたいなレスを見たなぁと思ったら図書スレでか まぁこの手の話題は定期的にあがるもんだけど
C言語って難しいんですか??
難しいの定義による。
>>122 文法自体はかなり簡単な部類
ポインタで躓かなかったらな
英語とかって、出来てたほうがいいですかね??
>>122 難しいともいえるしやさしいともいえる。
低機能の言語なので、文法自体はシンプルで覚えることは少ない。(やさしい?)
低機能の言語なので、なんかやろうとするとめちゃくちゃ手間がかかる。(難しい?)
>>126 出来た方がいいに決まってるが、
そんな質問するアホには必要ない。
>>126 読みやすいプログラムはそれ自体英文として読めるプログラムだから(俺流の解釈)
読みやすいプログラムを書くためには英語は必要。
英語のできない人が書いたプログラムは大変。
CにしてもJavaにしても英語圏の産物なんだな。
プログラミング言語は、アルファベット使うけど英語じゃなくて数学に近いな
>読みやすいプログラムはそれ自体英文として読めるプログラムだから こんなこというやつの変数や関数は長くてむかつく ReadDataFromUserFileToImageBuffer() みたいなやつ あるいはアンダーバーでつなげてみたりして 今時補完機能があるからへいきだろう、とか言い出してさ >読みやすいプログラムを書くためには英語は必要。英語のできない人が書いたプログラムは大変。 こういうこと言うやつは俺がnamaeみたいな変数とかyomikomi()みたいな関数作ると怒り出すよな いいじゃん、日本人なんだから日本語にしただけで読みずらくなったりしないよ と見ず知らずの129にすげえむかつく
英語できないやつのプログラムは、 childs とか serch とか、ありえないスペルミスがあって、読みにくくてかなわん。
いや読みにくいから
>>131 日本語があやふやなお前が言っても説得力は無い
俺が普段書くスクリプトなんて一文字変数、スペースけちって詰め詰めばっかりだよ
SQL?
>>131 ReadDataとToImageBufferが意味的にかぶってない?
UserFileというのもちょっと。
ReadImageFromFileじゃだめかい?
英文として読めるように、というのはよくある指針だね。
RiyousyaFileKaraGazouBufferHeYomikomi() とか書かれたらキレそう
プログラムが正しく動作して、開発スタート時に決めた関数の命名規約 (※腐ったルールだとしても)を遵守しているなら、あまり気にしないレベル
>>137 そうそう、こういう人
上記のやうは例じゃん、適当に作ったさ
それにたいしてまで、こんな事言ってくる
そういう点がむかつくんだって事
ReadImageFromFileじゃだめじゃん
長々と英文を関数名にしてるやつが居るよねって例としては短すぎる
ここは多少英語としておかしくても長くして置かないと駄目
JISYO のように複数のローマ字方式をミックスしたり、 JYOHO のような適当ローマ字で書かれているのを見るとためいきが出る。
readdata readdata2 readdata3 readdataEX readdataEX2 みたいにされるのもむかつく、混在してたりするとさらに
とりあえず読みにくいのはお断り 関数名は英語とローマ字のどちらかに統一されていれば気にしない 混在してるとイラッとくるが
>>140 シンプルだが単語のせいで長くなる場合は仕方ない
i18nのようにごまかすのもいいけど、やりすぎはよくない
複数の意味を含めた名前になるのならそれは関数化が足りない
つかもともとCは単語を略す文化だよね intもcharもbufだってそう memcmpとかやっちゃうし 昔の本とかのソース見るとインデントもあって目を細めると螺旋模様のように見える 今のソースはBASICのようにブロック並べたみたい
スパゲティコードより読みにくいという説もあるいわゆるうねりコードですね
文化じゃなくて制限。creatとか今思えばひどいもんだよね 端末に表示できる文字数の問題もあったし、環境に合わせてその辺は変化していってもいいと思うんだ
148 :
デフォルトの名無しさん :2010/03/09(火) 11:45:10
すべてローマ字で書くことに決めたとしても、簡単なカタカナ語をどうするか悩む どうしてもrisutoと書かなきゃいけないのか、listにしちゃいけないのか そして無意識のうちにlistと書いちゃってコンパイルエラー
>>148 両方やってみて違和感が少なかったほうにすればいいよ
あ、気に入らなかったらフォルダごと捨てれば大丈夫だから、神経質にならずにためせばいいよって意味も含んでるよ 最初は確かにいろいろそわそわしたなぁと思い出したので追記
ありがとうございます オフにしてやってみます
153 :
デフォルトの名無しさん :2010/03/09(火) 12:26:20
> 読みやすいプログラムはそれ自体英文として読めるプログラムだから COBOL 屋かてめーわ
154 :
デフォルトの名無しさん :2010/03/09(火) 13:52:42
他人のコードを改造しているんですが コードの量が大きいので一つの変数の型を変更するとそれに関連するものを変更する作業が大変です。 例えばint型だったものを制度をよくしたいのでdouble型に変えたとします。 それに関連する関数の戻り値や引数、代入される変数等、膨大な数になってしまいます。 なにか自動で型を変換する方法ってありませんか?
typedefしておけばいい
理解力がなくてすみませんがtypedefでどう解決するのでしょうか?
全部変えてしまうのは、まずいだろ 見ながら1こ1こかえるしかねーべ、そういうものとあきらめて
mozillaではパーザで構文木作ってそれを木の変換技法を使って自在に書き換えするっていうのを javascriptで作って、それをコードメンテに使ってるみたい dehydraとかいうやつだっけか
検討の例えで整数変数を実数に入れ替えにしてるのは 釣りかい?
んだなぁ
(x == y)みたいなのは、型を変えただけじゃだめだしなぁ
結局
>>157 しかないな
たとえばビット演算を使っていたりしたらアルゴリズムから検討する必要が出てくるので 自動でやるのはとても不可能だろうなあ。
, -‐−-、 ヽ∧∧∧ // | . /////_ハ ヽ< 釣れた!> ハ レ//j け ,fjlリ / ∨∨V ヽ h. ゚l; ハイイト、"ヮノハ // |::: j 。 /⌒ヽヾ'リ、 // ヾ、≦ ' . { j`ー' ハ // ヽ∧∧∧∧∧∧∨/ k〜'l レヘ. ,r'ス < 初めてなのに > | ヽ \ ト、 ヽ-kヾソ < 釣れちゃった!> . l \ `ー‐ゝ-〈/´ / ∨∨∨∨∨∨ヽ l `ー-、___ノ ハ ´ ̄` 〈/‐-、
すいません、苦Cの事を一通り覚えた後は何をしたらいいでしょうか?
>>163 アルゴリズムとデータ構造が少ない希ガス
コマンドラインで動作する素数判定プログラムprimeを作っているのですがうまくいきません。 コマンドラインオプションでの整数取得・切り分けがうまくいかないです。 助言お願いします。
166 :
154 :2010/03/09(火) 16:59:15
多くのレスありがとうございます。 全intをfloat(double)に変換するとか強引な方法をとってはダメでしょうか?
駄目かもしれないしOKかもしれない なんでそんなことわかるの? でもきっとコンパイルエラーがわんさか出るだろうな sprintfとかの辺とかビット演算の辺とかまずそう switch文とかもまずそう サイズをsize_tじゃなくてintでやってるところとかあればまずそう 戻り値をintでエラーで分岐してたらまずそう
ダメだって書いてあんだろーが
#include <stdio.h> void hack(void){ printf("実行可能\n"); exit(0); } void func(void){ int iArray[2]; iArray[4] = (int)hack; } void main(void){ func(); } VC++のDebugで、 どうしてこれが実行できてしまうのでしょうか?
そういう風にできてるから
>>165 つ codepad
瞬殺でアドバイスが得られると思います。
運がいいから
173 :
165 :2010/03/09(火) 19:53:43
素数判定ではなく素因数分解factorでした
ttp://codepad.org/ESKYLo9R うまい具合に引数を整数にしたいです。
例えば、
factor 123451234512345
のときも動いてほしいです。
OSはwindows vistaでコンパイラはgcc、バージョンは
gcc version 3.4.5 (mingw-vista special r3) です。
その時のint型(4bytes)の上限は +2,147,483,647 (10桁)です
>>173 gmp みたいな多倍長整数ライブラリを使う
引数は整数になってると思うけど桁数を増やしたいって話? 20桁未満ならgccはlonglong使えるんじゃないか
176 :
165 :2010/03/09(火) 21:15:02
>>174 試してみます。
>>175 桁数を増やすのと、
例えばint型を使っていて、
引数argv[1]がその上限を超えたときに
エラーにしてくれるようなチェック方法を知りたいです。
>>176 コマンドラインオプションの解析は getopt(3)でいいんじゃない?
自分で判定するのは面倒でしょ。
パラメタを整数にするのも、strtol とかstrtoll あたりでいいかと。
上限超えたらどうなるかは、man 見れば載ってると思う
178 :
デフォルトの名無しさん :2010/03/09(火) 23:12:10
ヘッダファイルで #define RED 1 #define BLUE 2 ..... #define YELLOW 100 と数百個定義しているのですが(全部定義しているわけではない) 結構順番を入れ替えます.そこでインクリメンタル的なものをつかえないかと思っているのですが, よい方法ございますでしょうか? よろしくお願いします.
enum
ヒープメモリとスタックメモリって読み書き速度に差はあるの?
>>180 スタックは頻繁にアクセスされるためCPUキャッシュに乗った状態の可能性が高い
スタックもヒープも物理的に差はない。 C言語がやりくりする一定値のメモリがスタック。OSに問い合わせしないので解放取得が速い。 ヒープはOSに問い合わせる。 スタックもプログラム開始時にOSに問い合わせて取得する。 OSはこの二つの違いは認識しない。使われていなければ、スタックでもページアウトする。
100Mとか多めに確保したヒープにランダムアクセスしたら遅くなるが 確保できたとしてスタックでも同じ程度の速度。 はじめに一定値を確保してあるか無いかの違いだけ。
スタックはメモリプールという機能と同じってこと。
Windowsを初め、比較的新しいOSではスタックも追加確保 されるる時にOSに問い合わせます。
XPはスタックオーバーフローするが。 vistaからはそうなったか。
>>185 OSが許容するスタック上限値よりずっと低いスタック量で
プロセスを起動しても、行儀の良いプログラムだったら
問題がないんでそうしてるわけですね。
少し「仕事をする」(再帰とか使ってたり、ローカル変数に
配列とか大量に確保する)プログラムだったら当然それでは
足りないからスタックオーバーフローする。そのタイミングで
OSはスタックを追加してプロセスを停止させず続行するわけ
です。
OS的には、変数は極力グローバル変数に確保し、再帰を使わない プログラムであることを望んでいるというわけですね
OSはスタック追加などしないぞ。OSから見たらカタックとヒープの違いはない。 MS-DOS Windwos3.1では区別はあったとおもうが。 Windwos3.1はスタックの固定領域を指定して使い切ったら駄目だった気がする。
MS-DOSにおいて、カーネルを含むプログラムの実行に確保できるメモリ空間(コンベンショナル・メモリ)は8086のアドレス空間の最大1MBである。 ほとんどのコンピュータでは、この空間にBIOS ROMやメモリマップドI/O、VRAMなどの空間も存在するため、 アクセス可能なメモリ空間は最大でも640KBから768KB程度であった。 ただし、バンクメモリやEMS、プロテクトメモリ(80286/386以降)等のコンベンショナルメモリ以外の領域・手段の利用が一般化していたため、 「貴重な」コンベンショナルメモリがこれらの領域によって圧迫されることはなかった。 日本語入力用のFEPなどの常駐型のデバイスドライバを使用すると一度に使用できるユーザーメモリはさらに減少するため、 ユーザーはEMSやXMS、HMAやUMBなどの拡張メモリの管理機能を利用して、 辞書や常駐部やMS-DOSシステムの一部をそれらへ配置し、コンベンショナルメモリの圧迫を少しでも避けることが重視されるようになった。 「とりあえず動く」という状態を作るだけであればエンドユーザーがこれらを直接操作する必要はほぼ無かったが、 「とりあえず」に飽き足らず無駄を省き最適な設定をするためには知見と試行錯誤が要求されるある種の職人芸的な資質が要求されたため、 これらの事情が「MS-DOSの環境設定は非人間的で困難なものであった」とする後世の評価を招く原因ともなった。 MS-DOS - Wikipedia
XPでもコンベンショナル・メモリのような設定あるんだがな。 デスクトップアプリケーションヒープ、非対話型サービスヒープの設定可能。 ここ変えないといくらメモリふやしても、メモリ不足改善しないことある。
Win3.1の場合、8086向けのコンパイラを若干改造した もので生成出来るコードでGUIアプリが作れるという のが基本設計 8086ではスタックの動的変更を行う一般的 方法のCPUアーキテクチャーレベルのサポートは 殆ど無いしコンパイラでもサポートしている例は 皆無。
おまえは勘違いしている。 スタックというのは、OSから見たら特別な領域でない。 スタックとヒープというのは、C言語(その他)から呼ばれているだけ。 どっちもOSに合わせたメモリ取得関数を呼び出して確保する。同じもの。
昔のOSは区別してあった領域があるかもしれないが いまのメモリ確保はどれ使っても、OSレベルでは結局は一通りのメモリ確保しかないだろ。 レジスタとかGPUとかは別。
>>179 ありがとうございました.
うまくいきました.
暴れてる長文バカも 同じくらい環境依存なのに startupコードやセクションの話になるとサクッと黙るんだよな
>>193 WindowsはCPUレジスタそのものを管理しないって?
んなことない。ないからこそ他のプロセッサ向けに移植
されていない。初期のWinNT(4.0まで)はプロセッサ
が今のように分化してないから対応できたんだろうが
さすがに無理になってしまって現在はIntel以外は非対応
レジスタやGPUメモリは専用命令で扱えるが スタックとヒープを区別して扱う命令はない。 OSではこれらの差はない。
おっとMovail (CE)とかは上位レイヤーや言語インターフェース の互換性があるだけでメモリアーキテクチャーはIntel版とは全然違ってると考えたいね。HD非搭載なマシンでも動作させる必要がある わけだから違って当然だけど
入門スレであまり難しい話しないでよ
201 :
デフォルトの名無しさん :2010/03/10(水) 23:33:17
>>197 alpha とかサポートやめた主な理由は商業的なことで
儲かるとなれば技術的な問題はどうとでもなったはず
>>198 何を根拠にそういうこと言い切っちゃうの?
OSが無い環境もあるし、物理的にアクセス速度が違うメモリに振り分けられることもあるだろう。
結局は環境を絞らないと何も言えない。
Javaならどうだろうか?
Intelと一口に言っても、x86/x86-64とIA-64はまったく別物だしね。
CPUが特殊命令持っていて、スタック動作を速くすることが出来たとしても それが付いてないCPUでも、スタック、ヒープメモリは使えないといけない。 これより、C言語のスタックとヒープはソフトウェアとしての用語。
コンパイラの実装次第だがWindowsXP以降では、 スタックもヒープも同一のメモリ確保関数を使っているだろう。 すべてのコンパイラを知っているわけではないが。 CPUレジスタやCPUキャッシュのみをスタックに使う実装も出来ないことはないけど ないんでは。
「スタック処理支援命令が付いていないプロセッサなどCPUと 呼んではいけない」 という意見には必ずしも賛成ではないが、付いていることを 前提とするかしないかでは、OSのカーネル開発の開発者の 集団力学には大きな影響が発生し、それがOS全体に 作業環境全体に与える影響力は計り知れず、スタック支援命令が ついたプロセッサ上のOSしか知らない俺にとっては とてもじゃないが反対だとも言えない。
ハードウェアのスタック機能と、C言語のスタックとヒープは 名前と動作は似ていても別物。 C言語のスタックメモリは複雑だろ。auto変数や関数呼び出しや再帰とか。 ハードウェアの機能に丸任せできないだろ。
C言語に限らずプログラミングで頻繁に出現する データ構造の総称的名称としてのスタックやヒープと CPUが決定する「具体的な」ものとでは使われる コンテクストが全く違うだろうな(特に範疇性) 同じ用語を用いていてもコンテクストが全く異なる ので同じコンテクストで使われていると決めつける と何かと混乱の原因になりやすい鴨
文字列が数値かどうか判定するのにisdigitを使うと マイナスや小数が誤判定されてしまいますが これらも正しく数値と判定させるためには自前で関数用意するしかないのでしょうか。
>>211 isdigitは数字かどうかを判定する(一般には)マクロ
なんで、数値かどうかの判定を一発でするのは
無理
受け取った文字列をsscanf等で数値に直したものを
人の目を通して確認してもらうのが一番
0.9994242123123232132という文字列を数値
に直したのを表示させた時に
0.9994242123123456789
となった場合にそれが問題なのかどうかは状況に
依存。
>>211 atoiやatof等で不満なら自作するしかないね。
レスどうもです。 sscanfだと"1xyz"みたいに先頭だけ数字の文字列も数値として通ってしまうなぁ・・ と試行錯誤してたらatofで完璧でしたどうもありがとうございます。
とおもったらatofでもやはり先頭が数字だとだめでした;;
>>208 べつに、auto変数や再帰や関数の引数で特別なことはやっていないし C 言語のスタックメモリが複雑とも思えませんけれども。
>>215 じゃぁ、自作だね。
チェック関数だけ書いて後はatofに流すのが無難かなっと思うけど
用途や目的次第なのでお好きにどうぞ。
>>215 #include<stdio.h>
double get_value(const char *str)
{
double value;
int n;
if(sscanf(str, "%lf%n", &value, &n)==1)
{
if(str[n]=='\0') return value;
}
return -1.0;
}
#define TEST(str) printf("[%s]=%f\n", str, get_value(str))
int main(void)
{
TEST("0.12345");
TEST(" 0.12345");
TEST("0.12345 ");
TEST("1xyz");
return 0;
}
素直にstrto{l,ul,d,f,ld}を教えてやれよ
220 :
デフォルトの名無しさん :2010/03/11(木) 18:54:28
>>220 スライドショー フリーソフト でggrks
断片化対策にこういうことってやっていいの? サイズ違うのにキャストしても大丈夫かな? void *my_allocate(size_t size) { return malloc(size / 4 * 4 + 4); } void my_deallocate(void *address) { free(address); } int main(void) { char *pc = (char *)my_allocate(sizeof char); *pc = 'c'; printf("%c", *pc); my_deallocate(pc); return 0; }
>>222 4バイト単位で大きさ調整しても意味なさそう。
その式だと、最初から4の倍数だった時、必要なサイズより4バイト大きくなってしまう 普通はビット演算を使うと思う (size + 0x00000003) & 0xfffffffc
>225 それはsize_tが何バイトだと想定しているわけ いや、むしろ何ビットといった方が良いのかな
(size + 3) / 4 * 4 だな
>>226 それなら、0xfffffffcを~(size_t)3にでもすればいいと思う。
~((size_t)3)かな
昔は乗除算は必ずシフトに展開しろと教わったもんだが 今のCPUだとコストに差はないのかな (size + 3) >> 2 << 2
演算子の強度低減ぐらいなら処理系がうまく最適化してくれるので 意図をそのまま表現するのが良いとされるようになってきたような
/ 4 * 4 も >> 2 << 2 も & 0xfffffffc に最適化してくれるね
素直に「4の倍数に切り上げ」ってコメントに書くわ どんなに簡単な処理でもコメントがあった方が読みやすいし とくに何年も前に書いたソースだと
>>233 まさかとは思うが、こんなコードは書かんでくれよ。
++count; // カウントのインクリメント
235 :
デフォルトの名無しさん :2010/03/12(金) 15:08:47
教えてください。 システムソフト開発の会社に入ってそろそろ10年。 サポートや試験担当ということもあって、 まったく言語というものを知らずに来ました。 最近、なんかまずいかな? と思い始めて「猫C」を買って勉強しています。 でも、特に目的がないせいか、 この本やったあと次はなにを勉強すればいいかわかりません。 なにかおすすめの書籍があれば教えてください。
なにがまずいの?
会社の言語やってるやつに聞け 実用で使われないやつやっても無用の長物 配置転換でリストラにならないように現場で使われる率高いやつ
C言語などいくらやっても徒労に終わる 基礎が出来ても完成品が出来るまでの道のりは険しい 自分でした独習など焼け石に水状態 会社でやってるのをピンポイントでやるべき
239 :
デフォルトの名無しさん :2010/03/12(金) 15:17:38
ありがとうございます。 .NET(C#?)の問い合わせが多いので その言語のサンプルを読めるようになると サポートの幅は広がるよね。 とは言われました。 そうか、と思いつつ、 基本である(と思っている)C 言語の初歩本くらい やっといた方がいいのかな、 と思ってせこせこやっていました。
あとC#で何分野やってるのかも聞くといい。 GUIとかゲームとかネットワークとか。 その分野を重点してやる。
C#で開発ってXbox360かと思った。
Cできたところで結局ドカタなんすけどね
switch(c->programming){ case YES: printf( "Cができるとは素晴らしいですね\n" ); default: c->status = "土方" break; }
浮動小数を文字列に変換する方法について教えてください。
求める動作は次のとおりです:
* double型を文字列に変換
* printf系などの外部関数で変換しない
* 整数は整数として表示(小数点を付けない)
* 小数点以下の不必要な0は付けない
* 有効な精度(15桁程度?)で適当に丸める
* 出力が長い場合も扱える(例えば、「12340000000000000000000」など)
いろいろやってみたのですが思い通りのものが作れなかったので・・・
アイデア・ヒントいただければと
自分で作ってみたものも一応晒しておきます。
↓だと、「456」のときに「459.9999...」となってしまいうまくいきません。
http://codepad.org/lEqBv5Qz
246 :
245 :2010/03/12(金) 19:07:20
↑の「459.9999...」は「455.9999...」の間違いでした。 申し訳ない。
配列を関数に渡して、その値を取得したいんですが、上手くいきません どうすればいいでしょうか?
249 :
デフォルトの名無しさん :2010/03/12(金) 19:58:47
すみません、取得したいというのは int test[10]; func( &test ); a = test[ n ]; というつもりでした
>>249 質問がよく判らんが、こういうことか?
void func(int * test)
{
test[0] = 1;
}
void caller()
{
int test[10];
func(test);
int a = test[0];
}
>>250 それだと関数の中で1を代入しても関数を呼ぶ側では変化しないと思うんですが
普通の変数をポインタで引数を渡して変更した値を取得するプログラムの配列バージョンみたいなのは可能でしょうか?
勘違いしてました 解決しました ありがとうございます
254 :
デフォルトの名無しさん :2010/03/12(金) 23:31:42
>>238 違うね
「基礎ができて」ない奴の道のりが険しいだけ
計算をしっぱなしな奴と、ちゃんと検算する習慣がある奴の違いは
小学校で受けた教育の質から来る
基礎からやればいいじゃん 簡単なプログラム書くときでもホーア論理とか記述的意味論とか使って検証しながら書くとかさ
>>222 mallocがアライメント調整してるのに自前でもやる意味あるのかな?
「何故かは分からんが出来たからいいや」 こういうタイプは一生伸びない。 応用できるのは何故そうなったか、つまりプロセスの部分であり、解は応用できないからである。
うるせーばか 既解決問題の証明を一生再生産してろ
こうしてHTMLは死んだ
>>256 malloc()がアライメント調整してない場合も、pragma指定かAPIで調整できる場合が多いね。
>>239 10年っていったらもう30前後なんだろ?
今更言語やっても身につかないし
そんな奴は役に立たない
261の人気にシット☆
shit?
執刀
ファイルが存在すれば追記でオープン ってのを格好よく書くにはどうしたらいいかな あればエラー無ければ作成ってオプションならfopen()にあるけど 逆なんだよな〜access()使うの面倒くさいな〜
質問です ネストって一般的に何重が限度ですか?
何のネストだよ
C言語の弱点はネストだな。短い文で使えばいいけど 間に沢山あるとわかりにくくなる for{}つかえときはcontinue;で括弧を引きずらないようにするといい 場合によってはgotoもいい 長い部分は関数化
>>269 ,272
> 5.2.4.1 Translation limits
> The implementation shall be able to translate and execute at least one
> program that contains at least one instance of every one of the
> following limits:
> - 127 nesting levels of blocks
> - ...
>269 ISO/IEC 9899:1999 (E) 5.2.4.1 Translation limits 1 The implementation shall be able to translate and execute at least one program that contains at least one instance of every one of the following limits:13) 127 nesting levels of blocks 63 nesting levels of conditional inclusion 63 nesting levels of parenthesized declarators within a full declarator 63 nesting levels of parenthesized expressions within a full expression 13) Implementations should avoid imposing fixed translation limits whenever possible. number of characters as the corresponding universal character name, if any)14) 14) See ``future language directions'' (6.11.3). 15 nesting levels for #included files 1023 case labels for a switch statement (excluding those for any nested switch statements) 63 levels of nested structure or union definitions in a single struct-declaration-list ネスト以外の限界については省かせてもらった やっぱり63か >274 その一つ下じゃないか
277 :
デフォルトの名無しさん :2010/03/13(土) 20:56:03
>>273 ネスト深くてもわかりやすい言語なんかねーよ 安易にgoto勧めんなよ 場合によって、の解釈でとんでもないことになるし goto排斥主義者の人が来ちゃったら揉めるだろ
だからgoto使わなければいいだけ
>>276 "conditional includion" は 6.10.1 にある #if とかの話。
>276 あっ、ほんとだ プリプロセッサの話だ
282 :
268 :2010/03/13(土) 21:21:26
>>271 あー、オープンしてから自分でシークすりゃいいだけか。
ありがとう。
283 :
デフォルトの名無しさん :2010/03/13(土) 22:19:58
プログラム勉強始めたばかりの初心者です。例えば以下のようなif文があるとします。 カッコを入れるタイミングと位置がよく理解できていません。 なんで下記のように2回連続カッコが続いて記述されるのでしょうか? きっとそれぞれのカッコがどこで始まり終わっているのかが理解できていないと思います。 必ず対になるので偶数個になるのは理解できていますが・・・ おかしな日本語で大変申し訳ありませんが、どなたかわかりやすく解説をお願いできますでしょうか。 よろしくお願いします if (条件1) { if (条件2) { 文1; } else { 文2; } } ←これは何に対してのカッコ?なんで2回連続なんだろう??? else { 文3; }
>>283 2回連続しているけど、意味は別もの。
ネストしているカッコをそれぞれ別のカッコと考えれば分かると思うよ
if(条件1)「
if(条件2)『
文1
』else『
文2
』
」
else
>>283 例にあげた if 文自体が間違っています。
わからなくて当然です。
なんの本にかいてあったんですか?どこのサイトですか?
286 :
デフォルトの名無しさん :2010/03/13(土) 22:31:48
287 :
デフォルトの名無しさん :2010/03/13(土) 22:51:51
>>284 さんありがとうございます。
初心者の私にはこのように見えます。
if(条件1)「 @
if(条件2)『 A
文1
A』else『 B
文2
B 』
」@ ←上記の番号がきっとそれぞれ対になっていると思っています。ただ、
条件1が満たされなかったら下のelse文に続くからこの閉めカッコは何?とも感じます。
きっと私は文の構成の初期的なところを理解していないと思われます 汗
else
才能無い奴はやめてしまえ おまえがC言語をやらなくてもかわりはいくらでもいる ゴミなんだよお前は
むやみに煽りすぎだろ。
最初のうちは↓のような書き方をした方が分かりやすいかも if (条件1) { if (条件2) { 文1; } else { 文2; } } else { 文3; }
煽り?どこがだよ!お前もそうおもうだろ!正直に言えよ!
ifの中にifがはいってるってことはわかってる? 「ネスト」で調べてみましょう
>>291 ま、正直、あまりに根本的なところで、なんで?なんで?って聞かれるとイラっとはする。
>>294 はぁ?じゃあお前がちゃんと答えればいいじゃねえか!てめえがびしっとこたえねえからこんな事になってんだろ!クソが!
まず落ち着いて入門書を読むレベルだろコレ おまえらが半端に親切にするからチャット状態で何も考えずに質問しちゃうんだよ
九九の表を覚えないのに掛け算するレベル。
この程度で才能なのかよ。 可哀想だなお前ら。。
この程度もできないのはまさに才能だろうな。
>>287 疑問の回答になってるかわからないけど、
if( 条件1 ){
略
} ←このカッコ
else {
略
}
このカッコは、"else"があれば終わりが分かるんだから
不要じゃないか?っていう疑問なら、確かにその通り。
でもそれは"else"が来る場合限定の話で、else の来ない場合はそうじゃない。
C言語は、カッコでくくったブロックが基本単位になってるんだけど、
この辺りの感覚が分かってくると、閉じカッコが2重につくのも納得いくと思うよ
変なところでひっかかる人はたまにいる んで、引っ掛かりが取れたらグンと伸びることも結構ある 283もそうなのかは分からんけどね
んじゃとりあえず期待。
>>287 条件1が満たさた場合、「 @から」@までが実行される。
どこからどこまでか範囲を指定してるから、どこまでを示す閉めカッコが必要。
範囲じゃない場合は省略できるが、最初のうちは必ず{}でくくっておいた方がいいと思う。
if (条件1) { if (条件2) { 文1; } else { 文2; } } else { 文3; } は if ( (条件1) && (条件2){ 文1;} else if( 条件1) { 文2; } else {文3;}と等価でよいでしょうか?
実際に条件式書いてコンパイルしてみたら分かるでしょ。
if (条件1) { if (条件2) { 文1; } else { 文2; } } else { 文3; }
>>304 一般的には等価ではない。条件1を再度評価したとき同じ結果が
返るとは限らないから
そんな条件の条件があるのなら等価じゃないだろ
そもそもコーディングの意図が明らかに違う
だから適当な変数を用意して int 条件1結果; 条件1結果=(条件1)?1:0; if ( (条件1) && 条件2 ){文1;} else if(条件2) {文2;} else {文3;} と書くのがもっとも無難じゃないかと...
質問に答えてください
ここで聞くより入門書を買って読んだ方が手っ取り早い
ここは 「C言語なら俺に聞け(入門編)」 です 煽るだけの奴は去れ
>>312 お前が質問するのは自由だが、それに答えるかどうかもこっちの自由だ。
煽るだけじゃなく、例えば荒らしもする奴は居てもいい。
>>314 スレタイにだまされるな。
初心者の質問をネタに雑談するスレだ。
>>1 >C言語の*入門者*向け解説スレッドです。
質問または答えない奴はここにいる資格は無い
じゃあ俺に聞けなんて自信満々にいわないでください スレタイをC言語なら入門書を読んだ上でたまになら俺に質問してもいいよ(入門編)に改名するべきです
質問を議題とし、初心者同士がディスカッションするスレだよ
自信満々に答えられないなら来なきゃいいのに。
>>317 それでいいんだよ
通ぶってても規格票と違っている事を固く信じ込んでいる事はよくある
>>319 「俺に聞け」なんて不遜な言い方、ジョークに決まってるだろ。
324 :
285 :2010/03/13(土) 23:54:08
>>283 んー、私が間違っていましたね。
これであっています。失礼いたしました。
で、こういう書き方をすればわかりやすいかもしれませんが、いかがでしょうか。
if (a == 0) {
if (b == 0) {
x = 0;
} else {
y = 0;
}
} else {
z = 0;
}
マジに、ただひたすら初心者様に奴隷のように教えるだけのスレになったら回答者なんてだれもよりつかなくなるよな。
低レベルな回答者はいらないです。
逆ギレすんなよ
ヤフの質問箱とかOKWebとかなら、むやみに煽られないんじゃないのかね。 あそこらは「君たちは質問の意図を理解してませんね。 そういうことはいいから早く質問にこたえなさい」系の物言いも許されるイメージ。 あんまり見てないから知らんけど。
if文のネストで巧くいかなかったら 条件式を工夫してみろ 条件式をいじってうまくいかなったら if文のネストを工夫してみろ 両方駄目だったらあきらめろ 言えることはこれくらいかな
聞くだけならいくらでも聞いてやる ただし答えるとは誰も言ってない
答えないならせめてずっと黙ってろ
いや質問があるなら俺に聞けよ
333 :
デフォルトの名無しさん :2010/03/14(日) 00:34:56
>>329 最初から理屈だけで覚えようとすると得てして失敗しやすいからな
>>333 Cをかじったなら、それはCじゃないってわかるだろ。
おCりかじり虫〜
鉄分ミネラルビタミンCは
保存済みのメモ帳に書いてある10個の数字からランダムに5個読み取りたいんですけど、 fopen、fscanf、for、ifのみを使ってそのようなプログラムを作ることって可能なのでしょうか?
不可能
手書きだったら、スキャナで読み取って画像認識しなければ ならないから、相当難しいだろうな。 しかも使える関数や構文にも強い制限があるみたいだし....
/dev/randomとかある環境ならいけるんじゃね?とか思うけど
宿題はC/C++宿題スレへ。テンプレート持って。
ってnotepad.exeで作成したテキストファイルじゃなくてリアルメモ帳かよ!
木綿生地以外は全部ナイロンに分類してしまう某民族みたいな話だな
345 :
デフォルトの名無しさん :2010/03/14(日) 12:26:11
randとかの関数のアドレス調べておいて それでfopenを上書きすればいいんじゃね あるいはランダムな数字が入ってるテキストファイル用意しておくとか
却下
fopen、fscanf、for、ifだけじゃ無理だろ。 カッコや演算子もないとプログラムの書きようがない。
糞スレ
開くだけ開いて閉じないってのはなぁ
必要な関数を全部挙げろよカス
hoge.hにint num;というグローバル変数を宣言?します 全然関係ない所から、#include "hoge.h"をしてhoge.hのint num;を使うと numのスコープはどうなるのですか?
記憶クラス指定子にextern付けとけ どっかのコンパイル単位でint numで定義すればいい
355 :
353 :2010/03/14(日) 15:36:26
>>354 ひとまず、グローバル変数にはexternをつければいいことは分かりました
でも、いつグローバル変数が死ぬかわかりません
グローバルに限らず静的変数はmain()が始まってから終わるまで生きてる。 寿命をスコープと言わない。スコープってのは名前の有効範囲。
>>350 fopen()で開いたストリームは、プログラムが終了すると自動で閉じられるんで、
閉じるのは省略しても問題ないって場合もある。
358 :
353 :2010/03/14(日) 16:06:29
すみません、まだexternとグローバル変数について分からないので教えてください staticのまとめ 1.#include "hoge.h"とした時に初期化(定義)される 2.staticは何度も#include "hoge.h"としても、1度しか初期化されない 3.プログラムのすべてが終わると自動的に、削除される 4.オブジェクト指向のpublic? externのまとめ 1.#include "hoge.h"とした時に初期化(定義)される 2.#include "hoge.h"とする度に初期化されてしまうので、多重定義になってしまう 3.プログラムのすべてが終わると自動的に、削除される
>>358 #includeと切り離して説明すると、
file1.cとfile2.cで、それぞれ、static int n = 1; とstatic int n = 2; と宣言されていたら、
この二つのnはそれぞれ別の変数になる。
それぞれ1と2で初期化される。
file1.cで宣言されたnはfile1.cの中からしかアクセスできない。よそからは見えない。
file2.cで宣言されたnはfile2.cの中からしかアクセスできない。よそからは見えない。
file1.cとfile2.cで、それぞれ、int n = 1; とextern int n; と宣言されていたら、
この二つのnは同じ変数になる。
1で初期化される。
file1.cとfile2.cでnを書き換えると、同じ変数だから、とうぜん、file1.cとfile2.cから
みえるnは同じように書き換えられる。
360 :
353 :2010/03/14(日) 16:52:37
>>359 わかりました、ありがとうございます
また、疑問に思う事があったら質問します
C言語の入門サイトではヘッダの作り方がかかれていませんが、 C言語では普通ヘッダを作らないのでしょうか? ちなみに、*.cを*.hにするだけじゃダメなんですか
if(1) {〜} else {〜} elseブロックは最適化で消滅する?
>>361 ちょっと規模が大きいとファイルを複数にわけるんで、ヘッダを作るのが普通。
ヘッダには定数とか関数のプロトタイプを入れるもんなので、.cを.hに変えるだけじゃだめ。
だめだお。
>>362 おまえさんが使っているコンパイラに聞いてみろ
>>245 ソース見たら、たぶん20行から28行までのところを、なんかしたら、なんかなるかもなぁ〜〜って気がしたんで、
そこのところをあてずっぽうでいじったら、456 って出た(^_^/わーい
ソースの、ここのところを
/* 各桁の数字を、有効な桁まで計算しておく */
for(i = 0, trunc = 0; i < 15; ++i) {
m = modf(n, &n);
buf[i] = (int)n;
n = m * 10.0;
↓
こういうふうに変えてみたです。あとはいっしょです
/* 各桁の数字を、有効な桁まで計算しておく */
double def = n; // ここと
for(i = 0, trunc = 0; i < 15; ++i) {
m = modf(n, &n);
buf[i] = (int)n;
n = ( modf( ((def+pow(10.0,-15)) * pow(10.0,i)), &n ) * 10.0 ); // ここ
わかんないけど、「誤差とかが、掛け算で、かける10ってのを何度もしてると、誤差がでるのかなぁ〜」とかおもったので、
まいかい全部バ〜〜って、かける1000とかして一気にやったらどうかな?って思ってやったけどダメだったので、
しょうがないので0.00000......1 て小さい1足して、四捨五入しちゃえ〜〜 えいや〜〜ってやったら、なんか偶然456 ってなった。 よかった。
すいません、ぜんぜん知的じゃなくて(・_; 算数的な根拠はないです。なんかラッキー頼りですみません(orz はずぅ〜〜い
C言語のことならなんでも聞いてくれるんですか。
難しいのはちょっと・・・
さあ願いを言え どんな願いも一つだけ 聞き流してやろう…
いくらでも聞くよ
>>366 pow()のアルゴリズムを知っているか? 知っていればすぐに判ることだが非常に誤差が発生しやすい。
従って、第二パラメータが整数になるなら使わない方が無難。
後は、その分の計算量をどこでどう分散させるかだな。
いまだにミドルウェアっていうのがよくわからない
>>373 ミドルウェアってのはOSとソフトウェアの中間に値する物
ミドルウェア = DBMSって覚えておけばok
ヘッダファイルには全ての関数/変数に、extern/staticを付けなければならないんですか?
いいえ
>>375 そもそも、ヘッダファイルで定義をしてはいけません。
中間搾取w
元ダフ屋が金券ショップになりやがて中央銀行になったようなもの
>>338 #include <stdio.h>
#include <stdlib.h>
void main(int argc, char** argv ) {
char str[0xFF]; double n[1000]; int n_max = 0; int i=0;
FILE* fp = fopen( argv[1], "r"); while( fgets(str,0xFF-1,fp) != NULL ){ n[n_max++]=strtod( str, NULL ); }
srand((unsigned)(time(NULL)));
while( i < 5 ) { int r = rand()%n_max; if( n[r] != 1e+306 ) { printf( "%f\n", n[r] ); n[r]=1e+306; i++; }}
}
くじびき的な何か?
↑ fopen、fscanf、for、ifのみを使って という条件を満たしていない気がするのだが、いいのか。
うむ、randが使えないのが難点だな
>>380 fgets()の第二パラメータの意味を誤解していそうだ。
せめて現在時刻がわかれば乱数のように使えるのに 制限が厳しすぎる
__asm は使ってもいいですか? 関数じゃないからいいよね?
乱数の代わりに初期化していない自動変数の中身を読むってのは無し?
厳密なことをいうと、十分にランダムである保証がない 特に乱数や、乱数の種、ましてや暗号関係で使うのは厳禁 あと初期化されていない変数って、規格上は読んでいいんだっけ?
定義されていないだけで、読むのは別にいいんでない
>>381 #include <stdio.h>
#include <stdlib.h>
static double s;
static int rnd(void){ int p; if(s>1e+8){s*=1e-4;}; if(s<0){s*=1e+8;} s += 0.1*s; return((s<0.0)?-s:s); }
void main(int argc, char** argv ) {
char str[0xFF]; double n[1000]; double d; int n_max = 0; int i=0;
FILE* fp = fopen( argv[1], "r"); for( ; fscanf( fp, "%lf", &d ) != EOF ; ){ n[n_max++]=d; }
s=((double)((long)&str)); rnd();
for( i=0; i<5 ; ){ int r = rnd()%n_max; if( n[r] != 1e+306 ) { printf( "%f\n", n[r] ); n[r]=1e+306; i++; }}
}
な、なんか意味あんのん?… この制限て…(・_; ばたり…
もうひとつ制限がありました。7行で書いてください
改行しなきゃいいだけ
>>390 #include <stdio.h>
static int rnd(double* s){ int p; if(*s>1e+8){*s*=1e-4;}; if(*s<0){*s*=1e+8;} *s += *s*0.1; return((*s<0.0)?-*s:*s); }
void main(int argc, char** argv ) {
double n[1000]; double d; int n_max = 0; int i=0; double s =(double)((long)&n); rnd(&s);
FILE* fp = fopen( argv[1], "r"); for( ; fscanf( fp, "%lf", &d ) != EOF ; ){ n[n_max++]=d; }
for( i=0; i<5 ; ){ int r = rnd(&s)%n_max; if( n[r] != 1e+306 ) { printf( "%f\n", n[r] ); n[r]=1e+306; i++; }}
}
もぅ寝まつ…(つ_\
>>338 これでどうだ
ウチでは実行するたびに結果が変わったよ
#include<stdio.h>
#define DATA_NUM 1000
int main(void)
{
unsigned long rand_pool[DATA_NUM], rand_num[5];
int value[10], i, index;
FILE *fp;
if((fp=fopen("hoge.txt", "r"))==NULL) return 1;
for(i=0;i<10;i++) if(fscanf(fp, "%d", &value[i])!=1) return 2;
for(i=0;i<DATA_NUM;i++) rand_num[i%5]^=rand_pool[i];
for(i=0;i<5;i++)
{
index=rand_num[i]%(10-i);
printf("%d\n", value[index]);
value[index]=value[10-1-i];
}
return 0;
}
回答が知りたい。
こんな問題を出した意図とか。
どうせ
>>338 が問題を書き間違えて重要な情報が抜け落ちてたってオチだろうけど。
関数で参照渡しするときの所作を詳細に教えてくささい
まず、参照渡しの定義をしてから質問してください
C言語では参照渡しはできません JAVAを使いましょう
もどきはできるじゃん
ポインタによる間接参照
sprintfを使って整数から文字列に変換しようとするとき "%04d",i みたいに前をゼロで埋める指定で、0で埋める個数って変数にできないんですかね?
*
なるほど、%0*d , (int) , i でいけました ありがとうございます
超初心者ですがよろしくお願いします。 Macでも使えて軽いコンパイラってありますか?
gccでいいだろうに
軽いコンパイラって、どんなコンパイラだよ。
じゃ軽いライブラリで
俺の作ったコンパイラすごいぜ。 5年前のノートPCなのに、円周率計算させると2秒で5億桁まで出力する。 VisualStudio2008ってソフトなんだけど。
gccでプログラム作ってます。 例えば、buff=(char *)malloc(sizeof(char) * 10);とメモリを確保したあと 配列が不足するたびにreallocでメモリを増やしていこうと考えてます。 buff=(char *)realloc(buff, sizeof(char) * 20);という具合に。 そこで悩んだのですが、ある時点でbuffにどれくらいメモリが割り当てられてるか 確認する方法ってないですか? 「* 10」を「* i」みたいに変数を使って確認するしかないんでしょうかね?
サイズを保存するしか無いよ
>>410 > buff=(char *)realloc(buff, sizeof(char) * 20);という具合に。
出たよ。メモリ確保できないときにリークが確定するパターン。
初心者に realloc() 教えるとすぐこれをやらかす。
鬼の首でも取ったのか? 喜びすぎだろ
喜んでるわけが無いだろjk うんざりしてるんだよ。
#include <stdio.h> #include <stdlib.h> // 構造体 B typedef struct tagB { int max_size; char* buff; } B; // B を初期化する命令 void B_init( B* b ) { b->max_size=10; b->buff =(char*)malloc(sizeof(char) * b->max_size); } // B のメモリを10ふやす命令 void B_realloc( B* b ) { b->max_size += 10; b->buff = (char*)realloc( b->buff, sizeof(char) * b->max_size ); } // Bに char を一文字セーブする命令 ( B の buff が短かったら自動的に伸ばしてくれる ) void B_write( B* b, char c, int index ) { if( index >= b->max_size ){ B_realloc(b); B_write( b, c, index ); } b->buff[index] = c; } // Bから char を一文字ロードする命令 ( B の buff が短かったら自動的に伸ばしてくれる ) char B_read ( B* b, int index ) { if( index >= b->max_size ){ B_realloc( b ); B_read( b,index ); } return( b->buff[index] ); } void main() { B b; B_init( &b ); B_write( &b, 'A', 12345 ); printf("%c\n", B_read( &b, 12345 ) ); } おこられそう…w(^_^
>>416 怒りはしないが、ダメダメ。
ロードする関数でrealloc()しても、増えた領域に何にも書いてないから不定値が返るぞ。
それに、セーブする方も任意のindexを指定できるのに一度に伸ばせるのが高々10文字だから簡単に範囲外書き込みになってしまう。
それに、sizeof(char)なんて無意味なことは書くべきじゃない。
>>413 出たよ。問題の本質と関係ない話をする奴。
buffの宣言がないじゃん、と言ってるのと同レベルだぜそれ。
初心者じゃなくなったと思い込んでる初心者はすぐこれをやらかす。
そもそも、メモリ確保ができなくなる心配をする前にすることがあるだろうと。
その程度のサイズでrealloc使うとか、何の冗談だよw
足りなければ倍にするというやんちゃな方式が時として功を奏することもあるよ
とりあえず、ポインタを元にアロケーションしているサイズを知ることはできないので他で管理しましょう
>>420 ええと。
どうしても必要ならともかく、入門レベルでrealloc使わせるのはどうかと思うが。 余裕をもとって大きめに領域確保するほうがよっぽどマシ。
>>413 すぐそのあとに、if (buff == NULL) exit(1); と書けば問題なし。
メモリ不足なら、ほかのところだってまともに動くわけないんだから。
>>424 サイズをオーバーするかどうかちゃんとチェックするならありじゃね?
>>426 ・ごめんなさい、私には無理です
・オーバーする分はなかったことにしていいよね
どちらでもお好きに。
一行が長いテキストファイルを開くと落ちるエディタ 一行が長いと後ろのほうが切り捨てられるエディタ どっちもいやだなぁ
4G以上のファイルとかどうやって扱ってんのか気になる
>>429 4GB以上のファイルを普通に扱える環境なら、64ビットアドレッシングで使うのが当たり前だから特に工夫は要らないよ。
32ビット環境で扱いたいなら、一度に全部開かなければいいだけだからやはり、4GB以上だからといって別段大仰な手間は要らない。
>>428 初心者が作るのなら、取り敢えずそれでもいいのでは? まさか、そのまま保存するわけでもあるまいし。
431 :
デフォルトの名無しさん :2010/03/19(金) 19:50:57
文字配列についてお尋ねします char buf[6] = {'A', 'B', 'C', 'D', 'E', '\0'}; と宣言したとします。 このとき buf[1]は 'B'が格納されており文字コードが例えば66だとします buf[1]は数値そのものであるので、if(buf[1] == 66)もしくはif(buf[1] == 'B')のような比較が可能です。(ですよね?) ここでbufとするとABCDEという文字列を表すことになりますが、このときbuf自体の数値は bufのアドレスが入っています。(ですよね?) ここで疑問なのですが、bufは一体どこのアドレスが入っているのでしょうか? 例えば、buf[0]のアドレスと同じものであればAとしか表示されないはずです。 ABCDE\0をもってくるにはbuf[0]からbuf[5]までのアドレスが必要なはずです。 buf自体はアドレスの開始地点で終端文字の\0が現れる部分までのオフセットを割りだし そのアドレスをすべて与えて文字列を表示しているということでよろしいでしょうか? 回答よろしくお願いします。
>>431 だいたい合ってるが、1点だけ。
> ここでbufとするとABCDEという文字列を表すことになりますが、
bufがABCDEという文字列を表しているわけではない。
あくまで文字列の先頭のアドレスを保持しているにすぎない。
buf == &(buf[0])
puts(buf)で"ABCDE"と表示されるのは、以下のような処理をしているため。
for(char *p = buf; *p != '\0'; p++) { *pを出力; }
char buf[] = {'h', 'o', 'g', 'e', '\0'} char *p = buf; buf ↓ 'h' 'o' 'g' 'e' '\0' ↑ 0x00..... ← p
グダグダ言ってないでデバッガで変数見りゃいっぱつだろうが
>>431 >ここでbufとするとABCDEという文字列を表すことになりますが
ここでってどこだよw
>431 言っていることはその通り何だけど NUL('\0')終端文字列はNULが現れるまでを文字列とみなすから表示させたい最初の文字のアドレスを渡すだけでいいのよ あなたにお薦めなサンプルプログラム #include <stdio.h> #include <string.h> int my_print(char const*str) { size_t i; for ( i = 1; i < str[0]+1; ++i ) { putchar(str[i]); } return i-2; } int main(int argc, char **argv) { char foo[6] = {'a', 'b', 'c', 'd', 'e', '\0'}; char bar[16] = {'a', 'b', 'c', 'd', 'e'}; char baz[] = {3, 'b', 'a', 'z'}; memset(bar+5, '\100', 10); /* ゴミを入れる */ bar[15] = '\0'; /* NUL終端させる */ printf("%s\n", foo); printf("%s\n", &foo[0]); printf("%s\n", &foo[3]); printf("%s\n", bar); my_print(baz); return 0; }
439 :
デフォルトの名無しさん :2010/03/19(金) 21:22:55
配列はメモリ上連続しているので、先頭アドレスと型がわかれば計算で出ます。 コンパイラは &buf[5] を &buf[0] + (5 * sizeof(char)) と捉えます。
プログラミングに使う単語って英語ですか?
基本的には
皆さんは英語ペラペラですか?
My English is poor.
445 :
431 :2010/03/19(金) 22:18:43
>>433 buf自体がが先頭アドレスなのは↓に書いたように知ってます
>buf自体はアドレスの開始地点
結局全部
for(char *p = buf; *p != '\0'; p++) { *pを出力; }
これやってるだけなんですね…
446 :
431 :2010/03/19(金) 22:24:21
>>439 buf[5]を例えばprintfするときはオフセットで
文字列を全部表示するときはポインタをズラす方法で表示しているのですか?
for(char *p = buf; *p != '\0'; p++) { *pを出力; }
このようにポインタをズラしているのか、
それとも
&buf[5] を &buf[0] + (5 * sizeof(char))
のようにオフセットで計算しているのか
内部の処理はどっちなんでしょうか?
それが
>>431 の質問で一番知りたいことなんですが
447 :
431 :2010/03/19(金) 22:26:02
>>436 オフセットで計算したものか、ポインタをズラしたものなのか
格納されたアドレス見るだけじゃわからないんですよ…
どういう風にprintfを作るかなんて決まってないしコンパイラメーカーが勝手にやってるだけだよ きっと、前者だろうなって気はするけど
前者な気がする
450 :
431 :2010/03/19(金) 22:28:24
>>448 そうなんですか…
どっちが主流なのか知りたかったのですが(速度とかいろんな意味で)
そんなこと知ってどうすんだろ
速度とかそれこそきまってねえだろ おまえはなにか?コンパイラは全て同じ中身じゃないといけないと思ってんのか?主流ってなんだ?どの環境の主流だ? クソして寝ろや
>>450 もう答えは出てるだろう。文字列探索程度のコストを気にするより
もっと他の所の速度を気にしろ。
簡単なプログラムつくって、最適化全部はずしてバイナリを逆アセンブルして追っかけてみれば? ペンティアム以降になると急に難しくなるから、LSICの試食版あたりからははじめて あるいはgccならprintfもソースみれるよ そうやって3,4個調べてみれば主流もわかるんじゃね
robot C わかる人いる?
ボクは個人的には char c[1234] ってのを putchar( c[0] ); putchar( c[1] ); putchar( c[2] ); putchar( c[3] ); putchar( c[4] ); putchar( c[5] ); 〜〜〜ずーっとつづく って書くよりも char* p=c; putchar( *p++ ); putchar( *p++ ); putchar( *p++ ); putchar( *p++ ); putchar( *p++ ); 〜〜〜ずーっとつづく って書く方が、コピペが楽なので好きですw
?
頭おかしいのかおまえ
俺がコンパイラなら syntax error 出すわな
最終的にはsystem callを追っかけてlibcやkernelに入りそうだな
int 21Hで終わりでいいじゃん
char c[1234]; ってのは、使うときは putchar( c[3] ) みたいにして使います。 c[0] なら最初の文字、c[3]なら3番目の文字です。 &c[3] みたいに、頭に&マークをつけると、このデータがメモリのどこに書かれてるかがわかります。配列の先頭が、メモリのどこにあるかは &c[0] でわかります。 使うときにカッコを取って c って書くと、 &c[0] って書いたときと同じ数字がわかります。 この c そのものを c++ ってやって一個増やすと、 char型の配列なら、char一個分だけメモリをさしてる場所が増えます。 だから c++ とすると、つぎに使うときは c は &c[1] といういみになります。 int型の配列なら、int i[1234];
i++ で int の大きさ分だけ増えます。 や〜めた
>462 またまたご冗談を
>>462 そんなコンパイラなんて…
あるかもしれないが規格無視じゃないか
>>462 その場合cは定数だからc++なんて出来ないだろアホ
>>467 ほー
char c[1234]; c++; とやってエラーが出ないとでもいうのかい
定数だからできないというのがだめだという分かりにくいツッコミなんじゃないの
>>469 落としどころはどこですか?
意味不明なんだけど
コンパイラはコンパイルエラーを吐きますが
なんか必死だな
>>470 煽っても何がどう違うのかは説明できないから、答えは返ってこない。
放置しましょう。
474 :
462 :2010/03/20(土) 19:25:20
まちがえててすいませんでした。なるほど〜 c は変えちゃいけないポインタだったんですね。はじめてしりました。 べんきょうになるなぁ〜
ブログでC言語に関することを書いてるのですが、 ソースをページに表示するときに、そのまま貼り付けるだけだと TABで字下げされなかったり、コメントが色分けされなかったりして 見にくくなってしまうのですが、なにかいい方法はないでしょうか?
codepadに貼りつけてリンクを貼ればいいよ
>>475 どこのブログでもソースをそのまま貼る機能くらいあるだろ。
>>475 色分けについては自動でタグつけ(CSS使ってclass指定)してくれるツールを自分で作る
はてなで
char buf[6] = "abcdef"; fputs(buf, stdout); ↑が意図どおりに動かないことがわかれば終端文字の意味もわかる
?
>>483 たいていは意図どおりに動くような気がする
プログラマが意図した通りに死んでくれるな
いや、意図した通りにSegmentationFaultを起こしてくれずにしばしばcharbuf[] = "abcdef"と同じように振舞ってしまうと思うぞ。
488 :
475 :2010/03/20(土) 21:09:05
みなさんレスありがとうございます。
>>481 これダウンロードして、中に入っていたtest.htmlに自分のソース貼り付けて試してみたのですが
日本語コメの部分が文字化けしちゃいました・・・orz 残念
日本語コードとかによっては文字化けしないで使えるのかな・・・みなさんはいかがですか?
489 :
475 :2010/03/20(土) 21:10:02
<書き忘れ> でも、行番号まで表示されるのはすばらしいですね!
フフフフ
>>467 コンパイルしましたか?
>>462 の c はインクリメントできないという指摘は間違いないのですが。
>>488 日本語エンコーディングに注意すればおk
メモリの動的確保は失敗することがあったり確保開放が遅かったり、多少めんどくさいところがあるので、 下のコードのようにあらかじめ十分大きなサイズの配列を確保する、という方法がいいんじゃないかなぁと思うんですが、 あまり見ない方法ということは、あんましよくない方法なんでしょうか?もしそうなら理由を教えていただきたいです int func(BYTE n) { int temp[BYTE_MAX]; // int *temp = (int *)malloc(sizeof(int) * n); の代わり /* tempを使って処理、少なくともn個のint領域が同時に必要 */ return temp[0]; // tempのデータから最終的にintを一つ取り出す }
・BYTE_MAXが定数である必要がある ・BYTE_MAXの値によってはスタックオーバーフローが起きるかもしれない
495 :
475 :2010/03/20(土) 22:22:56
>>492 test.htmlのヘッダ部の charset=UTF-8 を charset=SHIFT-JIS に変えたら
ちゃんと日本語で表示されました。
自分の貼ったソースが(意識してなかったけど)SHIFT-JISだったからみたいです。
ただし載せようとしてるのがFC2ブログでEUC-JPなので、その差異をどうしようかなって感じですが。
allocaは遅いのかな?
>>496 スタックを使うからスタックオーバーフローの可能性は十分ある
>>495 アップロードするときに自動で文字コード変換するようにするとか
最初からEUC-JPで書くとか
mainで作業用の配列用意して関数に渡せば?
>>493 BYTE_MAXが大きくなかったらそれでもぜんぜん問題ないよ。
>>499 再帰使うときに要注意だし、作業用の配列を他で使うかもしれないというリスクも増える
それなら関数内で static で確保したほうがマシ
C99ってスタンダードじゃないじゃん。
BYTE_MAXってくらいだから、256くらいだったりするのかな? そのくらいのサイズだったら、ローカルに配列で持っても ぜんぜんふつー。 数キロとか数十キロくらいのサイズならぜんぜんおk。
>>493 「十分大きなサイズ」があらかじめわかっていて、スタックに十分な余裕があるならそれでいい
あとはうっかり再帰させなければおk
んで解放し忘れてメモリリークするんだよな
自動変数がリークするってすごいな
alloca使おうぜ
alloca()を使うくらいなら、c99を使えばいいじゃん。 今時alloca()が用意されているコンパイラならc99でも通るだろ。
みんなANSI C お前だけ99
C99使うくらいならC++使うだろw
>503==>510==>511? 知らないことは素直に知らないと認めた方が宜しいかと。 知らないことは罪ではないが、自分を偽るのは罪だ。
VC++もC99じゃねーからな
>>513 VC++にalloca()は実装されているの?
みんなANSI C
C99完全準拠のコンパイラってあるの?
なるほど、それじゃVC++では_malloca()を使えばいいから、やっぱりalloca()はユーザが使う必要のない子だね。
519 :
475 :2010/03/21(日) 00:54:08
Hello \n world!w
>>509 alloca()はふるい関数だから、C99でなくてalloca()が通るコンパイラとか余裕。
テキストから読み込んだ文字列を定数のシンボルに変換することはできないんでしょうか。 /* main.h */ const int TEISU = 10; /* main.c */ #include "main.h" if((テキストから読み込んだシンボル) == TEISU){ 処理 } /* テキスト */ TEISU
atoi?
524 :
493 :2010/03/21(日) 12:18:27
レスありがとうございました どうやら今やってるケースでは大丈夫そうなのでこのままやろうと思います
別個変換テーブルを用意しておくしかないのかなあ
syntax highlighter使ってて、ソースの表示はできたのですが、 ブラウザによってはアンダーバーがところどころ消えて半角スペースになってしまいます。 (例:IEだとダメ、Safariだと問題なし) 対処法ご存知の方いませんか?
スレチ死ねば?
IEだから仕方がない。
自己解決できました お騒がせしました
#include <stdio.h> main() { printf("Hello\nWorld!\n"); } なにか間違いはありますか?
main関数の戻り値が無い。
>>533 戻り値といと?
初心者なので詳しくお願いします
くだらない免罪符晒してないで検索位しろよ
どこの糞サイト見ながらプログラミングやってんの?
>>532 は本当に間違っているのでしょうか?
買った本に書いてあることそのまま書き写しただけなんですが
古い時代のCはそういう書き方をしていた時期もあるのでコンパイルは通るかもしれないが、 そんな本捨ててしまったほうがいい。
Cの絵本は糞だから捨てろ
hello, worldは小文字、感嘆符を付けるなぞもってのほか
え! そんなにひどいんですか? どこかいいサイトを教えてくれませんか?
何で間違いがあるんじゃないかと思ったの
>>539 古いっていうか、新しいCやC++でmainのreturnは省略化とはっきり決まった。
古いCでも、K&Rのhello worldとか省略してある。
Cの絵本についてamazonより
>初心者でも、入門編を一通り読みこなした人でなければ
>いきなり読んでも良く分からないと思う。
>細部までの解説が不十分なので
結論、今すぐ捨てろ。
>>542 C言語で調べれば出てくる上位のサイトで勉強すれ
>>543 Visual C++2008でデバッグをしたところビルドエラーが出たからです
下のほうには「'#include "stdafx.h"' をソースに追加しましたか?」とでています
それはプロジェクトの作成ミスだと思うぞ
むしろ、ちょっとしたサンプルを示すのに、main()のreturnが省略 してあると、わかってるやつっぽいな。 2chあたりで、数行のサンプルだからと思って、returnを省略すると 揚げ足を取りたくてしょうがない厨房が、煽ってきて、 returnが省略できるって知らないのって煽り返すと、涙目で 暴れだして、省略してはいけないって屁理屈を延々と続けるって いつものパターン。
警告でるじゃん
コンパイルエラーを解説する本が必要だな
>>551 よくわからないけど、IDEからプロジェクトの新規作成ってやるか、
パスの設定とかしてコンソールでやるのとどっちがいいかって話?
どちらでもいいけどIDEからやればいいんじゃない?
fsljfだfjぁdぁdfじゃdlfjdfsdg もう、何が何だか分かりません
君にCプログラミングなんてまだ早すぎたんだよ・・・。 素直にhtmlでTable作る練習でもしてなさい。
558 :
デフォルトの名無しさん :2010/03/21(日) 19:29:03
mallocで確保した領域を、使い終わったらfreeで解放する必要があるのですが、 それをやらずにすむ方法はないのでしょうか。 スタック変数の場合、関数呼び出しが終わった際に自動で解放されるのでプログラマは 解放を意識する必要はないからいいのですが。 それずるくありませんか。
alloca
ポケコンでもできますか?
asm文を含むプリプロセッサで専用の「リターンアドレス書き換えちゃうよブラザー」なmalloc作ればいいんじゃないかな returnの後にfree処理を経由して戻る
>>558 一般に、領域の生存期間は静的に決定できない
したがってプログラマ側が明示的に操作してやるしかない
あるいは、ガーベジコレクタを使うか
コンストラクタでmemallocしてデストラクタでfree
main()のreturnを省略してwarning出さないようにするには どうするのが理想的?
void main()
alloca()で取得したメモリをreallocすることは可能?
昔は↑だったな 最近return書かれるように
VCの2008は、int main() でreturn省略しても警告はでない。
○○では、××では〜ってそんな解答ばっかり
そこは出して欲しいところ。 intを返すよと宣言しといて何も返さないんじゃ、いわばプロトタイプエラーだ。
汎用性がないコードだな
>>571 main()は特別扱いだから。
そもそも、リターン値がvoidでない関数で、returnを忘れても
エラーにならないCの仕様をなんとかしてほしい。
575 :
デフォルトの名無しさん :2010/03/21(日) 21:11:03
なんかしらんがmainの戻り値の型をintとするよりはvoidのほうが節約になるんじゃね? 0か1を返すだけでもメモリ使うからな
>>575 規格でmainの型はintと決められてる。
577 :
デフォルトの名無しさん :2010/03/21(日) 21:57:42
reallocでサイズを大きくしたとき、変更前にその領域に入っていた値は消えるの?
C++ならC++スレへ。 VisualStudioの使い方ならVisualStudioスレへ。
583 :
デフォルトの名無しさん :2010/03/22(月) 00:41:56
>>561 ガーベジコレクタをC言語で実装することは可能ですか
C++使えよ
585 :
デフォルトの名無しさん :2010/03/22(月) 01:02:13
>>584 C++なんて私にはとても。Cでもっと学ばなあかんことがたくさんあるんです。特にポインタとか構造体なんかは…
>>583 勿論可能ですが、こんなところでそんな質問をするような人には難しかろうと思われます。
大人しくSTLの勉強をしてC++を使うか、いっそC#でも使っててください。
いつもC++使えって言う人なんなの? きもいんだけど。
int main(void) と int main(int, char**) を 最低限サポートしなくてはならないだけであって 環境依存で他の型をとることに問題は無い 実際 int main(int, char**, char**) とか普通にあるしな(3つ目は環境変数)
>>588 なんでCにしがみついているの?
適材適所だと思うけど。
そりゃさぁ、40過ぎで新しいことを吸収できなくなってしまったようなロートルなら無理もないとは思うけどね。
スレ違い
板違い
ただの気違い
>>590 引数の事は話題になってないとおもわれ。
>>591 ロートルとかじゃなくても組み込みの仕事だとアセンブラはさすがに減ってるけどCが多いよ
あんたが使ってるPCのOSやドライバはC++つかえるかもしれんけど
キーボードやマウスやディスプレイやハードディスクや、掃除機や洗濯機や
おそらくほとんどはC++なんか使えないし使えても無駄だから使わないぜ
つまりCを使わざるを得ないから使ってんでしょ、
そうじゃないならC++を普通に使うじゃん
スレタイトル読んでみればわかるとおもうけどC++を使えって言うほうが、よりおかしい
>>596 なんでC++使えないの?
コンパイラが無いの?
C++、使えますよ
ドライバはCで書くことの方が圧倒的に多いな。Linuxだと。
600 :
デフォルトの名無しさん :2010/03/22(月) 17:06:46
掃除機や洗濯機でC しったかもいいところw
>>596 > 使えても無駄だから使わないぜ
※ここにミッシングリンクの顕著な例が見られます。
> つまりCを使わざるを得ないから使ってんでしょ、
> そうじゃないならC++を普通に使うじゃん
そもそもスレタイ読めない人をかまっても時間の無駄。
C++にすると、メモリもCPUも期待するものがちょっと良くなるから 少しでも部品をケチるとCだよ コンパイラ自体も多いしね(つまり枯れてるから問題も少ない) 炊飯器で、飯炊きクラス継承しておかゆクラスとか作ってるの馬鹿っぽいじゃん
アプリしか作れないゆとり乙qwwwwwwwwwwwwww
C++の話題はスレ違い
C++ はひどい言語だ。これは、多くの平均以下のプログラマーが使ってるために さらに輪をかけてゲロゲロになっていて、どうしようもないゴミが簡単に生産されるようになってる。 正直いって、C を選ぶ理由が C++ プログラマーを追っぱらうため”だけ”だったとしても それ自体、C を使う強力な理由になりうる。
確かにC++でエレガントなソースは見たこと無いな
某バカ売れしてる液晶テレビもCだったな コメントとか//が使えたり構造体の宣言をC++風に書いても大丈夫なくらいのCだったけど
609 :
デフォルトの名無しさん :2010/03/22(月) 17:20:33
>>607 おまえがエレガントといえるCのソースを晒してみろよ
おそらく晒せないと思うがなw
いや別にC++が嫌いとかそういう話じゃなくて、 Cの質問スレで、質問者にC++使えよ、とか断りもなくC++の回答しちゃうやつとか 頭沸いてるんじゃねーの?
断りもなくC++で回答しちゃうのはダメだと思うが、 まさにC++で解決される問題についてC++を勧めるのは間違ってないと思うよ。 質問者がC++を使えない(使わない)と明示してない限りはね。 だって多くの環境ではCと同時にC++も使えるんだから。
「STL使えよ」をNGワードにしておけ
>>612 >質問者がC++を使えない(使わない)と明示してない限りはね。
明示して無くても、質問者がC++を知っている前提で回答しているのがムカツク。
混乱させてどうするのかと。
せめて一言「Cじゃないけど...」ぐらい付け加えておけ。
>>614 それは「断りもなくC++で回答しちゃう」やつだろ。それがダメだってのに反対してる人は居ないよ。
↓まとめ
>まさにC++で解決される問題についてC++を勧めるのは間違ってないと思うよ。 スレたい嫁よ Qホモにもてますが女にもてません、どうすればいいですか? Aまさにホモになれば解決する問題ホモを進めるのは間違っていないと思うよ
\ / .::::::::::::::::::::::::;;:;;::,ッ、:::::: ) く ホ す \ l ,ッィrj,rf'"'"'" lミ::::::: く れ モ ま Y ,!ミ::::::: ヽ な 以 な `ヽ、 | くミ:::::::: ノ い 外 い |、__ ャー--_ニゞ `i::::,rく か は ``''ー- ゝ、'l  ゙̄´彑,ヾ }::;! ,ヘ.) ! 帰 ゙ソ """"´` 〉 L_ っ / i , /| て r ≡=- 〈´ ,,.._ i 't-'゙ | ,へ ,r┘ ,、yx=''" `ー{゙ _, -、 ; l レ' ヽr、⌒ヽ' ゙、`--─゙ /! `、 _,,、- ゙、 ー'' / ; `、 -''"_,,、-''" ゙、 /;;' ,' / 、\ -''" / `ー─''ぐ;;;;' ,' ノ // / ヾ_、=ニ゙
女にもてないのはホモになれば解決するわけではない。 C++を使うことはホモになるのと同じぐらい難しいわけではない。
いやC++使いたいならCのスレ来ないでしょjk
>>612 >まさにC++で解決される問題についてC++を勧めるのは
回答者を馬鹿にしすぎてる。
C++みたいなゴミ言語を薦めると罠だろ
ここの質問者レベルの開発規模なら問題ないよ
俺もそう思う ここに来て聞いてる時点でCの話だと思う そこでC++の話されて、 「ああ、そうか」とか「なるほどその手があったか」なんて人はそもそも極めて少ないと思う >まさにC++で解決される問題 おそらくこういった質問をしてくる場合の一番多いパターンはc++の使用を考えたこともない人ではなくて C++だとXXがあるんだけどなぁCにはないのかな みたいな人だと思う
そうでもないんじゃないかな? 可変長配列なんかはその典型で、C++なら比較的簡単に実装できることを知らない人は実際多いし。 # VCを使っていてさえ知らない輩も! まぁ、いずれにしても噛み付く馬鹿が一番鬱陶しいわけで。
だからって、あーじゃあCやめてC++にしよう って思う人が、このスレの質問者の中にどれだけいるかね? 普通は「Cの回答」を期待するでしょ。 C++の知識があって切り分けられるならいいけど、知らなかったとしたら混乱するだけ。
じゃあC++とインラインアセンブラ使うの禁止な
っていうか1を読めば、もとからそうじゃじゃね C++はスレ違いだし、インラインアセンブラは環境への依存を少なくして書くのは難しいし
>627 あたま大丈夫? Cで実装しなくちゃいけないのに、C++でやれよとかC++の回答もらっても嬉しくないだろ。 (しかも頼んでもないのに!) むしろぶち切れるわ。
> 知らなかったとしたら混乱するだけ。 どうしてそうなるんだw C++の知識を必要なだけ補充して切り分ければいいだけじゃないか。
>>630 それをこのスレで強要するのは間違い。
しかもスレ違い。
CとC++は別物だろ 単純なことで、C++がCの機能を使えるからって CがC++の機能を使えるって訳じゃないでしょ
回答することは強要することじゃないでしょ。
とりあえずC++の回答するなら 一言Cじゃないよって断っておけよ。。
はい。
ま、そもそもスレ違いだし
>>636 いやこのスレ見てると質問者の意図無視して断りもなくC++の回答するヤツが
たくさんいるから、つい。すまんかった。
ずっと前からいるよ。空気もスレタイも読めないC++厨が。
C++に異様に固執する奴ってなんなんだろうな 始めて学んだ言語がC++で、ずっとC++を使ってた結果 それ以外を認めることができなくなってるようにみえるよ
デストラクタやガベージコレクタが欲しかったら別の言語使えって流れだったのでは?
Cに異様に固執する奴ってなんなんだろうな 始めて学んだ言語がCで、ずっとCを使ってた結果 それ以外を認めることができなくなってるようにみえるよ
じゃあ間を取ってJava
Javaこそ仕事で嫌々使う言語代表じゃないか
C言語の入門スレでどの言語が一番とかwww
まあ、あれも複雑すぎだよね。
Javaほどデストラクタと相性の悪い言語もないで
\ / .::::::::::::::::::::::::;;:;;::,ッ、:::::: ) く C す \ l ,ッィrj,rf'"'"'" lミ::::::: く れ 厨 ま Y ,! ミ::::::: ヽ な 以 な `ヽ、 | くミ:::::::: ノ い 外 い |、__ ャー--_ニゞ `i::::,rく か は ``''ー- ゝ、'l  ゙̄´彑,ヾ }::;! ,ヘ.) ! 帰 ゙ソ """"´` 〉 L_ っ / i , /| て r ≡=- 〈´ ,,.._ i 't-'゙ | ,へ ,r┘ ,、 yx=''" `ー{゙ _, -、 ; l レ' ヽr、⌒ヽ' ゙、`--─゙ /! `、 _,,、- ゙、 ー'' / ; `、 -''"_,,、-''" ゙、 /;;' ,' / 、\ -''" / `ー─''ぐ;;;;' ,' ノ // / ヾ_、=ニ゙
>>642 ここがC言語のスレだからじゃね?
きのこスレでたけのこマンセーしてれば殺されても文句は言えんところだ
中間を取るのならObjective-Cだろ これはかなりCに近い
自虐なら許されるから、そこんとこ考えて巧妙に批判しないとさ
凄い前から思ってるんだけど、 いい加減「C/C++なら俺に聞け」ってスレタイに変えてもいいと思うけど Cだけに固執する意味が分からん
>>652 「C++なら俺に聞け」
スレ立ててそこで勝手にやれ
655 :
デフォルトの名無しさん :2010/03/22(月) 21:18:57
Cのメリットは自分で考えた設計・アルゴリズムをコーディングレベルに置き換えられる点だと思います。 Cほど初心者に優しい言語は他にないと思うのです
いや別にどの言語でもできるよ?
凄い前から思ってるんだけど、 いい加減「C/N88-BASIC(86)なら俺に聞け」ってスレタイに変えてもいいと思うけど Cだけに固執する意味が分からん
C++/Java/Objective-C/(C#)についてはなるべく聞かないで 下さい。直系の類似文法であるので答えますが、合っていると は限りません。なるべく専用スレへ。
「C以外は他で聞け」ってスレタイにしたらどうか?
↑ 誰も聞いてないでしょw 回答者がお節介しているだけ
642==652==いつものC++厨
>>642 =652って、単にC言語が書けない奴なんじゃねーの?
だからなんでもかんでもC++で回答して、プログラム書ける俺スゲーwwとか思ってんだろ。
663 :
デフォルトの名無しさん :2010/03/23(火) 00:11:48
いやさすがにC言語やらずにC++から始められる人はいないんでは・・
ちょうど別のスレでC++だけやれば良いとか言ってる人がいるね
そこでC99でう
>>663 普通にいるよ。同様にC++を知らずにJava覚えた人もたくさんいる。
詭弁だろそれは
どこがどう詭弁なのか詳しく
Cを知らずにC++を覚えることと C++を知らずにJavaを覚えることは 同様ではない
JavaコンパイラもC++コンパイラもC言語コンパイラ無しに 製造するのは非常に難しいと思われ Javaはある程度ここから始めてもC/C++をどっかで自習する 限り問題無い水準にあるんじゃねぇがと. さすがにJava一辺倒で押していくのは無謀。 JavaScriptという逃げ道があるんで、行き詰まったらそこに 逃げて充電しながらリタイヤか再挑戦かを決めるのが吉かと C++はCは勿論Javaの素養が必須。 Objective-C?シラね
JAVAだけは学習する気にもならない C++はいつかチャレンジしたい
Javaが一番使われてる言語だろ
Cでは大規模なプログラムは書けないので、C++を使った方がいいです
>>673 C++で大規模なプログラムを書こうとすると散々なことになるよ
>>674 全っ然違う。Javaを覚える前にC++を覚えましょうなんて習慣はない
CもC++も時代遅れ これからはC#だ
これからはHaskellだろjk
プログラミングで必要とされる力の僅か5%の部分の議論ですな しかしその5%の部分が意外な程その後の運命を決定付ける。 Cを選ぶかC++にするかJavaにするか....結構悩ましい問題 じゃないかと...
C#のコンパイラだってC/C++で書かれてるだろ。窓の中に引っ込んでろ
>>675 Java自体がC++を参考にして作られてるのに、お前は何を言ってるんだ…
>>680 やっぱりね。C→C++→Javaの歴史的な流れのことを言ってるんだと思ったよ
別にこの順で学ぶ必要はない。C++の前にはCを学ぶのが一般的だが
Javaはこの限りではないし、初心者がJavaから入るのも良しとされている。GCもあるしね
なぜなら、C++はC+αだが、JavaはC+++αではないから
Objective-C=C+ Java= ((C++)--)++ C++=(Java--)++
>>670 なんでJavaScriptがでてくんだ?
CやJavaと同じ考えをしてたらまともなものができないからこその気分転換ってことかなぁ。。。
一番簡単だといわれているCがまだまともに使いこなせない俺はいつになったらC++とかJavaに行くことが出来るのだろう・・・
>>685 新しい怒首領蜂(東方でもいい)よりも古い達人王の方が難しいだろ?
けど、達人王よりも新しいゲームのほうが覚えることが多いだろ?
そういうことだ。
>>681 単に習慣ってだけならC++の前にCを学ぶ道理もないよ
なぜならCで使えるものがC++で使えないことがあるから
言い換えればC++からαを引いてもCにはならない
Cが一番簡単だというのには賛否両論あるよね。ポインタやメモリ管理が難しいという人もいるし 最初のプログラミング学習に最適だとは思うけど
>>687 C++からα引いてCにならないことと
Javaからα引いてC++にならないことは次元が違う
>>689 は?JavaはC++ + αではないんだろ?αって何よw
それをお前が認めるなら、
>>666 が詭弁であることは自明だな。QED
>>685 新しい言語ってのは、古い言語の欠点を補うために必死なわけだよ。
そのために大抵は何かが犠牲になってる。
C→C++は互換性を保ちつつ新しい要素を入れた。これにより、C++本来の思想とは異なった、
ベターCとして利用するプログラマが現れた。
信じられないかもしれないが、boostはおろか、STLまでもを禁止するプロジェクトが存在する。
C++→JavaはCの部分を切り捨て、VMにより、移植の手間を大幅に省いた。
しかし、パフォーマンスが落ち、VMの制限により、ネイティブなやり取りは難しくなった。
C#は実行時に環境に応じた最適化を行うことで、パフォーマンスの劣化という欠点を補った。
しかしそれでもシステムの深いところを触ることは難しかった。代わりに架け橋となる技術を提供した。
どんどん言語仕様も変化していった。これにより、他のプラットフォームがついてこれなくなり、
結果として同一言語による移植ということが困難になってしまった。
初心者こそCを学べ、という意見も分かるし、初心者はとっつきやすいC#あたりを学べという意見もよく分かる。
個人的にはCから入ったほうが、あとが楽なんではないかなと思っている。
スレ汚しだったらスマソ。
Cから入った方が、コンピュータのことについてよく分かると思う
C++はベターCとして使うに留めるのが正解だよ
>>691 逆だろ能無しw
おまえがJavaからα〜つったんだろw
つーかおまえこそ詭弁並べてるだけじゃん
習慣のみをもって学習の順序とか言ってるし
Cを知らずにC++覚えるヤツは存在する
同様にC++を知らずにJAVA覚えるヤツも存在する
これだけが事実だ
Cを飛ばしてC++を覚えるのと C++を飛ばしてJavaを覚えるのは 同様ではない 後者は飛ばすという概念すら存在しない
Cマスターのみが真のプログラマ。それ以外は文型のえせグラマ。
C++は教材などがCの知識を前提としていることがある Javaの教材でC++の知識を要求されることは普通ない
>>692 >C++本来の思想とは異なった
これって本当なの?
状況によってはベターCとして利用できるのは
狙ったものだと思ってたんだけど
>>695 なんで同列に並べるんだろ
Cを知らずにC++なんて例外的で普通じゃない
C++やらずにJavaの方は、perlやらずにRubyくらい普通
何でおまえらはそんなに頭が悪いんだ…
それらの習慣の話が
>>663 の「CやらずにC++始められる人はいない」の理由になると思ってんの?
現実にオレの知人だけでも数人いるんだからそんなもの根拠にすらならないよ
おまえらが理由と思ってることは単に「知っていた方が入るのにラク」レベルの話
実際はCの書き方とC++の書き方は同じ部分のほうが少ない
それも当然で同じ書き方をするのであればC++を使うメリットが無いからだ
C++は自由すぎるからね あくまでCとして、融通の効かないところはC++を使う これがベターCとしてのC++を使うメリットでしょ C++から始めるとそうは思わないから、Javaから始めることと同様に語っちゃうのかな
Windowsプログラマ : C++から入る奴は普通にいる UNIXプログラマ : Cを知らずしてC++が習得できるわけない
if(x==y==z){
if(x==y==z){ } と書くと条件分岐がうまくいかないようなのですがこの場合はどうなっているんでしょうか。
if (x == y && y == z)
x=2,y=2,z=2 if(x==y==z) ↓ if(2==2==2) ↓ if((2==2)==2) ↓ if((1)==2)
不毛あるいは屋上屋な議論が続く中清涼剤のような輪を かけて不毛な話題tnx ただし、なんだかんだいってCは星の数ほどあるプログラミング 言語の中でもやはり別格。まともにOSを作った実績があるのは ほぼCのみ
void Func00(int a){ a++; } void Func01(int &a){ a++; } void Func02(int *a){ a++; } int main(void){ int n = 0; Func00(n); printf("%d\n", n); Func01(n); printf("%d\n", n); Func02(&n); printf("%d\n", n); } このプログラムを実行させる前は「0、1、(不定値)」 と表示されると予想していたのですが、実際は「0、1、1」と表示されます。 nのアドレスをFunc02へ渡して、そのポインタのアドレスをインクリメント(a++)しているので、 可笑しな値が表示されると思ったのですが・・・ 関数へ変数のアドレスを渡して、そのアドレスの場所を変えているのに、 なぜ呼び出しもとのアドレスは変わらないのでしょうか?(*a)++の場合は値が変わりますが・・・。
申し訳ないです。 ”アドレスのコピー”を渡しているから、変わらないのですね。 書き込んだ直後に理解しました。
>>709 Func00 を呼んでも n が 0 のままなのはわかるんだよね?
それなのになんで Func02 を呼んだら n のアドレスが変わると思うのか
よくわからないよ。
うは
慣れないうちはポインタを引数や戻り値にした場合、 ポインタ自体も普通の変数だということを忘れそうになる。
Delphiも書けないやつがCを語るんじゃねえ!
誰と戦っているんだ
どっかのスレでDelphiをDelfaiとか書いちゃったやつがいたんじゃねーの それで怒り狂って誤爆 なんていうかDelphiとそのユーザーの生き様をあらわしてるよな けっしてDelphi悪くない、というか結構良くできてんだけどな なんでか流行らんよな
何で文字列リテラルを途中で書き換えられないんですか?コンパイラ作る人がちょっと頑張ればすぐできるようになることだと思うんですが。そうできない問題が何かあるんでしょうか。
言わせんなよ、恥ずかしい。
>>717 すぐできると思う理由が分からない
書き換えたければコピーして使えばいいだけのこと
書き換えたくないものを使える仕組みも欲しかったんじゃね?
例えば char* p = "abc" として、aが1000番地、bが1001番地、cが1002番地に格納されているとして、 p[1] = 'd'; と書いたら1001番地の内容を'b'から'c'に書き換えるだけだと思うんですが コンパイラの人の立場ではこれは難しいんでしょうか。 できないことは知ってるけどできない理由が分からない。
>>721 セキュリティの観点からコード領域は保護されるべきということでわざわざ書き換えができないようになっている
大昔のコンパイラは変更できた。(というより保護できなかった。) 大昔というのはCP/M用のWhitesmiths-CとかBDS-Cとか。
書き換えられることが原因で何か重要な問題が起きるんですかね
うちのコンパイラは警告も出さないし、書き換えちゃうぜ
実行可能な領域であるコード領域を書き換え可能にすることによるメリットより、
デメリットの方が大きい。
わざわざクラッカーに攻撃手段を与える必要もないだろう。
文字列リテラルは、変更を要しないので、メモリ空間上ではコード領域と同じページに置かれる。
変更したければ、
>>719 のように変更可能な領域にコピーして使えばいいだけの話。
リテラル文字列をコード領域に置くって、どんな環境&コンパイラ?
あ、もしかして文字列リテラルって寿命がないのかな。 char* p; { p = "abc"; } printf("p[1]:%c\n", p[1]); こういうプログラムも間違いじゃないのか。。
>>717 それは逆で、昔の環境&コンパイラだと普通にできた。
データけでなく、自身のコードの書き換えもできた。
最近はそれをできないようにする環境(保護機能)が整ったので、
コンパイラもそれをサポートするようになった。
>>723 DOSでもできたよ。(できたというのは保護されないという意味ねw)
Lattice C、MS-C では普通にやってたから。
そもそもCである以上キャストすればできるわけで、
それを例外とするのはシステム側の機構だよね。
>>729 コンパイラだよ。
そこからコンパイル時にアドレスを確定できるメリットが発生する。
>>728 こういう関数もありだよ。つーか、割と常套手段だったりする。
static const char * foo() {return "foo";}
いや、今でもオプションでリテラル文字列書き替え可能にできるだろ。 たしか -pedantic だか何かだった。 同じ内容のリテラル文字列でも同一化せずに 別々に用意して、書き替えに対応してたはず。 char *a, *b; a = "hoge"; b = "hoge"; これで最適化しても a != b になる。
へーーーーー
736 :
デフォルトの名無しさん :2010/03/23(火) 17:17:06
>>734 これってどういうことなの?
あらかじめ確保してないところに書き込むとエラー起きるんじゃないの?
>>734 内容が同じリテラル文字列が別々のところで定義されていると、
それらをまとめてメモリを無駄遣いしないように最適化を行うコンパイラが存在する。(こっちのが主流だけどw)
そうすると別のところで定義していても a == b となる。
このためリテラル文字を書き換えると全然関係ないところの文字列も変わってしまい笑えることがある。
昔のCのプログラマなら常識。けど今の子たちは知らないw
そこから教えてあげないと。
740 :
デフォルトの名無しさん :2010/03/23(火) 17:30:32
なんだわからないのね
>>736 > a = "hoge";
これは、どこかに確保された文字列リテラル"hoge"の先頭のアドレスをaに代入しているだけ。
"hoge"をコピーしているわけではない。
>>738 > 環境は言えない。
なんで?
>>741 >
>>738 >> 環境は言えない。
>なんで?
ほんとは -pedantic じゃなくて -fwritable-strings なのに、間違えたのが恥ずかしかったから。
なるほどメモリを無駄遣いしないためにこうなってるのか。 文字列リテラルを書き換えようとしたときにそういう風にコンパイラがエラーを言ってくれればいいのに。 ただsegmentation faultとだけ言われても分からんし。
それランタイムだからコンパイラ関係ない
>>743 書き換えるのは実行時だよ、コンパイル時じゃないんだから、コンパイルエラーにはならんよ。
だから実行時にメモリを書き込もうとしたときにシステムが検知して例外エラーが発生している。
これはCの駄目なところであり、良いところでもある。
>なるほどメモリを無駄遣いしないためにこうなってるのか。 違う。 知らずに文字列が書きかえられるとバグのもとだから、書きかえが禁止されている。 char *getTemporaryFilename() { return "/tmp/temporaryfilename"; } char* p = getTemporaryFilename(); strcpy(p, "/etc/hosts"); されるといやじゃん。
アホでつか? 数値リテラルも文字列リテラルもユニーク(意味などないのですが 当然意味も変わることがありません) そしてアドレスなどありません。(アドレス演算子も使えません) 次の書式 char *q="ABCDEFGGH"; char p[]="ABCDEFGHJ"; これらはシンタックスシュガー(慣用表現)に 過ぎず「正式」なものではありません。多くのコンパイラが 鷹揚に char p[]={'A','B','C','D','E','F','G','H','I','J','¥0'}; char *q=(char*)&p[0]; と解釈してくれるだけのことです。
>>746 いやそれは違うぞ。
C言語は文字列の書き換えを検出する方法がないんだよ。
>知らずに文字列が書きかえられるとバグのもとだから、書きかえが禁止されている。
C言語で書き換えに禁止にしたりはしない。リテラル文字列を警告なしで char * で受けれるんだから。
書き換えられて困る場合は、プログラムが
const char *getTemporaryFilename()
と宣言して、少しだけ抵抗することができる。
>>747 あほですか?
char *q = "abc";
と
char p[] = "abc";
は全然違う。それに、昔は
char p[] = "abc";
とは書けず、
static char p[] = "abc";
しか許されていなかった。
その心を理解してから書き込まなきゃだめね。
おっと char *p="ABC"; は 少なからずのコンパイラは const char pp[]={'A','B','C',0} char *p=(char*)&pp[0]; と何故か解釈してくれます。 さらに「親切な」コンパイラはおせっかいにも 書き換えるとエラーになる領域にppを初期化して くれることでしょう。 "ABC"は何故書き換えられないかという問いは "ABC"は変数ではないから というのが正解ですが、書き込み不能な変数 だとか書き込み不能な領域に勝手に設定するのは 一部のコンパイラです。
日本語でOK
>>751 またまたアホですか?
char *p="abc";
と書くとき "abc" が格納される領域はスタックとはかぎらない、ことを再三申し上げているのですが。
寧ろ、普通はわざわざスタックにコピーするコストを避けてバイナリモジュールがロードされた空間をそのままポイントする。
756 :
デフォルトの名無しさん :2010/03/23(火) 18:08:45
ちょっと質問なんですけど、メモリのアドレスって00000000からFFFFFFFFまでしかないじゃないですか。 この範囲を超えたアドレスはどのように表すんですか?
>>749 ,
>>751 は文法の知識だけで C を理解したと勘違いしている。
スタックとかヒープとかテキスト領域、BSS とかを意識していない。
>>756 その昔、アドレスをあらわすのにセグメント+オフセットで表現していた環境がありまして‥‥‥。
>ちょっと質問なんですけど、メモリのアドレスって00000000からFFFFFFFFまでしかないじゃないですか。 >この範囲を超えたアドレスはどのように表すんですか? アドレスがその範囲しかないなら、この範囲を超えたアドレスって存在しないんじゃないですか? アルファベットってAからZまでの26個しかないじゃないですか。 この範囲を超えたアルファベットはどのように表すんですか?
1個目のやつとか2個目のやつとか、指定できたりする あるいは、バンク切り替え命令みたいなのがある 後半***あたりを(物によって違う)ごそっとバンク切り替えて使ったりする
>>759 後者には答えがある。記号を付加して使う。
á, ä, à, ã, ç, ÿ などがそう。
64ビット整数ならもっと表せる
>>758 その答えは、質問が
「メモリのアドレスって0000からFFFFまでしかないじゃないですか。」
というときに使ってくださいw
64kBなんて広大なメモリ空間を使いきれるはずないだろJK
765 :
デフォルトの名無しさん :2010/03/23(火) 18:32:13
すいません。質問の仕方が悪かったようです。 C言語のアドレス演算子で求められるアドレスは8桁の16進数じゃないですか。 C言語で4GB以上のメモリの扱いはどうなっているの?ということです。
>>765 コンパイルオプションを変えたら分かるさ
>>765 そんなもん、C言語の種類による
君が使ってるC言語の種類を書けばすぐに答えてやるから
>>764 僕のパソコンはRGBをプレーン切り替えしてるんだぞ。すごいだろ。
769 :
デフォルトの名無しさん :2010/03/23(火) 18:41:11
>>767 Borland C++Compiler 5.5.1です。
>>769 それ 32bit だからアドレスは 4GB までしか扱えない。
intってサイズが規格で決まってないよ 環境やコンパイラしだい
アドレスのビット幅は C 言語の仕様とは関係ない。 Borland C++ Compiler 5.5.1 が 32ビット CPU のためのコンパイラだから 32ビットになってるだけ。 アドレス長が 64 ビットの CPU 用のコンパイラならアドレスは 64 ビットで 8 バイト。
64bitOSをつかいませう
先生! func(...)(xxxxx); の形をした関数あるんですが、なんでこんな形なの、どう解釈するの 関数に()()が2つあるって...
>>774 ... と xxxxx の部分をちゃんと書けよw
>>774 こんなん?
#include<stdio.h>
typedef void (*func)(void);
void hello(void){
printf("hello\n");
}
func foo(void){
return hello;
}
int main(void){
foo()();
return 0;
}
func(s->scriptptr)(s, s->scriptptr);
文字列の16進アドレス値をポインタの数値に変換するには?
トリッキーな書き方だこと 今時流行らないって カッコつけて書くと ( *( foo() ) ) () わかりやすい
780 :
デフォルトの名無しさん :2010/03/23(火) 19:57:06
>>777 func が関数へのポインタを返すので、その関数のポインタが示す関数を呼び出しているだけのこと。
関数へのポインタから関数へは自動的にキャストされる。
>>779 余計にわかりにくいぞ。
百歩譲って
(*foo())()
だな
32ビットCPUでlong longが使えるのは何故ですか。 しかしtime_tは32ビットです。これは何か理由があるのでしょうか。
別にlonglongを1つのレジスタに乗せる必要もなし
>>783 long longが使える32ビットCPU
でlong long が使えないのは何故か?
というのならわからない。
使えるのは何故かというのはわかる?
time_tが32ビットなのはきっと2038年
問題とかを発生させたいという理由じゃないかと..
キミは邪推するのかな?
じゃすい?
>32ビットCPUでlong longが使えるのは何故ですか。 ソフト的に複雑な計算をしているから >しかしtime_tは32ビットです。これは何か理由があるのでしょうか。 その環境の制限
七八三です。 回答ありがとうございました。
>>780 アンダースコアをスペースに変換してみると、32ビット符号無し整数の内部形式(2進数)を
考え、1のビットを左詰めにしてるようだ。このソースだと 0〜0x7fffffffの間は動作するけど
0x80000000を超えるとバグる。宿題スレでも質問してるみたいだけど、2進数、ビット演算、
3項演算子の知識が無いと、ソース見ても分からないかもね
http://codepad.org/VC9NYyKN atof の逆のftoaを外部関数を呼ばずに書こうと思ったのですが float d=456.456 を ftoa(s,d) すると 456.456000000.... となってしまうのでこまってます(コードパッドの出力、23行目)
自分の環境では(ubuntu10.04(64bit) gcc4.4.3)なぜか 456.456 となります。コードパッドでも456.456と出力されるようにする方法がわかりません
お前ら、ありがトン
>>782 の(*foo())() で何やっているかわかったよ
>>790 %.3fとかにすりゃいいじゃん
.20って欲張りさんだろ
textファイルで 41424344と16進数のデータがあります。 これを ABCDに変換したい場合どうすればいいのですか? たとえば 41に0xをつければいいような気がするのですが、 どうやってつければいいかわかりません。 41読み込んだエリアがbufとして、"0x"+bufとかはだめっすよね。 お願いします。
その41は16進の41なの?(つまりデータにはFFとかも入ってるの?例だと数字ばっかだけど) 十進の41を十六進にして、なの? sprintf("0x%d",buf) か sprintf("%x",buf) じゃね
41という10進数の数値としてbufに読み込んだんなら buf / 10 * 16 + buf / 10 最初から16進数として読み込むなら fscanf(fp,
途中で書き込んだ fscanf(fp, "%2x", &buf);
ミスった。 buf / 10 * 16 + buf % 10 だった。
直接fscanfだとフォーマットエラーに弱いで
つ[strtol()]
( ^ω^)いやいやおっおー
1. char buf[2] と long xを用意 2. bufに2バイトずつ読み込む 3. x = strtol(buf, NULL, 16); 4. xの内容をどうにかする 5. 2へ戻る
>>802 つーか間違ってた。char buf[3]だなw
読み込みはasciiでもbinaryでもいい。
>>802 テキストファイルで4142〜なんだから、binary表示すると34 31 34 32〜でしょ
>>804 いやいや 33 34 33 31 33 34 33 32 という状態で読まないといけないから4バイトずつ読むべき
って流れに持っていけばよろしい?
,,-‐----‐、 , -'"` ̄ ̄"`''-,__, --‐‐-.., / 、゙ヽ、 ‐-'´ ヽ‐- / / ヽ ,/´ .., ヽ,,l_)' zェェェァ' ;rfァt ヽ ,ト/ / ヽ / ヽ,r' ,l′ _,,, . __,, ,l゙.-〈__r,'、 ヽ_ _.l ヽ」 ,l .イてソ` l イにj`,/ ゙‐ヽ、_,, /l ここおかしいんじゃねえか? ,l l| −'´ll ,l rソi" ヽ じ'' f゙l .,//゙l //\ l`l| l|ヽ v'⌒ヽ .,ノ j/ |l // } l \ l| ,l l_U> r‐--‐ァ ,l |,l // l / '\ l|`l ゝ_,´ ゙ヽ__r′ .,.' ___l ヽ // | ,l '\ l| .lヽ__lL..,,, __ ,, _イ___./ | ∨/ ,} | ヽl | ,| .ヽ \ //ヽ ,| ,l | l ,l ヽ \// l \ / ヽ | \. ヽ/ l ヽ /j \ / ヽ ヽ | l / ゙l\.. / ヽ ヽj | , / ヾ ヽ ヽ ヽ / ,l ヽ、 ヽ l } / ,r′ ヽ ヽ | /′ ,,...'' `'':..、 ___ ___,..-.. |, ,l , :..-‐'"´  ̄ /lr‐‐‐'--、_..... l_,..-'''""'
つーか正確な問題を教えてくれ
質問。 .net系の言語にある、timer関数。 一定期間ごとに指定関数を呼び処理を行う関数ですが、 この機能と類似した処理を行うのに参考になるページを教えてください。 例:Aメソッドの処理時間 20-350ms Aメソッドの処理時間に関係なく、500ms毎にAメソッドを呼び出す。 ちなみにgccです。
alarm は危険
スレッド作ればいいだけじゃね
>>808 wait する前に現在時刻と以前の時刻を調べればよかろ
時間が着たら教えてくれる子プロセス作るとかは? あとよくわからんけど、Aメソッドの処理時間に関係なくってことは割り込みみたいに 関数が2重3重に動く必要があるんじゃねーの?
だからスレッドなんじゃね? forkでもいいけど
ck: switch((gettime()>t+500)?0:++i){ case 0:t=gettime();A();break; case 1: // 物凄く時間のかかる処理を分割した其の1 goto ck; case 2: // 物凄く時間のかかる処理を分割した其の2 goto ck; defaulet:break;}
別にいーじゃん
>>816 main 関数は必ず int を返すように教わったんだろうな、ぷっ
>>816 INTを返すのが仕様なんだろ?仕様である証拠もってこいや。
ぱーどぅん?
>>816 main()については
1. int main()
2. int main(int argc, char **argv)
3. 1.2.のコンパチ
4. 環境による
と定義されてる。環境次第で void main() もあるということ。
余談だが、main()の戻り値が省略されたとき、C99では
戻り値がintだったら0を返す、とも規定されてる。
つまり、「戻り値がintでないこともある」ということがここでもわかる。
>>823 void でいい場合があるのに、駄目とか言う方がおかしいだろ。
そもそもCの規格なんて何種類もあるのに、
全部に当てはまるコードなんて書けるわけないんだよ。
もし最初質問者が「〇〇の仕様に準拠する形でお願いします。」
とか書いてあるんなら別だが、そうでないのにどんなコードで書こうと自由だろ。
あと参考までに聞きたいが
君の推奨する「JIS X3010:2003」に完全準拠したC言語って実在するのか?
>>824 > void でいい場合があるのに、駄目とか言う方がおかしいだろ。
今まで何度かPC環境で void main(void) で終了コードが不定なプログラムに
悩まされたことがある。やめてほしいんだ。
> そもそもCの規格なんて何種類もあるのに、
> 全部に当てはまるコードなんて書けるわけないんだよ。
誰もそんなことは頼んでない。
> もし最初質問者が「〇〇の仕様に準拠する形でお願いします。」
> とか書いてあるんなら別だが、そうでないのにどんなコードで書こうと自由だろ。
それは自由だが、無駄に対象環境を絞る意味も無い。
> 君の推奨する「JIS X3010:2003」に完全準拠したC言語って実在するのか?
特定の規格を推奨した覚えはないんだけど、「完全」というなら実在しない
可能性のほうが高いだろうね、とは言える。だからどうだということもないんだけど。
void main(void)が原因ってのなら元のソースはあるんだろ?書き換えてコンパイルすりゃいいのに
>>825 PC環境っていう環境に限定した話だろ、それ
勝手に悩んでろクズ
そのソフトの終了コードが不定という仕様を曲げて使ったおまえが悪いとしか。
>>825 >今まで何度かPC環境で void main(void) で終了コードが不定なプログラムに
>悩まされたことがある。やめてほしいんだ。
void で宣言してるんだから、終了コードを返す意思などないということだよ。
終了コードを返さないプログラムの戻り値を見るというのが間違い。
もし int で宣言されていて固定の0が帰ってきても、正しいエラー番号が帰ってくる保証などない。
こんなことはプログムの仕様がどうなっているかの問題であり、それがわからない状態で
エラーコードに依存した処理を行おうとしていることが根本的な過ち。アホ過ぎる。
main を int で宣言したところで、なんの問題解決にもならない。
>>825 >無駄に対象環境を絞る意味も無い
そのとおり! いいこと言うね!
前提もなしに「PC環境」とやらにいきなり限定する必要も無いからな。
想定できることは全て想定してから、ひとつずつ潰すのが大事だ。
いきなりPC環境の話に絞った話を始めてもしょうがないし。
>>825 悪いことは言わないから、
JISの仕様を気にする前に、社内の仕様を確認した方がいいよ。
void main 必死だな
>>825 戻り値を見る必要があるのにvoidで宣言したプログラマに
仕様を問いただすのが先決だと思うよ。
そしてコードレビュアをひっぱたくのも忘れずに。
もし、組込み分野等から持ってきたソースを流用してるとか
そういうのなら自分の脳の出来を疑うのが先。
このあたりは特に動作環境や言語仕様には関係ない話かな。
これを以ってvoid mainは撲滅じゃい!と言い出すのはお門違いだね。
こういう話では盛り上がるのに質問にはろくに答えないのなw
せっかく答えた人の揚げ足を取るような発言してるのはどっちなんだよ
自転車置き場の話はほんと盛り上がるわ
総理を見ているようだ
プロセスの戻り値が意味を持った時代は プロトタイプ宣言無しで未定義の関数を バシバシ書いたCコードがコンパイルで きた古き良き時代と重なる 今では考えられないくらい小さなシステ ムだけど(メモリ8Mバイト、HD 20Mバイトw プロセッサクロック 20MHz。これでも当時200万円 はした)
>>839 お前がプロセスの戻り値を使ったことが無いだけじゃね?
>>839 この時代のC言語は void というキーワードすらなかったよね。
>>839 LinuxだろうとDOSだろうとWindowsアプリだろうと
プロセスの戻り値は今でも重要な意味を持っています。
>>842 Windows のアプリなんて 0 しか返さないよ。
そんなもんチェックして何がわかるの?
今のシステムでは、うNIXでも最早プロセスの戻り値は 使わないほうが(精神衛生上)良い 使えないツールが増えているから 軽量DB経由ってのがよさげ
>>843 強制終了されたりすると0以外(1とか)が返る。
電卓を起動して、タスクマネージャで殺してみるといいよ。
>>844 起動スクリプトを読んでからもう一度ここに来い。
Windowsだってエラーコード(プログラムの中でリターンしてるやつ)が帰るよ ただ半分の256には死んだ理由が入ってるよ メモリ取れないとか、強制終了とか 正常終了なら自分が返してるやつ
>>846 あのね、それはシステムが1を返してるんだよ。
プログラムの main で値を返すようにしてあっても無視されるの。
だから意味がないと言ってるんだよ。
Windows標準のプログラムでさえ、戻り値は常に0としてるのに、
他のところで作ったプログラムの戻り値に統制などあるはずもない。
常識知らずにも程があるよ。
むかしよ、WindowsのMSDNについてる新聞あるじゃん英語のやつ あれのDr.ナントカのコラムで 「ねえねえドクター、ウインドウズはmain関数はvoidで良いの?」みたいな外人の質問があって 「WindowsもOSがプロセスの戻り値見てるからゼロ意外だと処理が違う さらにvoidだと余計なことしなくちゃいけない 小さいことだけどmainから始まるプログラム書く人はWINDOWSに優しい気持ちになって voidやめてreturn 0をちゃんとしてくれ」 って書いてたよ もちろんUnix系ならなおさらint mainだろうけど Windowsに冷たくても平気な人だけvoidにすれば?
そもそもプログラムのリターンコードを返すのに、 main の戻り値なんかに頼るとか。もうアホかと。 エラー処理ならそのままexit関数呼ぶでしょ。なんで main まで戻すの。 それに Windows のアプリケーションで main 関数なんか定義しないでしょ。
>>849 これって何に使うAPIだと思う?
GetExitCodeProcess
>>849 例は不適切だったな。
とにかく失敗したら0以外、成功したら0が返るってのが
仕様として決められてるので、それに則るべきだろう。
わからないときは0にしとけってことだ。
>main で値を返すようにしてあっても無視されるの あ?本当にそうか?んなわけねーべ 今まで何度も子供に仕事させてその成否を親に返すみたいなプログラム作ったぞ お前らにとってGetExitCodeProcessとかは何なの?
>>851 いい加減なことばっかり言うな。
>WindowsもOSがプロセスの戻り値見てるからゼロ意外だと処理が違う
どう違うの言えよ!
int main() で宣言して return 1; したらどうなるんだよ?
システムがクラッシュするの????
>>852 exitで返すのとmainのreturnで返すのは
意味的にどっちも同じです。
>>856 しねーよ、それは値を返しているのだから
ゼロとは違うけどクラッシュはしねえ
voidでもクラッシュはしねえ
でもなんか余計なことやらんといけないからintで書いてくれって話だよ
もちろんいい加減な記憶で書いてるよ
>return 1; したらどうなるんだよ?
親プロセスが起こした子供ならその値を取得できるよ
>>853 >>855 GetExitCodeProcessで得られるのは、終了ステータスであって、
プログラムが返すリータンコードじゃないよ。こんなことの知らずに使ってるの???
リターンコードの時もあるけど、そうじゃないときもある。
というかこれを利用してどういうプログラム組んでるの君ら?
これで main の戻り値拾ってるの?????
>>856 その場合、そのプログラムはエラーを検知して終了したとみなす。
外部アプリを起動するプログラムを書くときは
そのプログラムが正常に動作したかどうかを戻り値でチェックする。
だから、わからないときはゼロにしとけとなってる。
>Windows のアプリケーションで main 関数なんか定義しないでしょ。 ビジュアル系のプログラマの方ですね 世の中にはまだまだmainから始まる黒い画面見て仕事してる人もいっぱいいますよ
>>859 GUI しか知らないっぽかったからお前のために Windows API を挙げただけだよ
>>858 >親プロセスが起こした子供ならその値を取得できるよ
できる場合もある。だろ。
>>861 >世の中にはまだまだmainから始まる黒い画面見て仕事してる人もいっぱいいますよ
だから、Windows 環境では通用しないと言ってるんだろ。
>>864 同じじゃない。
プロセスが既に終了した場合は、終了ステータスとして次の「「「「「いずれか」」」」」が格納されます。
?ExitProcess または TerminateProcess 関数で指定した終了コード。
?プロセスの main または WinMain 関数の戻り値。
?プロセスを終了させた、まだ処理されていない例外の例外コード。
>>865 あのなー世のすべてのWindowsプログラムがWindowを持ってるわけじゃないのな
cmdで立ち上がってくるコマンドラインってもしかしてWindows環境じゃないと思ってるのか?
>>866 同じだよ ちょっと上のほうで誰かが書いてるだろ
Unixでも強制終了のときはreternの引数なんか入らないで
osが詰めた強制終了とかメモリ確保失敗とかが入るって
>>867 コマンドプロンプトでの %errorlevel% でも同じなんだよ。
プログラムが特定のエラーコード返していても
強制終了すれば %errorlevel% は1 になる。
>コマンドラインってもしかしてWindows環境じゃないと思ってるのか?
それはお前のことだろ。
>>852 お前は一辺WinMainの戻り値の型見てみろよ
>>869 で、それが理由で main は必ず int で宣言するの。
すごいな会社だな。もう笑うしかないな。
メインの最後に行く前に落ちたらreturnの値が入るわけないじゃんな いずれかが入って当然 それを拾える*場合*もあるだろ、とかえらそうにさ 子供が万引きして、「取れるような状況にしておくのが悪い!」とか言う親みてえ
>>871 だからね、見れば main の int 宣言が意味ないことがわかるだろ。
ふつう何も考えなくintだよなあ っていうか、そういう小さいけどちゃんとした理由すらあるのにvoidにしてる会社のほうがすごくね?
ゴルフ目的ならmain(){}だろうしvoidに拘る理由が分かんないな 警告気にしない人なのかな
入門書でintになってるんだからintでいいだろ
>>866 mainからのreturnもExitProcessだって知らないの
>>877 void mainの方はただの遊びだろ
void main()は文法上許されてるわけだし特に問題ない。
returnしろといわれてる環境でvoidでいいじゃんというやつは
頭がおかしいけどな
>>870 >強制終了すれば %errorlevel% は1 になる。
強制終了じゃなくて、子供が仕事終わってそいつが正常に終了したときに
値を見たいんですよ、どうだったかとか
>>876 何にも考えてないから int なだけであって、
真面目にプロセスの実行結果を利用することを考えるのであれば、
もっと意識しなければいけないことがあるということ。
そういうこともわからず、盲目的に int にすればいいと思ってるのが馬鹿なの。
リターンコードのことを意識して組まれていないプログラムであれば、
int でも void でも変わらん。
あれ?なんかvoid氏の意見が当初と変化してるようなwww int意味なしとか、戻り値0とか威張ってなかったっけ?
voidにするコレといった理由はないのだから 「盲目的にint」は推奨こそしても批判する理由なくね? gotoとかと違ってさ
>>881 で、その時にどんな値を返せばいいの?
わからないでしょ。
そういうことがわかった上で、リータンコードに関しての仕様も決めて、
そういう状況で始めてリターンコードが使えるようになるんだよ。
何にも決まってない状況なら、何を返しても問題ない。
DOS、Windows、Unix、Linux、、、等の処理系であれば、
どんなリターンコードを返しても問題ないことが保証されている。
つまり void でも問題ない。
そうじゃない処理系があるんだったら、そのときはその処理系の条件を
満たすようにリータンコードを返してやる必要があるのは当然だけどね。
>>884 void を盲目的に否定するのがおかしいと言ってる。
最初から変わってない。
元は
>>816 の発言に対するもの。これがおかしい。
>で、その時にどんな値を返せばいいの? >わからないでしょ。 お前馬鹿じゃないの?わかるよ unixだと下位バイトしか使えないから256通りの値を遅れるよ 上位バイトには強制終了とかの時にOSが値を入れる (Windowsでもそうだと思ったが64bitWindowsで確認してない) そう言うのって何を意味させるかは仕様で決めるんだよ
あえてめんどくさいこと避けたいなら void盲目的に否定はアリじゃね? 何も困らないじゃん
>>885 そんな処理系はないだろw
仮にあったとしても、その処理系では return 0; が問題かもしれないよ。
リターンコードは意味はないわな。
>>887 だから、そういうはっきりした仕様があって、
それに準拠するプログラムを作る必要があるときに、
int にする必要があるということでしょ。それ以外はvoid でいい。
なんでここで質問に回答するときに、そういう仕様調べて準拠する必要があんの?
質問者が要望してるんならわかるけどね。
>>885 少なくとも、DOS及びLinux系Unix系では
戻り値はちゃんと返してもらわないと、困る。
戻り値が0以外のときは検知して異常シーケンスに突入
ってのが一般的だからな
なんだかんだいってvoidさんが明日あたり会社で後輩が void main() って書いてたらめちゃくちゃ馬鹿にしそうww 「〜って理由がアンだよ!プンプン」ってかんじで なんか書き込みとか違う人が書いたことにしようとしてるし
で、上司やら先輩のintさんに ぼこぼこにされると
>>880 遊びと言われれたら返す言葉はないな。
>>884 だよね。
>>886 偏見だけど
void main() とわざわざ書いちゃうような人は
定型文ですら毎回毎回全部手入力してる馬鹿に思っちゃう。
void にも深い理由があるとわかったよ。 確かに何も考えず int としてる奴は多いからな。
↑ なに他人の振りしてんだよww めっちゃバレバレな感じで voidでも許されてるってだけで意味なんかひとつもなかったじゃんww
ワロタ
>>890 逆だ。
voidにする明確な理由が無いときは、
int型にして戻り値を0とする のが正解になる。
普通は戻り値を見ることになってるから。
これはひどいwww
0にする 、じゃないな。 「仮に見る人がいなくたって戻り値を適切に設定する」 が正解だな。
int FAR PASCAL WinMain()
>>902 おめーのバカな質問疑問に答えてやっただろ
void main でも質問に答えてくれる方がありがたいでしょ。
入門編ならば int main() にしとけ →ぐだぐだ論争の種になるので アプリ終了時に malloc したものは free すべきなの? →それは聞いちゃイカン
>>906 freeしといた方がいいよな。
終了時の解放はただの親切機能だし。
喰らいボムが実装されてるようなもんだろ。
必ずallocと対のfreeを確認する習慣は、何度か俺の命を救った もうアプリは死ぬんだからfree書かなくても良いなんて 「生理だからゴムなしでいっか」って言うようなもの 書いちゃってから「あ、ここ最後だからいらないんだ」とか言ってわざわざ消してるやつは性病で死ね
void main ってのは言わばパンチパーマみたいなものだ 初対面でも見た目がいかにもという人はそれ相応の対処を取るだろ? void mainも同じ 最初にカマしとけば相応の目で注意深く見てくれる ま、ある種の優しさだな
CFAQかなんかだと思うけど
クソな参考書見分けるコツは?ってのに対して
void mainって書いてるやつは買うなってのがあったと思う
>>909 後輩がお前のこと笑ってるぞ「voidの、あ、voidさんのソースってくそっすよね 読む気しねー」って
>>909 困ったときに、
助けてくれたパンチパーマの人と何にもしてくれなかった七三分けの人だったら、
僕はパンチパーマの人に感謝しますよ。
>>910 参考書に書いてあることは丸暗記できるけど、
応用力はなくて自分ではコード書けない人の典型ですね。
void先輩は悪くないスよ
作ったおもちゃを見てもらいたかっただけなんすよね
>>815 それをみんな、よってたかってフルボッコにして
あ、でも先輩ちょっと俺に話しかけるの止めてもらえないですかね
ホラ俺達までvoid mainだと思われるのはちょっと
>>908 そういうこと気にしてたら exit 関数が使えない。
大きなプログラムではエラー処理が滅茶苦茶煩雑になる。
こいうのはケースバイケースで、メモリリークを起こさなければ問題ないでしょ。
自分でフリーしない方が速いし。
>>916 どんな結末を夢見てる?
何も考えてない?
>>917 メモリリークを起こさないようにプログラムを組んでたら
普通はalloc/freeの対応は付くと思うのだが・・・
どんなOSとコンパイラと状況でmallocで確保したものをfreeせずに終了して不具合が出ました? 煽りとかじゃなく、純粋に知りたいんですが
>>917 例外的に明示的にexit()するときは、もうどうでもいいだろ
>>919 エラーとかの例外処理でそれを貫くは無理でしょ。
大きなプログラムの場合だよ。
致命的なエラーだったら、エラー報告してそのまま終了することもあるでしょ。
変数を初期化しないことのどこに問題あるの? この次元の議論
>>921 聞いた話だが、alloc/freeにラッパーかかってたときかな
メモリの代わりになんか違うリソースを取得してたらしい
malloc/freeで作ってたのを単純置換したとかなんとかで
>>921 不具合が出るとすれば、そっちの方が問題だよ。
メモリリークじゃないんだから。
>>923 お前のプログラムは致命的なエラーしか起こらないのかw
>>927 ケースバイケースだろうと言ってるのに。どっちの場合もあるんだよ。
逆に君は致命的エラーで終了処理だけして、終了するプログラムを組んだことがないのか?
だとしたら経験がなさすぎるんだよ。
>>925 そんな話じゃなくて、mallocの話なんですが
>>921 ないんじゃね?
デバッグ中は「freeしてねーよ」警告が山ほどでるが
無いわけないでしょwww こんだけ否定されてんだからwww
組み込みだとOS自体が無い。プログラムから見て「返すべき相手(親)」がいない。 そんな時にvoid main(void)を使ったりする。ただそれだけの話だな。
mallocとfreeは対な方が美しいからやったほうが良い exitの前にも if(aaa_buf)free(aaa_buf); if(bbb_buf)free(bbb_buf); if(ccc_buf)free(ccc_buf); とかってやるべき できればすぐ死ぬとしても aaa_buf = NULL; ・ ・ もやるべき、これはスピードとかではなく本人の生き方の問題 やりたくなければやらんでよろしい でも俺がリーダーの場合の開発では必須な ちなみにaaa_bufは命名規則的にはいくないけど、説明のために使った
>組み込みだとOS自体が無い。 こいつは、底抜けの馬鹿だな
もういいよ。訳も分からず講釈垂れてる奴はJava使ってろ
void main ↓ mainの戻り値 ↓ malloc/free ←今ココ 次は後藤さん?
>>935 そういう時代もあったってことでしょ
今でもたまにOSなしでやらされるが
>>934 exit を呼んでいるところで、aaa_buf とか参照できない場合があるでしょ。
実際にexit を呼ぶのはライブラの奥の方だったりするんだよ。
参照できるようにしようと思えば、その関数に関係ないポインタを延々と渡し続けないといけない。
>>934 これはexit()関数使わなくて済むようなプログラム例だろw
そんな時の話はしてないぞ。
美しいとかじゃなく、どんな不具合があるのかときいてるのに。
>>935 プログラムが必ずOSから呼ばれると思っているお前の方が馬鹿な気がする
最近alloca()をよく使うからfreeしないわ
>>941 コードをコピペして再利用するときに不具合がでやすい
組み込みってBIOS作るのと似ている?
>>941 mainを抜けた後にまだ続きがあったとき、かな。
そういう変態コードは稀に良くある。
>>944 それはexit前にfreeをすれば解決されるの?
>>934 exitの前にも
if(aaa_buf)free(aaa_buf);
if(bbb_buf)free(bbb_buf);
if(ccc_buf)free(ccc_buf);
これやると対じゃなくなるけどいいの?
ことあるごとにポインタをヌルポインタにしないと動かないけどそれは美しいの?
突然ここではexitしないでエラー復帰してくれと言われたら どれだけ手間かかるんだろうなー
素敵なをおもちゃありがとう、今年3歳になる子供も気に入ったみたいです。
素敵なをおもちゃありがとう、今年33歳になる嫁も気に入ったみたいです。
素敵なをおもちゃありがとう、今年333歳になる主も気に入ったみたいです。
をおもちゃになってしまった。まあ良いか
>>944 お前根本的に勘違いしてるぞ。
malloc して free するのは基本。これをするなと言ってるのではない。
けど malloc してから free するまでの間に、
そのデータとは関係ない関数を呼び出す必要があって、
その関数の中でexitするような場合に free できないのはしょうがない場合もあるだろうと言ってるんだよ。
malloc で確保したメモリは終了時に free されることが保証されてるんだしね。
関数はエラー復帰して、それ見てfreeしてexitじゃないの
終了時にfreeされるって? OSがやっていることとfree()のそれを混同しすぎ。
メモリはいいけど 共有リソースの中には自分で開放する必要のあるものもたまにあるんじゃないの
>>959 ここではmallocを使ってexitの前のfreeの話をしているのです
>>956 基本はそうだけど、それやってられないことがあるの。
そもそもそうやって関数の呼び出し元に戻れるんなら、
exit() 関数など使わないようにコード書けるでしょ。
けど実際にはexit() 関数が必要なわけで、
C++ではtry chatch が用意されているよ。
exit() が必要 → free() できない場合もある
ということなんだよ。
>>959 その辺を一々管理するのが大変だから終了時にまとめてやるのもありでしょ。
で、malloc はそうなってる。
atexit
>>962 なんで例外がここで出てくるのか分からんが、try-catchが欲しいなら
gotoやlongjmp使ってそれらしくすればよろしい
exitを使わざるを得ない状況ってのがわからん
exitは超便利
>>963 状況によっては終了時にまとめてリソース開放でもいいけど、大抵はそれじゃだめかな
exitやabortは終了処理が走って欲しくない場合には使わざるを得ない
> free() できない場合もある どんな状況?
>>968 終了処理の中で分岐入れれば済む話では?
>>965 exit の必要性がわからないんだったら、わかるはずがない。黙ってなさい。
小さなプログラムなら要らんからね。
exit は積極的に使うものではないけど、状況によってはコードが煩雑にならないで済むから使うんだよ。
まぁ君にはわからんだろうけど。
>>970 データが明らかに壊れてて
終了処理を走らせるのが逆に危険な場合とか
まあバグでしかないが
>>970 正規の終了処理のところまで、戻すのが大変な場合があるの。
>>972 だから、どうやったらそんな状態になるのか、そしてfreeしたらそれが解決されるのか聞きたいんですが
gotoじゃなくてexitの流れになったかw
>>971 exitを使うことで便利になる場面があるのは分かるよ。
> exit は積極的に使うものではないけど、状況によってはコードが煩雑にならないで済むから使うんだよ。
これは、利便性を考慮して、exitを選択しただけ。
でもそれは「使わざるを得ない状況」ではないでしょう?
> まぁ君にはわからんだろうけど。
そうすか。
978 :
816 :2010/03/25(木) 20:30:38
void main() (高笑)
if(aaa_buf)free(aaa_buf); って糞コードじゃね?
free(aaa_buf);だけでいいのにな
次スレ立てます
>>979-980 aaaが確保できたbbbがまだでも死ななきゃいけないって時に
確認しないでフリーしたらエラーじゃん
NULLつめとけば
2重のフリーも防げるし
freeにNULL渡しても別に何も起こらないだろw 何でエラーになるんだよ
設計手法って、これっていうのがないのかも
free()の仕様も知らないで語ってたのかw
>>984 bbbをNULLで初期化していれば、な
>>988 未初期化の変数がifを通り抜けてfreeされてエラーになるだけだろw
>>989 エラーになればいいけど、もしも偶然が怖いだろ!
そこまでしてfreeする理由って美しいかってだけ?
そしてfreeの後には毎回0を代入しろと
>>992 まともにfreeできないコードはそもそもどこかがおかしい
>>992 コードを読んで即座に意味が通じるかどうかが重要だからな
free()をしていないコードを読んで、終了間際だからサボってるのか
単なる解放漏れなのかの区別が瞬時につかない。
必要のないif()に突っ込んでるんであって、 NULLで初期化には誰もけちつけてないのにw
Linuxでの仕事でfreeにNULL渡したら死んだことがあってびっくりした事がある 死ぬときあるよね
単なる解放漏れってなによ
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。