08/06/02 13:48:38
>>48
あなたがお使いのコンパイラはあくまで>>45のいうような動作をするだけで
別のコンパイラだと違った結果を出すこともあると覚えて置いてください。
50:デフォルトの名無しさん
08/06/02 13:51:34
>>47
そういう言い方すると単に評価の順序が不定みたいな感じがするが、
>>41のコードはコンパイルすら通らない可能性もあるし、実行時にエラーが発生する可能性もある。
51:デフォルトの名無しさん
08/06/02 13:52:18
>>49
ありがとうございます
>>46様の言われている未定義動作と、言うのはコンパイラ別に判断される動作、ということなのですね
52:デフォルトの名無しさん
08/06/02 13:53:04
>>42
副作用完了点の間で同じ値を二度変更するのは常に未定義である。
未定義であるとは、その結果 ど ん な こ と が 起きても、
例えばパソコンが壊れるようなことがあったとしても、
規格もコンパイラもいっさい責任を持たないということである。
一般に言ってそのようなコードを書くことはまったく推奨されない。
少なくとも、全てを自己責任で行わなくてはいけない。
53:デフォルトの名無しさん
08/06/02 13:54:32
「規格が明確に定義していない」には3種類あって、以下のように定義されている。
・処理系定義(implementation defined)の動作
どう動作するかを実装が選択する。そのプログラムがコンパイルできないというのは許されない。
(この構成概念を使ったプログラムは誤りというわけではない。)
(実装が)何を選んだかは(コンパイラの作者が)文書にしておかなければならない。
規格が合法な動作をいくつか用意していてそこから選ぶことができるかもしれないし、
必要条件をとくに課していないかもしれない。
・未規定(unspecified)の動作
処理系定義の動作に似ている。ただし、どういう動作を選んだかは文書にする必要がない。
・未定義(undefined)の動作
本当に何が起きても不思議はないことを意味する。規格は何の必要条件も課さない。
コンパイルできないかもしれないし、誤った動きをするかもしれないし
(クラッシュしたり黙って誤った結果を出したり)、
あるいはたまたまプログラマの意図したとおりの動きをするかもしれない。
以上、CFAQより抜粋
54:デフォルトの名無しさん
08/06/02 13:56:00
>>51
違う
「やってはいけないこと」の類
55:デフォルトの名無しさん
08/06/02 13:57:28
まあ、勉強用の課題でだされたのかもしれないけど
普通にプログラミングしてて
printf("j++ * j++結果:%d\n", (j++) * (j++));
は気持ち悪いと思ってまず組まないけどなw
56:デフォルトの名無しさん
08/06/02 18:03:09
C言語なら俺に聞け(入門篇) Part 28
スレリンク(tech板:992-番)
URLリンク(www.kk.iij4u.or.jp)
ここを参考にしたのですが先頭の2バイトに設置されている"BM"が曲者で
ヘッダも14バイトなのでせめて2バイト予備で入れてくれればいいのに・・・
という状況で・・・・
自分のプログラムで使う構造体なら考慮して作りますけどすでにある
共通のフォーマットだとそうもいかなくて無理やりやってるんですよねorz
57:デフォルトの名無しさん
08/06/02 18:03:25
>>前スレ992
gcc なら
#pragma pack(1)
でおk
58:992
08/06/02 18:04:29
>>57
ある構造体だけを指定してpack制御するとかは無理ですかね?
59:デフォルトの名無しさん
08/06/02 18:08:01
>>58
#pragma pack(2)
struct ほにゃらら;
#pragma pack(0) // 元に戻す
60:デフォルトの名無しさん
08/06/02 18:10:09
>>56
struct Foo {unsigned char c[14];}でも用意して、適宜変換する関数群でも用意しておけばよかろ。
static inline unsigned long getBfSize(const Foo f)
{
union {
unsigned long u;
unsigned char c[4];
} v;
v.c[0] = c[2]; v.c[1] = c[3]; v.c[2] = c[4]; v.c[3] = c[5];
return v.u;
}
位の関数なら、最適化で消えてなくなるだろ。
61:デフォルトの名無しさん
08/06/02 18:12:26
#pragma pack(push, 1)
struct ほにゃらら;
#pragma pack(pop) // 元に戻す
つーのもあったような
62:デフォルトの名無しさん
08/06/02 18:15:53
>>61
そっちのほうが行儀がいいな
63:デフォルトの名無しさん
08/06/02 22:01:24
>>20
あなた、感覚がかなり可笑しいよ。アセンブラ勉強したら?
成り下がるって事ではなく内部からすれば Call by Value の方が処理多くなるでしょよ。
一般の言語から C 系に来ると逆転するんだよね。
64:デフォルトの名無しさん
08/06/02 22:20:11
3人のテストの点数がそれぞれ90,45,82(int型)だった。3人の平均点を実数(float型)で求め、少数点以下1桁まで出力するプログラムを書け。
の作成をして頂けませんか‥‥??
手元にemacsがなく、しかし、答え合わせをしたく思います‥!!
65:デフォルトの名無しさん
08/06/02 22:20:44
規格の仕様と実装の区別がついてない方はお引取りください
66:デフォルトの名無しさん
08/06/02 22:21:26
>>64
教えて欲しいのではなく宿題を丸投げしたいならこちらへ。
C/C++の宿題を片付けます 108代目
スレリンク(tech板)
67:デフォルトの名無しさん
08/06/02 22:25:07
>>64
脳内にCインタプリタを構築して、神と鉛筆を持って脳内ステップ実行してみろ。
机上デバッグといって昔はみんなそうしてた。
68:デフォルトの名無しさん
08/06/02 22:26:37
>>67
懐かしいなw
学校にコンパイラすらなくてマシン語手打ちしてたときは
そんな感じだったよw
69:デフォルトの名無しさん
08/06/02 22:32:21
>>64
サンプル・・・だけどあえて罠が入ってる。
int a,b,c,d;
float e;
a = 90;
b = 45;
c = 82;
c = a + b + c;
e = c/3;
(ここに標準出力)
70:デフォルトの名無しさん
08/06/02 22:33:28
その程度のコードでemacsは必要ないな
71:デフォルトの名無しさん
08/06/02 22:33:37
>>64
emacsでないと書けないというのは奇妙な話だ。
君のコンピュータにはメモ帳がないのか?
72:デフォルトの名無しさん
08/06/02 22:35:34
Cと思わせてemacsだったのか
73:デフォルトの名無しさん
08/06/02 22:35:35
文脈から外人の気配を感じる
君のソースをここに書いてみて
もし間違いがあれば指摘してもらえるよ
74:デフォルトの名無しさん
08/06/02 22:36:09
>>65
あなたは実引数に配列識別子を指定した場合、
関数に対してポインタに成り下がったものが渡ると思いますか?
それとも、配列の先頭アドレスを指すポインタに変換された後、
そのポインタが指すアドレスが渡ると思いますか?
75:デフォルトの名無しさん
08/06/02 22:48:54
>>74
お引取りください
76:デフォルトの名無しさん
08/06/02 22:49:52
人の話を論理的に解釈できない奴になに言っても無駄だよ
放置しろ
77:デフォルトの名無しさん
08/06/02 22:49:55
おとこわりします
78:デフォルトの名無しさん
08/06/02 22:57:41
>>74
その2つは、同じことを言い換えただけだと思います。
79:デフォルトの名無しさん
08/06/02 23:09:33
>>78
むやみに触ると火を吹くよ><
たぶん、たぶんなんだけど、後者だと思う。
C言語は値渡しだから、ポインタ変数を引数に指定した場合に、
それ自体を関数側で操作する事はできず、ポインタ変数の値である
番地しか渡せない。つまり、ポインタ変数を渡したい場合は、
そのポインタ変数が格納されているアドレスを渡さないといけないって
いいたいんだと思う。
こんがらがってきたorz
…噴火したらゴメンヨ。
80:デフォルトの名無しさん
08/06/02 23:10:55
気を取り直して、、、
>>69
ありがちな罠ワロスw
81:デフォルトの名無しさん
08/06/02 23:12:41
罠とは関係ないけどdはなんだったんだw
82:デフォルトの名無しさん
08/06/02 23:29:11
Dだって?
忘れろ
忘れるんだ
2.0なんか出てないんだ
83:デフォルトの名無しさん
08/06/02 23:32:45
「プログラムと同じフォルダ内のbmpファイル(256色)(200*300pix)をプログラム実行
時に読み込ませ,1pixごとにそのRGB値を調べさせてCSV形式で書き出すプログラム 」
というプログラムを「C/C++の宿題を片付けます」で作っていただいたのですが、RGB値を読み込むことが出来ません。どうすれば読み込めるようになるか教えてください。
以下のプログラムが作っていただいたプログラムになります。
URLリンク(kansai2channeler.hp.infoseek.co.jp)
84:デフォルトの名無しさん
08/06/02 23:38:32
なぜ
ここで
聞く
85:デフォルトの名無しさん
08/06/02 23:55:11
つーかGetPixel使ったほうが楽だよ
86:デフォルトの名無しさん
08/06/03 00:05:00
>>85
GetPixelはこのプログラミングにそのまま使っても問題ないのでしょうか?
あと流れとしては
GetPixelでpixel指定をする。
↓
指定したPixelでRGB値を読み込む。
↓
これをfor文で繰り返す。
87:デフォルトの名無しさん
08/06/03 00:11:19
課題かなんかで使っちゃダメって言われてないなら問題ないでしょ
int i,j;
COLORREF savecolor[XSIZE][YSIZE];
for(i = 0; i < XSIZE; i++){
for(j = 0; j < YSIZE; j++){
savecolor[i][j] = GetPixel(i, j);
}
}
あとはCSV形式にするだけ
88:デフォルトの名無しさん
08/06/03 00:20:43
>>87
私自身の実験解析手段なので、使わせていただきます。
あと、これを用いた時にRGB値を調べるのによいプログラミングはどういったものなのでしょうか?
RGB値を読み込むものを探したらいろいろと出てきてどれを使えばよいのか分からないのですが。
お手数おかけします。
89:デフォルトの名無しさん
08/06/03 00:27:21
ごめん
>>87のGetPixel引数1個足りないわ
HDCにビットマップをロードしとかないとダメだった
RGB値を調べるというのは意味がちょっと分からないけど
GetRValue, GetGValue, GetBValue でCOLORREF型からRGBが取得できる
90:デフォルトの名無しさん
08/06/03 00:27:45
ビットマップって意外と面倒なんだよなw
縦のライン数が正か負で情報の保存されてる方向がちがうんだよなw
91:デフォルトの名無しさん
08/06/03 00:38:02
>>89
HDCは普通に画像を読み込んで、それをFILEのポインタで用意したものを使ったらいいのでしょうか?
あとざっと調べてみたのですが、GetRValue, GetGValue, GetBValueは例えば
color=getpixel()
で読み込んだものを
r[i][j]=GetRValue(color)
見たいな感じで組んでいけばいいでしょうか?
92:デフォルトの名無しさん
08/06/03 00:38:47
まじめにBMPをサポートするとこんな感じ?
URLリンク(www.kk.iij4u.or.jp)
ここの下のほうにあった
URLリンク(www.kk.iij4u.or.jp)
93:デフォルトの名無しさん
08/06/03 00:50:38
>>92
ありがとうございます。このデータを参考にもう一度プログラムを練ってみようと思います。
本当にありがとうございました。
94:デフォルトの名無しさん
08/06/03 00:57:38
1から100の合計を求め、改行を表示するプログラムを教えてください
95:デフォルトの名無しさん
08/06/03 01:00:11
おせっかいかもしれませんが、ついでなので最適化もしておきました。
#include <stdio.h>
int main(){puts("");return 0;}
96:デフォルトの名無しさん
08/06/03 01:03:07
申し訳ございませんが、合計は返りちでお願いします
97:デフォルトの名無しさん
08/06/03 01:07:46
教えて欲しいのではなく宿題を丸投げしたいならこちらへ。
C/C++の宿題を片付けます 108代目
スレリンク(tech板)
98:デフォルトの名無しさん
08/06/03 01:15:54
あ、気分を害しちゃいましたか?
宿題ではないんですけどね
99:デフォルトの名無しさん
08/06/03 01:21:32
int ReSum(int min, int max)
{
int sum = 0;
for(; min < max; min++)
sum += min;
printf("\n");
return sum;
}
100:デフォルトの名無しさん
08/06/03 01:23:59
エレガントですね
ありがとうございます
これからもちょくちょくお邪魔することにしました
101:デフォルトの名無しさん
08/06/03 06:12:04
#include <stdio.h>
#include <ctype.h>
void Oomoji( char *st );
void main()
{
char *moji = "abc";
char moji2[] = "abc";
Oomoji(moji2);
}
//大文字に変換する関数
void Oomoji( char *st )
{
int i = 0;
while( *(st+i) != '\0' ) {
*(st+i) = toupper( *(st+i) );
i++;
}
printf( "%s\n", st );
}
すいません、質問したいのですが変数moji2だと、ちゃんと大文字に変換できる
のですが、ポインタ変数mojiだと変換できないのですが、なぜなのか教えて
もらえないでしょうか、お願いします。開発環境はVisual C++です。
102:デフォルトの名無しさん
08/06/03 06:23:57
mojiのポインタ内に入ってるのはchar型じゃなくてconst char型だから書き換え不可
C++じゃなくてC言語だと書き換えも可能だけど絶対やらない事
103:デフォルトの名無しさん
08/06/03 06:38:17
>>102
ありがとうございます。
104:デフォルトの名無しさん
08/06/03 07:49:47
>>102
つまりchar *型で宣言した文字列は絶対にconst charになるので、
101のような書き換えは、するなと言うことなんですかね?
105:デフォルトの名無しさん
08/06/03 07:57:49
ポインタと配列は同じだと思ってる人多いけど気を付けた方がいい
それと配列を関数を通してポインタにキャストするのも、あまり好ましくはないかな・・・
void Oomoji2( char sz[], size_t sz )
微妙に意味合いが変わるしね
ついでに、strncpyみたいに配列サイズの指定も推奨
106:デフォルトの名無しさん
08/06/03 09:05:56
>>101
コンパイラによっては、文字列リテラルは読み取り専用領域に用意される
(オプションで動作を切り替えられるコンパイラもある)
>char *moji = "abc";
この場合、読み取り専用領域に確保された文字列"abc"を指すように、ポインタmojiを初期化している
mojiは"abc"を指しているだけで、その指す先は読み取り専用領域だから、書き換えられない
>char moji2[] = "abc";
この場合、"abc"という内容で配列moji2を初期化している
どこか別の領域を指しているわけではなく、moji2自身に文字列の内容が含まれているので、書き換えられる
107:デフォルトの名無しさん
08/06/03 09:31:12
>>106
どうも、ありがとうございました。理解できたと思います。
108:デフォルトの名無しさん
08/06/03 10:01:10
scanf関数での入力に手を焼いているけど、一番無難な入力関数ってなんだろ?getchar関数だと、処理速度が気になるし。
109:デフォルトの名無しさん
08/06/03 10:05:07
fgets
110:デフォルトの名無しさん
08/06/03 10:33:56
fgets(buff,BUFF_SIZE,stdin);
fflush(stdin);
111:デフォルトの名無しさん
08/06/03 10:35:11
fflush(stdin)は処理系依存って怒られるぞw
112:デフォルトの名無しさん
08/06/03 13:55:50
文字列を配列30個作り、奇数15の配列を順に表示するのはどうやんの?
今日変な課題出された。
113:デフォルトの名無しさん
08/06/03 13:58:49
for(i=1; i<30; i+=2) puts(str[i]);
114:デフォルトの名無しさん
08/06/03 13:59:05
>>112
奇数15というのは文字列の配列30個のうちの奇数番号の配列15個でOK?
115:デフォルトの名無しさん
08/06/03 14:03:25
>111
処理系依存っつか未定義な
116:デフォルトの名無しさん
08/06/03 14:05:40
番号は0スタートでいいんだよね?念のため
117:デフォルトの名無しさん
08/06/03 15:11:05
変な課題だな。
118:デフォルトの名無しさん
08/06/03 15:26:06
#include <stdio.h>
#include <stdlib.h>
#define LIMIT 50 /* スタックに入る数の最大値 */
typedef int a ; /* 真偽値の型 */
int StackArray [LIMIT] ;
int top ; /* スタックの先頭を指す */
void push (int x) ; /* 関数のプロトタイプ宣言 */
int pop (void) ; /* 関数のプロトタイプ宣言 */
a push_1 (void) ; /* 関数のプロトタイプ宣言 */
a pop_1 (int n) ; /* 関数のプロトタイプ宣言 */
void error (void)
{
}
int main(int argc, char **argv)
{
int order, x, y ;
top = 0 ;
119:デフォルトの名無しさん
08/06/03 15:26:45
while (1)
{
printf ("\n現在のデータ数:%d\n", top) ;
printf ("現在のスタックの状態:") ;
{int i ; for (i=0; i<top; ++i) printf ("%d ", StackArray[i]) ;} printf ("\n") ;
if (push_1 ()) printf ("(1) push ") ;
if (pop_1 (1)) printf ("(2) pop ") ;
printf ("(3) finish ") ;
if (pop_1 (2)) printf ("(4) + (5) - (6) × ") ;
printf (">") ;
scanf ("%d", &order) ;
switch (order)
{
case 1: if (push_1 ()) { printf ("input data: ") ; scanf ("%d", &x) ; push (x) ;} else error () ; break ;
case 2: if (pop_1 (1)) { printf ("%d\n", pop ()) ;} else error () ; break ;
case 3: return EXIT_SUCCESS ;
case 4: if (pop_1 (2)) {y=pop() ; x=pop() ; push (x+y) ;} else error () ; break ;
case 5: if (pop_1 (2)) {y=pop() ; x=pop() ; push (x-y) ;} else error () ; break ;
case 6: if (pop_1 (2)) {y=pop() ; x=pop() ; push (x*y) ;} else error () ; break ;
default: error () ;
}
}
}
120:デフォルトの名無しさん
08/06/03 15:27:07
a push_1 (void)
{
return top < LIMIT ;
}
void push (int x)
{
StackArray [top] = x ;
top = top++ ;
}
a pop_1 (int n)
{
return 0 <= top-n ;
}
int pop (void)
{
top = top-- ;
return StackArray [top] ;
}
121:デフォルトの名無しさん
08/06/03 15:33:36
逆ポーランド記法のプログラムを作ってて、1~9の範囲の整数を入力したいんですけど、どこに入れたらいいですか?
また、1~9の範囲の整数を入力するプログラムって
#include<stdio.h>
int main(void)
{
int x;
if(x>0 || x<10)
{
printf("1~9の整数です\n");
}
else
{
return 0;
}
}
こんな感じでいいですか?
122:デフォルトの名無しさん
08/06/03 15:45:10
だめです
123:デフォルトの名無しさん
08/06/03 15:53:18
>typedef int a ; /* 真偽値の型 */
アホなことやるな
124:デフォルトの名無しさん
08/06/03 15:53:55
#include <stdio.h>
void main()
{
int year, month, day, weekday;
for (year = 2001; year <= 2100; year++){
for (month = 1; month <= 12; month++){
weekday = ((year + year/4 - year/100 + year/400 + (13*month+8)/5 + 13) % 7)+8;
if (weekday == 13)
printf("%4d年 %2d月 %2d日\n",year, month, weekday);
}
}
}
この実行結果の13日の金曜日の個数はどうやって求めればいいですか?
125:デフォルトの名無しさん
08/06/03 15:55:42
>>118
なんか全体的に気色悪い書きかただなぁ
126:デフォルトの名無しさん
08/06/03 15:57:21
>>122
どこがダメですか?教えてください
127:デフォルトの名無しさん
08/06/03 16:04:02
とりあえず
top=top++;
top=top--;
これ未定義
128:デフォルトの名無しさん
08/06/03 16:09:27
>>121
>>118-120までで出来てるんじゃないのか?(>>127の間違いあるけど)
それとも自分で書いたソースじゃないのか?
とりあえず1~9を判定したいなら scanfでxに値を入れてから if(x>0 && x<10) だ
129:デフォルトの名無しさん
08/06/03 16:14:38
>118
・真偽型なんか宣言するな
・スタックの状態を判定する関数の名前をもう少し工夫しろ
・while(1)よりも、orderを初期化した上でdo{ ... }while(order!=3); のほうが構成的に綺麗
気になるのはそんなとこか
130:デフォルトの名無しさん
08/06/03 16:19:08
>>126
x に値が入っていない
条件は || じゃなく &&
return は else の外に出せ(elseは必要ない)
131:デフォルトの名無しさん
08/06/03 16:26:11
>>124
変数に記録でもすれば?
132:デフォルトの名無しさん
08/06/03 18:04:59
#include<stdio.h>
int main(void)
{
int x;
scanf("%d", &x);
if(x>0 && x<10)
{
printf("1~9の整数です\n");
}
return 0;
}
これでいいですか?
133:デフォルトの名無しさん
08/06/03 18:14:47
OK
134:デフォルトの名無しさん
08/06/03 19:21:21
C言語でミリ秒待たせるプログラムですが
みなさんのお薦めで教えて
簡単なヤツがいいです
135:デフォルトの名無しさん
08/06/03 19:23:44
>>134
DOSならSleep
Linuxならusleep
136:デフォルトの名無しさん
08/06/03 19:47:24
Sleep()がコンパイラにダメだと言われました、
ミリ秒待たせるにはどうしたらいいでしょうか(T_T)
sleepとか色々な綴りもやりました(;_;)
137:デフォルトの名無しさん
08/06/03 19:54:08
gettimeofdayとnanosleep
138:デフォルトの名無しさん
08/06/03 19:54:15
>>136
Cの標準関数じゃなくAPIになるから、環境をかけ。OSとコンパイラの種類とバージョンだ。
139:デフォルトの名無しさん
08/06/03 20:02:02
要素数noであるint型の配列vcの要素の最小値を返す関数
int min_of(const int vc[],int no)の作成の仕方を、どなたか教えてもらえませんか?
140:デフォルトの名無しさん
08/06/03 20:08:53
int min_of(const int vc[],int no)
{
/* 必要な変数を宣言 */
/* 最小値を記憶する変数にvcの最初の値を入れる */
/* カウンタを1から初めてno未満であるあいだ1ずつ増やしながらループし */
{
/* vcのカウンタに対応する位置の値と、
最小値を記憶している変数の値のどちらが小さいか調べ、
その小さいほうを最小値を記憶する変数に格納する */
}
/* 最小値を記憶した変数をreturnする */
}
141:デフォルトの名無しさん
08/06/03 20:13:22
>>136
#include <Windows.h>
142:デフォルトの名無しさん
08/06/03 20:15:37
いつも思うんだが <widows.h>の hってなんの略?
143:デフォルトの名無しさん
08/06/03 20:16:29
header
144:デフォルトの名無しさん
08/06/03 20:16:30
>>142
ヘッダーのh
拡張子だよ
cソースの場合はxxx.c
145:デフォルトの名無しさん
08/06/03 20:17:16
最近の学生はヘッダという言葉を知らんのか
146:デフォルトの名無しさん
08/06/03 20:19:09
>>143
>>144
>>145
あ、ヘッダーだったのか
ありがとう
147:デフォルトの名無しさん
08/06/03 20:27:35
いいかい?これはおまじないだから忘れないようにね!
#include<stdio.h>
とか教えられたんじゃない?
スタジオドットエッチ、とか発音してそうな雰囲気だよー
148:デフォルトの名無しさん
08/06/03 20:30:21
でも本当に最初の最初はおまじないって教わった事を思い出した
まあ、最初からヘッダファイルがどうとかこうとか言ってたら中々始まらないしなぁ
149:デフォルトの名無しさん
08/06/03 20:32:14
まあな。
ちょっとなれたころに
#include<stdio.h>
なんかをはずしてみると、今まで使えてた関数が
コンパイルエラー起すでしょ、とか言って教えれるんだけどな。
150:デフォルトの名無しさん
08/06/03 20:33:09
最初からできるわけないもんな。
ファイル分割とかしてみてえと思って何回挫折したことか。懐かしいわぁ
151:デフォルトの名無しさん
08/06/03 20:33:25
#include <cstdio> とか h のないのを見かけるのですがあれは何ですか?
152:デフォルトの名無しさん
08/06/03 20:33:28
stdio.hを外してコンパイルエラーが出る関数ってのは難しいな。
FILE外したら関数以前にエラーが出るからなぁ。
153:デフォルトの名無しさん
08/06/03 20:34:08
>>151
それはすれ違い。
154:デフォルトの名無しさん
08/06/03 20:35:30
>>152
ん?極端に言うと、stdio.h無しだと何もコンパイルできない、と言っている?
155:デフォルトの名無しさん
08/06/03 20:38:24
>>154
逆。大抵の関数はエラーにならない。
156:デフォルトの名無しさん
08/06/03 20:40:39
stdio.h
stdlib.h
まあ、この二つをググッて調べてみるといいよ。
どういう関数が使えるようになるかわかる
157:デフォルトの名無しさん
08/06/03 20:45:52
>>155
やってみたら警告で済ませてくれた。
コンパイラやさしいな!
158:デフォルトの名無しさん
08/06/03 20:46:41
何の警告が出たんだ?
159:デフォルトの名無しさん
08/06/03 20:46:42
実は簡易的なHTMLの<この中の内容>を取り出す関数を作ろうと思っているのですが、
html->nextはHTMLの内容
#define BODY_SIZE 214
/* <>の切り出し */
html->body = (char *)malloc((size + 1) * sizeof(char));
if(html->body == NULL) goto END;
char *tmp;
while(*html->next++ != '<' && *html->next != '\0');
for(int len=0; html->next[len] != '\0'; len++){
if(html->next[len] == '>'){
html->body[len] = '\0';
break;}
if(len >= size - 1){
size += BODY_SIZE;
tmp = (char *)realloc(html->body,size);
if(tmp != NULL)
html->body = tmp;
else
goto END;}
html->body[len] = html->next[len];
}
HTMLの<>内を取得していくにあたり、動的なヒープ領域が足りなくなれば、
reallocを使って拡張し、また取得していく、という処理なのですが、
コードが複雑になり、非常に読み難いものになってしまい、
これをもっと簡潔には出来ないものでしょうか?
160:デフォルトの名無しさん
08/06/03 20:48:10
>>158
printfは組み込み関数じゃないよって警告。
161:デフォルトの名無しさん
08/06/03 20:50:11
>>159
それこそ線形リストがいいんじゃね?
162:デフォルトの名無しさん
08/06/03 20:55:18
>>161
今は>>159のコードを簡潔にしたいです。
163:デフォルトの名無しさん
08/06/03 20:55:53
あー、printfは使うのね
164:デフォルトの名無しさん
08/06/03 21:02:09
>>163
てか、各種ライブラリを使わずに使える関数って何があるの?
read と write は知ってるんだけど
165:デフォルトの名無しさん
08/06/03 21:09:33
>>159
そのソースの全体的な思想が分からないからなんともいえないんだけど
'<'から、次に見つかる'>'までがとにかく取れればいい、というのであれば
strposとかでキュッキュすればいいんじゃないかな。
<<>とか<hoge foo=">">とか無視していいならね。
166:デフォルトの名無しさん
08/06/03 21:11:26
>を多用しているソースは苦手だなw
167:デフォルトの名無しさん
08/06/03 21:14:40
環境はVS2005、Windowsなのですが、
strposをMSDNで調べましたが、見つかりません。
168:デフォルトの名無しさん
08/06/03 21:18:11
>>167
アイヤー。ごめん。strposはphpですた。
Cだとstrstr?
169:デフォルトの名無しさん
08/06/03 21:21:46
>>168
はい
170:デフォルトの名無しさん
08/06/03 21:23:00
>>168
なるほど、
ではreallocの部分は簡潔になりますでしょうか?
171:デフォルトの名無しさん
08/06/03 21:23:59
コピーの開始地点と終了地点がわかってから一気にmalloc()すれば
realloc()必要ないでしょ。
172:デフォルトの名無しさん
08/06/03 21:31:27
>>171
strstrで二点間(<>)の出現場所を計算して
mallocする、ということでしょうか?
ではstrstrを使わない場合で
>>159のreallocの部分を簡潔にするためにはどうすればいいでしょうか?
173:デフォルトの名無しさん
08/06/03 21:33:07
>>172
双方の出現場所が分かれば必要なサイズが分かるでしょ?
んでmalloc。
出現場所を調べる部分を簡潔にしたかったのでstrstr案を
出したわけでして、なぜ却下されたのだろう。ふしぎ!
174:デフォルトの名無しさん
08/06/03 21:34:54
>>172
なぜstrstr()やらstrchr()を使わない?
サイズが事前にわからないのならrealloc()するのは仕方ない。それが嫌
ならコピー元のhtml->nextの残りサイズと同じサイズをmalloc()してお
くしかない。
Cではこのへんが限界だよ。C++ならもっとすっきり。
175:デフォルトの名無しさん
08/06/03 21:37:47
>>174
strchr!思い出させてくれてありがとう。
indexofとかじゃなかったっけ?とかせっせと探してたんだw
176:デフォルトの名無しさん
08/06/03 21:38:46
とゆーか構造体htmlの仕様がなんか怪しくね
177:デフォルトの名無しさん
08/06/03 21:40:20
単にソースをすっきりさせるだけなら、size を html->body_size にして、
bool html_ensure_capacity(html_t *html, size_t new_size) {
void *tmp;
if (new_size < html->body_size-1) return true;
html->body_size += BODY_SIZE;
tmp = realloc(html->body, html->body_size);
if (tmp == NULL) return false;
html->body = tmp;
return true;
}
で、html_ensure_capacity(html, len);を呼ぶ。
178:デフォルトの名無しさん
08/06/03 21:41:42
>>173
私が先程聞いたのは、strstrを使わない場合に
>>159のコードのreallocを簡潔にする方法は無いか、という事です。
却下ではなく、場合の話です。
新しく聞いている訳で、あなたが教えてくれたstrstrを使う案を退けたつもりはありません。
179:デフォルトの名無しさん
08/06/03 21:42:52
簡潔という言葉が一体何を意味するのかがいまいち判然としないが、たぶん無い
180:デフォルトの名無しさん
08/06/03 21:44:25
俺だったら内容コピーしたりせずに先頭を示すポインタと長さを表す変数で済ませるね
181:デフォルトの名無しさん
08/06/03 21:46:22
あ、boolとか書いちゃったよ。てへ☆
182:デフォルトの名無しさん
08/06/03 21:47:23
本当に簡潔に済ませたいならreallocなんか使わずに済む方法を考えること
見たところファイルを全部メモリにロードしてるようだし、
範囲確定してから戻ってmalloc & strncpyすればいいじゃない
183:デフォルトの名無しさん
08/06/03 21:48:06
ではとりあえず
>>179
>>180
>>168
で試していきます。では
184:デフォルトの名無しさん
08/06/03 21:48:40
>>178
あ、タグを見つける部分を簡潔にするのと
realloc周りを簡潔にすることのどちらかしか行わないのね。
両方すればいいのにな、と思っただけですスミマセンスミマセン。
185:デフォルトの名無しさん
08/06/03 21:51:16
短い=簡潔
と思っているフシがあるのかな?
goto使ってたり、}の場所が、とか。
なんか、いろいろ違和感を感じるコードだなって思うわ。
とりあえず試行錯誤しながらがんばって成長してくだされ。
186:デフォルトの名無しさん
08/06/03 21:53:51
構造体の仕様とか名前付けのセンスとかでいろいろ察してしまう
個別のタグ内容を割り当てる構造体にファイル全体へのポインタを含めて
そこからデータをコピーしてくるってのは正直気色悪い
187:デフォルトの名無しさん
08/06/03 21:56:02
>>186
あなたが気持ち悪くならない方法を教えて下さい。
188:デフォルトの名無しさん
08/06/03 21:57:02
まあタグ以外の内容がいらないなら一つ一つバラしてコピーした後に
ファイル全体のバッファを捨てることになるんだろうけど
ふつーテキストと合わせてなんかやるよね
189:デフォルトの名無しさん
08/06/03 21:58:33
>187
ファイル全体のバッファ(のどこか)を指しているポインタは独立で用意して関数の引数で渡す
だけ
190:デフォルトの名無しさん
08/06/03 21:58:47
>>186
まだ成長途中なんだなあって思えてほのぼのするよね。
自分が昔書いたコード見たら気持ち悪い、というか、
なんでこう書いちゃったのwwって思う場所がよく見つかる
191:デフォルトの名無しさん
08/06/03 22:04:14
>>189
その様にした理由を教えて下さい。
192:デフォルトの名無しさん
08/06/03 22:06:49
>191
気色悪いから
193:デフォルトの名無しさん
08/06/03 22:10:36
>>192
論理的理由を聞いている訳ですが、
194:デフォルトの名無しさん
08/06/03 22:11:23
>193
ない
195:デフォルトの名無しさん
08/06/03 22:24:34
>>193
経験で分かるようになるよ。
「気持ち悪い」っていう感覚ってかなり重要だよ。
196:デフォルトの名無しさん
08/06/03 22:45:12
C言語なんだけど
終了しますか?(Y/N)とか、終了(1)
継続(0)とか、入力をさせる。
んで入力値をscanfで取って判断してるんだけど、
scanfって直前のEnterとか認識不能なコードをストリームに
残しておくとのこと
おかげでバグだらけで困っているのだ…
他にキーボードからの入力を受け取れて不具合の無い関数は無いかな?
初歩くさくてすまんが…
197:デフォルトの名無しさん
08/06/03 22:46:04
getcharとかそんなのなかったか?
198:デフォルトの名無しさん
08/06/03 22:49:32
動作が定義されている環境ならば
fflush(stdin)
でいいかな。
199:デフォルトの名無しさん
08/06/03 22:50:51
>>196
標準入力は全てfgets()で済む。
200:デフォルトの名無しさん
08/06/03 22:51:43
早速ありがとう。けど使い方がよくわからん
今ケータイだから使用例なんかを挙げて
もらえるとすごく助かるかも@新入社員、今帰り
明日午前中にコードレビューだから帰ったら今日中に
仕上げなきゃ…
201:デフォルトの名無しさん
08/06/03 22:54:30
printf("終了しますか?(Y/N)");
do {
c = getchar();
} while(c == 'y');
こんなんとかか?CUI系の関数使うの久々だから自信ない
202:デフォルトの名無しさん
08/06/03 23:04:51
>>200
ケータイだから使用例をってどういう流れだ?
conio.hのgetchとかもいいんでないの?
203:デフォルトの名無しさん
08/06/03 23:33:03
確定的にある入力を捕まえたいなら
プロンプトを表示する前にずべての文字を読み捨てておく
それが唯一の汎用な解
204:デフォルトの名無しさん
08/06/03 23:44:12
しかし、すべての文字を読み捨てたのかまだ文字が残ってるのかを知る術はない
205:デフォルトの名無しさん
08/06/03 23:50:46
バグが出るのはscanf()が悪いんじゃなくて使い方を理解してないのが悪い。
まあ、きちんとした使い方を理解させないで安易にscanf()で入力させる入門書や教師が一番悪いんだが。
206:デフォルトの名無しさん
08/06/03 23:59:22
仕事を持ち帰らせる会社が悪い。新入社員なら特に。
207:デフォルトの名無しさん
08/06/04 00:05:14
>>196だけど、様々ありがとう!
とりあえずgetcharを用いて行ってみるよ
文字として受けるから書式指定せずにいけるからね
これから実装だ…
208:デフォルトの名無しさん
08/06/04 00:12:37
fseek(stdin,0,SEEK_END) って未定義だっけ?
209:デフォルトの名無しさん
08/06/04 00:13:20
>>206
納期は明日の午前だからしょうがない
別に業務じゃないけど、納期に遅れる訳にはいかないことを
教えるためだと思う
210:デフォルトの名無しさん
08/06/04 00:13:53
wikipediaには改行コードまで読み飛ばすって方法が載ってるけど、scanf()が行単位で動作してないんだから、
そんなことしてたら、エラーのときと正常動作のときと動きがちがってくるとか面倒なことがありそう。
stdinをfflush()したりファイルポインタを先頭にもどすとかってフラッシュのやりかたがあるけど、移植性ないし
リダイレクトとかされたら、どう動くかわからんし。
fgets()とかで行単位で読み込んで、sscanf()を使うなり自力で解釈するのがシンプルで紛れのないやりかた。
211:デフォルトの名無しさん
08/06/04 00:23:35
>>209
業務では無いみたいだし、つか勝手に持って帰ってるだけだと思うけど
「納期に遅れる訳にはいかない」なら会社に泊まらせた方がまだいいなぁ
212:デフォルトの名無しさん
08/06/04 00:25:34
C言語で、リスト構造によるスタックとキューから要素数を取得する方法を教えてください(><)
213:デフォルトの名無しさん
08/06/04 00:27:34
要素数を別に記憶していないなら、先頭から始めて末尾まで順に辿ってその回数を数えるしかない
214:デフォルトの名無しさん
08/06/04 01:13:26
>>211
泊まり込みなんてほんとにあんのかなあ?
寝ないと逆に集中出来ないんじゃね?
215:デフォルトの名無しさん
08/06/04 01:16:47
3日ぐらい寝ずに仕事すれば覚醒する。
216:デフォルトの名無しさん
08/06/04 01:18:40
寝ないと集中できない は真
泊り込みなんてほんとにある も真
217:デフォルトの名無しさん
08/06/04 01:25:08
会社で寝ればすべて解決
218:デフォルトの名無しさん
08/06/04 01:57:58
>>217
移動時間が節約できるんだよね。
あとは思い立った瞬間に仕事ができるんだよね。
夜2時とかにひらめくこともある。
219:デフォルトの名無しさん
08/06/04 08:19:08
132のプログラムを118~120のプログラムの中に入れたいんですけど、どこに入れたらいいですか?教えてください
220:デフォルトの名無しさん
08/06/04 08:35:54
>>219
1~9の範囲の整数を入力してくれなかったら困るなあってところにいれる
221:デフォルトの名無しさん
08/06/04 19:35:54
>>218
無理をすると、あとでしっぺ返しがくる。
無理をしなければ納期に間に合わないようであれば、納期を延ばしてもらう。
これがいい。
そういう調整能力を身につけることも、プログラマーにとっては重要。
222:デフォルトの名無しさん
08/06/04 21:51:52
>>221
それがヒューマンスキルってやつ?違う?
223:デフォルトの名無しさん
08/06/04 21:54:28
何かの大賞とった川柳思い出した
無理をさせ 無理をするなと 無理を言い
だったけな?
224:デフォルトの名無しさん
08/06/04 22:17:30
ベーシックのスレは何処でつか?
225:デフォルトの名無しさん
08/06/04 22:18:08
(*p)++と*(p++)の違いがわかりません。
226:デフォルトの名無しさん
08/06/04 22:20:36
(*p)++は、
int n = *p;
n++;
*p = n;
*(p++)は、
int* p2 = p + 1;
くらいだと思っとけ
227:デフォルトの名無しさん
08/06/04 22:24:39
(*p)++;
は中身をインクリメント
*(p++) 及び *p++ は
はポインタをインクリメント
228:デフォルトの名無しさん
08/06/04 22:46:52
文字列の配列ってどうやって作るんですか?
char str[5]
str[1] ="文字列1"
str[2] ="文字列2"
str[3] ="文字列3"
printf(%s\n,str[1]);
とやってもエラーになるんですが。
229:デフォルトの名無しさん
08/06/04 22:48:06
それは文字列の配列じゃなくて
文字の配列だからね
どうしてもしたいなら二次元配列使う
230:デフォルトの名無しさん
08/06/04 22:49:41
str[][8] = { "文字列1", "文字列2", "文字列3" }
231:デフォルトの名無しさん
08/06/04 22:50:15
せめてこうだな
char* str[5]
まー、何がやりたい分からないから、これがベストとはとても言えないが
232:デフォルトの名無しさん
08/06/04 23:10:12
>>228
厳密な意味での文字列の配列とは、文字の二次元配列の各行要素に文字列が入っているものを言う。
char strlist[3][8];
このように宣言したとき、strlist[0] ~ strlist[2] は、それぞれが char str[8]; と宣言した str と等価となる。
しかし、上記の配列では、全ての行要素の配列の大きさが同じである必要がある。
つまり、それぞれの行に入る文字列の長さが違っても、最も長いものに合わせなければならず、メモリを浪費しがちである。
それが嫌な場合には、主に文字列へのポインタの配列が使われる。
char *strlist[3];
char str0[5], str1[8], str2[4];
strlist[0]=str0;
strlist[1]=str1;
strlist[2]=str2;
見ての通り、strlist[0] ~ strlist[2] は charへのポインタであり、それぞれが対応する配列の先頭を指している。
ということはそれぞれを文字列として扱うことができ、しかもそれぞれに対応する配列の大きさを個別に設定できる。
ただし、実際にはこのように静的な配列を行要素に使うことはほとんどない。通常、malloc() で割り付けた動的な領域を使う。
malloc() の扱いには熟練を要するので、安易に手を出すのは控えること。
それと念のために言っておくが、Cの配列の添字は 0 から始まる。char str[5]; と宣言したら各要素は str[0] ~ str[4] である。
233:デフォルトの名無しさん
08/06/04 23:13:28
早い話、C言語に文字"列"型というものは存在しない
234:デフォルトの名無しさん
08/06/04 23:17:15
>>233
それを言ってもまったく早くはならないと思うが
235:デフォルトの名無しさん
08/06/04 23:40:55
早い話、文字列は使わないほうがいい
こうですか
236:デフォルトの名無しさん
08/06/04 23:58:14
文字列をしっかり理解してないのに文字列の配列に手を出すな
だろ
237:デフォルトの名無しさん
08/06/05 00:00:21
char str_array[N][]とchar *str_array[]じゃ、メモリ構成的にも全くの別物だしな
238:デフォルトの名無しさん
08/06/05 00:26:26
いきなり好奇心からCを勉強するのはおバカさん
Cの前にPASCALを勉強することはお利口さん
ただし、ハマるとオ××に転落さん
そこにさえ気をつければ、本当はPASCALから入って欲しいのだが
Cの勉強は、PACALを初歩をマスターしてからという奴
Free-PASCAL/Turbo-Delphi/ラザルス(だったけ)
みたいなフリーな処理系がネットで入手可能だし、条件は
恵まれているのだが...
なにせ、良いPASCALの入門書は絶版に近いのがイタい。
やっぱり××ムの影響だろな。
239:デフォルトの名無しさん
08/06/05 00:38:16
>>238
はいはいスレチスレチ
240:デフォルトの名無しさん
08/06/05 00:58:13
Cは初心者にはかなりハードルが高いプログラミング言語だよ
241:デフォルトの名無しさん
08/06/05 01:03:31
でもCから始めたよ
242:デフォルトの名無しさん
08/06/05 01:11:20
>>240
書き方次第だよ
判定式の中に計算とかそういうのをやらなければどうってことはない。
243:デフォルトの名無しさん
08/06/05 01:27:05
>>222
「約束を守る」という社会人の鉄則にすぎないのですが、なにか?
244:デフォルトの名無しさん
08/06/05 01:27:45
基本はわかった
スキルあげるため、どういう本がいい?
245:デフォルトの名無しさん
08/06/05 01:32:14
基本がわかったんなら自分で判断しろよw
246:デフォルトの名無しさん
08/06/05 01:35:42
ある程度の大きさの配列を宣言するとき、256とか1024とかキリのいい数字で割り当てた方がいいですか?
247:デフォルトの名無しさん
08/06/05 01:37:18
いや別に
248:デフォルトの名無しさん
08/06/05 01:38:47
>>238-242
以前こんなコードみた
int split_tsv(char ****split,char *filename);
【仕様】
タブ区切り文字列のみで構成されるテキストファイルを読み込み
を文字列配列の配列に変換。 char ***(ポインタ変数)をsplitに参照渡しする。
(sはNULL不可) 戻り値は、行数.
こういったコード、ちょっとやればすぐに出てくるけど、これって初心者向けか?
初心者には絶対に弄らせたくないコードだよな。
構造型プログラミング言語の黎明期の時代に、多くのプログラミング言語(特に
PASCAL)が型の概念を導入したんだが、実プロジェクトに投入したら中間型が乱造
されてしまい名前空間管理が極度に困難になって開発が大停滞してしまった。
このことの反省を十分に取り入れたのがCなんだが、
型の概念を徹底的に学んでない初心者がCで上のようなコーディングをしなければな
らないんだとあせるのは、危険きわまりない。とは家、中間型(作業型)の問題も実
にやっかい。
この世界は、やはり余り普通の人が入ってくる世界じゃないよ。
249:デフォルトの名無しさん
08/06/05 01:51:40
>>243
きめぇ
250:デフォルトの名無しさん
08/06/05 02:12:04
**** はさすがに気色悪い
自分ならそこまでやるなら多段の構造体に仕込んじゃうかも…つーかC++(略
251:デフォルトの名無しさん
08/06/05 02:19:31
char配列で表現した2進数を、頭から一文字ごとに比較したいのですが、
ソースAのような表記ではそもそも「error C2446: '==' : 'const char *' 型から 'int' 型への変換ができません。」が発生しコンパイルが通らず、
ソースBのような表記では、1文字ではなく、文字列全てを読んでしまって、if分岐に入ってくれません。
使用しているOSはWindowsXPHome, 使用しているコンパイラはVisual Studio 2005 Academic Editionです
どなたかご教授いただけないでしょうか
ソースA)
char tmp[8];
strcpy(&tmp[0], "11111000");
if (tmp[0] == "1")
{
...
}
if (tmp[1] == "1")
...
if (tmp[7] == "1")
{
...
}
252:デフォルトの名無しさん
08/06/05 02:20:02
ソースB)
char tmp[8];
strcpy(&tmp[0], "11111000");
if (strcmp(&tmp[0], "1") == 0)
{
...
}
if (strcmp(&tmp[1], "1") == 0)
...
if (strcmp(&tmp[7], "1") == 0)
{
...
}
253:デフォルトの名無しさん
08/06/05 02:23:15
'1'
254:デフォルトの名無しさん
08/06/05 02:27:21
>>253
if (strcmp(&tmp[0], '1') == 0)
{
...
}
とした場合は、下記のエラーが出てしまいます・・・
error C2664: 'strcmp' : 2 番目の引数を 'char' から 'const char *' に変換できません。(新しい機能 ; ヘルプを参照)
255:デフォルトの名無しさん
08/06/05 02:27:59
いや、
tmp[n] == '1' って事を言っているんだろう
256:デフォルトの名無しさん
08/06/05 02:31:01
なんでBのほうにとるw
257:デフォルトの名無しさん
08/06/05 02:33:55
>>255
おお、コンパイルも通り、動いてほしい動作もしてくれました!
ありがとうございました!
…よろしければなぜ通ったのか、っていうか"1"、'1'の違いは何なのか、お時間があればお教えくださいませんか
258:デフォルトの名無しさん
08/06/05 02:36:15
ああ、あつかましくて申し訳ないです。
入門サイトの、それについての解説が載っているページへのリンクや、
ググルキーワードでもお教えいただければ…
259:デフォルトの名無しさん
08/06/05 02:38:15
そんなのも知らないのにstrcpyとかは知ってるのか
260:デフォルトの名無しさん
08/06/05 02:40:05
"1" は { '1' , '\0' } の文字列、 n == "1" で比較してるのは(正確には違うんだろうけど)アドレス
'1' は 1バイトの文字コード(要するに数値)になる
まあ>>236
261:デフォルトの名無しさん
08/06/05 02:40:32
"1"だと文字列なので中身は
1\0 (\0:ヌル文字)
となって先頭の1の部分のアドレスが入る
'1'だとそのままの文字が入る
あと8文字入れたいなら\0まで考えて
tmp[9]取っときなさい
262:デフォルトの名無しさん
08/06/05 02:43:59
>>259
恐縮です
独学の偏った順番で勉強しているからだと思います…
>>260
ありがとうございます!
文字列処理も場数ということで…
気を引き締めて使用していきたいと思います
263:デフォルトの名無しさん
08/06/05 02:47:02
>>261
あー、自分の手元のソースの方ではヌル文字を意識した配列していたのですが…
問題点を抽出化したサンプルを作成する際に、手落ちしてしまったみたいです…
ようするに、まだヌル文字分まで意識して文字列配列を宣言することを、意識しなれていない、ということですね
繰り返さないように精進します
ありがとうございました!
264:デフォルトの名無しさん
08/06/05 02:51:37
>>251
'1' は文字定数である。
Cでは文字はすべてそのマシン上での文字セットに対応する整数値と等価である。
そしてこれが通常 char 型の変数に格納される。
連続したchar 型からなるデータ領域に任意の文字の値を並べて格納し、
最後にヌル文字( '\0' )を加えたものが文字列と呼ばれるデータ構造である。
文字列は通常、その先頭の文字へのポインタを使って操作される。
配列の場合はその配列名が先頭の文字へのポインタに変換されるので、
つまり大抵の場合は文字列を格納した配列の名前を使って文字列を操作する。
この場合、配列 tmp に文字列を格納し、tmp という名前を通じて操作しようとしている。
"1" は「文字列リテラル」と呼ばれる、固定の文字列である。
コード上では配列名同様に '1' へのポインタに変換される。
コンパイラによる自動的な変換がある限られた場合を除き、
どんなときも == 演算子で互いに比較する対象は
「同種の」データオブジェクトでなければならない。
この場合 tmp[0] は char 型つまり整数型であるのに対し、
"1" はその文字列リテラルの先頭を指すポインタ型であるから
正しく比較できるわけがない。文字定数 '1' を使え。
265:デフォルトの名無しさん
08/06/05 02:52:32
もう四半世紀近くやってきて思ったこと。
経験は絶対的に必要だが、努力や熟練とは異質の世界だなと最近痛感。
足を洗うヨテイ
266:デフォルトの名無しさん
08/06/05 02:56:02
>>263
if (tmp[0] == "1"[0])
とか
if (tmp[0] == *"1")
でもコンパイルが通らない事は無いがオススメはしない
文字列が指すのがポインタってのはこれが一番わかりやすいかも?
267:デフォルトの名無しさん
08/06/05 02:58:04
&tmp[0]は絶対に蛇足(tmpと同じ)ということも覚えておくこと
268:デフォルトの名無しさん
08/06/05 03:06:25
C++だとvectorと合わせるために&tmp[0]とかやるけどな
趣味で好きな方を選べばいいと思う
269:デフォルトの名無しさん
08/06/05 03:12:41
&(tmp[0])はtmpと等価だがtmpをポインタ変数と同一視するのはCでもやめたほうがいい。
Cでは変更不能なポインタ変数というのが無い(C++ではある)から。
仮に実際にそうであっても、変更不能なポインタ変数であるとtmpをコード上で見なすこと
はしないほうがいい。
*(tmp++)とか書けないだろ?だからポインタ変数とまぎわらしい書き方はしないほうがいい。
char配列をchar*型引き数に渡す場合は、(char*)&(tmp[0])とか(char*)&tmpというキャスト
をして値渡し(アドレス値は、ポインタ変数にアサイン可能)する。
270:デフォルトの名無しさん
08/06/05 03:30:10
>>265
食っていくだけなら経験があればいい
腕を上げるには努力や熟練よりも好奇心が必要
と、八半世紀(ってなんだ)くらい思い続けてるんですがどうですか
271:デフォルトの名無しさん
08/06/05 08:09:27
>>249
なに、すべてはお金のため。あなたもその年になれば嫌でも理解するでしょう。
272:デフォルトの名無しさん
08/06/05 09:42:19
独学で先週から勉強してるんですが、引数だの返却値だののくだりで分からなくなりました
高校時代の数学の成績を聞いて一言返すだけのプログラムなんですが
seisekiがどんな値でも返事が「苦手なんすね」になります
どうしたら成績に合った返答ができるようになりますか?
どうやらこのスレで自分の質問だけかなり低レベルなようですがよろしくお願いします
#include <stdio.h>
int func ( int );
int seiseki ;
int main ( void )
{
printf("高校時代の数学の成績は5段階評価で言うと大体どのくらいでした? :");
scanf("%d",&seiseki);
switch(func(seiseki)) {
case 1 : printf("苦手なんすね\n"); break;
case 2 : printf("普通っすね\n"); break;
case 3 : printf("得意なんすね\n"); break;
default: printf("え?\n");
}
return 0;
}
int func ( int seiseki )
{
if(seiseki == 1 || 2) return 1 ;
if(seiseki == 3) return 2 ;
if(seiseki == 4 || 5) return 3 ;
else return 4 ;
}
273:デフォルトの名無しさん
08/06/05 09:45:46
int func ( int seiseki )
{
if(seiseki == 1 || seiseki == 2) return 1 ;
if(seiseki == 3) return 2 ;
if(seiseki == 4 || seiseki == 5) return 3 ;
else return 4 ;
}
if ( seiseki == 1 || 2 )
だと、seiseki == 1 もしくは 真(0以外) になるから
必ず真になってしまって条件の意味が無い
274:デフォルトの名無しさん
08/06/05 09:46:15
>>272
>if(seiseki == 1 || 2
if(seiseki == 1 || seiseki == 2
275:デフォルトの名無しさん
08/06/05 09:48:14
>>273-274
即レスありがとうございます!
引数とかの問題じゃない初歩的な間違いだったんですね・・・
276:デフォルトの名無しさん
08/06/05 11:22:54
>>269
正しく理解していれば混同することなどナイヨ
そんな冗長なキャスト使うほうが読んでて知識を疑うわ
277:デフォルトの名無しさん
08/06/05 12:00:54
>>269
もし君が配列名をポインタ値として扱うべきでないと真剣に考えるなら、
tmp の要素にアクセスするあらゆる場所で ((char *)&tmp)[0] のように書くべきである。
しかし前スレで書いたように、C規格はそのような冗長な書き方を避けるために、
配列はその先頭要素へのポインタ値に成り下がるという動作を規定した。
規格を正しく理解するかぎり、tmp[0] という書き方はまったく正当で安全である。
理解しないならどのような書き方をしたとて遅かれ早かれ間違いを起こすだろう。
1から10までアセンブラを叩くようなものの考え方を押し通すまえに、
高級言語というものがそもそも何のためにあるかを考え直すこと。
278:デフォルトの名無しさん
08/06/05 12:35:41
どっちも正しいんだから好きな方を選べばいい
279:デフォルトの名無しさん
08/06/05 12:41:45
>>265
俺も、アセンブラから始めて、pascal C++と4半世紀歩んできたが、今C++&boostで面白さが更に拡大してきた。これで10年は戦えそうだ。
280:ロベ
08/06/05 13:34:30
・BMPファイルの情報(画像サイズ、色数等)を表示する
・BMPファイルの画像を上下・左右反転させる
・BMPファイルの画像を回転させる
・BMPファイルのカラー画像をグレースケール化する
式 Y=0.298912*R+0.586611*G+0.114478*B
・Windows形式とOS/2形式どちらにも対応できるようにする
このようなプログラムを作りたいのですが
ネットで調べてもほとんど参考になるものを見つけれませんでした
どこか参考にできるHPなどありますかね?
281:デフォルトの名無しさん
08/06/05 13:47:27
>>280
BMPファイルのフォーマット解説
URLリンク(www.kk.iij4u.or.jp)
282:デフォルトの名無しさん
08/06/05 13:49:23
あと>>56>>83>>92も参考に
283:ロベ
08/06/05 13:56:26
>>281 >>282
ありがとうございます
参考にします!!!
284:デフォルトの名無しさん
08/06/05 14:52:45
今まで
struct hoge __attribute__((aligned(16))) hogehoge[] =
{
{-0.53878,5.12228,-0.46578},
{-0.53878,5.62244,-0.05845},
{-0.53878,5.12228,-1.13112},
{-0.53878,6.47772,-0.82431},
{-0.53878,6.55215,-0.05845},
・
・
}
とソースに組み込んできた情報が肥大してきたので
ファイルから読み込む予定なんですが
16バイト区切りで読み込みに必要なメモリをmalloc
させる方法ありますでしょうか?
285:デフォルトの名無しさん
08/06/05 15:21:06
ない。gccの拡張機能でもなかった気がする。
286:デフォルトの名無しさん
08/06/05 15:23:30
>>284
UNIX系だとmemalign()とかposix_memalign()があるかもしれない。
VC++だと_aligned_malloc()というのがあるかもしれない。
malloc()を使っても簡単にできますけどね。
287:デフォルトの名無しさん
08/06/05 15:25:42
malloc自体は16バイト境界に合わせてくれる保証がないから、
大きめに取って自分で境界調整するしかなかった気がする
なんにせよ処理系に依存する話
288:284
08/06/05 15:27:59
>>285
マジっすかorz
>>286
>UNIX系だとmemalign()とかposix_memalign()があるかもしれない。
>VC++だと_aligned_malloc()というのがあるかもしれない。
ちょっと調べてみます。
ちなみにCygwin + gcc 環境での開発になります。
>malloc()を使っても簡単にできますけどね。
これで思いついたのが、実際に必要なサイズ+16バイトでmallocで
確保した上でアドレスを16バイト区切りになるようにずらすというのもいけそうですかね?
289:デフォルトの名無しさん
08/06/05 15:34:37
>>288
>確保した上でアドレスを16バイト区切りになるようにずらすというのもいけそうですかね?
freeするときに元のアドレスに戻すのを忘れないように
290:デフォルトの名無しさん
08/06/05 15:41:13
戻すのは危険な香り
確保した領域の先頭を指すポインタと実際に使う領域の先頭を指すポインタを別に用意したほうがいいかも
291:デフォルトの名無しさん
08/06/05 15:42:59
>>289
そうですね。
>>290
ポインター2個の予定です。
こういうケースのアドレスのずらし方がわからないorz
292:デフォルトの名無しさん
08/06/05 15:49:58
ポインタの内部表現によるけど
基本的には整数値として見たときに
16の倍数になるように後ろにずらせばいいんじゃないの?
293:デフォルトの名無しさん
08/06/05 16:07:58
>>277
だからtmpは定数を表すマクロシンボルじゃないんだって。Cでは予約語や関数以外、識別子を定数と
みなすことはされない。(もしかして関数も変数なのかも知れないし)
Cでは、配列識別子は、実質ポインタ変数だよ。ただしポインタ変数として書き換え不能という属性がある。
書き換え可能なポインタ変数を、型は同じでも属性が異なるポインタ変数に値を複製する場合も、
明示的キャストが必要.本来的にはCではポインタの型(格)だけでなく変数属性にも煩いぞ。
異なる格や属性のポインタ変換が多用され、多用できるが故のメリットを享受するのに必要な当然の
危機管理文化だ。
Cは簡潔記述が目的で設計されたわけじゃない。この点、絶対誤解するな。
コードを簡潔かつ流麗にし記憶しやすくする為に、型/格/属性の相違をすべて型に吸収させいちいちそれ
にもっともらしい名前を付けることによる弊害(乱用され、乱造されるので、ちょっとしたコード書くの
にも、膨大な資料を参照しなければならなくなるハメになり、そのうち正しいコード(他人のバグに依存し
ない)を書く事すら不能になる)だけは避けたいというのが設計理念。
Cはキャストまみれの冗長記述になるのが自然だし、冗長に書いて真価を発揮する。
294:デフォルトの名無しさん
08/06/05 16:14:04
>Cはキャストまみれの冗長記述になるのが自然だし、冗長に書いて真価を発揮する
ありえない
そんな思想で作られたとしたら
そもそも配列がポインタに変換される仕様が入るはずがない
295:デフォルトの名無しさん
08/06/05 16:15:46
>>291
void *p = malloc(required_size + 16);
uintptr_t addr = (uintptr_t)p;
addr = (addr & ~0xf) + 16;
struct hoge *phoge = (struct hoge *)addr;
...
free(p);
296:デフォルトの名無しさん
08/06/05 16:27:30
>>293
ぜんっぜん逆。
Cはそういうわずらわしさを、ある一定の原則さえ守っていれば(そこがちょっと難しいが)
環境ごとの差異にさえ捕らわれずに排除できることを目指した。
だからそれぞれの型の複雑な格上げや符号拡張や変換や比較の法則があって、
そしてそれらが 自 動 的 に 行われる。
お前さんは単にそういう原則を正確に把握していないために、
コードの実際の動きを予想することができなくて、ガチガチに規定した冗長コードを書いてしまうだけ。
297:デフォルトの名無しさん
08/06/05 16:30:30
Cには配列という概念は無い
ポインタ(変数/値)に対する演算子[]が定義されてるだけ
pointer[integer_value]は無名変数(ポインタの型/属性/格に対応する型/属性/格を持つ)を
表す。
298:デフォルトの名無しさん
08/06/05 16:32:35
少なくとも strlen((char *)&array) はないだろ常識的に考えて
299:デフォルトの名無しさん
08/06/05 16:33:36
>>297
「概念」はあるよ。
オブジェクトがないだけ。
300:284
08/06/05 16:33:43
>>295
おーありがとうございます。
301:デフォルトの名無しさん
08/06/05 16:43:27
>ただしポインタ変数として書き換え不能という属性がある。
すくなくともこれは大間違い
配列に代入しようとしたときと
char*constに代入しようとしたときの
エラーメッセージを読めばわかるはず
配列識別子は配列全体そのものを表す
ただし一部の例外を除いてその先頭要素への
ポインタ値(変数ではなく)に変換される
だよ
302:デフォルトの名無しさん
08/06/05 16:47:00
>>296
言語仕様を勝手にガチガチに規定して、それに依存したコードを書いてると後で泣きを見るかも知れません
(俺モナー)
303:284
08/06/05 16:57:47
早速組み替えて思ったように動作しました。
感激!!ありがとうございます。
304:デフォルトの名無しさん
08/06/05 17:10:29
必要のないキャストが大量にあるコードを見たときの常人の反応は
「うわあ、この人はすごい厳密なコードを書くんだなぁ」じゃなくて
「うわあ、この人はC言語の仕様をよく知らないんだなぁ」だ
一方で、明示的なキャストが大量に必要なコードがあったとしたら、
たぶんそれは設計に問題がある
305:デフォルトの名無しさん
08/06/05 17:14:22
Cの経験がある常人って事か…
普通に考えてどっちであろうが
常人がコードを見たら「うわぁ…」としか思わないだろ
とか思ってしまったよ
306:デフォルトの名無しさん
08/06/05 17:16:15
ポインタを制するものはCを制すとはよく言ったものだ
307:デフォルトの名無しさん
08/06/05 17:29:01
特定のコンパイラは文句を言わないだけで本当は必要なキャストが大量にあるコードを
見たときの賢人の反応は
「うわあ、この人はC言語の仕様の良く知らない人なんだなぁ」じゃなくて
「うわあ、この人はC言語の仕様の流動的な部分に依存しない信用のおける人」だ
一方で、明示的なキャストが皆無に出来るほど、型やクラスが大量に作ってあるような
(その反面、根本改革は至難の技になる)コードは、CじゃなくてPASCAL系とかで書いた
ほうがいいんじゃないかという気がする。
というのは独り言
308:デフォルトの名無しさん
08/06/05 17:32:40
C++への移植のためにキャストは必要
309:デフォルトの名無しさん
08/06/05 17:36:42
キャストしたら負けかな、と思っている
310:デフォルトの名無しさん
08/06/05 17:49:44
>>307
>特定のコンパイラは文句を言わないだけで本当は必要なキャスト
具体例plz
311:デフォルトの名無しさん
08/06/05 17:59:54
少しでも心配だなと思うところには明示的にキャスト
そうじゃないところは面倒なのでスルー
そんな俺
312:デフォルトの名無しさん
08/06/05 18:29:04
char a = 2;
int b = a << 8;
こんな感じのプログラム書いてはまったことならあるな
格上げって処理系依存なんだっけ?
313:デフォルトの名無しさん
08/06/05 18:36:33
決まってるでしょ。
それでどんな風にはまったの?
その例じゃ出ないけど符号拡張?
314:デフォルトの名無しさん
08/06/05 18:37:12
規格では両オペランドが演算に先立って整数拡張されるはずだが。
315:デフォルトの名無しさん
08/06/05 18:43:32
両方ともunsinedで宣言してたかな?
VCだと512が求まるんだがとある環境だとキャストしないと0になった
316:デフォルトの名無しさん
08/06/05 19:04:06
なんか冷静に思い出してみると、16ビット環境で32ビットの計算をさせようとしてたのかも
typedefされてたのintじゃなくてlongだったような
勘違いスマソ >>312は忘れて下さい
そりゃキャスト必要だよな
317:デフォルトの名無しさん
08/06/05 19:17:05
基本型の型変換にはキャストに似た書式が使われるが、これはキャストとは言わないほうが
いいと思うような...
int m;
double d;
d=(double)m;
とかね。このコードをint変数をdouble変数にキャストするコードとは言わず、int値をdouble値に
型変換してアサインすると言って欲しい。本当は別の書式にしたいんだろうな。設計者は。
318:デフォルトの名無しさん
08/06/05 19:19:02
これは別に煽ってるとかじゃなくて本当に教えて欲しいんだけど
キャストと型変換はまったく違うものなのか?
319:デフォルトの名無しさん
08/06/05 19:25:43
C++ではいろいろ増やしたんだよね。型変換だとstatic_castかな。
dynamic_cast
static_cast
reinterpret_cast
const_cast
320:デフォルトの名無しさん
08/06/05 19:53:14
ビルトインの型変換(密かに関数が呼び出され、その関数が宣言されない)
を使う場合は、使う場所すべてに、わかるようにコメントを入れておくのが後々のことを考えると
ベターかと。(書式は一般的なキャスト演算子にするしかないが)
コンパイラが変るだけでも影響してくる可能性があるし...
321:デフォルトの名無しさん
08/06/05 20:11:45
c言語のスタックについての質問なんですが
int fibo_stack( int n )
{
int f =0;
push(n);
while(!empty())
{ n = pop();
if( n==0 ) f+=0;
if( n==1 ) f+=1;
if( n>=2 ) {push( n-1); push( n-2);};
show()
};
return f;
}
の振る舞いにつて説明する問題なのですが、f+=0やf+=1で何が行われているのか解りません。
スタック内部に影響するのでしょうか。ご教示ください。
322:デフォルトの名無しさん
08/06/05 20:13:40
f = f + 0;
f = f + 1;
323:デフォルトの名無しさん
08/06/05 20:13:51
f = f + 0
f = f + 1
の略
324:デフォルトの名無しさん
08/06/05 20:16:47
f = f + 0は理解してます。しかし、これがスタック内に影響があるのかが解りません。
説明不足ですいません
325:デフォルトの名無しさん
08/06/05 20:19:01
意味の分からないことをいわないでくださいおねがいします。
326:デフォルトの名無しさん
08/06/05 20:23:39
>317-318
本質的な動作は同じである。
キャストは型変換演算子であって、元の型の値をもとにして
指定したデータ型の右辺値を生み出す。ポインタかそうでないかは関係ない。
単に型変換という場合は、コンパイラによって自動的に行われるものを言う場合が多い。
たとえば>317のコードで言えば d=m; と書いた場合である。
(double) のキャストをつけようとつけまいと、コードのやることは変わらない。
327:デフォルトの名無しさん
08/06/05 20:27:00
自分の考えた振る舞いは
n=4の場合
4
_
3 2
3
3 1 0
3 1 f=0
3 f=1
_
2 1
2 f=2
_
1 0
1 f=2
_ f=3
となるのですがこのfが何なのか解りません
328:デフォルトの名無しさん
08/06/05 20:31:54
その関数だけ見せられてもわからん
全部貼れ
329:デフォルトの名無しさん
08/06/05 20:32:56
つーかこの関数おもいっくそ間違ってるんじゃねぇか?
330:デフォルトの名無しさん
08/06/05 20:32:57
>>328
これで全部です
331:デフォルトの名無しさん
08/06/05 20:36:22
関数の処理が正しいかどうかは知らんが
フィボナッチ数列ならf(0) f(1)は固定でいれなきゃじゃない?
332:デフォルトの名無しさん
08/06/05 20:36:25
>>330
なら答えはひとつしかない
「わからない」
fの値がなんになるかはnの値のほかpush()、pop()、empty()、show()の仕様に依存する
fの値がどう使われるかはこの関数を呼んだ場所のコードに依存する
つまりこの関数だけ見せられてfがなにものであるか答えられるわけがない
333:デフォルトの名無しさん
08/06/05 20:38:12
>>329
少なくともこのままコンパイルにかけたら構文エラーだな
334:デフォルトの名無しさん
08/06/05 20:38:51
>>327
それであってるし0から始まるフィボナッチ数列の四番目は3だからおk
335:デフォルトの名無しさん
08/06/05 20:45:03
push()は()内をプッシュ、
pop()はポップしてその値を返す、
empty()はタックが空かどうか判定する、
show()は現在のスタック内表示です
336:デフォルトの名無しさん
08/06/05 20:46:54
>>334
fはスタックとは別のところで計算されてると考えてよろしいんでしょうか?
337:デフォルトの名無しさん
08/06/05 20:47:18
int fibo_stack( int n )
{
vector<int> x;
int f =0;
x.push_back(n);
while(!x.empty()) {
n = x.back();
x.pop_back();
if( n==0 ) f+=0;
if( n==1 ) f+=1;
if( n>=2 ) {x.push_back( n-1); x.push_back( n-2);};
}
return f;
}
極普通のスタックだと思うのですが因縁つけてくる人が多いので
C++になっちゃいますが動くようにしました。
引き続きお答え願います
338:デフォルトの名無しさん
08/06/05 20:49:07
そこまでわかっててなぜわからんのかわからん
339:デフォルトの名無しさん
08/06/05 20:49:44
単にフィボナッチ数列というものを知らないのでは
340:デフォルトの名無しさん
08/06/05 20:55:23
このプログラムのfを足していく理由がわからないんです。
スタックを計算する上で必要な事なんでしょうか
341:デフォルトの名無しさん
08/06/05 21:03:35
fって言う時点でフィボナッチと関連あるとか想像付かないかな・・・
URLリンク(ja.wikipedia.org)
342:デフォルトの名無しさん
08/06/05 21:09:37
解りました!!fはn番目のフィボナッチ数を計算するためにあったんですね!!
ずっとスタック内に影響するものだと思ってました。
ありがとうございました。
343:デフォルトの名無しさん
08/06/05 21:10:51
なぜこれで正しく計算できるかまではわかったのかなー?
そこが意図のはずだが
344:デフォルトの名無しさん
08/06/05 21:11:56
>343
どっちかっつーと数学板の仕事だし…
実用でこんなタコなアルゴリズム書いたら殴られるわ
345:デフォルトの名無しさん
08/06/05 21:12:14
やってることは再帰と同じくらい効率悪いなw
346:デフォルトの名無しさん
08/06/05 21:14:47
スタックを使う理由がわからん
347:デフォルトの名無しさん
08/06/05 21:17:10
数学的な数列の再帰証明をプログラムに変換するために必要だったんだろう
こんなことやる意味がそもそもあるのかと思うけど
348:参考
08/06/05 21:28:29
再帰呼び出し関数で、フィボナッチ数列を計算するコードを定義した際にn=0,1の条件で関数が何回
呼ばれるかを計測するプログラム。奇しくもこれはフィボナッチ数列そのものを与えるという
トリック
unsigned int fib(unsgined int n){
static unsigned int m=0;
static unsigned int result=0;
if(m==0)
m=n;
if(n<=1)
result++;
else{
fib(n-1);
fib(n-2);
}
if(m==n)
return result;
}
(この関数は1回しか呼び出せないのがイタいが)
349:参考
08/06/05 21:33:06
mなんていらねぇな。
unsigned int fib(unsgined int n){
static unsigned int result=0;
if(n<=1)
result++;
else{
fib(n-1);fib(n-2);
}
return result;
}
350:デフォルトの名無しさん
08/06/05 21:33:08
当たり前って言えば当たり前の結果だよな
351:デフォルトの名無しさん
08/06/05 21:35:29
つーか、IT関連の授業教えてる先生ってこんなのばっかり出題してるのか?
大学院とか行って研究するやつなんてすくないんだからもうちょっと実用的
な問題だせよ。
昨日もBMPの読み込みとかなかったっけ?
352:デフォルトの名無しさん
08/06/05 21:40:15
この件については議論せずにスルーしような
353:デフォルトの名無しさん
08/06/05 21:46:10
>>326
キャストは左辺値にも出来ますが何か?
char *p;
void *q;
(char*)q=p;
354:デフォルトの名無しさん
08/06/05 21:48:42
フィボナッチ理解できない人間が結構いることに驚き
355:デフォルトの名無しさん
08/06/05 21:49:57
>>353
それはだめじゃないのか?
356:デフォルトの名無しさん
08/06/05 21:51:39
>>353
間違いである。少なくともANSI/ISO規格の保証する動作ではない。
357:デフォルトの名無しさん
08/06/05 22:00:43
固定長のフィールドからなるレコードを
fgetsした後にsscanfでバラバラにして
フィールド毎にprintfで表示したいんだが
うまくsscanfでバラせてないみたい・・・
AAAAA
BBB
CCCC
こうなって欲しい。
入力ファイル(固定長5、3、4の3フィールドからなる)
AAAAABBBCCCC
358:デフォルトの名無しさん
08/06/05 22:01:14
禁止しても、抜け穴が幾らでもありそうだな。
359:デフォルトの名無しさん
08/06/05 22:04:01
>>357
それって区切りになる文字が無いから失敗するんじゃないの?
360:デフォルトの名無しさん
08/06/05 22:04:15
>>357
sscanf(s, "%5s%3s%4s", a, b, c);
これで済まないのか?
361:デフォルトの名無しさん
08/06/05 22:06:17
>>342
だから>>331でフィボナッチだっつってんじゃん
関数名見ても分からないとか大丈夫か?
362:デフォルトの名無しさん
08/06/05 22:07:53
>>357
ばらせてるけどNULL終端じゃないから残りが出てるだけに5ペリカ
363:デフォルトの名無しさん
08/06/05 22:07:54
>>361
まーそういうなって。
初めてのころは「自分が何にはまってるかそれがわからない」
ということもあるよ。
あることをきっかけにどんどん進むのさ・・・
364:デフォルトの名無しさん
08/06/05 22:10:26
わかってないのに見当違いのレスつけてるヤツらよりはマシだけどな
365:デフォルトの名無しさん
08/06/05 22:10:34
>353
4.5
質問:charのポインタがあって、そのポインタがたまたまintを指していた。
intの次へポインタを進めたい。なぜ以下の式ではうまくいかないのか。
((int *)p)++;
回答:C言語でキャスト演算子は「ビット列が別の型を持っているふりをして、
そういう風に扱ってやろう」ということを意味しているわけではない。
キャストは変換演算子であって、それは右辺値を生みだすと定義されている。
右辺値であるとするなら、代入することも++で足し算することもできないことになる
(古いコンパイラやgccの拡張機能が上のような式を受け付けることは例外である)。
References: K&R2 §A7.5 p.205 / ANSI §3.3.4(とくに注14) / ISO §6.3.4 / Rationale §3.3.2.4 / H&S §7.1 pp.179-80
366:デフォルトの名無しさん
08/06/05 22:28:22
公開された定義に基づいて
再解釈可能なものについては再解釈し、そうでないものは絶対に通さないというのが
基本だったのだが...
いつのまにやら処理系に依存する話になってしまった。
367:デフォルトの名無しさん
08/06/05 22:55:01
こう書けばとおるが、
*(char**)&q=p;
そもそもvoid *へ/からの変換はキャストが不要なのでこの例なら
q=p;
でよい。
368:デフォルトの名無しさん
08/06/05 22:55:55
- キャストが不要なので
+ 明示的なキャストが不要なので
369:デフォルトの名無しさん
08/06/05 22:56:40
((struct hoge*)p)->fuga
370:デフォルトの名無しさん
08/06/05 22:58:00
**a と a[][] って、同じ?
371:デフォルトの名無しさん
08/06/05 22:58:40
仮引数でなら
372:デフォルトの名無しさん
08/06/05 23:00:54
仮引数でも違う。
というか、不完全型の配列型は存在しない。
373:デフォルトの名無しさん
08/06/05 23:01:33
コンパイルは通るよ。
374:デフォルトの名無しさん
08/06/05 23:02:23
通らんかった。二次元はダメか。
375:デフォルトの名無しさん
08/06/05 23:06:05
>>370
仮引数に限ってT**とT*[]は同じ。T[][]はT[]が不完全型だから許されない。
376:デフォルトの名無しさん
08/06/05 23:07:39
仮引数の[]は、識別子に最初に結合する一回だけポインタ扱い
377:デフォルトの名無しさん
08/06/05 23:20:18
>>369
-> の結果は左辺値になりうる。
378:デフォルトの名無しさん
08/06/06 00:04:07
多次元配列はC/C++の最もクサいところ。使わないでね。なるべく。
(普通の1次元配列を工夫して使って)
379:デフォルトの名無しさん
08/06/06 00:07:57
int main(int argc, char** argv)
int main(int argc, char argv[][])
380:デフォルトの名無しさん
08/06/06 00:08:46
>>379
悪い例ですね、わかります
381:デフォルトの名無しさん
08/06/06 02:21:47
メモリの動的確保とポインタについて勉強したのですが、
分からないところがあったので質問します
・mallocで確保したメモリは、プログラムの終了と同時に解放されることは保証されているのか
・関数内でmallocで確保したメモリは関数が終了しても解放されず、
別の関数から参照できることは保証されているか
両方、正常に動くことは確認できたのですが、あらゆる環境・状態で成り立ちますか?
382:デフォルトの名無しさん
08/06/06 02:25:13
・プログラムが終了すれば解放はされる
・別の関数にアドレスを渡せばそりゃ参照できる
383:デフォルトの名無しさん
08/06/06 02:25:20
>>381
Cの規格では保証されてない、プログラム終了後の処理はOS頼み
ただし、間違いなく解放されると思って問題ない。(されないOSが昔あるにはあったが)
二番目は保証されてる、こっちはそう決まってる
384:デフォルトの名無しさん
08/06/06 02:27:49
関数からポインタを返すときって混乱しやすいところだよね。
385:デフォルトの名無しさん
08/06/06 04:34:47
あんまりC言語関係ないけど
#include <stdio.h>
#include <stdlib.h>
void main(){
int a[25];
int i,j;
for(i=0;i<25;i++){
a[i] = rand()%25+1;
for(j=0;j<i;j++){
if(a[j]==a[i]){
a[i] = rand()%25+1;
j=0;
}
}
printf("a[%d]は%dです。\n",i,a[i]);
}
}
↑のは
a[0]~a[24に]1~25の乱数を生成し、且つどれも一致しないというモノなんだけど
乱数が何度やっても決まった値しかでないんだけどどうすればいいのかな?
あと、j=0;とかやってたりソースかなり読みにくいので、訂正などあったらガンガンお願いしますmm
その際解説もつけてくれるとありがたいです
386:デフォルトの名無しさん
08/06/06 04:37:29
#include <time.h>
srand(unsigned)time(NULL));
を足す
387:デフォルトの名無しさん
08/06/06 04:37:53
括弧抜けた
srand((unsigned)time(NULL));
ね
388:デフォルトの名無しさん
08/06/06 04:46:41
あー解説か…まあ細かい話はおいておいて
乱数発生させるには最初に種みたいなのが要るんだけど
srand((unsigned)time(NULL));
はプログラムを実行させた時の現在時刻を拾ってきて
それを種にするように設定する関数なわけ
>>385のプログラムだと何もして無いのでsrand(1);
と設定した事とみなされて
常に同じ乱数が生成されてるのよ
389:デフォルトの名無しさん
08/06/06 06:06:42
Cのプログラムの中で、
system("hoge")で起きたコマンドの結果を文字配列に格納したい場合、何かいい方法は無いですかね?
コマンドライン上ならls > fileで一発なのに・・・orz
390:側近中の側近 ◆0351148456
08/06/06 06:21:52
>>389
(っ´▽`)っ
popen, pclose
標準ライブラリ関数ではないが、unix系OSだと使える。
391:デフォルトの名無しさん
08/06/06 06:29:17
>>390
感謝。さっそく調べて試してみるっすー。
392:デフォルトの名無しさん
08/06/06 08:34:52
>>381
まあmallocも関数でvoid*ではあるけどポインタ返ってくるよね?
393:デフォルトの名無しさん
08/06/06 10:48:52
#include <stdio.h>
#include <float.h>
int main(void)
{ float f;
double x;
long double ld;
printf("\nTesting the precision of float, double, and long double : \n");
f = 1.0f + 1.0e-7;
printf(" 1.0 + 1.0e-7 = %.10f\n", f);
f = 1.0f + 1.0e-8;
printf(" 1.0 + 1.0e-8 = %.10f\n", f);
x = 1.0l + 1.0e-15;
printf(" 1.0 + 1.0e-15 = %.20lf\n", x);
x = 1.0l + 1.0e-16;
printf(" 1.0 + 1.0e-16 = %.20lf\n", x);
ld = 1.0L + 1.0e-19;
printf(" 1.0 + 1.0e-19 = %.30Lf\n", ld);
ld = 1.0L + 1.0e-20;
printf(" 1.0 + 1.0e-20 = %.30Lf\n", ld);
printf("\nThe experiment above is explained by constants from float.h :\n");
printf(" precision of float : %e\n", FLT_EPSILON);
printf(" precision of double : %.15le\n", DBL_EPSILON);
printf(" precision of long double : %.30Le\n", LDBL_EPSILON);
return 0; }
表示された結果のうち、
1.0 + 1.0e-7 が 1.0000001 にならず、同様に
1.0 + 1.0e-15 が 1.000000000000001 にならず、
1.0 + 1.0e-19 が 1.0000000000000000001 という、きれいな数にならない理由を、FLT_EPSILON, DBL_EPSILON, LDBL_EPSILON との関係から説明してもらえないでしょうか。
よろしくお願いします。
394:デフォルトの名無しさん
08/06/06 11:07:42
宿題丸投げは宿題スレへ
自分で考えるヒントが欲しいなら、まずそこに出てくる制限定数の意味やIEEE浮動小数点数フォーマットについて調べること
395:デフォルトの名無しさん
08/06/06 11:33:43
板違いごめんなさいッ
ありがとうございます。
396:デフォルトの名無しさん
08/06/06 12:42:40
問03
学科の出席簿作成。
15人分の学生を表示し、入力により内容を変動させる。
表示順番:
出席表
<入力>学生番号0~14
<入力>曜日番号0~6
<入力>時限番号0~3
<入力>出欠番号0~1
<入力>学生番号0~14の時に99を入力するとプログラム終了。
誰かこの問題教えてください。
397:デフォルトの名無しさん
08/06/06 12:44:01
>>396
氏ね
398:デフォルトの名無しさん
08/06/06 12:59:39
>>396
/* stdio.h をインクルード */
int main(void)
{
/* 必要な変数を宣言し、出席簿の初期値を設定 */
/* 学生番号を入力から一時変数に取り込み、それが妥当な値である間、以下の処理を繰り返す */
{
/* 曜日を入力から一時変数に取り込み、もし妥当な値でなければエラーメッセージを表示して continue する */
/* 時限を入力から一時変数に取り込み、もし以下略 */
/* 出欠を入力から以下略 */
/* 入力された一時変数の値を出席簿に反映する */
/* 出席簿の現在の内容を表示する */
}
return 0;
}
399:デフォルトの名無しさん
08/06/06 13:02:11
>/* 学生番号を入力から一時変数に取り込み、それが妥当な値である間、以下の処理を繰り返す */
親切そうに見せて性格悪いなお前
400:デフォルトの名無しさん
08/06/06 13:23:10
出席簿のデータ構造くらいは教えてやったほうがよくね?
int book[15][7][4]={0};
まあcharにするほどのサイズではあるまい
401:デフォルトの名無しさん
08/06/06 13:23:58
日曜日に授業あんのかよ
402:デフォルトの名無しさん
08/06/06 13:25:40
たまに・・・・・
403:デフォルトの名無しさん
08/06/06 13:28:03
>398
必要な変数ってこれでいい?
データ形式:
(一人分のデータ)
学生番号<int>
名前<char*>
性別<char*>
曜日番号<int[]>
時限番号<int[]>
出欠番号<bool>
変更番号<bool>
404:デフォルトの名無しさん
08/06/06 13:30:25
Cにboolはありません
405:デフォルトの名無しさん
08/06/06 13:31:02
396のどこに名前と性別があるんだよ
406:デフォルトの名無しさん
08/06/06 13:32:38
じゃあ _Bool で
407:デフォルトの名無しさん
08/06/06 13:34:00
学生の名前も含めて構造体で表すなら
struct{
char name[NAMELEN_MAX];
int sex;
int attend[7][4];
}student[15];
ってとこか
408:デフォルトの名無しさん
08/06/06 13:38:20
>>403
学生番号は不要。要素15の配列の添字で扱えば済む。
名前は動的割付するほど大きなデータじゃない。適当な大きさの配列で十分。
性別は整数でいい。男か女かそれ以外しかないのだから。
曜日、時限、出欠を別々に宣言しても意味がない。多次元配列を使え。
Cにbool型は無い。メモリを節約したいならchar型を使え。
変更番号ってなんだ説明しろ。
409:デフォルトの名無しさん
08/06/06 13:41:19
> char name[NAMELEN_MAX];
そこは NAMELEN_MAX+1 にしとけよ
一応
410:デフォルトの名無しさん
08/06/06 13:45:44
>>408
退学とかで、欠番の可能性は?
411:デフォルトの名無しさん
08/06/06 13:47:18
>>410
問題の前提が番号は0~14まで15人ってなってる
412:デフォルトの名無しさん
08/06/06 13:47:40
そこで性別をenumですよ
413:デフォルトの名無しさん
08/06/06 13:48:43
>408
>名前は動的割付するほど大きなデータじゃない。適当な大きさの配列で十分。
初期化したあと変更しないならconstポインタのほうがいいんじゃね?
414:デフォルトの名無しさん
08/06/06 13:52:11
後出しの条件はともかく、まずは>398を作れ
話はそれからだ
415:デフォルトの名無しさん
08/06/06 14:03:48
入力はgetchar?99を入力するとプログラム終了ってどうやんだっけ?
416:デフォルトの名無しさん
08/06/06 14:06:50
本当はfgetsを使うんだがこのレベルの問題ならscanfでいいだろう
417:デフォルトの名無しさん
08/06/06 14:07:31
>>415
おいおいそこから教えなきゃいけないのかよ
もう一回最初から本を読み直せ
418:デフォルトの名無しさん
08/06/06 14:10:57
どうやんだっけ?じゃねーよw
素直に全く分かりませんって言えよ
419:デフォルトの名無しさん
08/06/06 14:14:51
すまぬがちょっと質問。
MinGWとVC++でDLL連携をしようと思って下記みたいなソース書いたんだ。
GeoOpen関数に「1」を渡してるのに
返ってくる値は何故か「63」。
printfで出力される値も「63」。
なんぞこれー
DLL作成側cpp(MinGW)
extern "C" __declspec(dllexport) int __stdcall GeoOpen(string strLicence, string strGeoDBDir, string strNormalize, int intA) {
printf("%u", intA);
return intA;
}
DLL呼び出し側cpp(VC++)
// GeoOpen関数のポインタ取得
GEOOPEN geoOpen = (GEOOPEN)GetProcAddress(hGEOCODERDLL, "GeoOpen@16");
int testInt = 1;
// GeoOpen関数のポインタ取得成功
if (geoOpen != NULL)
{
// GeoOpen関数呼び出し
int intRes = (*geoOpen)(strLicence, strGeoDBDir, strGeoDBDir, testInt);
}
420:デフォルトの名無しさん
08/06/06 14:15:34
エラーメッセージって表示しなきゃなんないのか?
421:デフォルトの名無しさん
08/06/06 14:17:05
>420
「そんなの問題に書いてないじゃないですか」で押し通せるならしなくていい
常識的にはする
422:デフォルトの名無しさん
08/06/06 14:17:13
>>419
MinGWとVC++のstd::stringの内部構造が異なるんじゃないのかたぶん
423:デフォルトの名無しさん
08/06/06 14:19:51
というか完璧スレ違い
424:デフォルトの名無しさん
08/06/06 14:28:13
>>422
試しにintを第一引数にしたらちゃんと1が返ってきたよ。
stringが邪魔してたのか、、、これは気づかなんだ。
サンキュー助かった。
>>423
あぁC++はスレチか。すまん
425:デフォルトの名無しさん
08/06/06 14:28:58
異なるコンパイラ、コンパイラが同じでもバージョンが違う場合、モジュール間でのクラス渡しは御法度。
クラスで渡したければCOM使うしかない。
426:デフォルトの名無しさん
08/06/06 14:35:16
COMってなんぞえー!?
427:デフォルトの名無しさん
08/06/06 14:37:39
C++つかわず、CだけでCOM(ActiveX)のプログラムするのは死ぬほど辛い
428:デフォルトの名無しさん
08/06/06 15:48:13
素直にポインタを使え
429:デフォルトの名無しさん
08/06/06 21:35:24
strtokを使ってカンマ区切りの文字列を分け、それぞれの文字配列に格納する関数を作ってるのですが、
関数の中で正常に表示される文字配列が、関数の外だと化けるんですよ!
何が原因なのでしょうか?お手上げです。どなたかどうか、教えてくださいm(_ _)m
430:デフォルトの名無しさん
08/06/06 21:36:24
ローカル変数を外に持ち出そうとしてるのか?
431:デフォルトの名無しさん
08/06/06 21:41:00
ソースうp
432:デフォルトの名無しさん
08/06/06 21:45:23
B木の話なんですが質問させてください、二分木でも同じと思いますが
ノードに入るkeyの値は自然数としています
現在の木に例えば3という値が入っているときにさらに3を挿入する場合は
すでに入っている3の手前と後ろのどちらに入れるかは決まっているんですか?
433:デフォルトの名無しさん
08/06/06 21:49:14
比較の仕方によるけど、だいたい後ろになるんじゃね?
434:デフォルトの名無しさん
08/06/06 21:54:38
>>430
文字配列はmainで宣言していて、関数の中では、char*型で引数宣言しています。
>>431
今携帯なので、うち帰ってからまたソースうpさせていただきますね。
すみません、また来ます。ありがとうございます。
435:デフォルトの名無しさん
08/06/06 21:57:55
>>434
たぶん、その引数のポインタにstrtokの戻り値を代入してるだけだろう?
ちゃんとstrcpyしろ
436:デフォルトの名無しさん
08/06/06 22:03:51
>434
こういうことをやってないかどうか
#include <stdio.h>
void hoge(char *str)
{
str="STRING"; /* 間違い */
/* こっちが正解
strcpy(str, "STRING");
*/
}
int main(void)
{
char str[]="string";
hoge(str);
puts(str);
return 0;
}
437:デフォルトの名無しさん
08/06/06 22:04:41
>>436
まてそれは大丈夫だろw
438:デフォルトの名無しさん
08/06/06 22:06:36
>>437
落ち着け
439:デフォルトの名無しさん
08/06/06 22:08:22
>>438
ごめんおちついた、ごめんなさい
mainみないで条件反射してしまいました・・・
440:デフォルトの名無しさん
08/06/06 22:10:46
435の解釈が妥当そう。
strtokの戻り値は次のstrtokの呼び出しで破壊されるから、
strdupしておくべし。
441:デフォルトの名無しさん
08/06/06 22:11:29
>440
お前も落ちつけよ
442:デフォルトの名無しさん
08/06/06 22:14:59
>strtokの戻り値は次のstrtokの呼び出しで破壊されるから
されんされん
443:385
08/06/06 23:01:23
>>386-388
なるほど、ありがとうございます
444:デフォルトの名無しさん
08/06/06 23:08:26
>>443
for(i=0; i<25; i++) {
j = rand() % (i + 1);
a[i] = a[j];
a[j] = i + 1;
}
こうやるとムダなチェックが必要なくなるよ
445:デフォルトの名無しさん
08/06/07 00:45:33
URLリンク(ytteter.so.land.to)
446:デフォルトの名無しさん
08/06/07 02:50:52
>>444
ぱっと見では、なんでうまくいくのか分からなかったけど面白い方法だ
447:デフォルトの名無しさん
08/06/07 03:23:54
わからん
448:デフォルトの名無しさん
08/06/07 03:49:22
確かに重複は回避できるけどシャッフルの度合いとしてはどうなんだろう……
前方にかたよる気がするが
449:デフォルトの名無しさん
08/06/07 04:56:54
シャッフルの度合いw
前方にかたよるw
450:デフォルトの名無しさん
08/06/07 08:03:17
もっといい擬似乱数がほしければメルセンヌ・ツイスターでも使えばいいよ。
451:デフォルトの名無しさん
08/06/07 09:00:24
>>448
くじ引きは最初と中間と最後のどこで引くのが有利だと思う?
452:デフォルトの名無しさん
08/06/07 09:08:43
>>451
商店街のクジ引きなら最後のほうw
453:デフォルトの名無しさん
08/06/07 09:12:39
>>452
当たりが1つで残りn個全部ハズレのクジとした場合、
1)引いたクジを戻す場合は常に確率は一緒
2)引いたクジを戻さない場合はそのときによる。
2)は最初に引く人はかなり確率は低いけど当たりも引ける。
後に引く人は当たりを引く確率は上がるが、最初に当たりを引かれると残りは
ハズレのみになる・・・・・
454:デフォルトの名無しさん
08/06/07 09:26:24
>>453
マジで言ってる?
2)の場合
1回目は 1/n
2回目は (n-1)/n*1/(n-1) = 1/n
最初から最後まで確率は一定だよ。
455:デフォルトの名無しさん
08/06/07 10:33:49
たぶん>>452は
商店街とかだと当たりを前半に出すわけにはいかないから、
後半にしか入ってないことをいってるんだと思うぜwww
456:デフォルトの名無しさん
08/06/07 13:25:48
>>444のやり方はこのスレや宿題スレなんかではよく出る中身がある配列のシャッフル
for(i=0; i<N; i++) {
j = rand() % (i+1);
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
と同じ理屈だろ。
これが偏ってるとか思うヤツはセンスないな。
>>450
擬似乱数の精度の話なんかしてない
457:デフォルトの名無しさん
08/06/07 13:30:52
>>454
それは違うな。
あらかじめ引く順番が決められてるなら(2)でも(1)と同じ確率になるが、
自分でいつ籤を引くか決められるなら、(1)とは異なった確率にできる。
たとえば当たり籤が一本しかなかったとして、
当籤が出るまでは誰かが籤を引くたびに当たり確率が高くなっていくが、
当たりが出た途端に当たり確率は0になる。
458:デフォルトの名無しさん
08/06/07 13:31:42
数学的な話か実際の話かの差だから論じても意味が無いと思うけど
459:デフォルトの名無しさん
08/06/07 13:53:49
>>456
マジレスすると、センスないのはお前だ。それは偏る。
<Proof>
N=3とすると、置換の可能性は3^2=27。
一方、3つの要素の並べ方は3!=6。
27/6は整数ではない。故に、偏る。q.e.d.
実際に列[0,1,2]に対して、6万回の試行をしてみると、
[0,1,2]:9063
[0,2,1]:10843
[1,0,2]:11236
[1,2,0]:11121
[2,0,1]:8719
[2,1,0]:9018
この程度のばらつきが出る。
数学的に考えれば、9000前後の数字が出ている列は、
それぞれ並べ替え方27のうち4を占めていて、
11000前後のはそれぞれ27のうち5を占めている。
正確にシャッフルしたければ、並べ替え方が6!のKnuthシャッフルを使うべし。
460:デフォルトの名無しさん
08/06/07 13:56:32
>>459
j = rand() % N;
じゃなくて
j = rand() % (i+1);
になってるんだよ
461:デフォルトの名無しさん
08/06/07 13:57:15
>>458
数学的には、確率を考えているか条件つき確率を考えてるかの違い。
数学vs実際の違いじゃないぞ。
462:デフォルトの名無しさん
08/06/07 14:01:54
暗号化に関する質問です
char str[] = hairetu //暗号化する文字列
int j = 0; //暗号化する文字列の現在位置
strとjが上記の場合
while(*(str+j) != ’\0’)
このwhileの条件ってどういう意味ですか
なぜ文字列に位置を示す数を加算できるのですか??
463:デフォルトの名無しさん
08/06/07 14:04:08
それのどこに暗号化が関係してるの?
464:デフォルトの名無しさん
08/06/07 14:07:01
暗号化のところで出てきたので暗号化特有の構文かと思ったわけです
465:デフォルトの名無しさん
08/06/07 14:07:19
>>459
恥ずかしいヤツw