1 :
デフォルトの名無しさん :
2008/06/27(金) 21:31:43
>>997 どういうことですか?教えてくだあさい。
型が未定の要素へのポインタの配列へのポインタを作りたいのですがvoid **pでいいですか?
「ポインタの配列へのポインタ」 厳密には 「ポインタの配列の先頭要素へのポインタ」 それはつまり 「ポインタへのポインタ」
>>前スレ971 rand()%900+100 ってのは具体的に言うと rand()%(1000-100)+100 rand()%(a-b)+b でb〜a未満の数値が出る
ポインタの配列へのポインタ void *(*p)[]
>>5 「『型が未定の要素』へのポインタの配列」を「void *の配列」として作るならそれで合ってる
「『型が未定の要素へのポインタ』の配列」を「char *かlong *か決まってないが、何かのポインタの配列」で作るならただのvoid *になる
Q 6.13 配列へのポインタをどうやって宣言するのか。 A たいていは、そんなポインタを宣言したいのではない。 なにげなく配列へのポインターというときは、 たいてい配列の最初の要素へのポインターのことをいっているのである。 配列へのポインタではなく、配列の要素へのポインターを使うことを考えること。 型Tの配列は型Tへのポインタに成り下がる。これは都合がよい。 なぜなら結果としてできるポインターを使って添字つきで参照したり、 整数を加えることで配列の各要素にアクセスしたりできる。 これに対して、本当の配列へのポインタは、 添字つきで参照したり整数を加えると、配列全体を飛び越してしまう。 これではせいぜい配列の配列を扱うときにしか役立たない。 本当に配列そのものへのポインターが必要な場合は「int (*ap)[N];」のような表現を使う。 ここでNは配列のサイズを表す。配列の大きさがわからない場合、Nを省略することができる。 しかし 結果として得られる「大きさが未知の配列へのポインタ」は役に立たない。
char型へのポインタを < で比較するソースがあったのですがどういう意味なのでしょうか?
ポインタの大小を比較してるんだろ
きっと連続した領域に対してみてるんだと思うけど、 アドレスを比較してる。それ以上はちょっと見てみないと。
配列の要素を指すポインタ同士を引き算するとその要素の距離を求めることができる たとえば char str[4]; char *p1=&str[0], *p2=&str[3]; としたらp2-p1は3になる だからif(p2-p1>0)なんて文も書くことができる これを書き換えるとif(p2>p1)になる
Quiz: 16bitの頃のCコンパイラなら兎も角、32bitコンパイラにおいては、 switch文のコンパイルでジャンプテーブルを作成して、実行時に それをスキャンし、ジャンプするような最適化は為されることは 余りない。何故か?
>>16 ちょっとした分岐程度なら
ジャンプテーブルのメモリアクセスのコストの方が高くなるから?
clock_t初めて見ました 面白そう
40くらいまで増やしたら差が激しく。 /O2スイッチつけたら両方とも0msでオワタ。HAEEEEE(違
ifはわざわざご丁寧に else 以下も条件判定をする switchはcaseに該当がなければdefaultへ そこが無駄の差
>>17 そのコードだとswitch文のほうは実は最適化が施されて何もしてないんじゃねーの?
ifのほうはご丁寧に20回まるまるやってるとか
っと、ちと補足。 ifはわざわざご丁寧に、21以上でも最初から順に else if 以下も条件判定をする
>>23 だからそれが必要の無い条件判定による処理時間の差に出ているんじゃん
ちとは意味のある命令をいれとかないと最適化抑制してもだめだめだな。 意味のない足し算でもさせるか。 VC++系なら cl /FAsc hoge.cpp で
任意の論理式を扱う ifと列挙型(int)の値比較に限られるswitch分岐を 比較すること自体が無意味というオチでした。 論理式がint値の値比較であることがif文の最適化の際に判明したら、 比較に関してはswitchと同じようにレジスタに持っておいた値と コード上の固定値の比較に置換するので処理速度差が無くなりました。 というだけね。
char *a; で宣言したaに、関数で文字列を入力したらエラーになるのですがなぜでしょうか?
始めまして、C言語の勉強を始めて半年ほどの者です。 トランプやUNOの様なカードゲームを作りたいと思うのですが、そういった物の作り方を順番に解説してくれている様なサイト、 もしくは本などを知らないでしょうか?
*aだけだと、aがどこを指しているのか不定だから
文字列は先頭文字のアドレスを表すから、char型ポインタに代入できるのかなと思ったんですが・・・ダメなんですかね?
文字列の先頭アドレスを*aに代入するなら問題ない。 そうしてないとは思うけど。
>>30 他の言語でもいいならサイト巡れば載ってると思う
大体やってることは一緒だし挑戦してみたら?
>>32 char型にしろint型にしろポインタ宣言しただけだとアドレスを格納する入れ物
ができただけで、中身は不定。
>>34 ありがとうございます。
少し別の言語の物を探してみます。
文字列はリテラルされる(アドレス固定)
そのアドレスが入っている入れ物(変数)の中身を別のアドレスに移動しようとしたから、
おまえ、システム領域弄るんじゃないよ!
とACCESSVIOLATIONで怒られる。
>>33 の言ってる*aは数値だから構わない。(参照ではなく代入)
>>28 で宣言したaに、関数で文字列を入力したらエラーになるのですがなぜでしょうか
入力とは何?
a = "hoge";
とかなら大丈夫だろうけど
strcpy(a, "hoge");
はだめだよ。
>>32 文字列は先頭文字のアドレスを表すから、char型ポインタに代入できるのかなと思ったんですが・・・ダメなんですかね?
文字列の方はconst charの「配列」です。
39 :
38 :2008/06/28(土) 01:12:27
誤字だった。 文字列の『型』はconst charの「配列」です。
誰も関数にポインタをそのまま渡してる可能性を指摘しない件
>>29 がしてるじゃん
アドレス入れる器に文字入れればそりゃエラー起こられる罠
ミス main() { char *a; hoge(a); hoge(char *a) { a="HOGE";
28がどうやったのかはっきりしない限りどれも想像でしかないけどな。
亀だが if switch 検証。 if (j <= 20 && 1 <= j) { if (j == 1) ... if (j == 20) } else { } としたところifの方が速くなりました。 んで、if (1 <= j && j <= 20)にしたら比較のコストが大きくなって ifの方がやや遅くなりました。
>>46 なんか初めてハッシュを知った新入りのような喜びようだなw
ほほえましくてイイヨーイイヨー
>>48 ちがうちがう。
状況によってはifを使う方が速いこともあるよっていいたかっただけだ。
ついでに、条件文の書き方でも十分代わりうるということをいいたかった。
適した場面に適したコードを書くのは当たり前で、
switch(str)
{
case "hoge":
}
ってかけなくてswitchざまあなんて言い回しと同じように、
switchを使う方が良い場面においてif遅いなどというのはおろかなこと。
初心者の頃にnyを使い始めて、ハッシュを知ってはしゃいだことのある
>>47 が可愛いよ皮良いよ
>>50 なぜny?ハッシュが何を指しているか理解してない、のか?
さすがにないと思いたいんだが。
しっかり勉強しろよ?
>>47 なんか初めてハッシュを知ったny厨のような喜びようだなw
ほほえましくてイイヨーイイヨー
以上、チンパンジーのアイちゃんの自演でした。
>>47 論破されて涙目だなwwww
ハッシュなんて持ち出すなら、なおさら指定範囲内の
数値に対する話は論外になるな。無関係な話ではあるが。
>>47 茶化したつもりがハッシュなんて持ち出すから、さぁ大変。
ny厨乙。お前がそれを知って喜んでいたことの自己紹介ですか?
にしても、switch はえーなぁー、をいっw
ハッシュとny厨に何の関係があるんだろう
switchが早いのでこれからは if (a == b) { // 処理 } を switch (a == b) { case 1: // 処理 } と書くようにします!
色々なC言語のコンパイラがありますがおすすめとかありますか?
>>59 プロトタイプ宣言かな?
コンピューターは先頭から後ろにかけて順次処理してくのは
得意ですが、人間のようにソースを見渡して関数の宣言場所
と利用箇所を眺めてちゃんと定義されてるという確認ができない
ある意味融通が利かない人なのです。
なので関数を使ってる箇所よりその関数が後ろに定義されてる場合
はソースの先頭付近に関数の頭の部分を定義してコンパイラに
こんな関数があるよと先に結論を教えてあげます。
プロトタイプ宣言がいやなら関数を使ってるところより
先に関数を配置すればOKです
>>60 windowsPC持ってるならVC++かVC#でいいんじゃないの?
Cygwinとかって環境構築ではまりそうだしね
>>61 の続き
プロトタイプ宣言をしたくない?ようなソースはmain関数が
ソースの一番最後にあって、main関数より呼ばれるその他
関数が上置くようになってます。
63 :
59 :2008/06/28(土) 10:57:36
>>61 >>62 なるほど、ありがとうございます。
この宣言において、*minなどを違う文字に変更してもエラーが出ないのはどうしてなんでしょうか?
例えば
BSTREE_NODE *deleteMinNode(BSTREE_NODE *p, BSTREE_K_TYPE *min);
を
BSTREE_NODE *deleteMinNode(BSTREE_NODE *a, BSTREE_K_TYPE *mn);
などに変更してもエラーは出ずに実行されるのですが・・
プロトタイプ宣言は引数の数と型だけ見てるから。
65 :
59 :2008/06/28(土) 11:08:56
なるほど、わかりました。 ありがとうございました
>>62 ありがとうございます。vc++ダウンロードしてきます。
☠ฺ☠ฺ☠ฺ☠ฺ☠ฺ☠ฺ☠ฺ毎日新聞社による日本人女性への誹謗中傷☠ฺ☠ฺ☠ฺ☠ฺ☠ฺ☠ฺ☠ฺ
・母親は受験勉強をする息子の学力向上のためにフェラチオをする
・日本人女性の55%は、出会ったその日に男と寝る
・ファストフードは女子高生たちを性的狂乱状態におとしいれる
・ティーンたちはバイアグラを使ってウサギのようにセックスをする
・女子高生は、刺激のためにノーブラ・ノーパンになる
・日本の最新の流行 : 70歳の売春婦
・老人の売春婦の人気にもかかわらず、日本では小学生の売春婦にも仕事がある
・日本の若い看護婦は売春婦に勝る
・24時間オルガズムが止まらない病気で苦しむ日本人女性の数が増えている
・15未満の子供を対象とした疑似ポルノが日本に蔓延している
・OLの72%が、セックスをより堪能するために何らかのトレーニングを受けている
・人妻は気分転換の目的で昔の恋人に抱かれに行く
・主婦は郊外のコイン・シャワーで売春をしている
・日本男子は柔道や空手の部活で男相手に童貞を捨てている
・ほとんどすべての漁師は海でマンタとSEXしている
・まだ10代の少年から退職した老人までみんな2980円の手コキを利用している
・六本木のあるレストランでは、食事の前にその材料となる動物と獣姦する
※同社が全年齢向けコーナーで七年以上にわたり世界に向けて配信していたものの一部です
※同社の行為は日本人への偏見や人種差別、婦女暴行、幼児虐待を助長するものです
◆毎日新聞の英語版サイトがひどすぎる まとめ@wiki
http://www9.atwiki.jp/mainichiwaiwai/ ◆毎日新聞問題の情報集積wiki
http://www8.atwiki.jp/mainichi-matome/ つまり日本国民は
http://www.vipper.net/vip552788.jpg
改行と復帰というのがありますが、 改行が行を改めて、復帰が先頭に戻る、という認識で合ってますか? もしそうなら、 Unixでは、改行LF Windowsでは、改行LF+復帰CRが必要 という違いは、 Unixでは改行LFだけで、改行+復帰の機能を果たすってことなんでしょうか?
typedef struct{ int x; int y; }XY; XY a,b,c; c = a+b; //エラー こんな風に同じ型の構造体を演算したいのですが、関数を使うしか方法はありませんか?
>>69 C言語の範囲だと関数を使うしかありません
C99 であれば complex 型のみできるようです
C++なら演算子のオーバーロードでできますがスレ違いです
71 :
69 :2008/06/28(土) 17:21:21
>>68 タイプライターが使われていたころは
改行: 次の行に移動(入力位置を横に移動せず下に1マス移動するだけ)
復帰: 行の頭に移動
のように両者は個別の機能を持っていたらしい
Windowsの改行がCR+LFなのはこれに基づいていると思われる
じゃあUnixのLFで改行できちゃうのはなぜってことになるんだが
一番大きい理由は改行に2バイトも費やすのが勿体無いからだろう
まあスレ違い
>>72 プリンタの制御コードがまさにそれだな
0x0d CR キャリッジリターン
0x0a LF ラインフィード
改行以外の標準の空白類文字を消してファイルを更新する関数です。 void SkipSpace(FILE *fp) { char str[4000] = { NULL }; int c, i = 0; while((c = fgetc(fp)) != EOF){ if(!isspace(c) || c == '\n'){ str[i++] = c; } } str[i] = EOF; rewind(fp); fprintf(fp, str); } 結果がこれです abcd efg hijk lmn opqr stu vwxy z ↓ abcdefghijklmn opqrstuvwxyz�vwxy z z以下を消したいのですが、どうすれば良いでしょうか
fprintfの書式は fprintf(fp, "%s", str); が正解だと思う
76 :
74 :2008/06/28(土) 19:24:04
#define EOF (-1) /*stdio.h*/
>>74 文字列の最後には\0が必要
>>76 入力ファイルの中に%dって書いてみればわかる
strに%が含まれていたらどうするんだ?
>>77-78 str[i] = NULL; も試したのですが、変わりませんでした。
ファイルの最後はEOFだったかと思い、入れてみたのですがこちらもだめでした。
>>78 なるほど
81 :
68 :2008/06/28(土) 19:30:36
>>72 分かりやすい説明ありがとうございます。
改行という言葉が二つの意味を持ってるのが紛らわしいんですよね
>>74 ファイルを開いてしまったあとで長さを短くするためには
truncateを使わなければね。
するとfopen+fprintfという関数でははく、open+write+truncateというシステムコールを
使った方がうまいことがわかる。
ただし上手に使わないと遅くなる。
83 :
82 :2008/06/28(土) 19:34:34
補足 一度ファイルを閉じて fopen(... , "w") で長さ0のファイルを作り直しても良い。 inodeが変わる可能性があるから、それが気にならないならこちらの方がスマート。
>>81 翻訳者が悪い。
日本では、new line と line feed を同じ意味だと思われてるし。
同じ意味だろ
86 :
74 :2008/06/28(土) 19:37:29
fprintf(fw, "%d", i); fwにiの値を10進で書き込む
↓この手の暗号ってハカーには見破られるの? #include <stdio.h> int main(int argc, char *argv[]){ FILE *from, *to; char *key; char ch; if(argc != 4){ puts("arg err"); return -1; } if((from = fopen(argv[1], "rb")) == NULL){ printf("%s ", argv[1]); puts("open err"); return -1; } if((to = fopen(argv[2], "wb")) == NULL){ printf("%s ", argv[2]); puts("open err"); return -1; } key = (char *) argv[3];
while(!feof(from)){ if(fread(&ch, sizeof(char), 1, from) != 1 && ferror(from)){ printf("%s ", argv[1]); puts("read err"); return -1; } ch = ch ^ *key++; if(!*key) key = (char *) argv[3]; if(!feof(from)){ if(fwrite(&ch, sizeof(char), 1, to) != 1){ printf("%s ", argv[2]); puts("write err"); return -1; } } }
if(fclose(from) < 0){ printf("%s ", argv[1]); puts("close err"); return -1; } if(fclose(to) < 0){ printf("%s ", argv[2]); puts("close err"); return -1; } puts("successful"); return 0; }
一瞬で解かれると思っていい。暗算レベル
そんな・・・い、一瞬だと・・・?
データの内容によると思うけど、もとがテキストなら比較的簡単に解けるんじゃないの
>>91 がすごいハッカーだということは分かった。感動した!
強制jmpで最後まで飛ばすレベル
>>89 argv[3]で境界バグが出るんじゃないかそれ
境界バグってなんですか?
限界値で生じるバグみたいな?
バグが生じるわけじゃないか。異常が生じる
質問ですけど struct tstate *list[20]; struct tstate data1[10]; struct tstate data2[10];と用意して data1[i].stateに0から9までをいれて,data2[i].stateに同じく0から9をいれて struct tstate{ struct gstate *next1; struct gstate *next2;}; として data2[2].next1=&data1[3]; という風に木をつなぎ k=0; for(i=0;i<10;i++){list[i]=&data1[k];k++} k=0; for(i=10;i<20;i++){list[i]=&data2[k];k++} とするとdata2[2].next1=&data1[3];はちゃんとつながるんですか?
気持ちとしては 10個の状態を2列用意して, data2の3つ目とdata1の4つ目をつなぎたいって感じなんですけど
自分の説明能力に自信があるのかもしれないけど、 stateというメンバについては書かれていないね
難解だな
>>88-89 > key = (char *) argv[3];
> ch = ch ^ *key++;
空文字列だと終端を飛び越えるね
struct gstate{ int state; };でお願いします。 まあ入門編できくべきではないかもしれませんけど
>>105 > まあ入門編できくべきではないかもしれませんけど
そうだね
よく分からないけど試せないの?
G-tasteを思い出した
>まあ入門編できくべきではないかもしれませんけど 自分が頭悪いのを棚にあげてこの台詞w
>>81 復帰改行という言葉もあるデスヨ。
ちなみにOSによってはLFCRLFなんてのもあったり。
コンピュータの時代になって、改行をすれば復帰するのが当たり前となり、
じゃあ分けなくてもいいじゃんって言う流れがあったようです。
最近やっとポインタを本当に理解できた やっぱアセンブラまで掘らないと本質って見えてこない しかし今度はアセンブラの命令の中身を知るために回路をいじりたくなってきた 組み込みって楽しそうだな
>>111 アセンブラで扱うデータはアドレスと即値データのみ
変数名をオペランドに記述でしたとしても、機械語ではアドレスになる
ヒープについて質問なのですが、 プログラムA Bというのを自前で用意します。 それぞれ別のタスクとして起動します。 Aがmallocで確保したエリアをBに渡すことがあるのですが この渡されたエリアをBの中でfreeして問題ないでしょうか? それとも一旦Aに戻してAの内部でfree?
がんばってレスしてみるぜ
>>100 ちょっと内容つかめてないが
ループでは list に値をセットしてるだけだから
data2[i].next1 には何もおこらない。
>data2[2].next1=&data1[3];
>という風に木をつなぎ
あらかじめつないであるのなら、つながってるのでしょう。
でも、data2のnext1にdata1をつなぐのなら
next1は tstate へのポインタであるべきでしょう。
「気持ち」を察するに、用件を満たすデータ構造は次のようなものでは?
struct tstate {
struct tstate *next1;
struct tstate *next2;
int state;
} tstate;
どうか?
>>114 mallocで確保したメモリーが共有できない。
プログラムの論理アドレスと物理アドレスのマップはプロセスごとに異なるので
アドレスを渡したとしても、同じメモリーにアクセスするという保証はない。
共有メモリーがGlobalAlloc(WIndows)を使う。
>>114 どうやって渡のかkwsk
なんにせよAでfreeすべきだろう・・・ AのヒープはAのモノだ
116だけど WindowsのGlobalAllocが使えるかどうかはよくわからない 基本は共有メモリー
馬鹿の溜り場?
>>114 UNIX 共有メモリー shmxx関数
Windows メモリマップドファイル CreateFileMapping関数
これらの共有オブジェクトは、内部で使用を宣言したプロセスの数を管理しており
すべてのプロセスがデタッチしたときにシステムから消去される仕組みになっている
>>114 スレッドのことと混同してるのかもしれないが、
>プログラムA Bというのを自前で用意します。
と書いてしまってるからな〜
とりあえずプロセス間通信で方法は共有メモリも含めていくつかある。
>>119 お前基準のバカは当てにならないということだ。
触るなキケン
125 :
114 :2008/06/29(日) 04:28:31
windowsやUNIXのようなOS環境下ではなくどっちかといえば組み込みに 近い形の環境なので若干違うんですかね^^;
環境も明示せずに質問するなよ。阿呆すぎるだろ
>>125 組み込みといってもいろいろ
まったくOSにないものから、「ちゃんとした」OSがあるものまで
なんにせよ、0と1の組み合わせのデジタルデータの塊を 入れて処理して出して結果を出力、その基本部分は変わりは無い。 あとはOSや環境によって、使われているインターフェースや 表現力などに差はあるがな。インターフェースの便利さにも。 原始的なコマンドライン入力でもやれることは十分ある。
129 :
114 :2008/06/29(日) 05:32:18
あー環境ですか・・・ PSPの非公式開発でCygwin * toolchainなんですけどね・・・ windowsのDLLのようなライブラリを起動する際にヒープサイズの制御ができないというのが1つ。 あとはライブラリの中身を公開すれば最大ヒープサイズをコントロールできるんですができれば 非公開で行きたいというのが1つ。 そこで苦肉の策として関数で各ライブラリ間のデータの受け渡しが可能というのを利用して 最初に作ったライブラリ郡はヒープサイズをほとんど取らないように変更。 ヒープを総合管理するライブラリを別途設けてこいつの中でmallocだけしてアドレスを戻す関数(たとえばmymalloc) を用意して他のライブラリから従来のmallocの代わりにmymalloを呼ぶ。 現状としてはmallocはできてるようでとりあえず動いてるようなんですが、freeのほうがうまく行かず 大きなプログラムでデータの読み込み破棄を繰り返すとメモリーリークを起してるようでいずれフリーズ という感じなんです・・・
フラットなメモリ空間に配置されたプロセスで相互にポインタを渡しあえる環境なわけか。 モバイル機器にありがちだね。Windows3xとかもそうだった。 その環境特有のノウハウがあるはずでC言語うんぬんの話じゃない。 一般論から言えば、allocしたランタイムでfreeするのが原則だがPSPはわからん。
mallocで獲得する領域の管理はプロセスごとに行っているので、 mallocしたプロセスがfreeしないととんでもないことが起こる。 ということが回答なのかな?よくわからないけど・・・
132 :
114 :2008/06/29(日) 08:18:16
ところがfree関数のラッパー?をヒープ管理元に実装して そこで開放するように処理を変更してもフリーズは起こるという なんとも・・・
>>133 そこの住人です^^;
最近はあんまり活発な書き込み無いので・・・
まあ環境依存ぽいのでこれまでにします。
レスくれたかたありがとうございます。
>>129 ライブラリ内でmallocした領域は、ライブラリ内でfreeしないとだめだゾ
mallocとcallocはどう違うの?
独学でプログラムの勉強始めたのですが、 ロジックよりもプログラム特有の言い回しがなかなか理解できません。 関数を宣言する 関数を定義する 変数を宣言する 変数を定義する 宣言と定義の意味の違いって何なんですか? 関数の場合は、宣言→戻り値と引数を定める。定義→中身の処理まで記述。ってことでしょうか? だとしたら変数の定義って何だろう
しらべたけど、アライメントがよくわからない・・・アドレスをきっちり隙間なく整頓して順番に埋めてくれるってこと?
>>139 ちがう
それはパックだっけ?
アライメントっていうのは処理系(CPUなんか)が扱いやすいバイト単位にアドレスを確保すること。
ものすごーく大雑把に言ってしまえば 8bitCPUだと1バイト単位で問題ない。 16bitCPU(8086)だと1バイト単位でもアクセスできるけど2バイト単位でないと速度が落ちる。 32bitCPUだと4バイト単位・・・
数日前から苦CってとこでC言語勉強してるけど文字列を扱う方法あたりからわからなくなってきた。 誰かわかりやすく教えてください。
>>141 うっわー、何その井の中の蛙発言。
世の中にはバイト単位アクセスできない16ビットCPUも沢山あれば、
1バイト単位アクセスでも速度が落ちない16ビットCPUもあるぞ。
で、誰かまともにmalloc()とcalloc()の違いの説明してくれない?
>>142 あんなところで勉強してたような人に、どう説明すればいいのやら。
取り敢えず、何が判らないのか書いて味噌。
>>138 メモリの領域確保をして名前と結びつけるのが定義
領域確保はせず、ただ名前を使うよと宣言するだけなのが宣言
厳密にはこのように宣言と定義をきっちり分ける
しかし両者をひっくるめて宣言と呼ぶこともきわめて一般的
例えば int a; とすれば、int を入れられるだけの領域を
変数としてメモリ上に確保するので定義
しかし extern int a; なら、どこか他で領域確保は済んでいる
ただ a を使うよと宣言するだけなので宣言
よくわかんなかったら無理せず先に進むこと
つまり、アライメント云々はmalloc()でも保証されているということでいいのかな。
>>147 あくまで処理系に最適な・・・は保証されるかもしれないけど
せいぜい4バイトとか8バイトじゃないかな?
デバイスによっては16バイトアライメントが必要な場合も
あったりするのでその場合は自前で調整しないとだめだし。
お好きなところでどうぞ。できれば、間違いの多いサイトは避けましょう。
でも勉強中の人には、そのサイトが正しいか間違ってるかわからないんじゃない
>>147 つい一昔前までは、mallocはバイトアライメントだったので、CPUによっては
>>141 がいう「速度が落ちる」などではすまず、bus errorなどを引き起こしていた。
ごく最近になってから、mallocも任意のオブジェクトでクラッシュだけはしないように
なった。
>>145 ありがとうございます!
ちゃんとした違いがあったんですね。よく分かりました。
エラトステネスの篩の問題で、2以上で10000以下の自然数を入力し、2から入力した自然数以下の素数を全て表示する。 素数間にタブを入れ、3個区切りで表示せよ。*一次配列を使うこと。 という問題なのですが、分からないので質問しました。 ちにみに素数間にタブを入れというのは、 2 3 5 7 11 13 こんな感じに表示されるらしいです。
>>142 とにかくわからないので教えてください、って
全然苦しんで学ぶ感じじゃないのはなぜだ
間違った勉強法に苦しむっていうことだろうか
C "境界調整"
>>155 マルチになったようだけど、答えてもよろしいでしょうか?
適切なスレで適切な回答を
>>154 エラトステネスの篩はぐぐれば必ず出てくる、
篩の問題を解く前にまず次の問題を解いてみそ
「0から1000までの数を順次表示する。
それまで表示した個数が3の倍数の時は後ろに改行記号を
3の倍数でない時は、後ろにタブを付けて表示しろ
(それまでの表示した個数を表す変数を宣言して使用して
良い)
すべての数の表示が終わってから改行記号を出力しろ。」
ゆとりはまず人に聞くことを最初に教えられます 解決するまで粘るということは教わりません そして最後まで自力で解決することを覚えません
人に教えたくないならレスしなければいいだけ 質問に答えるスレで調べろってレスする人が理解できない
質問したいんじゃない、答えを知りたいんだ
放置か「調べろ」かといえば「調べろ」のほうがいいのでは
ゆとりは、最後迄全部自力でやったという錯覚 に陥いつつ実は単にコンピュータにやらせている だけの人から答えを聞くことを最初に覚えます。
>>164 放置の方がいい。
質問に対して調べろ、と言うのは
お前はアホだから帰れと言っているのと同じで
大変失礼な行為。
それは質問じゃなくて詰問
質問に答えないことを表明する自由ぐらいは認めてもいいだろう。
「調べろ」というのは「ここで聞くより調べた方がマシ」という意見
ぐぐって分かる人は対象外
結局無償でやるには何事も限界があるのさ 分からないので教えてくださいというのは基本的にその限界を超えている
教えることと煙にまくことの相違について
教えることと、教えてあ・げ・る〓ことの相違について
金とって教える程のことでもない件について
それが故に、自分でやってみて分かるという経験を奪うことの罪悪感に 無感な奴が多い件について
教えることの代価は、相手の成長だと思うんだな。
お前らどうせ現実では人と話すのが苦手で会社で浮いてるタイプなんだろ 似たもの同士助け合えよ
おまえもな
ジュラシックパークツアーになるかどうか
質問は具体的であればあるほどよい。 「C言語がわかりません。教えてください。」みたいな、質問になってないのは返答しようがない。 質問者に言いたいことは、以下の3点。 ・何をしたいのか、まず「目的」を明確にしろ。(開発環境、実行環境を含む) ・考えていることと、試行結果を簡潔に書け。(試行しない人はプログラマに向いてない) ・要約する自信がないならソースを貼れ。恥ずかしいなどと考えるな。
ソースを張るときは省略するな。 エラーメッセージも張れ。 も追加しといて。
Javaでは int[] i; のように配列を宣言できますが、 Cで配列の大きさを決めないまま宣言することは可能ですか?
>>184 おまえらウゼーンだよ。すれ違いのこと議論続けるならどっかいけ。
テンプレ読めとか過去スレ嫁とかどうでもいいんだよ。
どうせ馬鹿な奴は何も読まずに日本語になっていない質問をしてくる。
そんな奴には「ググレカス」と言って追い返せば、質問の仕方を考えるようになるよ。
int* i;
C言語がわかりません。教えてください。→初心者歓迎スレ 自分でもやってみる方針ですが、出来ないところがあります。→入門編スレ 酷い教師が、無理難題を言ってきます。助けて下さい。→宿題スレ という分類でおk?
>>185 純粋に配列として宣言することはできないのでしょうか?
概ねOKかと。 自助努力をしないやつに教える必要はないよ。
>>187 Cではできない。C++なら(構文は違うが)できなくはない。
>>187 Javaでも、考えようによっては
int[] i;
で宣言されるのは純粋な配列ではなくて、Cでいう int *i;
みたいなものだよ。
何となれば、i = new int[100];
とかしないとぬるぽになるだろう。
これはCで i = calloc(100, sizeof *i);
としなければならないことと同じ。
>>189 >>190 ありがごうございます。
配列のサイズ決めるのが難しそうですね。
Javaの生ぬるい仕様しか分からないへっぽこPGにはCは色々と難しい…。
>>191 ありがとうございます。
実はまだポインタがよく分かってないので勉強してからもう一度レスを参考にさせてもらいます。
勉強してから質問しろよカス
偉そうにしてる奴は自分が出来なかった頃を思い出せ
自分が出来なかった頃は一人でUnixいじって勉強してたな 数少ない文書を元に研究と試行錯誤の繰り返し 基本的にはすべて自己解決 最近のゆとりはネットに溢れる情報があるのにくだらない質問をしやがる たまには何日もかけて自分で研究して解決してみろよ
時代の流れに取り残された化石のような方ですね
まあ下らない話をずるずる引き延ばして荒らすのがナウいわけですけどね
先人たちの知恵があって初めて今の情報があふれた世の中があるということに対して 感謝を忘れてはならないと思う
文書の数が少なかったからこそ自分でやれたという視点もちとは 頭に入れたほうがいい時代になってるね。
一瞬「視点持ち」と読んでしまって思考が途切れるから「視点も、ちとは」にした方が読みやすいかも
C言語なら俺に聞け(単位獲得篇) を立てるべき これでだいぶすっきりするはずだよ
>>197 こういう偉そうなことを言うヤツの本音は
「自分が苦労したから他人も同じだけ苦労するべき。
そうでなきゃ自分が可哀想」
これに尽きるんだよ。アホらしい。
自分で背負い込んだ苦労なら自分の中で消費しろ。
数学でもなんでも公式だけ勉強していくと行き詰るだろ? プログラムだって楽したら成長しないんだよ 長い目で見て、教えないのはむしろ善意
一概に言えない。これに尽きる。まず教える教わるの関係を明確に する。そうなったらケースバイケース、ダイアログで対応していく のが基本。
とりあえず教える気のないやつがなんでこのスレにいるの?って思います
「ぐぐれ」ならよく使うな しかし検索すらしない人がどうやってスレに辿り着くんだろうな
「ぐぐれ」は暗に「ぐぐったら見つかるよ」を意図してることがあり得るから、(そう邪推するとして)かなりの情報量をもっているよね。 だれも答えてくれず、「ぐぐれ」ともいってくれなかったら相当に難しい問題なのかもしれない。
別に「ぐぐれ」とか「調べろ」といったら他の人が答えられなくなるわけじゃあるまいし、 くだらないと思うけどなw
「お前が出来ないのはC言語だけじゃない」 その一言が言えなくて
超初心者を小バカにして虚栄心を満たすぐらいの効果しかなさそうだが まあ悩んで判らなければとりあえず聞いてみてもいいと思うよ この流れで本当に悩んでる人が質問するのを躊躇してたら可哀想だ
C言語が途中からわからなくなりました。さて、何でしょう。
はじめてのCを思い出すんだ。
自己解決しました ありがとうございました
教えた方がいいと思うなら自信を持って教えればいいだけ
道端であかの他人にレクチャー頼んでるようなもんだ 無理があるだろ
それは違うだろ
違わないね
同じ道端でも多少Cに詳しそうな人が通ってると思われる道で聞いてるという違い
道端を通りかかった人と、ある程度目的を持って一箇所に集まった人が同じなわけないだろ
>>223 おまいさんはこのスレに常駐しているのか
ご苦労さんなこった
道端は言い過ぎだと思うね
>>142 > 数日前から苦CってとこでC言語勉強してるけど文字列を扱う方法あたりからわからなくなってきた。
> 誰かわかりやすく教えてください。
>>144 >
>>142 > あんなところで勉強してたような人に、どう説明すればいいのやら。
> 取り敢えず、何が判らないのか書いて味噌。
>>149 >
>>144 > じゃあどこで勉強すればいいですか。
でもこれは無理だと思うよw
同じ教えるってことでも 可愛い部下に対しては相手の将来を考えて付きっきりで教えてやる気にもなるけど 赤の他人に対しては所詮自分の自己満足でしかないなぁ
>>227 あんたのような上司がいたら俺のような馬鹿でも苦労してないんだわ
まぁCを独学で少しかじった程度でこの業界に入ったのが人生最大の失敗だった
なぜかこのスレの流れ見ながらリアルで涙目
191っが
>>228 キミはバカなんじゃないと思うよ。向いてないだけだ。
向いてない、というのはバカにしてるわけじゃない。
論理的思考が得意な人と、ひらめきや直感で物事を進めるのが得意な人がいる。
「こうなったのは何故だ?それはここがこうだから。じゃあここはいつ決まったんだ?」
みたいに、順番に進めていくのが好きな人がプログラマに向いてる。
同情誘ってる暇があるなら勉強しろカス
苦Cっていうのは人気なの?
少しは自分で調べろよカス
ぬるぽいんた
職場での知の伝授=教育は基本的に安全じゃない 特に異性が混じる職場ではタブーに近い。これが基本。 だからネットはそれなりに貴重
どう教えてもどうにもならなかった新人は何人もいた。
・何度教えても変数の概念さえ掴めなかった
・何度指摘しても同じミスを繰り返した
・何度ダメだと言っても他人の丸写ししかしなかった
まぁ、向いてないんだろうね。
>>236 そんな基本聞いたことがない
職場色に染まらないと上司に怒られます
俺の会社は男:女が5:5だけど先輩が休日出勤までして勉強に付き合ってくれるぞ まぁ社員全員合わせても20人もいないんだけどね
半分女だったら気が散って仕方ないな 会社は男だけの方が色々と楽だわ 女なんて会社の外でたくさん作ればいい
会社から出られない場合はどうすればよいのでしょうか orz
ほとんど回答出来ないけど、 質問と回答のやりとり見てると面白いから見てる 一人一人の考え方の違いが割と参考になる
246 :
デフォルトの名無しさん :2008/06/29(日) 23:00:28
#define hoge(a.b.c.d) struct 2ch a ## nyaa = { b, c, d, }; ってのがあるんですがこの##ってなんでしょうか?
249 :
デフォルトの名無しさん :2008/06/29(日) 23:19:24
すみません たいへんにわかりました。 素のページみたのにきずきませんでした。あほすぎ^^
250 :
デフォルトの名無しさん :2008/06/29(日) 23:19:57
ありがとうございました。
いい雰囲気
TVとかでも雰囲気を「ふいんき」って読んでるひといるよな
253 :
年ローと :2008/06/30(月) 01:08:12
教えて欲しいです。 Sjisのファイルを読み込みSjisからJisへ変換する処理を作りたいです。 SjisからJisへ変換する処理はわかっているのですが、 ファイルから変換処理へ文字を渡す個所がわかりません。 C1を第一バイト。C2を第二バイト。 if(C1>=0xe0){ C1=C2-0x40 } と処理は進むのですが、例えば「ア」なら「8341」で値が来る事を前提としています。 しかし、ファイルから読み込んだ直後は「ア」と文字列できます。 どのようにして「ア」を「8341」と変換して渡せばよいでしょうか? 宜しくお願いします。
>>253 質問の意味が分からないけど、変換は必要ないよ
#include<stdio.h>
int main(void){
unsigned char sjis_str[]={0x83, 0x41};
printf("%c%c\n", sjis_str[0], sjis_str[1]);
printf("%02X%02X\n", sjis_str[0], sjis_str[1]);
return 0;
}
257 :
年ローと :2008/06/30(月) 01:39:25
>>254 夜分、返信ありがとう御座います。
更に質問させてください。
@ファイルを読み込み、バッファへ入れ込む。
ファイルの中身を入れたバッファを変換処理にかけるで良いのでしょうか?
A「ア」を入れたバッファaを第一バイト、第二バイトに分けるにはどうしたらよいでしょうか?
>A「ア」を入れたバッファaを第一バイト、第二バイトに分けるにはどうしたらよいでしょうか? charの配列としてアクセスして1バイト単位で取り出せば勝手に第一第二になるよ。 でもリトルエンディアンとかビックエンディアンは気にしなくていいのかな?
259 :
年ローと :2008/06/30(月) 01:55:33
皆さん、ありがとう御座います。 やりたいことは、 @SJisで保存したファイルを読み込み形式でオープン。 for(バッファの中身全て変換するまで){ Aそのファイルの中身を一文字ずつaバッファに入れる。 Bそのaバッファの中身をSjis→Jisへ変換をかける。 C変換した物をbバッファへ入れる。 終了です。 たちまち、リトルエンディアンとかビックエンディアンは気にしなくて良いです。
叱ってやって下さい。
>>259 文字列とは基本的に配列である、というのはわかるんだよね
何がわからないんだろう
>>257 どこがsjisの第一バイトかを判定したいなら
iskanji でググってみるといい
それ以前の問題なら下のコードを実行してみるとか
#include<stdio.h>
int main(void){
unsigned char buf[1024];
char filename[FILENAME_MAX];
int readsize, i;
FILE *fp;
printf("読み込むファイル名を入力してください : ");
gets(filename); // 終端処理をしたくないだけなので gets にはつっこまないように
fp=fopen(filename, "rb");
if(fp==NULL){
fprintf(stderr, "\nError : %s file cannot open.\n", filename);
return 1;
}
while((readsize=fread(buf, 1, sizeof(buf), fp))){
for(i=0;i<readsize;i++) printf(" %02X", buf[i]);
}
fclose(fp);
return 0;
}
265 :
年ローと :2008/06/30(月) 02:32:54
>>254 はわかったような、わからんような。
迷ってるのは、バッファに取得したとき、
@a[0] = "ア"
Aa[0] = 8,a[1] = 3,a[2] = 4,a[3] = 1
Ba[0] = 83,a[1] = 41
どれで入ってくるかです。
3番だろう。0xが抜けると意味が変わってくるけど。
>Aa[0] = 8,a[1] = 3,a[2] = 4,a[3] = 1 これはありえないw charどころか4bitで分解しちゃってるじゃん
269 :
年ローと :2008/06/30(月) 02:44:44
みなさん、ありがとうございます。 モヤモヤが取れました。何がわかってないのかもわかってない状態でした。 すいませんでした。皆さんのおかげでハッキリしました。
Linux環境なんですが、time関数よりちびっと精度の高い(ミリ秒単位)ってありませんか?
271 :
270 :2008/06/30(月) 11:56:18
一旦、この質問は、保留します もうすこし自分で考えてみます
この3分で何があったか知らないがおまいはすごく成長したと思う
ロボットが前後(出来れば全方向)に動くプログラムを書きたいのですが、 どのようにすればC言語で書けますか? 参考になるサイトなど教えてもらえると幸いです
>>274 プログラミング言語の前に"日本語"を復習されては?
ロボットと聞いて大きく二つのジャンルを思い浮かべてしまった。
しかもどちらのジャンルも開発環境なんかがかなり多岐にわたってて
そんな漠然とした質問では答えようがなかった。
もちろんgoogleのロボット型検索のことを言っているのだと似非エスパー
277 :
274 :2008/06/30(月) 14:58:47
ロボコンなどでよくある、ライントレースロボットみたいな感じです。 それのラインが無い状態でも前後に動く奴は作れるのかな?と思ったので。 やっぱり質問が漠然としてましたねw すいません
>>277 そのロボットと3Dで表現するロボットじゃあ違うからねw
マイコン ロボット
とか
レゴ ロボット
とか
調べてみるといいよ。
あとH8とかAVRとか
そのロボットによるとしか言いようがない
>>274 まず「制御」という言葉はわかる?
ロボット 制御 C言語
とかのキーワードで本もすぐ見つかるはず
sin と cos の結果入れる0から359のテーブルをfloatで 実装してるんだけどそれをintに置き換えて実装する場合 ってどうすれば最適になるでしょうか? 宣言部分 float SinTablef[360]; float CosTablef[360]; int SinTablei[360]; int CosTablei[360]; 初期化部分 int i; for (i=0;i<360;i++) { SinTablef[i] = (float)sin(i*PI /180); CosTablef[i] = (float)cos(i*PI /180); SinTablef[i] = (int)SinTablef[i]*1024; CosTablef[i] = (int)CosTablef[i]*1024; } これで実際に使うところでは1024倍で計算したあと >> 10で1/1024してます。
282 :
281 :2008/06/30(月) 16:05:19
みす こっちが正解 初期化部分 int i; for (i=0;i<360;i++) { SinTablef[i] = (float)sin(i*PI /180); CosTablef[i] = (float)cos(i*PI /180); SinTablei[i] = (int)SinTablef[i]*1024; CosTablei[i] = (int)CosTablef[i]*1024; }
283 :
281 :2008/06/30(月) 16:08:19
>これで実際に使うところでは1024倍で計算したあと >> 10で1/1024してます。 これも文章がおかしいですねorz これで実際に使うところでは1024倍のままで計算したあと >> 10で1/1024してます。
>>274 ロボットがC言語で開発可能なチップで制御されているのならできるでしょう
どういうことだろう。 SinTablei[i] = sin(i*PI /180) * 1024; とするのでは何か気に入らないってことかなあ。 doubleをfloatにキャストしてるのも何でだろう?
286 :
281 :2008/06/30(月) 16:13:49
>>285 最初はdoubleでやってたのですがそこまでの精度がいらないのと
速度が欲しいのでとりあえずfloatにしました。
でさらなる高速化のためにintにしてみようかと思ったのですが
うまくいかなかったので・・・
>SinTablei[i] = sin(i*PI /180) * 1024;
あーそうですね。
これでいけそうですね。
>>282 SinTablei[i] = (int)SinTablef[i]*1024;
じゃなくて
SinTablei[i] = (int)(SinTablef[i]*1024);
か
SinTablei[i] = SinTablef[i]*1024;
288 :
281 :2008/06/30(月) 16:44:32
289 :
285 :2008/06/30(月) 17:46:01
>>288 どういたしまして。うまく行ったようでよかったですー
C FAQにあったんだけど struct name{ int namelen; char name[1]; } これってどんな使い方するの?
d
CFAQを読んでその疑問が出るっておかしくないか
英語で書かれた部分が読めなかったんじゃないか? (まさか日本語訳の方ってことはないよね。)
いや、大体予測はできてたんだけどひょっとしたらと思って聞いたんよ
単純に理解できなかったんでないの? 実装例見て、ああ、なるほど、的な。
とっとこ主
スレチかもしれないが c++のソースファイル(.cpp)をcにしたら(.c) error C2143: 構文エラー : ';' が 'type' の前に必要です。ってエラーが 山のように出てきたんだがどゆこと? c++の時は問題なく動きました。 Microsoft Visual C++ 6.0 使ってます。
>>298 エラーだけじゃなくてソースも貼らないと
せめてエラーの行だけでも貼らないと
>>298 >c++のソースファイル(.cpp)をcにしたら(.c)
なぜこういうことができると思ったか、を白状してみると面白くなる気がする
>>298 cファイル内に i++; と記入されてたとする
それをcppでコンパイルすると ++ がry ってエラー吐くコンパイラもある
構造体の配列で0番目から1番目に移りたいときって 文字列とかと同様にポインタに1足してあげればいいのですか?
配列になってればね
けどchar *だとだめだよ。構造体の型にあわせてね
>>281 CPUによっては、三角関数を計算してしまう方がキャッシュを汚染しない分早かったりするから要注意。
まして整数でテーブル持つと、無茶苦茶遅い型変換を行なわなければならなくなるので……
特に、C99やC++ならfloat版の三角関数も使えるわけで、ますます工夫する甲斐がない罠。
SinテーブルあったらCosテーブルいらないんじゃないか
速度を速めるために必要なんだろ
速度速めたいのならsinかcosを元にもう一方を算出した方がはやいしょ。 ついでに90度まででいいしね。
それは扱っているデータがわからないとなんともいえないなあ
>>306 ほんと?
そんなCPUと三角関数の計算式の例を教えてほしい。
312 :
281 :2008/07/01(火) 05:24:54
>>306 開発はC言語なんですよね。
一応ベンチマークぽいことはやってみて
1)sin cos そのまま計算(double)
2)sin cos floatテーブル化計算
3)sin cos intテーブル化計算
1<2≠3
ってところですかねえ・・・
これを適用してる部分は4ベクトルの同時回転なので
intで精度をある程度保った計算をしたあとシフト演算x4回
するより素直にfloat演算したほうが最近のCPUだとスマート
かなあという結論でした。
A. 0-90度までの10度おきのsinの表(10エントリ)と 0-9度までの1度おきのsinの表(10エントリ)、合計20エントリを作っておく。 B. 加法公式をつかって、0-359度までの1どおきのsinおよびcosを、 0-90度までの10度おきのsinと0-9度までの1度おきのsinからなる式に分解する。 これをBで作った表を使って計算する。
314 :
281 :2008/07/01(火) 05:36:45
>>306 >三角関数を計算してしまう方がキャッシュを汚染しない分早かったりする
あーこれってもしかしてL1L2の話ですか?
sin cosの計算ロジックが占有するキャッシュ容量と
floatx360個が占有するキャッシュ容量の差ってことですかねえ。
でも片方は命令で片方はデータなので最終的には格納される
箇所が違いません?
そもそも論で申し訳ないんだけど、その処理って複数回呼び出されないですよね? なら、その処理がわずかに速くなっても、全体としてはあまり変わらない結果になりそうです。 勉強のためにこれを速くしてみたい、もしくは、もうここしかチューニングすべき点が 見当たらないのならやる価値はありますけどw
doubleそのままよりもintの方が速いだろう、と思ってやってみたら遅かったので、という ピンポイントの話だったのですね。 ごめんなさい><
317 :
281 :2008/07/01(火) 13:17:06
いえ複数回呼ばれますので速度は大事ですw ((1ベクトルの回転にsin x 2 cos x2) x 4ベクトル) x 約4000 これが1/30秒の間にこなさないといけないのでw
そこまでいくと結局は言語云々じゃなくハードウェアの仕様の話になる
>>317 それなら、複数回sin配列を作成しないような構成にすればよいのでは?
>>319 >それなら、複数回sin配列を作成しないような
テーブル化といえばプログラム起動時に作っておくってことなので
あとは参照だけのような・・・
>>320 ってもテーブルの初期化処理が複数回呼ばれると、主がいっている。
話が食い違っていると思う
その処理 1. テーブル作成処理 2. テーブルの値を参照する処理 俺は2だと思っていた
食い違ってるな。
>>315 が勘違い発言してるだけだろ。
普通テーブル作成を複数回呼ぶなんてありえんだろw
325 :
、 :2008/07/01(火) 13:54:44
横からすいません。今、SJISからJISへの変換処理を作成してます。コード変換処理は出来てます。が変換前後の処理がわかりません。変換コード前後に何かコードを付け加えなければいけないのでしょうか?
327 :
、 :2008/07/01(火) 14:51:36
すいません。ネットにつなげのが携帯しかないので。出直します。
SDやらに保存して携帯へ転送は?
>>325 漢字イン(旧JIS) 1B 24 40
と
漢字アウト(Roman set) 1B 28 4A
あとASCII 1B 28 42
新JIS 1B 24 42
331 :
デフォルトの名無しさん :2008/07/01(火) 20:29:06
ポインタを宣言するとき、どうして int* a; ではなく int *a; と書くのが普通になっているのですか? 上のでも書けますけど、int* a, b, c;みたいなことはできませんし。 宣言しているのは「int型の値を指すアドレスを格納できる型」の変数なのに、 下のやつだとまるでint型の何かを宣言しているみたいじゃないですか。
callocを使うと、確保された領域の全てのビットに0が入ります。 本などには、エラーチェックに「if(p == NULL) {エラー処理} 」と書いていますが、 成功した時、pには0が入っているのに、何故if文が実行されないのですか?
0になってるのはpじゃなくて*pなんじゃないじゃない?
>>332 pに0が入ってるわけじゃない。
pの指すアドレスに格納されている値が0になっているだけで、pにはちゃんとアドレスが格納されている。
>>331 いつも思うんだけど、そんなことどうでもいいじゃん。
スペースの位置が違うだけなのになんでそんな拘るの?
>>336 スペースは重要でしょう。プログラミング言語の区切りはほとんどスペースじゃないですか。
宣言の標準的な形式は
型名 変数名
ですよね。だったら型名の次にスペースがあったら、それ以降は変数名とみなすべきです。
わざわざ特殊な例外を作って煩雑にする意味はなんなのですか?
>>337 型名/**/変数名
でもいい。
トークン区切りがスペースである必要なんて無いのだ。
↑×2 話を理解していない馬鹿
>>337 この場合スペースがなくてもOKだよ。Cにとってはスペースはその程度の問題。
>>337 関数ポインタ型の変数の宣言は
int(*f)(int, int);
だけど、これはどこにスペースを入れて型名と変数名に区切るの?
>>337 極端な話
#include<stdio.h>
int main(void)
{
int
i
=
0
;
printf("%d",i);
return 0;
}
これでもいい
>>337 コンパイラが無視するのなら何でもいいんだ
ただしキーワードや変数名を区切ったらエラー
>>331 int* a, b, c;
これだとaだけがポインタになるから
int* a,b,c = int *a, b, c ってこと
>>331 は int* a, b, c = int *a, *b, *c って思ったんじゃね
俺なら違う型は別の行で宣言するね
いや、
>>331 は
int* a,b,c;
と書くことで int * 型の変数 a,b,cができるならまだしも、そうはできないのが納得いかないんでしょ
型の後に名前を羅列したのに、実際は型が異なる変数が出来上がる。
逆に、int *aとかくのは、型名と変数名がくっついていてそれも他と統一されていなくて気持ち悪い、と。
そこがC言語のクソなとこ
型は型でポインタはポインタなんだよ int型 の ポインタ 変数a
なれるまでの辛抱というか、思想を理解すればすぐ苦じゃなくなるな。 クソと思う人はそう書くものなのだと覚えてるだけなんだろう。
とは言っても後発の某言語では「修正」されてるしなぁ
>>350 「int型」だったら整数を格納する4バイトの領域であるべきじゃね?
int i,*p,a[42],(*f)(int); とかいっぺんに宣言できて便利じゃん。
多少の便利さは犠牲にしても、言語仕様は論理的かつ簡潔であった方が美しいと思う
簡潔かどうかはさておき、少なくとも論理的ではある。
全然
int a, b, *c と宣言した場合に、aとbは整数を格納する領域なのに、cだけがアドレスを格納する領域となる。 型名は同じで、あとは変数名を並列しただけなのに意味上の差が出る。これがどう論理的なのさ?
>>359 aとbはint型、cはint*型。
なんで型名が同じなの?
>>359 わざわざcにだけ変なもんつけてんじゃんw
それで意味上の差が出ないほうが非論理的だよ
#include <stdio.h> typedef char *pc; int main() { pc a,b; char *c,d; printf("%d %d\n", sizeof(a), sizeof(b)); printf("%d %d\n", sizeof(c), sizeof(d)); return 0; } ピンとこない結果だよね。
(コンパイル&実行中。しばらくお待ちください。)
>>360 そう、実際は型名自体が変わってしまう。こんなことポインタだけの例外じゃん。
素直にintとint*で宣言を分割させれば、例外なんて作らずにより簡潔にできたってことだろ。
>>361 型の決定に加えて、何か更にオプション的な要素が追加されるってんなら話はわかる。
でも、*を付けただけで型自体が変わってるじゃん。これは非論理的だと思うが。
int 〜 という宣言文はint型の変数だけでなく、int派生型もすべて宣言できるように したところに混乱の元があるような typedefは特定の型のみを対象とするのでそのような挙動に
>>364 > こんなことポインタだけの例外
配列型も関数型も関数ポインタ型も同様だよ。
typedef char *pc pc a, b =*(a,b) こんな宣言ありえんが
>>367 int で始まる宣言がint型の宣言のみに使うのではないという考え。
>>372 それによって、宣言の先頭を見ただけでは型名が決定できないというデメリットが生じた。
それを補って余りあるメリットがあるの?
>>375 intとintのポインタを同時に宣言するときにタイプ数が減るという素晴らしいメリットが生じた。
>>375 int a, b[10];
と書かれた行を見て、bがint型ではないことに対しても不満ってことでよろしい?
レスがつかないのがさみしい。 不満なのであれば、配列についてもこまめに typedef int int_array_10[10]; int_array_10 a, b; などとやっていただきたいし、 不満ではないのであれば、ポインタの宣言に対して目が慣れてないだけとしか。
では要するに、論理的であることよりも、タイプ数を減らすことを重視したわけ?
普通に論理的だよ。 論理的じゃないと思うのは理解力が足りないだけ
という事にしたいのですね
後付けの論理だろ。 タイプ数を減らしたいがための、いわばこじつけだろ。
いいえ,事実です。
*int って書き方できたらいいのに *int a,b,c = int *a,*b,*c って意味で
宣言時のint *aと、使用する時の*a = 100で、*の意味が変わってくるのも気に入らない
タイプ数が少なくなるとかw 派生型を明示的なほかの型にしちゃうと型が掛け算で増えちゃって大変じゃん。 それをやったのがLPTSTRとかLPCTSTRとかなんだけどね。
そんなこといったら乗算演算子はどうすればいいんだ
>>385 int*a;はデリファレンスしたものがintであるような型でaを宣言してるだけ。
型が増えても別に大変じゃないと思うが。基本形から容易に予測できるなら問題無い。
分かりにくいよ派が劣勢になってきたようです
論理的であるとは一貫した法則があるということで、それはCの規格において厳密に定められている。 規格を読んだことがないのなら問題外であるし、もしその法則が性に合わないというなら、 今すぐCコンパイラをWindowから放り出すことをお勧めする。
>>387 後者の*は、aの示すアドレスの中身を見るためのものだよな。
前者も同じだと言うの?宣言時に不明なaの中身を見てどうすんの?
お前ら荒らし相手につきあいいいな
レス乞食だから
>392 うまいこと言ったつもりか!!
>>373 アホじゃないあなたの口から!説明を!今から!
>>393 int *a;
はaの中身を見たときにintであるようにaを宣言する。と読めばいい。
を指すポインタ と読めばよい
>>398 なるほど。しかしその場合、a自体はどうなる?
aは自動的にポインタ型に定義されることになるの?
一つの宣言で二つのものが定義されるならばそれは例外的な処理じゃないか。
のアドレスと読めばいい
俺らがどうこう言っても仕方ない 黙って従うしかない
int *a; の場合には *a と書くと int になる変数と考えればいいんじゃない? int (*b)(int, int); の場合には (*b)(1, 2); // * は省略可能 と書くと int になるとか
406 :
デフォルトの名無しさん :2008/07/01(火) 23:10:33
>>398 は教え方としてはわかりやすい。
しかし今の論点は、intと型名を書いてるのに宣言されるものがint型ではないのがおかしい、ってことだろ。
Cの規則はこういうところで筋が通っていない。
>>405 それならint *a = 100みたいな書き方もOKにすべき
>>408 なんで「int」以外も見なくちゃいけない仕様にしたの?
宣言時の記述と、コード内で出現する記述をなるべくあわせたから、だったと思う。 int &a; であった方が分かりやすかったということ?
>>409 もう一度聞くが、
int a, b[10];
と書かれている場合、bの型を知るためにはintだけ見ていてはダメだよね。
それについても問題視しているの?
およそ人間の作り出したどんなルールも、人間生来に身についているものではない。 これは、ルールを理解するということは、それだけでひとつのタスクであることを意味する。 あえて言い切ってしまえば、規格を理解するのはプログラマの能力であり義務である。 もし君がC規格を理解することができないなら、君にはCは使えない。 そしてよほど状況認識に問題のある人間でない限り、 使えないものを無理矢理使わせようとする者はいない。 こんなところで言いがかりめいた愚痴を垂れ流す暇があったら、 別な言語を勉強することに時間を割いたほうが、きっと有意義である。
してるよ
なんかもう釣りに見えてきた 釣りじゃなかったらよっぽど・・・
そういう風に決まっているから というのが正しい答えだと思う 気に入らなければC言語なんて使わずに自分で言語を作ればいい
416 :
325 :2008/07/01(火) 23:22:02
出直してきました。 今、SJISからJISへの変換処理を作成してます。コード変換処理は出来てます。が変換前後の処理がわかりません。変換コード前後に何かコードを付け加えなければいけないのでしょうか? unsigned char cSJbuff [256]; unsigned char cJbuff [256]; unsigned int i = 0; unsigned int iLen = 0; memset(cSJbuff,0,256); memset(cJbuff,0,256); iLen = strlen((const char*)cSJbuff0); for(i = 0; i<iLen; i+=2){ if(cSJbuff[i] >= 0xE0){ cSJbuff[i]=cSJbuff[i]-0x40; } if(cSJbuff[i] >= 0x80){ cSJbuff[i+1]=cSJbuff[i+1]-1; } if(cSJbuff[i+1] >= 0x9E){ cSJbuff[i]=(cSJbuff[i+1]-0x70)*2; cSJbuff[i+1]=(cSJbuff[i+1]-0x70; }else{ cSJbuff[i]=((cSJbuff[i+1]-0x70)*2)-1; cSJbuff[i+1]=cSJbuff[i+1]-0x1F; } } memcpy(cJbuff,cSJbuff,iLen);宜しくお願いします。
>>413 では、配列はどのように宣言できればスマートだったであろうか?
int [10] a, b;であれば分かりやすい?
それとも、それでは要素数の異なる配列を宣言するのが困難であると、
int [] a 10, b 10;のような表記にしておけばよかった?
前者であれば要素数が異なる場合に不便であり、
後者であれば結局は要素数を知るために int [] のみを見ていてはだめということになる。
というか、対案だしてください。
>>417 int[10] a;
int[20] b;でいいよ。
一文にまとめる必要が無い。
結局、便利さを追求するために例外的なこじつけを作り出したってことだろ。認めろよ。
>>417 自分でもわかってるじゃん。正解はないって
かまってちゃんにしか見えないお
>>420 言語作成者が神です
その言語を使用する以上は神に従うしかありません
>>416 君のやろうとしていることは、ただ単にSJISの2バイト表現をJISの2バイト表現に変更しているだけである。
実際にはSJISのコードは2バイト表現だけからなっているわけではないし、JISで2バイト表現を使うにはシフト処理が必要である。
もう一度それぞれの文字コード仕様を読み直すこと。
>>417 var
a: array [0..9] of integer;
b: integer;
>>417 同じものを複数宣言するなら一文でもいいが、違うものを宣言するなら複数の文。
俺のスタンスはずっとこうだよ。
>>420 絶対に間違っている点がひとつ
それを認める権利ないし責任があるのは規格を制定した人間で、俺らではない
くっだらね 自分の頭の悪いのを言語のせいにするようなバカはとっとと寝ろ
>>421 俺は今の仕様で何も問題ないと思ってるよ
いつまで規格を読んだこともないようなやつの相手してるんだ
ひ、百の嫌いな理由なんて、
与えられたものを盲目的に受けることしかできない能無しは黙ってろ
>>432 これが欲しいのか?
#define BEGIN {
#define END }
(相手したくなければ静かに去ればいいのに。)
>>420 少ないキー入力でプログラミングを打ち込むことができる
これがC言語開発者の考えのひとつなんだよ
したがって、ハショっているところはいくつかあるし
言語仕様として美しくないところもある
何が嫌いでじゃなくて、何が好きかで自分を語れよ!!
彼のいう例外的な部分が何を指してるのか分からないしなあ
439 :
ヒント :2008/07/01(火) 23:53:03
type cell=^integer; celler=array[1..100] of cell; organet=^celler; organizy=array[1..1000000]of organet; unit=^organizy; units=array[1..1000]of unit; unity=array[1..1000]of organizy; unitaly=array[1..100]of unit; unipotent=array[1..100]of unity; ...こーゆーのが1000個以上 名称の変更やエイリアスはコーディングルールで一切不可! 一度名前を自由に付けることが許され、その後それに修正を許さないような 特権を与えた場合、後々の人がそれによって、どのような苦労をさせられるかの例
やべえ、ここまで普及するなら、もっとちゃんとした言語仕様にしとくんだった そうカーニハンは悔やんでいるかもしれない いくつかの規格の変遷を経て、仕様はかわってきているけどね
一方、リッチーはcreatをcreateにしとくべきだったと悔やんだ。
既にそういう発言してなかったっけ? リーナスの方かもしれない
HTMLの<>内を抽出した後、その中から属性名と属性値を取り出し、 属性名hrefがあれば、属性値をEditBoxに出力する、というプログラムを作っているのですが、 二次元配列に<>内の属性名と属性値を一括で抽出して一括でhrefであるか比較していき hrefであれば、出力するか、 それとも<>内から一つずつ属性名と属性値を抽出し、その都度hrefかどうか比較して hrefであれば出力するか どちらが良いでしょうか? それを選んだ理由も教えて下さい。
一次元配列に属性名と属性値を順にいれておき、 インデクスを2づつすすめながら処理する。 <eXpat/>の仕様にあわせた。
>>443 前者はソースコードを見たときに処理内容が把握しやすい
後者はエンドユーザが使いやすい
HTMLがローカルファイルであり、ファイルサイズが小さいならば前者
HTMLがWeb上のファイルであり、ファイルサイズが大きいならば後者
その他の場合は状況に応じて
int *a, **b, c; みたいに結果の型をそろえた書き方は、、 struct Node *head, **curr = &head; こんなのしか思い浮かばぬ
やりたくなければやらなければいいだけよ
ポインタは特別なものではない。何の変哲もない変数であり、また、型と変数は別のものである。 int型へのポインタ、double型へのポインタ、構造体型へのポインタ、関数型へのポインタなど。 これらが存在し得るのは、型と変数が別々に存在するから。ポインタとは型ではなく、変数であることを理解すること。 言語仕様として「キーワードを区切らない形での空白」はどのように書いても許容される。 だからint* aでもint *aでも、書き方として許されている。あとはどちらが読み手に誤解を与えないかというだけ。 しかし認識として正しいのは、「intポインタ型の、変数a」ではなく、「int型の、ポインタ変数a」である。
×int型の、ポインタ変数a ○int型への、ポインタ変数a
>>416 新JIS 1B 24 42
ASCII 1B 28 42
451 :
デフォルトの名無しさん :2008/07/02(水) 10:04:10
char型が9ビットの処理系もあると聞いたのですが、 どのような理由で9ビットなのですか?
>>451 36bit word の内部を任意のフィールドに区切って使用可能
使用するchar codeにもよるが, 4 char から 6 char 格納可能
PDP 10 とか調べると幸せになれるかも...
sizeofについての質問なんですが char HOGENAME[] = "<HOGEHOGE>"; HOGERead(HOGENAME,sizeof(HOGENAME)); といった配列の長さをある関数に渡す際にsizeofが算出する文字数は純粋な文字数? それとも文字数に終端コード分+1が正解?
+1
それくらい自分で試せば? char str[] = "abc"; printf("%d", sizeof str); とでもやればここで聞くより早いだろうに。
456 :
453 :2008/07/02(水) 16:52:34
レスありがとうございます。
457 :
453 :2008/07/02(水) 16:54:45
>>455 あ、一応自分で試したというか、構造体なんかと同じで+1されないつもりで
組んだプログラムが思ったように動かなくて調査してたらどうも+1されてそうな
感じなのでその認識が間違ってないかで質問させていただきました^^;
この辺の話ってCやってる人だと当たり前なのかぐぐっても
でてこなかったような感じだったので・・・
>>457 配列の大きさは記憶領域の大きさであって、
文字列の実質的な部分がどうたら、という内容には関係ないよ。
もし、記憶領域の大きさから文字列の長さを推定するような処理を書いているとしたら、
ビミョーではないかと思う。
460 :
453 :2008/07/02(水) 17:14:34
>>460 配列の長さを渡したいんだったらstrlenは常にダメじゃないか?
配列の長さなら+1しなくてもいいよ
質問なんですが #define MEM_FREE(x) do{ \ if(x != NULL){ \ free(x); \ x = NULL; \ } \ }while(0) のバックスラッシュは何なのでしょうか お願いします
マクロを定義するときのお決まり?といったほうがいいのかな?
行末の改行文字をエスケープしてるです 一行にずらーっと書いてるのと同じ
>>464 >>465 お早い返答ありがとうございます
やっと理解することができました
ありがとうございました
>>465 じゃないけど補足
バックスラッシュの後ろに空白とかタブが入ってると素敵な体験ができます
納期間近でテンパッてるときなんか特にw
>>463 #defineは2行以上にまたがる場合は後ろに\を付けるんだYO
#define M(s) printf("%s\n",\
s)
とかね。
ちなみにそのマクロなんだが、使用しないほうがいい。
p="freeしてはならない文字列ポインタ";
MEMFREE(p);
とかしがちなんで。
マクロ関数はプリプロセッサに過ぎないので、行数を少なくする為だけの目的で使うのは本来的には邪道。 重大なバグの原因になる。 C99ではinlineとか出来てるらしいから、マクロではなくinline関数とか利用するほうが正統性が高いよ。 古いCの凝ったマクロは使わないほうが安全。
>>463 #define は改行があるとそこで終了してしまう
改行をなかったことにするために\をつける
C99に対応してれば、ね
>>468 そんなもんマクロにくるまなくても同じだろう
そのマクロは、freeにヌルポインタを渡したときに
何もしないことが保証されていなかった古い実装のためのものだね
現在では最初のifの意味がない、が正しい
>>470 行数を少なくすることはそれなりに重要なことである。なぜならそれは保守性に貢献するからである。
inline が使える環境が決して多数でない現状、もちろん関数を使ったほうがよい場合は多いけれど、
実行速度を重視してマクロを使用する選択肢は、決して邪道ではない。
475 :
デフォルトの名無しさん :2008/07/02(水) 20:04:28
マクロは速度には効果があるけど、プロ向けではない。 オブジェクト指向にあってない。 変数もマクロで定義すると複雑になる。
>プロ向けでない んなアホな プロこそ現実のどうしようもない制限の枠内で妥協を図るものだろう そもそもCはオブジェクト指向言語じゃないし
>>474 邪道だと思う。
実行速度云々の世界なら profile して呼び出しの多い関数への引き渡しを見直すとかそういうのがいいのでは?
マクロの多用はとにかくトラブルの元になりがち。
仕方がないとはいえC++と話がまざるとどうしてもおかしくなるな
>>474 マクロにするぐらいで速くなる場合ってそんなに多いかな?
>477 そんなことはとっくにやった上での話だろう トラブルを起こすのは大抵の場合マクロが悪いんじゃなくて使う奴が悪いし マクロを使うことでなくせるトラブルもある
>>479 違う
もともとベタで数行書いていた処理を
関数ではなくマクロにするから遅くならないという話
決まりきった一連の処理が二箇所以上で必要なときマクロでまとめるのはよくあること あとはC++でも特にGUIを使う場合には定型だがクソ長いメソッドをマクロにしてしまうのもよくあること
>482 いやC++ならinline使えよ
標準ライブラリにもマクロで実装されているものあるしなぁ 関数とマクロの区別がついていればトラブルは起こらないわけだし でもまあ大抵は関数使ったほうがいいよね
マクロの利用目的 推奨度 1位:複雑な式の間違いの無い展開 2位:冗長性の高い初期データ設定時の設定ミス防止 3位:保守工程における関数合成共通化作業時(グローバル名前空間を浪費する似たような関数は一箇所にまとめて 公開名称にして、旧関数使用箇所ではマクロでパラメータで切り分ける新関数コードに置換) 3位クラスになると、管理者クラスじゃないとやらしてはもらえないね。多くの開発現場じゃ。 それ以外の使用は関数テンプレートだろうな精々。それでも関数テンプレート禁止の開発現場もあるし。 Cじゃもといできないし...
はstdinなどもマクロであることが許されているので、処理系によってはまさにマクロになっているときがある。これが原因で茶筅が修正なしで移植できないことがあったことは、遠い昔のできごと。
今日はマクロの話ですか
昨日の宣言に今日の関数マクロ 的確に秘孔を突いてくる奴は間違いなくプロ
明日の話題を大胆予想 1. name space 2. reentrant 3. goto 4. trigraph
gotoは結論が出てるから面白くない
メルセンヌツイスタについて詳しく
ググレカス
そういや以前マクロの中での\の意味を知らなくてファビョってたヤツがいたなw あいかわらず、このスレや宿題スレで基地外長文を連投しまくってるが。
494 :
デフォルトの名無しさん :2008/07/02(水) 22:26:24
>>493 基地外だという自己紹介乙w
それ、お前だろ?白々しいw
>>493 うわっ、まだそんなことを思い出して、わざわざ書き込むなんて
お前の方が人間性が腐ってね?お前みたいな言動をする奴って
結局引きこもりなんだろ?かなり性格が悪いぞ。
相変わらず自分のことは棚に上げて言いたい放題だなw
>>493 > あいかわらず、このスレや宿題スレで基地外長文を連投しまくってるが。
それがそいつだと言う証拠は?IDもなし、トリップ無しで、不特定多数の人が
来る場所で、まだいると思っている妄想乙。お前がそういうのに過剰反応しているだけだろ。
もっとも、ファビョっているのはお前のようだが・・・自己紹介乙。
マクロの中の \ を知らなかったんだろ、お・ま・え・が?w
蒸し返す奴ほど、頭がおかしい。そういう奴の方が、常駐している人からしてみりゃ
迷惑で鬱陶しい。
お前のファビョり長文連投がわからないやつなんていねーよw
すいません メモリ消費がパソコン資源を超えるプログラムを実行した場合の挙動について 聞きたいんですが、OSからエラー吐き出されたりしますかね? 現状では実行した瞬間に終了するという感じで、それがプログラムのエラーなのか メモリ容量不足が問題なのか知りたいのですが。
>>500 自分で作成したプログラムですか?
デバッグでmainまで飛んでこないとかですか?
>>500 C言語の範疇で答えられることは、
スタックや静的変数とかが足りなくなった場合にどういう挙動をするかは環境による
malloc系の関数でメモリが足りなかったときにはヌルポインタが返されるので、
それを無思慮に使ったらたぶんアクセスエラーかなんかが起きて落ちる
ただよっぽどのことでないかぎり、メモリが足りないということはない
(OSもがんばって捻出しようとするから)
普通はまずプログラム自体のバグを疑うべき
>>501 >>502 winxpのメモリ512M、コンパイラはborland、エディタはC言語をはじめようってやつです。
自分で作った分子シミュレーションのプログラムです。
今までデバッグが必要なほど長いプログラムを書いた事がないので
よく分らないのですが、
main関数で変数定義の後に3MBほどの入力ファイルを読み込んで、
書き出し用ファイルを作ったところで
scanfでプログラムをとめようとしたんですが
前述の状況となりました。
書き出しファイルもできてませんでした。
ちなみに
doubleで要素数3万の配列を8つと
3次元配列[50][50][50]を二つ定義しています。
borlandだとわかんないな。 VC++の場合は途中のバージョンからスタックオーバーフローが 何もメッセージを出さずに落ちてしまうようになったから困ってるのだが。 ところでそのプログラムはGUIそれともCUI? それからその配列はスタックかヒープかstaticにとってるかとかわかる?
そのよっぽどのことか…… 配列で連続的に確保できるメモリってそう多くないのよ
いくら大量にメモリを積んでいても、その空き容量をそのまま配列にできるわけじゃない 大抵の場合分断されてて、一つの空き領域のカタマリとしてあるわけじゃないから
>>504 とりあえず、でかい領域の変数を外部変数にしてみるとかだな。
200M越えの配列か 静的宣言でなんとかなるものかねぇ
>>504 それはスタックメモリオーバーだろう。
ボーランドだとコンパイラオプション-lS
でメモリサイズ指定するんだっけ。
0x400000位あればOKか
>>509 その数字はどうやって出したの?
>ちなみに
>doubleで要素数3万の配列を8つと
>3次元配列[50][50][50]を二つ定義しています。
これだけ見る限り、俺の計算ではdouble1つで8バイトだとしても、
何回計算しても4M弱になっちゃうんだけど...
512 :
504 :2008/07/03(木) 01:17:27
>>505 データは数字で出力してそれをAVSというソフトで可視化するという感じなので
CUIですかね、ちょっと用語の意味が分からず答える事ができないのですが(汗
不勉強で申し訳ありません。
>>506-510 返答ありがとうございました。
プログラムの勉強をして出直してきます。
どうもすいません。
>>498 パブロフの犬のごとく反応しているよな、お前w
別人に噛み付いて、あっお前か?って揺さぶり、煽りだろ?
お決まりのパターンだな。。。だからねらーはキモイって言われるんだよw
>511 壮絶な勘違いですた 死ね俺
同じヘッダファイルを2回インクルードしても何も変わらない?
多重読み込みを考慮してるかどうかで変わる
>>515 厳密には、そのヘッダファイルの内容による
べき乗を考慮してないヘッダなら多重定義でエラーになるだろうし、
複数回読み込まれると何かの値が変化するように作ることも可能
一般的には、つまり普通のライブラリが用意しているヘッダなら、変わらない
二次元配列を関数に渡す時に例えば、array[][2]と渡せば 2列目のポインタを渡した事になりますでしょうか?
>>518 Cでは列単位で配列を切り分けることは不可能
処理の中で1列目を読み飛ばすしかない
サイズが2である配列が格納されている配列のポインタが渡されることになる 具体的には、array[3][2]や、array[5][2]などを渡したいときにそのように書く
なんかずれたことかいてしまた。
>>521 は受け取る側の話なので無視してください
524 :
、 :2008/07/03(木) 21:24:24
教えてほしいです。 戻り値unsigned shortの関数があります。それを unsigned charZ[32]で受け取りたいのですが、どのように行うのがよいでしょうか?
>>524 残念ながら、Cではそれを簡単に行う方法はありません。
プログラムを見直して、どちらもintに統一するのがよいでしょう。
そうすればスマートかつ移植性の高いプログラムになります。
sprintfが使えるか?
>>524 関数の戻り値をunsigned char Z[32]の先頭で受け取ったとしたら
Z[0]とZ[1]に分けてアクセスしたいとかそういう話?
共用体
文字列に変換するか、バイトに分割して入れるかのどっちかだろうけど、
>>524 にもどっちかわからないんだろうなぁ。
531 :
524 :2008/07/03(木) 23:00:01
すいません。524です。 うまく伝えれませんでした。 【前提条件】 ・unsigned shortの関数は外部提供関数です。 ・unsigned charZ[32]はこちらで定義してるのですが変更できません。 ・unsigned charZ[32]ですが、実際、使用するのは[0][1]の16ビットのみです。 @やりたいことは、unsigned shortの関数を発行する。 Aunsigned shortの戻り値を何らかの処理をしてunsigned charに変換する。 BAで変換した値を8ビットずつZ[0]、Z[1]に入れる。 という事を行いたいです。Aがわかりません。 なんかシフト演算を使用すればよい聞いています。 しかも、一行ですむとか。 ググル事もできないアホ女です。宜しくお願いします。
ヒントは出てる ググレメス
>>531 一行ですむ&シフト演算 って難しいじゃないか
一行っていうとキャストしか思い浮かばない(バスエラー?99%大丈夫)
memcpyで、と思ったけどエンディアンとか考えないと駄目なのか
これを1行でやれってこと? unsigned charZ[32]; unsigned short HogeA = hogehoge(); unsigned charZ[0] = (char)(HogeA >> 8); unsigned charZ[1] = (char)(HogeA & 00FF);
unsigned charZ[32]; unsigned short HogeA = hogehoge(); unsigned charZ[0] = (unsigned char)(HogeA >> 8); unsigned charZ[1] = (unsigned char)(HogeA & 00FF);
エンディアンの話もあるけれど。 unsigned short a = 0xaabb; unsigned char Z[32]; Z[0] = (unsigned char)(a >> 8), Z[1] = (unsigned char)(a & 0x00ff); printf("%d %d\n", Z[0], Z[1]); memcpy(Z, &a, sizeof(unsigned short)); printf("%d %d\n", Z[0], Z[1]);
そんなのはもう2行で書けよ。
キャストなんていらなくね? Z[0] = a >> 8, Z[1] = a; printf("%d %d\n", Z[0], Z[1]);
(Z[0] = a >> 8) && (Z[1] = a); じゃあこう
541 :
540 :2008/07/04(金) 00:12:18
ごめんうそ。調子に乗った。
543 :
デフォルトの名無しさん :2008/07/04(金) 00:55:54
画像認識で自転車を認識したいのですが、どのように認識させていいのかわかり ません。 今は自転車の簡単な特徴点をテンプレートととして用意してその点を認識させよ うとしているのですが なかなか認識させることができません。(テンプレートは自転車の車輪を想定し て円状に点を6点取っています。 うまく自転車を認識させる方法がありましたら教えてください。
>>543 三輪車のテンプレートから車輪をひとつとる
546 :
545 :2008/07/04(金) 01:11:25
なーんてね。スレチだから画像認識関連のスレできいてね。
547 :
デフォルトの名無しさん :2008/07/04(金) 01:14:14
スレ違いでしたか(汗 すいません 了解しました
OpenCVのスレとかあったな
549 :
デフォルトの名無しさん :2008/07/04(金) 07:29:52
よくtypedef int _int みたいなことしてるけど なんでこんなことするんですか? すごいわかりずらくなってるんですが?
× わかりずらく ○ わかりづらく
551 :
デフォルトの名無しさん :2008/07/04(金) 07:40:41
よくtypedef int _int みたいなことしてるけど なんでこんなことするんですか? すごいわかりづらくなってるんですが?
>よくtypedef int _int みたいなことしてるけど いったいどこの国でよくしてるのか詳しく
553 :
デフォルトの名無しさん :2008/07/04(金) 08:01:34
どこの国がよくしてるかはわかりませんが たしかにみたことはあるんです。
そんな、_intみたいな、というおぼろ気な記憶じゃなくて 正確な記述を持って来たら説明してやるよ
555 :
デフォルトの名無しさん :2008/07/04(金) 08:14:08
じゃあglibの gintとかでどうでしょうか。
みたことがあるていどのものを よくしてる とはふつうひょうげんしませんよ
557 :
デフォルトの名無しさん :2008/07/04(金) 08:26:06
そうでした。質問のしかたがわるかったです。すみません。 よくしてるかどうかわかりませんがtypedef int _int みたいなことしてるけど なんでこんなことするんですか? すごいわかりずらくなってるんですが? 改めておねがい致します
やった人に聞いてください
そんなもんそれを書いたやつに直接聞け
>>557 判断材料が少なすぎてなんとも答えようがありません
該当のソースをまるごとアップロードするか
ソースの作成者本人に聞いてください
直感的に表現方法を変えたかったとしか思えない
562 :
デフォルトの名無しさん :2008/07/04(金) 08:36:33
glibのgintとかは全然わかりやすいのでおしゃれ的にはありだとおもうの ですが たとえばカーネルソースとか明らかにわかりずらくなってて おしゃれ的になしだとおもうのですが理由があるのかなあとおもったのですが
環境によってサイズが変わる型だからでは
× わかりずらく ○ わかりづらく
移植性の高い方法で書こうと思ったけどやってみるとそうでもなかった
おしゃれ的 おしゃれ的ってなんだ
567 :
デフォルトの名無しさん :2008/07/04(金) 08:45:45
環境によってサイズが変わる型だからでは そっかなんとなくわかるかもしれないです。 いまからよくかんがえてみます。 みなさま本当にありがとうございました。
charやshortをBYTEやWORDに置き換える人?
環境によってCのソースファイルのサフィックスが.cで無い場合ってありますか?
別に.cである必要がないと思うけど
571 :
、 :2008/07/04(金) 13:35:37
お願いします。教えてほしです。 @unsigned charM[2]の値を何らかの処理をしてunsigned Shortに変換する。 A@で変換した値をunsigned ShortN[2]にセットする。 この処理を行いたいです。 M[0]をシフト演算で左8ビット。 M[1]を(0X000FF&M[1])と操作しましたが上手くいきません。
>>571 M[0]を8ビット左シフトしたら中身0だと思うよw
一旦
unsigned Short wm0 = (short)M[0];
unsigned Short wm1 = (short)M[1];
といったshortの器に入れて
(wm0 << 8 | (0x00FF & wm1))
とかね。
wm1はマスクいらないかな?
みす >unsigned short wm0 = (short)M[0]; >unsigned short wm1 = (short)M[1]; unsigned short wm0 = (unsigned short)M[0]; unsigned short wm1 = (unsigned short)M[1];
あ、すまん
>unsigned ShortN[2]
これって2つあるってことはM[0] とM[1] をそれぞれ加工して別に入れるでいいのかな?
だったら
>>572-573 は合成しちゃってるのでだめだ
576 :
575 :2008/07/04(金) 13:46:17
ShortN[0] = (unsigned short)M[0]; ShortN[0] = ShortN[0] << 8; ShortN[1] = (unsigned short)M[1];
577 :
、 :2008/07/04(金) 13:48:13
ありがとうございます。 575さん。結局は一つにします。操作しやすいと思って配列にしてます。
>>524 の人?
まあ、誰かは関係なく、こちらもエンディアンを意識する必要があると思うがな
分割した方法によって結合する方法が変わる
初心者質問ですみません。 下記のソースの違いについて教えてください。 1、*mjd[3] 2、(*mjd[3])
580 :
たすけて :2008/07/04(金) 15:17:37
5次方程式 f(x)=x^5ー8x^4ー26x^3+56x^2+48xー1=0 の実根のひとつを小数点以下7位まで求めよ
スレ違い&マルチすんなゴミ
>>579 同じ。
聞きたいのは、(*mjd)[3] じゃないの?
関数の引数に多次元配列の変数を指定することってできますか?
586 :
デフォルトの名無しさん :2008/07/04(金) 18:01:30 BE:2466256199-2BP(300)
というか1次配列のときもアドレスを渡してる ポインタについて詳しく勉強することをオススメする
>>583 できる。ただし、配列はすぐにポインタに成り下がるので、
引数に配列を指定したときに実際に関数に渡るものは
その配列の先頭要素へのポインタである。多次元配列の場合、
(一つ次数の低い)配列へのポインタが渡される。
func(int array[2][4][5]) という宣言は int の3次元配列を
受け取ることを期待しているが、実際に渡されるのは
その先頭の要素つまり int [4][5] へのポインタである。
最初の array[2] の部分は常に *array と書いたのと
同じように処理される。[] の中の数字は関係ない。
array[][4][5] と書いても同じである。
そしてこの array を使って、もとの配列の各要素に
array[1] のようにしてアクセスすることができる。つまり、
さらに下位の配列要素に対しても array[1][0][3] のように
アクセスすることができる。
ただし、ここで array はポインタであって配列ではないので、
sizeof 演算子や & 演算子を作用させたときの挙動は異なる。
>>589 array[][4][5]というふうに受け取る場合に、array[1][0][3]とアクセスできるようになるのは
何のおかげなんですか?
*arrayとして受け取るとサイズが分からないのでarray[1][0][3]のようなアクセスはできないですよね。
ポインタにはできないはずのことができているように見えるのに、やっぱりポインタなんでしょうか?
int (*array)[4][5] というポインタ
なるほど。。たとえば、[4][4][5]のサイズのメモリを確保したい場合に 以下のような記述はアリなんでしょうか? int (*arr)[4][5]; arr = malloc(4 * sizeof(*arr));
書いてから思ったのですが、たとえば2次元配列を動的に確保したい場合は どのように記述するのが正しい(もしくは一般的)ですか?
多次元配列 動的確保 でぐぐれ
>>594 いろいろ出てきましたが、
多次元配列を動的に確保しつつ、それが連続した領域であり、添え字によるアクセスが可能な方法
について記述されたサイトはありますか?
>sizeof(*arr) sizeofに実体のない参照を渡すことできたっけ?
>>595 見つからないなら、一般的でないということだ
餅
>>595 ??
一回自分でやってみなよ
全部満たしてるはずだけど
配列を正しく表現できるポインタを宣言して、そこに必要なだけの領域数を計算して割り付ければいいだけ
多次元配列を確保し、出力してみたのですが、連続領域ではないため2個目のアクセス方法だと出力がおかしくなります。 freeやallocエラーについては省いてあります。 int **arr; int row_num = 7, col_num = 8; int i, j; arr = malloc(row_num * sizeof(int *)); for (i=0; i<row_num; i++) { arr[i] = malloc(col_num * sizeof(int)); for (j=0; j<col_num; j++) { arr[i][j] = i * col_num + j; } } for (i=0; i<row_num; i++) { for (j=0; j<col_num; j++) { printf("%d ", arr[i][j]); } printf("\n"); } for (i=0; i<row_num * col_num; i++) { printf("%d ", *(arr[0] + i)); if (i % col_num == col_num - 1) { printf("\n"); } } 逆に、連続領域を確保するために malloc(row_num * col_num * sizeof(int)); などとすると 添え字によるアクセスができなくなりますよね。 これらを解決できる方法について知りたいのですが。。
>>601 なんで?
mallocの戻りアドレスはvoid*なのでキャストすればOKなんじゃ?
せめて、C-FAQぐらい読んでみて。
604 :
デフォルトの名無しさん :2008/07/04(金) 19:58:17
人を救うプログラムってありますか? 分散コンピューティング的なもので、
>>602 int *arr;
arr = malloc(row_num * col_num * sizeof(int));
として、
arr[1][3] というアクセスは可能ですか?
>>595 にも書いてありますが、動的に連続領域を確保しつつ添え字でアクセスできるのかどうかを知りたいんです。
連続領域でなければ、それはmemcpyなどにも使用できないということですよね?
FAQってどうしてもファックユーって読んじゃう
>>603 すみません、不勉強でした。
以前読んだものの、すっかり忘れていました。あらためて読み直そうと思います。
>>605 領域が連続であることと、2次元以上の添字でアクセスできることとは別のこと。
mallocで確保した領域は連続
>>605 の方法で確保した領域にarr[1][3]としてはアクセスできない。
RTFFAQ
>>608 はい。もっと理解して、次はちゃんとないものねだりできるようにしてきます。
>>609 不連続領域です。
int (*a)[4]; a = malloc(2 * sizeof *a); a[1][3] = 0;
>>611 4が固定です。
というかFAQむしかえしてしまってほんとごめんなさい。
ああ、つまり要素数が不定の多次元配列を作りたいのね。 むり。
要素の数が決まっていないなら、連続した領域として、 つまり本来の意味での多次元配列として作成することはできなくなる。 ポインタの配列を用いて多次元配列をまねる方法を使うこと。
どうしても連続領域でやりたいなら添字に頼らずに自分で場所を計算するか、C++を使うしかない
かくしてC-FAQに戻りぬ
>>617 >>615 がいっていることの意味が分かってるのか?
a[j][i]の代わりに、*(a + row_size * j + i)
と書くということだぞ。
>>618 あれ?ほんとですね。
じゃあ、
>>617 そうではなくて、添え字でやれることを理解しました。
思うんだがなんでそんなに多次元配列にこだわる?
>>620 なんとなくです。では忍びないので
array[][4][5]
という表記をみて、各次元のサイズが不定な多次元配列を動的に確保するには
どうしたもんかと思ったからです。
で、思いついた方法では連続領域にならなかったのがなんだかつまらなかったからです。
要するにやりたいことはこういうことだろう 連続領域として割り付けて、多次元配列をまねたポインタの配列の各要素を注意深くその領域の妥当な位置を指させる
これだとデータ領域だけなら連続領域になるよ #include<stdio.h> #include<stdlib.h> #define ROW 10 #define COLUMN 5 int main(void){ int **data, *data_area; int i; data_area=malloc(sizeof(*data_area)*ROW*COLUMN); data=malloc(sizeof(*data)*COLUMN); for(i=0;i<COLUMN;i++) data[i]=&data_area[i*ROW]; printf("%d\n", data[2][3]); free(data[0]); free(data); return 0; }
FAQと同じ手法ですね。 わざわざありがとうございます。
>>621 >>622 の方法を使う。
ただし関数の宣言はfunc(int ***arr)みたいになる
>>621 あとは構造体を使って良いなら数が決まってる部分を構造体にしてみるとか
>>621 コンパイラの気持ちになってみてよ。そしたらもっと気持ちよくなるから。
628 :
デフォルトの名無しさん :2008/07/04(金) 22:42:27
将来医療に関わるプログラムを作っていたいのですが、 この中に医療に関わるプログラムを作っている人はいますか?
医療に関わってればいいなら 作ってるよ
医療関係のソフトウェアって特殊なするの? 他の電子機器の影響で誤動作する可能性に備えて 同じ計算を複数回行って多数決とるとか それともECCメモリ使うだけとか コンピュータを電磁波を通しにくい素材で覆うとかの ハードウェアよりの対策のみなのか
同じく、医療に関わるだけでいいならやってるよ
ああ、けど、医療機器組込とかならやってない
医療関係って言ってもかなり広いが組み込み系の話か? 現状はまだ、基本的にハードウェアで対策して 見るドクターが数字に誤差を加味してるのがほとんどだと思う
コンピュータ自体が誤動作することはほとんどないよ たいてい問題は計測データのノイズのほうだから
最近RFIDで誤動作的なニュースがなかったっけ?
636 :
デフォルトの名無しさん :2008/07/04(金) 23:40:05
Cプログラミングのフリーソフトをダウンロードしたいのですが、どこですれば良いですか。
一年くらい、検体を管理したり測定機械と通信したりするシステムの部署で働いていたことがある。 ありえなくいらい質が低くて、そのシステムを導入してる病院にはいかないようにしてる。
腰痛に悩んでるCプログラマは多いはずです なにかいい対策はありませんか?
#include<stdio.h> int main(void){ char x[]="123456789"; printf("%s %s %s %s %s %s %s %s %s\n" ,x[0],x[1],x[2],x[3],x[4] ,x[5],x[6],x[7],x[8]); return 0; } これって何で動かないんでしょうか?
自腹も辞さない覚悟でいい椅子を導入する、かな あとは適度な休憩およびストレッチ
>>639 動くとは思うが、多分望んでいる動作にするには%sを%cにする
%sの方が正しくて、x+0, x+1, x+2,……ってやるのが望んだ動作かもよ?
printf("%s %s %s %s %s %s %s %s %s\n" ,&x[0],&x[1],&x[2],&x[3],&x[4],&x[5],&x[6],&x[7],&x[8]);
それぞれ1文字出力したいんじゃないのか?
どっちが間違ってるのかは本人以外には確定できないからな。 %cの方が可能性は高いと思うがね。
>>641-
>>644 ありがとうございます
%cにしたら解決しました
>>643 をやってみたらなんか興味深い実行結果になりましたね
まず質問を上手くできるようになろうな
>>639 この俺様が猛烈に解説してやろう。
まず、
char x[]="123456789";
この文で行っていることを分解して考えてみる。
[]とは添字演算子であって、例えばx[5]と書くと、*(x+5)と同じ意味になるといったものだ。
つまりこれを付けることによってポインタを意味することとなるわけだ。
よって
char *x="123456789"
と書き換えることができる。ここでxはポインタ、つまりアドレスを格納する変数であり、
そのアドレスの中身がchar型だということになる。
次に"123456789"は""で囲まれているために文字列リテラルと呼ばれ、その名の通り文字の列である。
文字列には、その終端に\0というヌル文字というものが必要であり、
文字列を操作する関数はこのヌル文字を発見すると文字列がそこで終了するのだと認識できる。
一見すると、上記の宣言においてヌル文字はどこにも見当たらない。
しかし「文字列リテラル」として""で囲っているために、自動的に付加されたのだ。
つまり実際にはx[0]=1, x[1]=2, ... ,x[7]=8, x[8]=9, x[9]=\0という値が代入されていることになる。
ここで一つ気になることがあるかもしれない。
どうしてxにはアドレスが格納されるべきなのに、まるで文字列が格納されているように見えるのか。
これは"123456789"という表記の実際の意味に関係してくる。
文字列リテラルとして""で囲って書いた場合は、メモリのどこかにデータとしてその文字列が書き込まれ、
その先頭アドレスが返される。つまり「"123456789"」というものは、文字列123456789が書き込まれた場所の
先頭アドレスを意味しているのだ。だからポインタ型であるxに直接代入できる。
これでこの行の説明は終わり。printfの説明に移る。
続く
printfには知っての通り、変数をある形に変換して出力する機能がある。
数を出力したかったら%d、文字を出力したかったら%c、といったもので、これらは変換指定子と呼ばれる。
さて、ではここで使われている変換指定子の一種である%sとは一体どのようなものか。
%sは、与えられた変数の値をアドレスだと認識して、
そこに格納されている文字から始まる文字列を表示するものである。
このプログラムでは、例えば%sに対してx[0]を対応させている。しかしx[0]は'1'という値であり、アドレスではない。
printf("%s",x[0]);としてしまうと、x[0]の値を無理矢理アドレスとして読み込んでしまうので、
結局無意味な場所を読み込んでいることになるので、思った通りの動作にはならない。
ここで
>>643 を見てみると、x[0]に&が付いて、&x[0]となっている。
これは何を意味するか。これは、x[0]が存在する場所のアドレスを示している。
%sにはアドレスを渡すべきなので、このようにするとうまく動作する。
しかしまだ気がかりなことがあると思う。どうして一文字ずつ表示されるのではなく、連続して数字が表示されるのか。
その答えは、%sがどういった動作をするものかをよく考えてみればわかってくるだろう。
%sは渡されたアドレスから始まる「文字列」を表示させるものだった。そして文字列とは、先も述べた通り\0で終わるものだ。
printf("%s",&x[0])とした時に何が起こっているかというと、x[0]、つまり1から始めて\0までを連続して表示させている。
決してx[0]の一つだけを表示させるものではない。そういう役割は%cが担っている。
ここで\0はx[9]に格納されているわけだから、結果的にx[0]からx[9]までを順に表示させていることになる。
あとは同じように考えればわかるはず。例えばprintf("%s",&x[5]);ならば、x[5]から始まり\0のx[9]までが順に表示される。
これで大体わかってもらえたと思う。わからなかったらもう一度聞いてくれれば誰かが答える。
うそをかくな うそを
細かい指摘は控える 乙
>つまりこれを付けることによってポインタを意味することとなるわけだ。 >よって >char *x="123456789" >と書き換えることができる。 これはひどい
内容のモーレツさ加減にひっくりかえった > わからなかったらもう一度聞いてくれれば誰かが答える。 これでさらにひっくりかえった 乙
後からじわじわ来た
mallocした領域で、プログラムの終了まで開放する必要のないものは、freeしなくても問題はありませんか?
プログラム終了前にfreeする必要があるかどうかという質問?
そうですね 何も問題が無いなら省こうと思って
>>658 終了まで解放する必要が無い
=
終了までfreeする必要が無い
解放する=freeする
だから
終了までfreeする必要が無い変数を使って問題ありませんか?
という問いになると、一概に言えない。
OSを占有的に使うことが出来るプログラムならば、バンバン
使っても大丈夫だろうが、そうでない場合は、そうとも限らないことが
あるが、最近は、スタックの使い方のほうが影響が大きい。
ええと・・・ ちょっと理解できないです。 プログラムの終了まで使う変数なので、終了時に自動的に解放してくれるならfreeを書く必要がないなと思っているのですが、 freeしないまま終了してしまうと何か影響がでるのかなと不安なので質問させてもらいました。 けど、やっぱり書けばいいだけなので書く事にしようと思います。 返答ありがとうございました。
>>662 ちょいちょいそれは議論になるよ
個人的には実行時間がそれほど長くないアプリケーションであればOS任せでいいと思ってる。
対極にある常駐プロセスなんかはもちろん随時freeすべき
>>662 殆どのOSの場合、mallocは自分のプロセスのメモリ空間に割り当てるものだから
プロセスが終了した時点で、freeしてなくとも、OSにメモリの所有権/使用権が戻される。
しかし環境によっては、共有領域からの割当を意味する場合もある。
その場合は、そのプロセスが終了しても、共有領域には、使用中という状態
のままになってしまうかも。オーナーのプロセスの存否を調べて、修復して
くれるようなメカニズムがそういう場合は用意されてはいるのだろうが、
あまり期待も出来ない。
C言語は一応、様々な環境を想定しているので、malloc,freeだから
一概に〜であるということは出来ない。
が、unix系OS(windowsも含む)なら、まずfreeしなくても大丈夫
malloc したらfreeをきちんと書けという言われる理由は、malloc/freeの
対応を取ることが難しくリークを起こすようなコードには変数の使い方が下手などの
問題があることが多いからであり、リファクタリングを促す意味であることが
多い。
>>663 freeをやたらと使うとヒープの断片化が発生しやすくパフォーマンス
に影響が出てくることがあると聞く。
freeが幾らきちんと出来ていても、瞬間的にでも凄い量のスタックを使ったり
すると、むしろそちらのほうがOSに影響が出やすい。
プログラムがfreeしないまま終了した場合、OSがかわりにfreeしてくれるので freeしなくて終了しても、動作にはなんら問題なないです。 だけど、自分でfreeすることを薦めます。 今後、途中でfreeする必要があるプログラムを作成することを考えて 自分で後始末をする習慣をつけておいたほうがよいからです。 ひとつだけなら簡単ですが、たくさんmallocしているプログラムでは freeするのはやっかいですよ。安全なコードっを書くには、スキルと経験が要ります。
freeしなくてもコンパイラが文句も吐かずに通ったのでいざ実行してみたら 終了時に「ま、mallocしてるんだからfreeしなさいよ!」と怒られてしまいました これは警告ですか?脅迫ですか?それともツンデレとか言うやつですか?
いや、つまんないから
freeしてないプログラムを1週間くらい使い続けると、 いつの間にかフォーマットされて何も入ってないHDDがからから回し続けるようになる。 これだとヤンデレですか。
>>665 >プログラムがfreeしないまま終了した場合、OSがかわりにfreeしてくれるので
OSがfree関数を呼び出してくれるようなことは無い。
Java仮想マシンでは、freeに相当する処理をしなくても、有効な変数にバインドされて
いないオブジェクトは自動的にfreeに相当する処理をしてもらえて、再利用される
ことは有名な話。
それと混同されたのかなと一瞬思った。
うそをかくな うそを
>>669 共有メモリーならばOSはfreeするだろうけど、ヒープ領域はコードやスタック領域とおなじで
プロセスが死ねば自動的に消滅ってことか?
ヒープに対する特別な後処理はOSはしないということか。
なるほど。
メモリをデバイスと考えるOSでは違ってはおかしくはない。 一般的にOSがプロセスのコードを勝手に呼び出すことは普通無い。
malloc/freeを何度も実行する常駐プログラムを書いています。 みなさんはメモリのフラグメント化をどのように解消していますか?
別に
特にないです
char buf[] = "akbh42"; int len = 512; int done = len < sizeof(buf); 以下のコードがどのような処理をしているのかが分かりません。 int done = len < sizeof(buf);
doneに len < sizeof(buf) を代入してる。 この場合 512 > sizeof(buf) だから doneには0が代入される。
len がsizeof(buf) より小さければ len < sizeof(buf) と言う式は1 を返す そうでなければ0 を返す その値でdone を初期化してる
>>673 malloc/freeを何度も実行しない。
freeとかdeleteで開放されたメモリって再利用されないの?
>>680 フラグメント化により、利用できないことがある。
>>680 疑問に思ったら自分で試してみるんだ
環境依存、実装依存だしな
#include<stdio.h>
#include<stdlib.h>
int main(void){
char *p;
int i;
for(i=10;i<(1<<20);i*=2){
p=malloc(i);
printf("%d %p", i, p);
free(p);
p=malloc(i);
printf(" %p\n", p);
free(p);
}
return 0;
}
つーか多くのシステムはプロセスにある程度の大きさのヒープ割り当ててるので malloc/freeはそこをちまちま使ってるだけでしょ? ヒープサイズ超えるとまたOSに再要求して大きなヒープに変えるのかな? mallocサイズが決まってるんであれば リスト構造にでもして使用中リストと未使用リストでつなぎ変えだけするとか
そんぐらいはOSがやってくれるんじゃない?
ヒープの管理はランタイムライブラリがおこなう。 ヒープそのものの領域はOSからもらう。
C++やらないでCだけのやつなんているの?
いるよ。
呼んだ?
なんでCだけしかやらないの?
仕事でいらないから
とても明確な理由で逆に感心した
なんでもっと楽で稼ぎのいい仕事しないの?
余裕こいてる奴は実はラクでなく稼ぎも悪いw
Cは学校の授業で習った後、趣味程度でやっているが 稼ぎでやるほど本格的にはやってない。稼ぐなら もっと本格的にやるが、研究機関には敵わない。 むしろ、もっと稼ぎやすいもので稼いで、こういった分野も取り込んで 商売として雇った方が楽、自分が直接やるよりは。 世の中、そんなもん。
プログラマとはプログラムを自動生成するプログラムのことです
>>694 ある程度できるのなら外注に出すより安上がりだけどな
きもかっこいい
ポインタの参照先が動的に確保されたメモリかそうじゃないかを調べる方法はありませんか?
その程度なら趣味って程でもないな
>>698 ランタイムライブラリのデバッグ関係ヒープ関数にあったと思う。俺も知りたいから解ったらレポートしてくれ。
#include <stdio.h> #include <stdlib.h> int *test(void){ int *p; *p = 100; fprintf(stdout, "2 %d\n", *p); return p; }; int main(void){ int *x; *x = 0; fprintf(stdout, "1 %d\n", *x); test(); fprintf(stdout, "3 %d\n", *x); return 0; } 実行結果が下のようになりました 1 0 2 100 3 100 test()ではxを使ってないのに、*xに100が代入されてるのはなぜでしょうか?
実行環境が気になる木
pとxが初期化されてないため、たまたま同じアドレスになってたんだろ。
>>702 未初期化ポインタの指す先が偶然一緒だっただけ
やっちゃダメですw
winXP コンパイラはbccです
変数は定義と同時に初期化すべきですか?
それができる環境ならしたほうがいい
int array_n[10] = {1}; と初期化値を指定した時 array_nの配列の内容がarray_n[0] == 1で、 初期化値の指定が無い残りが全て(array_n[1]〜array_n[9])が「0」で埋まるのはC言語の規格上そうなっているのですか? それともコンパイラによっては[1]〜[9]は不定値のままだったりする?
規格上そうなっている
>>710 古いコンパイラなら不定値が入っている可能性が高い
比較的新しいって、どの規格で?
配列の初期化の足らないのを0で埋めるって仕様がサポートされてないようなコンパイラなんてもうないだろ。
KnRぐらいかな。 pccはどうだったんだろう?
>>708 できるだけ使う直前で初期化した方がいい
はいはい 釣りはいいから
>>716 つか, static に取った奴は .bss に置かれるから, 処理系依存で 0 で埋められる
組み込みもんで boot が遅いってので .bss の初期化やめたシステムがあったが
逆に boot が遅くなったって笑い話がつい最近あった.
ふつー使う直前だよな。
俺もつい使う直前に初期化してしまう
業務コードでは 変数宣言 情報セキュリティ対策の一括した初期化 (memset,ヌルクリア) コード上の分離された箇所での明確な処理が必要) 初期値設定 主処理コード を取る形態が多いが、主処理コードの後にも、情報セキュリティコード(ヌルクリア) も入れたほうが良い。(大抵の業務用コードではそれは入っていない) 呼び出し側のバグによって、作業データが漏洩する可能性があるから
staticが0で初期化されるのは、処理系依存じゃないよ。
されないのもあったぞ
処理の内容と無関係に初期化(しかも0)は、よくない筋ですね。 そういうことをやってるところが多いかどうかはしらない。 コンパイラの機能として、自動で、使われなさそうな値で埋めてくれるのとかそういうのはいいと思う。
>>723 すまん. OS とかの実行環境を含めての処理系だ
実行時に必ず初期化されることが保証されているが コンパイラが警告を出すときには変数宣言時に初期化してる
>>724 でも処理系依存じゃないよ。
まともな処理系は0が入る。
C99とかJavaみたいに、変数の宣言が自由にできる言語は、使う直前で宣言 & 初期化。 Cみたいにブロックの先頭でしか宣言できない言語は、使う直前で初期化。宣言と同時には初期化しない。
宣言時以外は代入とか言ってみる。
スタイルの問題は宗教論争になる
俺は結論出てるから高みの見物
>722の例にあるよーな効率の悪い現実の話は別として とにかく値を使う前に正しく入ってればいい 大切なのはまちがいを減らすことで、 有効なのはどっちにするのかを決めておくこと どっちが正しいのかということではない
734 :
710 :2008/07/05(土) 22:53:05
>>711-715 とりあえず、0で埋められる前提でコードを書いても大丈夫そうですね
ありがとうございました
宗教論争つーか、世間でたかく評価されてるようなプロダクツで、(Cで)宣言と同時に初期化ってスタイルのってある?
結論: 宣言同時初期化は、処理ロジックを誇張する傾向が高いが、全体から見てそのモジュールの 処理ロジック(役割)が堅くなりすぎる傾向があり、嫌う人も居る。 コード部冒頭の同時一括初期化コードは情報セキュリティー対策をソースコード上で明示的に行う 無駄なコード。関数のリターン前に不要な変数のクリアを同時に行わないと無意味
C++で順列を出力する短いプログラム作ろうとしてるのですが誰か教えてください。 show(string &s,int n)が文字列sの位置nより右の組み合わせを表すとして forと再帰でバックトラックさせようと考えてます ↓このプログラムだとabcの順列6個のうちcabだけ表示できないのですが 最後の詰めがうまくいきません。 どのようにすれば良いでしょうか void show(string& s,int n){ if(s.size()-1==n){cout << s << endl;} for(int i=n;i<s.size();++i){ if(i==n){ show(s,n+1);} else{swap(s[n],s[i]);show(s,i);swap(s[n],s[i]);} } } int main(){ string v="abc";show(v,0); }
altu-!失礼しますた。別スレへ移動します
html並に簡単なGUIライブラリはないのかよこのやろう
>>736 結論
モジュールの分化性が嫌であり、なおかつスタックやヒープに変数を割り付けることによる
情報漏洩が嫌いな奴はBASICでも使ってろ。
>>740 htaもあるが、そもそもぺたぺた貼ってつくれるじゃん
Delphiのこと、ときどきでいいから思い出してあげてください
xmlでGUIをってな話はどうなったんだろ?
WPF?
>>746 キーワードをありがとう。XAMLでした。
デラーズフリートのモビルスーツですね
>>730 処理系はそうは思っていないようですよ。
宣言に現れる = は、配列を初期化する = を除いて、
その出現順を保ちながら宣言の直後に書かれているかのように扱われ。
言葉の定義に処理系がどうとか意味わからん。
原理原則と実装レベルあるいは運用の話をごちゃ混ぜにするのはイクナイ
基本的にはC言語というくくりで話す場合は規格のことを言っているんだが なぜか執拗に実装の話をしたがるのがいるな
質問させてください。C言語初心者なのですが、仕事でC言語のバグ取りを命じられました。 typedef struct{ 〜メンバ〜 }ABC; ABC *abc; char *str; 〜処理〜 abc = (ABC*)&str; //←これ
まさか&が余分というオチじゃあないだろうな。
755 :
753 :2008/07/06(日) 17:44:34
あ、書き込みミスです。 ↑のような処理があったのですが、コメントをつけてる部分がコンパイル時に警告が出ています。 この部分は何をしようとしているのでしょうか? また、このようなコードを書くメリットやよくある使い方を知ってる方が居たら教えてください。
int func(){ static char a='a'; static char z=a-'a'+'z'; 多分これコンパイルとおらない。 宣言同時初期化は基本的にはサービスだと思ったほうがいいのかも知れない。
758 :
753 :2008/07/06(日) 17:47:24
>>754 &をつけるとポインタのアドレスって意味でしょうか?
また、書き忘れましたが
abc = (ABC*)&str[1];
というパターンもありました。[1]にする意味もご存知でしたら教えてください。
>>753 それじゃあchar型のポインタ strのアドレスを本来はABCという構造体を
指すポインタabcに入れてるからじゃないの?
static変数は、
761 :
デフォルトの名無しさん :2008/07/06(日) 17:51:05
>>753 は学生レベル。 今まで業務に支障でなかったか? ポインタ使って書く方は悪いが
>>761 どっちかというと新人研修用のお題にしか見えない
>>753 が経歴詐称してんのか、教育用の専用コードなのかわからんな。
765 :
デフォルトの名無しさん :2008/07/06(日) 17:54:41
char *str; のとき str = &str[0] ですよ。 あと strに"abcde\0"が入っているとして printf("%s",str); はabcdeが出力され printf("%s",&str[1]); はbcdeが出力される。
766 :
753 :2008/07/06(日) 17:55:02
すみません、3月まで学生で、C言語もほとんどやったことなかったのです。
ポインタもよく分かってません。
>>759 なぜstrは構造体ではなくchar型のポインタにする必要があったのでしょうか?
767 :
759 :2008/07/06(日) 17:57:11
さー作った人の考えはわからんけど ABCという構造体でこちらは見たいんだけど もらってくる際はchar型のアドレスの場合 はそうやるのかなあ?とか
768 :
デフォルトの名無しさん :2008/07/06(日) 17:57:44
バグとりの前にC言語の入門書を読んで下さい。 才能やセンスとか関係ない入門レベルの知識が不足しているようです。
769 :
753 :2008/07/06(日) 17:58:17
>>765 それは分かります。ですが、[1]と書いてあるんですよ。
>>766 最近のCコンパイラは、それが宣言された時に指す「型」が異なるポインタ変数の
チェックを厳格にするようになり、「型」が異なるものには警告を出すように
なっている。良いか悪いかは分からないが、そのような場合を避けるようにコーディング
することは出来るし、実際それが避けられない場合は、コード設計に大きな問題が
あることが多い。
struct であるABCという型へのポインタと&strの型であるchar **は一般的には関連づけ
ることは考えにくい。
なんかこんな手法って通信系とかマイコンとかのかなりレイヤーの低いところなのかな?
構造体をfreadやfwriteでそのまま読み書きするのになんの疑問もたないたやつも多いんで、 char*にキャストするやつがいてもおかしくはない。
>>773 じゃあ、構造体はどうやって読み書きするのが正しいの?
typedef struct{ 〜メンバ〜 }ABC; ABC *abc; char *str; 〜処理〜 abc = (ABC*)&str; これってさ strでもらってくるのってABC構造体を配列にした連続領域ってことじゃねーの? [1]の付けるのがあるって段階でなんかそんなにおいがする
776 :
デフォルトの名無しさん :2008/07/06(日) 18:05:44
freadはchar*型しか読み取れないのでは? char*でよんでそのアドレス渡すとか、キャストして読み込むのでは?
777 :
753 :2008/07/06(日) 18:06:21
UNIXの通信系のプログラムのようですが、何百もソースがあって、 処理内容は全く把握してません。 やはり勉強不足のようです。もう少し勉強します。
まあabc も strもポインターなんだから そのまま abc = (ABC *)str; として扱えばいいんじゃねーの? でstr指す領域がABC構造体の配列であれば abc[1]->xxxxとかでみればいいんだし
780 :
デフォルトの名無しさん :2008/07/06(日) 18:10:22
781 :
779 :2008/07/06(日) 18:11:39
でも通信系の怖いところはもらってくる領域の先頭数バイト捨てる・・・とか言い出しそうだしなw
>>775 構造体の配列の可能性ですか・・・。
調べてみます。ありがとうございます。
>>779 すごく分かりやすい説明ありがとうございます。
やはりポインタの概念が理解不足でした。
>>777 ちょっとまえにやってた仕事で、socketで通信するのに生のintを送ってて、
エンディアンの違う環境になったからバグったってのがあったな。
char[4]にコピーして、順序を入れ替えて、またintにコピーするって方法で回避してた。
このバグに対応するのに、1日かかったって言ってたし、これから先も、二つの
バージョンのソースを管理する必要があるし、通信の入門書の一冊でも読んでれば、
こんな無駄は回避できてるのになぁ。とオモタ。
>>783 某金融機関でダウンしたのはそれかーーー
といってみるテスト
通信回線 Cコンパイラ ハードウェア(メモリ) それらの性質を良く調べないと、データ転送は成立しない。(w:
通信のような異機種間の場合はエンディアンやアラインメント、文字コード、 実数や整数(これが違うことはまれだが)のフォーマットもあわせとかないと いけないからいろいろ面倒。 新しいものほどキャラクターベースでやり取りするものが増えてる。
最近は、確かXMLとかいう、恐ろしく効率の悪いものも使われていると聞く。
XMLとか画像ファイルとか、なんにしても、最近はライブラリのコール一発で読み込めちゃって、
ファイルフォーマットを調べて自分で読み込むとかしないから、
>>774 みたいな疑問をもっちゃうんだろうね。
便利になってるんで、おれもその方向性でいいと思ってるけど。
それが、本当にいいことなんだろうか。
車輪の再発明をし続けるよりかは良いんだろうけども…
書籍に残してくれればライブラリ一発ってのでもいいんだけど 日本では書籍の地位が低いのかなんだか知らないが消え行くばかり まともな技術書は残すような政策がないものかな? もちろん濫造入門書は対象外で
>>790 構造体の読み書きをfreadとfwriteを使わないでどうやってやるの?
790はそこんとこは言及してないと思うけど。 ちなみに、構造体の読み書きは read/write で簡単にできる。
>>792 どっちかっていうと、車輪よりもコロの方が多いんだけど。
ほんとに車輪を作れるプログラマは数えるほどしかいない気がする。
%d と %1d ってどういう違いがあるんですか?
%d 渡された数字をそのまま表示 %1d 上記と同じだけど1桁だけ
>>798 マルチ&意味不明
scanf
printf
その他
お前の考えてることなんて分からない
分かるように説明しろ
>>799 最小幅が1になるだけだから同じだと思うけどどうなんでしょ。
それでも理解しました!って言ってるんだからそもそも試してすらなかったんだろうなー
%1dでも桁全部表示するけどな
質問です 学校でvisual studio2008というのを使ってC言語の勉強をしてるんですが 家でもちょっと練習できたらなーと思ったのですが 無料でC言語ができるソフトとかってあるんでしょうか? うちのPCは一般的なXPのPCです。 お願いします
Visual C++ 2008 Express Edition
808 :
デフォルトの名無しさん :2008/07/06(日) 20:13:31
visual studio2008
>>806 ー808
ありがとうございます!
さっそくインストールしてます!
MSから無料の物も出てるんですね〜!
こうやって純真無垢な若者がM$に絡めとられてゆく。
何ぃ!純真無垢で美しく気立てのよいうら若き乙女だと!
>>757 それが許されないのは静的変数が定数でしか初期化できないからで
宣言と同時の初期化が本来的ではないこととは関係ないだろ
関係あるようなないようなあるような・・・
C#>>C++>Cでおk?
より高級って意味か?
作りやすさにしても処理時間にしてもそれぐらいかね
>>819 一般的に、高機能なものほど処理は遅くなる
そうでもない
一般論では赤ん坊とボケてない老人の比較まで対象にしなければならない場合すらある
>>821 一概には言えないとは言え、ライブラリにおいても
高水準と低水準とでは、高水準の方が扱う変数が増えて
まぁほぼ一瞬で終わる処理とはいえ、必要の無いものまで
抱えている分、必要な領域、処理時間には差が出るもんさ。
必要の無いものまで抱えるというのは、ちと間違い。 使用するに当たって、必要としない部分も含まれている 可能性がある、といった感じ。まぁ、すべて使うなら それはそれで低水準では逆に手間や手順が増えてしまうがね。
>>824 プログラマの腕次第で高水準のと同じになるだけじゃないか?
たいていのへぼプログラマでは、そうはいかないだけで。
Cでdecimal実装したいんだけどどうすればいいの?
Cで型を実装、もしくはまるで実装されているかのようにみせかけることは無理じゃないかな
>>826 decimalとやらの仕様を入手し、アルゴリズムを検討して必要なライブラリなどを入手し、
然る後に徐に実装すれば宜しかろう。
リトルエンディアンかどうかの判定って↓みたいなのでいいの? if(0 == 1 >> 1) fprintf(stdout, "LE\n");
不可能
だめ。 ビッグエンディアンだろうがリトルエンディアンだろうが1は1だろ。
いったん変数に入れてunionかキャストで任意のバイトを取り出せば判定可能 *(char*)&x とかね。
あれ?だめなのか・・・ リトルエンディアンだと1は 00000000 00000000 00000000 00000001 右シフトして 00000000 00000000 00000000 00000000 = 0 ビッグエンディアンだと 00000001 00000000 00000000 00000000 右シフトして 00000000 10000000 00000000 00000000 ≠ 0 ってことだと思ったんだけど・・・
右シフトする場合はレジスタに取り出すので ビックエンディアン あくまでエンディアンが関係するのはメモリなんかに格納する場合の話
>右シフトする場合はレジスタに取り出すので シフトする場合はレジスタに取り出すので
そういうことかーたぶん理解したd
いくらなんでも、1
>>1 が 32768 になるとかありえないだろw
でも実はCPUのシフト命令によってはビットがループしたり フラグ情報のビットが入り込んできたりするんだよね。 Cのシフトはあいたところは0埋めみたいだけど。
>>838 > ビットがループした
一般にローテート命令と言う
あると暗号系のソフトの最適化がらくちん
>>838 算術シフトか論理シフトかは処理系依存であってCだからどうだということではないよ
おさらい Cの右シフト演算は、符号なし値に対しては常に左から0を詰める 符号あり値に対して1を詰めるか0を詰めるかは処理系依存
きれいにまとめてくれてありがとう
処理系依存なのだけど ほぼすべてがそういう実装になってて そのうち後追いで規格化される
1を詰める処理系と0を詰める処理系の例を教えて
符号あり値に対する右シフトで1を詰めない処理系ってあるのか?
符号と絶対値を使っている処理系がある。
といいますと?
上位ビットとは別にあるということだろう
多分具体例を欲しがってるんだと思う。 俺は具体例なんかどうでもよくて処理系依存にならない書き方するだけだけど
SHシリーズ
ttp://japan.renesas.com/ 記憶が不確かだったから確認したが、SHのコンパイラは「負の値を持つ符号付きスカラ型の右シフトの結果は符号ビットを保持」というのが仕様になってる
ってことで、こいつは算術シフト
でも、signedでシフトって怖いからunsignedでしか使ったことない
852 :
デフォルトの名無しさん :2008/07/08(火) 09:39:21
教えてください 1. For 文を使って、次の図形を表示しなさい。 * *** ***** ******* ********* *********** ************* 2. scanf 文を使ってキーボードから10人の得点データを入力し、11番目のデータはー999とする。そして、while 文を使って、この10人の得点の平均点を求めよ。 3. 2次元配列を使って、6人の身長と体重をstatic データで入力し、それぞれの平均を求め、次のような表をつくれ。P75参照。 平均 身長 165 156 173 163 159 168 体重 45 48 54 56 49 55 4.ピタゴラスの定理を満たす1から100までの整数のうち、3つともが偶数になるものを出力せよ。for文とif文を使う。 5.自分の生まれた月の今年のカレンダーを作れ。printf文と改行の使い方。P55を参照。
854 :
852 :2008/07/08(火) 10:13:16
>>853 すみません、そんなスレがあったんですね
ありがとうございました
助かります
ファイル入出力で、標準入力で指定されたファイルを1文字づつ 別なファイル(ab.c)に書き込むプログラムを作りたいのですが、 どうもうまくいきません。 #include <stdio.h> #include <stdlib.h> int main(void) { FILE *fp; char temp; fp = fopen("ab.c", "w"); while((temp = getc(fp)) != NULL) { putc(temp , fp); } fclose(fp); } ab.cが作成されているので、while文に間違いがあるのだと思いますが、 どうすれば動くようになるのでしょうか?
>>855 何がどう上手くいかないか言葉にしてみ。
自ずと分かるはず
while((temp = getc(fp)) != NULL) getc(fp) != NULL ってやるより特定の記号タイプで終了にしたほうがいいんじゃね?
858 :
デフォルトの名無しさん :2008/07/08(火) 11:51:44
859 :
858 :2008/07/08(火) 11:59:32
>>855 もう一度、自分の書いたコードが何をやっているのかを注意深く読み直すこと。
やりたいことは、あるファイルから1文字ずつ読み取って別のファイルに1文字ずつ書き出すことである。
そのコードは、ファイル ab.c を「書き出し」モード "w" でオープンし、そこから1文字ずつ「読み取り」、
さらにそこへ1文字ずつ書き出そうとしている。これは何かの間違いでしか上手くいかない。
なお、while((temp = getc(fp)) != NULL) も間違いである。
getc(FILE *stream) は stream から1文字ずつ読み取って値を int 型にして返し、
stream の終わりに達したときやエラーが発生したときに EOF を返す。
だから通常は EOF を検出して入力の終了とするが、この EOF は、
通常読み取られる文字( unsigned char )の範囲に含まれない場合があり、
これをすぐ char に代入してしまったら、EOF ではない何か別の値になってしまうかもしれない。
そうなると終わりを検出することができなくなって無限ループとなる危険性がある。
正しいコードは以下のようになる。
int temp;
while((temp = getc(fp)) != EOF) { ……
質問です まず、環境は コンパイラは VC6.0 OSはXP です 以下のコードを見てください(コメントは気にしないでください) #include <stdio.h> /* 外部変数として変数を宣言 */ long di; /* long型 */ char ch; /* char型 */ int i[3]; /* int型の配列 */ char *p; /* char型のポインタ */ int *ip; /* int型のポインタ */ int main() { /* 各変数のアドレスとサイズの表の表示 */ printf("┃変数(配列要素)| アドレス | サイズ ┃\n"); printf("┃ di | %p | %3d ┃\n", &di, sizeof(di)); /* long型変数のアドレスとサイズを表示 */ printf("┃ ch | %p | %3d ┃\n", &ch, sizeof(ch)); /* char型変数のアドレスとサイズを表示 */ printf("┃ i | %p | %3d ┃\n", i, sizeof(i)); /* int型配列の要素全体のアドレスとサイズを表示 */ printf("┃ p | %p | %3d ┃\n", &p, sizeof(p)); /* char型のポインタ変数のアドレスとサイズを表示 */ printf("┃ ip | %p | %3d ┃\n", &ip, sizeof(ip)); /* intr型のポインタ変数のアドレスとサイズを表示 */ printf("\n"); return 0; } このようにすると、プログラムを弄る度に(printf分を追加する等)変数のアドレスが変化するのですが、 それを変化させないようにするやりかたがあるそうなのですが、本当でしょうか あればやり方を教えてください 意味がないかもしれませんが、私に課題として与えられていることなのです
ほんっと意味ねーな……課題出した奴の頭を疑うわ
windows上で動かすプログラムが毎回同じアドレスを使える確率って どのくらいあるんだ?
ちょっと答えは知りたい
>>863 いや、この場合はプログラム内から見えるアドレスだからOSは関係ない
VCでどうやるか知らんけどコンパイラの設定である程度固定できるはず
ほとんど意味ないがな
.data の固定のこと言ってんのかな? printf追加したくらいじゃ動かんと思うけど、、、 メモリをファイルマッピングしてMapViewOfFileExでアドレス指定して 変数割り当てる、とか?
>>866 >メモリをファイルマッピングしてMapViewOfFileExでアドレス指定して
>変数割り当てる、とか?
もうこんなことをしないといけない時点で教材用の題材じゃないことは明白だよな。
出題したやつ頭おかしいとしか思えん。
学生の宿題ってわけじゃなかろ 共有メモリとかの話でもないのかなあ
グローバル変数を全部structに置き換えて、mallocで確保したものにすると 多少はプログラムサイズ非依存性が高まる。 元のプログラムでも、順序関係とかはそんなに変わらない筈なんだが コンパイラ/リンカの都合でこういうのは決定できる(静的データの先頭アドレスの決定権 =コンパイラ/リンカ) 他にも隠された静的データ沢山あるだろうしね。特にWin32では。
>>861 ん、「bssを固定するリンカオプションを調べとけ」って事じゃないの。
871 :
デフォルトの名無しさん :2008/07/08(火) 16:01:51
論理演算子の真偽表 p_______q______p&&q______p||q______ !p 0_______0________0__________0_________1 0_______1________0__________1_________1 0_______1________0__________1_________1 1_______1________1__________1_________0 1_______0________0__________1_________0 ハーバード・シルト著/トップスタジオ訳/柏原正三監修 『独習C 第4版』 翔泳社 57ページより 上の表の意味がさっぱり分からないのですが、論理学か数学かに出てくるのでしょうか。 しばらくスルーしても大丈夫?
872 :
871 :2008/07/08(火) 16:02:33
すみません、ageてしまいました。
p=0,q=0のとき、 p && q == 0、p || q == 0、 !p == 1 以下同様
>>871 数Aとかで習ったような
AND演算とOR演算で調べてみな
ビット演算と絡めた話なら分かるが、 論理演算子説明するのにこんな表使う意味あるのか。
真理値表が大好きなんだよきっと
878 :
デフォルトの名無しさん :2008/07/08(火) 19:12:14
strcat()などの命令をを使ってコピーしたときに 大きさを超えてしまったらなにがおきますか?
やべageてた
>>878 何が起きてもよいですが、何も起こらないかもしれません。
881 :
デフォルトの名無しさん :2008/07/08(火) 19:18:48
機能 s2が指す文字列を、s1が指す配列の最後に連結する。戻り値は、s1の値である。 また、コピー先とコピー元が重なる場合の動作は未定義とする。 バッファオーバーラン strcatは、s1の容量に就いては一切関知しない。よって、s1の指す配列の範囲を越 えて、s2が書き込まれてしまう恐れがある。これによって、メモリ破壊を引き起こしたり、 プログラムがクラッシュしてしまうことがある。バッファオーバーランを防ぐ方法の1つ として、字数制限付き文字列連結関数であるstrncatを使う。
883 :
デフォルトの名無しさん :2008/07/08(火) 19:49:37
質問させてください。 配列c[k]の成分を全て書き出すようなプログラムなんですが 以下ではどうもうまくいきません! どこが違うのでしょうか・・・ int i,k; double x,c[k]; for(i=0;i<=100000;i++) { x=0.3; x=4*x*(x-1); for(k=0;k<=999;k++) { if(0.001*k<x && x<0.001*(k+1)) { c[k]++; printf("%lf",c[k]);
int k; double c[k]; この書き方がまず出来ない 配列を宣言する時は要素数を確定してなければならない
885 :
871 :2008/07/08(火) 19:55:23
>>881 によると
>字数制限付き文字列連結関数であるstrncatを使う
strncat(char *s,const char *t,int length)
C2008では、この関数は非常にインテリジェントになっており、
sの後ろに何文字書き込めるか、知らない場合はプログラム作成者
の携帯にメールを出してチェックしてくれるそうです。
lengthがsの後の有効書き込み可能メモリのサイズを超えた値を指定してみて下さい。
tの有効読み込み可能メモリサイズを超えたときもメールを出してくれるそうです。
いい時代になったものです。
簡易ボーカルキャンセラーをつくりました。 ステレオのwavの左チャンネルから右チャンネルを引いてモノラル化して センターキャンセルするという単純なアルゴリズムです。 ただ減算しただけだと、出来上がったモノラルファイルを聞くと、たまにブチブチノイズが入ってしまいます。 ためしに減算した値に0.6を掛けてみたらノイズが消えました。 原因はオーバーフローでしょうか?0.6をかける処理っていうのは正しいことなんですか? データの型はsigned shortです。
#define M 7 //patternの長さ char text[]="ababdeabababbabababab"; char pattern[]="abababa"; // 検索する文字列 int next[M]; // パターン検査用 検索する文字列の長さが不定だった場合、 現時点で自分は、nextをその都度検索する文字列の長さ分をmallocなりで確保しようと思っているのですが、 int next[M];はどのようにするのがベストですか?
思うんだが検索する長さが不定ならば 最初っから微妙に配列作ってないで必要な分だけmallocすれば良いんじゃないのか?
ごめんなさい、言い忘れてました。 KMP法による文字列検索です。
一定サイズ確保してそれ以上の大きさの文字列は検索できませんよとするか いちいちallocするかの二択
893 :
デフォルトの名無しさん :2008/07/08(火) 23:15:19
500行くらいの難判定復号のプログラムなんですが、 質問させて頂いてもよろしいでしょうか?
ソース上げれば暇な人が答えてくれるかも
多分凄い初心者な質問だけど、コンパイラのバージョンってどうやって調べられるのか教えてください GUI開発環境で、CPad for Borland C++Compiler ってのを使ってます。 それでコマンドプロンプトを起動しgcc -v と入力したら gcc version 4.3.0 20061021 というのが表示されるんですが、 これがコンパイラのバージョンを表してるんですか?
896 :
デフォルトの名無しさん :2008/07/08(火) 23:36:16
ちがうだろ
>>887 wavとか全然知らんくせにレスさせてもらうが
> 原因はオーバーフローでしょうか?
チェック文入れてみたらどうでしょう?
abort(SHORT_MIN <= l - r || l - r <= SHORT_MAX);
> 0.6をかける処理っていうのは正しいことなんですか?
オーバーフローが無いことを保証するなら 0.5 をかけるべきなんじゃないかな
違ってたらゴメンね
質問があります。 以下、typeA,typeBは任意の型とします。 typedef struct { typeA a; typeB b; structC c; } incC; typedef struct { typeA a; typeB b; structD d; } incD; typedef struct { typeA a; typeB b; union { structC c; structD d; } x; } incX; と定義したとします。 このとき、incCへのポインタ を incX へのポインタ(pX)にキャストしたら pX->x.c.membern で incCのcのメンバに正しくアクセスできることは確約されていますか?
>>897 やはりオーバーフローしてるところがあります。下にも上にもですね
short型にdouble掛けてもいいんでしょうか?
>>898 できない。
そもそもキャストできない。
incC*とincX*の大きさが違う可能性がある。
>>901 それでも小数点以下切捨てされちゃうのが・・・
いいのかな?と
903 :
898 :2008/07/09(水) 02:02:26
>900 レスありがとうございます。 大きさが違うとキャストできないってのがピンときません。 typedef struct { int len; char str[1]; } Str; Str *str = (Str*)malloc(sizeof(Str) + ...); はOKなのですよね・・・?
>>886 本当か?w
すごいいい時代になったな。何故strcpyでそれもやってくれないんだ?多分それstrcpyでも
やってくれるよ。
>>903 俺は保証されるように思う。あくまでも思うなので他の人のフォローに期待。
んで、キャストできないなんて事はないよ。
構造体が違ってもキャストは出来るだろうな 正しくアクセス出来ることを確約はされていないだろうが
あの構造なら、確約されると思うが。 確約されない理由ある?
アライメントによってはずれるんじゃね
アライのメットを装備すればおk?
unionのメンバの大きさが不ぞろいなときに 最大のメンバの末尾に合わせてつめるような処理系とかあるのかな? もしそうなら保証できないね っていうか規格スレのほうが詳しいと思う
関数について質問なのですが 2つの値を返す方法ってありますか? int ○○(void)ではreturnで1つの値しか返せないと思うのですが void ○○でできる方法があるのでしょうか?
パラメーターの参照渡し
引数にポインタを渡す
#include <stdio.h> void func(int *a, int *b) { printf("関数に入りました\n"); *a = *a + 1; *b = *b + 3; } int main() { int x = 0, y = 0; printf("x = %d y = %d\n", x, y); func(&x, &y); printf("x = %d y = %d\n", x, y); return 0; } とでも書けば結果を x, y ともに返せてることが分かると思う
>>908 ,指定された構造ではアライメンとは関係ないね
>>910 そんな処理系聞いた事無いけど、ある?
待った。あの構造でも、下のstructとオプション指定によってはアライメンが関係する。 失礼した。
アライメンって何。
粗い麺
マジレスすると荒井注のいとこ
ショウエイでも可
#define NENREI 25 struct ID { int Mushoku; int Doutei; int Hikikomori; int KanojoInaiReki; }; void func(ID *id) { id->Mushoku = TRUE; id->Doutei = TRUE; id->Hikikomori = TRUE; id->KanojoInaiReki = NENREI; } int main() { ID id; func(&id); printf("シコシコ…ああっ、いいお、いいお、足も胸もおなかもかわいいお…"\ "イッルたん最高だお…シコシコ…そろそろイクお……ウッ!"); }
つまり誰でもオナニーするってことでよろしいか?
あるあるあr
双方向リスト用の構造体で質問があります。 現在の双方向リスト用ポインターの配置 typedef struct hogehoge HOGEHOGE; struct hogehoge { int hogeint01; 〜 int hogeint02; struct hogehoge *prevdata; struct hogehoge *nextdata; } こちらに変更するとリストから切断する際に失敗してるようでフリーズします。 typedef struct hogehoge HOGEHOGE; struct hogehoge { struct hogehoge *prevdata; struct hogehoge *nextdata; int hogeint01; 〜 int hogeint02; } どういう原因が考えられるでしょうか? 領域の確保はプログラム起動時に構造体サイズxn mallocで確保しています。
>>924 今までは切断する処理がたまたま動いていただけ、かな?
最小限の再現ソースを見せてってよくいうのはそういうことです。
構造体書き換えたらフルコンパイルしているか?
927 :
924 :2008/07/09(水) 10:32:05
ちょっと気になる箇所があるので数回に分けます。 まず登録切断部分 void Entry(HOGEHOGE* wfp) { if (fpEntTy == NULL) { fpEntTy = wfp; wfp->prevdata = NULL; wfp->nextdata = NULL; fpEntTyLast = wfp; } else { fpEntTyLast->nextdata = wfp; wfp->prevdata = fpEntTyLast; wfp->nextdata = NULL; fpEntTyLast = wfp; } EntTyCout++; return; } void Del(HOGEHOGE* wfp) { if (wfp == fpEntTy) fpEntTy = wfp->nextdata; if (wfp == fpEntTyLast) fpEntTyLast = wfp->prevdata; if (wfp->prevdata) wfp->prevdata->nextdata = wfp->nextdata; if (wfp->nextdata) wfp->nextdata->prevdata = wfp->prevdata; EntTyCout--; return; } 起動時に構造体サイズxn mallocしたあとn回Entry関数でリスト化してます。
>>926 そうしてます。
以前ちょっとはまった経緯があるのでmakeの最後にコンパイル時に生成したxxx.oなどは
削除するようにしてありますので常にフルコンパイル常態なんです。
>構造体サイズxn malloc これは p=(HOGEHOGE *)malloc(sizeof(HOGEHOGE)*n); Entry(p); Entry(p+1); Entry(p+2); : Entry(p+n-1); という意味?
フリーズするってのは無限ループだろう
Del読んだ前後のループ部分貼れ
if (fpEntTy == NULL) { : } else { fpEntTyLast->nextdata = wfp; wfp->prevdata = fpEntTyLast; ここを見ると奇妙な事をしているな。 双方向リストの仕様は何だ?
別に奇妙でも無いじゃん。 デバッガもしくはprintfで途中経過見てる?
fpEntTyが先頭でfpEntTyLastが末尾なだけじゃないの? んでもそれならDelの処理は if (wfp == fpEntTy) fpEntTy = NULL; if (wfp == fpEntTyLast) fpEntTyLast = NULL; だけでもよさそうに思うし、別に今のでも大丈夫に見える
>935 落ち着け
>>933 fpEntTy側からのアクセスの場合、終端にはnextdataにNULLが入ります。
fpEntTyLast側からのアクセスの場合、終端にはprevdataにNULLが入ります。
Entry関数はもらった構造体を一番最後につけます。
だけ、はまちがい。 if (wfp == fpEntTy) fpEntTy = wfp->nextdata; if (wfp == fpEntTyLast) fpEntTyLast = wfp->prevdata; が、 if (wfp == fpEntTy) fpEntTy = NULL; if (wfp == fpEntTyLast) fpEntTyLast = NULL; でよさそうなのに、ってことです。 ちなみにNULLはどのように定義されていますか?
とりあえずフリーズの話をしようか
>938 いいから落ち着け まだ要素が残ってたらどうするんだ
いいから早く全部貼れよ!
そもそも
>>924 の情報だけで何とかしようと思うのが間違ってる。
デバッグしたことないのか?
} else { fpEntTyLast->nextdata = wfp; wfp->prevdata = fpEntTyLast; wfp->nextdata = NULL; fpEntTyLast = wfp; // これなに? }
>>940 oops
ひどくつかれているようだorz
ほんと、ごめん。
>>924 >>927 >>928 >>930 >>937 は私です。
>>938 >if (wfp == fpEntTy) fpEntTy = NULL;
>if (wfp == fpEntTyLast) fpEntTyLast = NULL;
これをやってしまうと、要素が残ってるかもしれないのに
リストを切断してしまうのでダメです。
なので今のようなロジックにして、登録の際に両端の構造体にはNULLを入れることを
保証すればOKなんです。
while(fpEntTyLast) Del(fpEntTyLast); とかしてんのかな
if (wfp == fpEntTy) { fpEntTy = wfp->nextdata; fpEntTy->prevdata = NULL; } if (wfp == fpEntTyLast) { fpEntTyLast = wfp->prevdata; fpEntTy->nextdata = NULL; } が要るんじゃないのか? バグ原因かも知れないがな。
949 :
924 :2008/07/09(水) 10:54:49
>>943 それは双方向リストのfpEntTy側から見た一番最後にくっつけるためです。
とりあえずリストのポインタ操作に慣れてないやつは口開く前にもう一回確かめろ
>>949 いや、ここだけに絞って欲しい
fpEntTyLast = wfp; // これなに?
struct のメンバ順入れ替えで振る舞いが変る ってんなら *prevdata, *nextdata が領域外アクセスして(されて) ポインタ値が壊れているんじゃないの? int hogeint01 … ってあるけど、実は配列があって、範囲外書き込みしてるだけとかさ
924はタコに応答してないでさっさと全ソースを貼れ
>>951 最後の要素を指してるだけだからおちつけってw
>>951 いやだから・・・
fpEntTy側から見た最後が変わったのでfpEntTyLastも更新しないと・・・・
双方向リストをご存知?
>>952 中に配列はないです。
構造体サイズの調整用の予備charはありますが使ってません。
正直、双方向リストのバグではなく、単に他のバグの可能性が大と思われ
>構造体サイズの調整用の予備char あ や し い
グダグダ言わずにソースを全部貼れ、な?
>>947 fpEntTyLast = wfp->prevdata;
fpEntTyLast->nextdata = NULL;
かな
>>959 アロケーション時 sizeof(HOGEHOGE) 使わずに 定数リテラル 使ってる悪寒
>>924 全ソース貼れorロダにあげろ
>>961 fpEntTyLast->nextdata = NULL;はあってもなくても大丈夫に思うが、先頭削除時のはいるだろうね。
が、それが原因で永久ループになる事はなさそうに思うので、みんな言ってるように他の部分もうpするんだw
# 先頭のprevがNULLかどうか判定する事はないと思いたい
とりあえず上の二つの関数に問題はない 突っこんでるやつは全員的外れ
ある程度allocした領域をガチャガチャした後に、新しく使う領域を探すのはどうやってやってるのかな 中間削除も行えるようだし、気になります
うp中かな。wktkwktk
UP用に小さくしてたら、問題なく動いてしまった落ち。
>>962 それはないですw
ちゃんとsizeof(HOGEHOGE)*nで確保してます。
いやちょっとうpするにはサイズが大きいのと元はちょっとそのままあげるのはできないものなので・・・
まあとにかく、他の原因だと思ってデバック頑張れ。
おかしくない部分だけ抜粋して原因は何が考えられますか? は無いだろ・・・
構造体のレイアウト変えたら動かなくなったので、構造体のレイアウトが 悪さをすることがあるか?って聞いただけじゃね? どつぼにハマるとそういう考えになることもあるよ。コンパイラのバグじゃね??とかさ。
void Del(HOGEHOGE* wfp) { printf("%p\n", wfp); /* ←追加 */ と アロケーション時に p=(HOGEHOGE *)malloc(sizeof(HOGEHOGE)*n); for (i=0; i<n; i++) printf("%p\n", p+i); /* ←追加 */ Del() 呼び出し時の アドレス比較だな アロケーション時のアドレス以外の値が来てるなら、何処かのコードが値をぶっ壊してる
実はこれ以外に大きくまとめてHOGEHOGEを確保する分とHOGEHOGEを動的に細かく確保するというのが混在してて、 ある箇所でリストを開放する際にまとめて取ったHOGEHOGEか1個単位でとったHOGEHOGEで扱いが違ってます。 そこが原因かなあ・・・とか思ってたりもします。 wfp = fpEntTy; while(wfp) { switch(HOGESwitch[wfp->Type](i,wfp)) { case -1 : if (wfp->prevdata == NULL) { wfp2 = fpEntTy; } else { wfp2 = wfp->prevdata; } Del(i,wfp); wfp = wfp2; break; case -2 : if (wfp->prevdata == NULL) { wfp2 = fpEntTy; } else { wfp2 = wfp->prevdata; } Del(i,wfp); free(wfp); wfp = wfp2; break; default : break; } wfp = (HOGEHOGE*)wfp->nextdata; }
975 :
924 :2008/07/09(水) 11:37:41
>>974 はいじってる過程のものなのでたぶんおかしいですw
・削除するときに削除される要素のprev nextをちゃんとNULLにする ・先頭要素を削除したときは新しい先頭要素のprevをNULLにする これやってもだめかな
977 :
924 :2008/07/09(水) 11:42:52
>>976 あーーーーそれぽいですねorz
wfp = fpEntTy;
while(wfp) {
switch(HOGESwitch[wfp->Type](i,wfp)) {
case -1 :
if (wfp->prevdata == NULL) {
wfp2 = fpEntTy;
wfp2->prevdata = NULL;
} else {
wfp2 = wfp->prevdata;
}
Del(i,wfp);
wfp = wfp2;
break;
case -2 :
if (wfp->prevdata == NULL) {
wfp2 = fpEntTy;
wfp2->prevdata = NULL;
} else {
wfp2 = wfp->prevdata;
}
Del(i,wfp);
free(wfp);
wfp = wfp2;
break;
default :
break;
}
wfp = (HOGEHOGE*)wfp->nextdata;
}
これが正解?
しらねーよ
>>976 それだと 『構造体のレイアウト変えたら動かなくなった』 の説明がつかないんじゃね?
元レイアウトであろうが、新レイアウトであろうが それが主因なら同じ挙動になると思うけど
>>977 何でDel関数じゃなくてそこなおすんだろ?
んで、case -2はますます関係ないんじゃないの?
>>979 同じデータ操作をしてない場合、たまたまうまく動く場合とそうではない場合があるんじゃないかな
982 :
979 :2008/07/09(水) 11:59:40
>>981 それは、、、、 問題の切り分けができていないパターンだな
主因は "とあるデータ操作順"であって "構造体のレイアウト変更"は無関係 ってやつか
こうできないものか wfp = fpEntTy; while(wfp) { switch(HOGESwitch[wfp->Type](i,wfp)) { case -1 : Del(i,wfp); // なんかiが増えてんね break; case -2 : Del(i,wfp); free(wfp); break; default : break; } }
ごめ、while 以降の wfp をすべて fpEntTy と読み替えてください
985 :
924 :2008/07/09(水) 12:05:41
>>983 実はfpEntTyは配列になってて0〜31で機能わけしてるんです。
本当は
>>974 のソースの外側で一段ループ処理が入ります。
梅
987 :
924 :2008/07/09(水) 12:26:38
>>974 のcase -2:の中のfree(wfp)をやめたらフリーズが回避できました・・・
>いじってる過程のものなのでたぶんおかしいです ということでなくて、オリジナルもそうなってたのか?
989 :
924 :2008/07/09(水) 12:31:01
>>988 いえ、リスト用ポインタを構造体の最後に配置した場合は問題ありませんでした。
今回そのポインターを前に持ってきたので問題となったのでいろいろ試してる最中でして
いや free(wfp); wfp = wfp2; freeして書き込んでるじゃん。
上書きしてるのにおかしくなってるってことは、どこかでこのアドレス使ってるんだろうな、と
992 :
924 :2008/07/09(水) 12:43:48
//free(wfp); wfp = wfp2; としたら想定の動きするんです・・・・ ポインターを先頭に持ってくるとまずいんですかね? ネットなんかの双方向リストのサンプルも大体構造体の最後に配置してますし・・・
リスト以前に基本的なことが分かってないんじゃないの
free(wfp) の代わりに memset(wfp, 0xcc, sizeof(HOGEHOGE)) これでアレなら、開放されてるのに使ってる場所(or そこを参照するリンク) が残ってることになる
リスト構成本体を構造体先頭にもってったらリスト操作で固まる =リスト構成本体を構造体末尾にもってったら、先頭側メンバの値が(いつのまにか)狂ってる どっちにしてもちゃんと動いていないコードだ
デバッグの仕方を教育する場所になりそうだな。
相談の仕方のほうだろ 表に出せないようなソースなら職場の人間に聞け
バグったらまずはクマのお人形に相談する ウメス
マジレスするとそんなちまちま書き換えながら出されても 俺らエスパーでも予言者でもないんで何も判断できない 問題の起こるソースをそのまま見せられないなら自分でなんとかしろ
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。