C言語なら俺に聞け(入門篇) Part 8

このエントリーをはてなブックマークに追加
758デフォルトの名無しさん:2007/03/04(日) 22:58:43
>>757
例えば n=10 として
i に 9 から 0 まで順に入れていってみ?

i=9 のとき b[10-1-9] = a[9] → b[0] = a[9]
i=8 のとき …
759デフォルトの名無しさん:2007/03/04(日) 23:04:12
716みたいなのはセンスが無いと思う
760716:2007/03/04(日) 23:10:32
>>758
i=9 のとき b[10-1-9] = a[9] → b[0] = a[9]
i=8 のとき b[10-1-8] = a[1] → b[1] = a[8]
i=7 のとき b[10-1-7] = a[2] → b[2] = a[7]
i=6 のとき b[10-1-6] = a[3] → b[3] = a[6]
i=5 のとき b[10-1-5] = a[4] → b[4] = a[5]
i=4 のとき b[10-1-4] = a[5] → b[5] = a[4]
i=3 のとき b[10-1-3] = a[6] → b[6] = a[3]
i=2 のとき b[10-1-2] = a[7] → b[7] = a[2]
i=1 のとき b[10-1-1] = a[8] → b[8] = a[1]
i=0 のとき b[10-1-0] = a[9] → b[9] = a[0]

お〜逆になっています、とても不思議ですね
解りました!!サンクスです。
761デフォルトの名無しさん:2007/03/04(日) 23:15:34
最初からそうやってやってみてから言えと
762デフォルトの名無しさん:2007/03/04(日) 23:16:47
かてきょで小学生に算数教えてるときを思い出したよ
763デフォルトの名無しさん:2007/03/04(日) 23:35:55
春だからな
764デフォルトの名無しさん:2007/03/04(日) 23:38:22
春消かw
765デフォルトの名無しさん:2007/03/05(月) 00:00:59
まぁでもプログラミングの基本は調べ物
調べ物が出来ない人は中々上達しないよな
766デフォルトの名無しさん:2007/03/05(月) 00:34:58
3桁の2進数加算機を下記のように作ったのですが、間違った所は無いでしょうか?
おかしな点があったら手直しをお願いします。


#include <stdio.h>
void main(void){

int c1,c2,c3,s1,s2,s3,h,i,x1,x2,x3,y1,y2,y3;
printf("x=");
scanf("%d%d%d",&x3,&x2,&x1);
printf("y=");
scanf("%d%d%d",&y3,&y2,&y1);

s1=x1^y1;
c1=x1&y1;

h=x2^y2;
s2=h^c1;
c2=x2&y2|h&c1;

i=x3^y3;
s3=i^c2;
c3=x3&y3|i&c2;

printf("s=%d%d%d%d\n",c3,s3,s2,s1);

}
767デフォルトの名無しさん:2007/03/05(月) 00:39:24
%d → %c
入力チェックで 01 意外はエラー

ぱっと見でそんくらいしか思いつかんが
768767:2007/03/05(月) 00:42:52
ああ、違うな
文字列で読み込んで一文字ずつ取った方が確実なのかな
769デフォルトの名無しさん:2007/03/05(月) 00:45:11
scanf("%[01]%[01]%[01]", ...)でいいんじゃね?
770デフォルトの名無しさん:2007/03/05(月) 00:45:39
fgets(buf,sizeof(buf),stdin)で取って後ろから0か1かそれ以外か判断しつつ計算
771767:2007/03/05(月) 01:05:02
花から悪魔出るかも試練けど、こういうのってどうなの?


while (1) {
  printf("x= ");
  fgets(buff, 8, stdin);
  sscanf(buff, "%1d%1d%1d", &x3, &x2, &x1);
  if (x1>=0 && x1<=1 && x2>=0 && x2<=1 && x3>=0 && x3<=1)
    break;
  printf("やり直し ");
}

s1 = x1 ^ y1;
i = x1 & y1;
s2 = x2 ^ y2 ^ i;
i = (i) ? (x2 | y2): (x2 & y2);
s3 = x3 ^ y3 ^ i;
i = (i) ? (x3 | y3): (x3 & y3);
772デフォルトの名無しさん:2007/03/05(月) 01:08:51
>>771
buffが適切に確保されていれば問題ないと思うよ

>>766
void main()はやめれ
773デフォルトの名無しさん:2007/03/05(月) 01:12:36
>>771
sscanf()の戻り値見ていないから、その次のifでのx1, x2, x3が不定値になりうる。
774デフォルトの名無しさん:2007/03/05(月) 01:26:59
#include <stdio.h>

void swap(int *, int *);
void sum(int, int);

main(){
sum(1,5);
sum(10,5);
sum(1,10);
sum(2,2);


void swap(int *a, int *b){
int temp;
temp = *a;
*a = *b;
*b = temp;
}

775774:2007/03/05(月) 01:28:33
void sum(int min, int max){

int i, n;

if(min > max)
awap(&min, &max);

printf("%d",min);
n = min;
for(i = min+1; i <= max; i++){
printf("+%d", i);
n += i;
}
printf("=%d\n", n);
printf("%dから%d%までの和はd%\n", min, max, n);
}


return 0;
}

776デフォルトの名無しさん:2007/03/05(月) 01:29:06
>>771
そんなことするより1文字ずつ取り出したほうがいい
777デフォルトの名無しさん:2007/03/05(月) 01:32:28
>>767-773
レスありがとうございます。

うーん、よくわからない・・・

>>772
何にしたら良いのですか?

778774:2007/03/05(月) 01:33:24
>>void swap(int *, int *);
このポインタは、どれを指すのでしょうか?
sum(1,5);
sum(10,5);
sum(1,10);
sum(2,2);
等のアドレスでしょうか?

>>int temp;
temp = *a;
*a = *b;
*b = temp;
で何をどう交換してて、交換する意味を教えて下さい。

>>if(min > max)
のminとmaxとは、何の事なのでしょうか?
>>awap(&min, &max);
これは、どういう意味でしょうか?

>>for(i = min+1; i <= max; i++) の min+1; とは・・・?

これら解説が一行もなく、さっぱりですので、
ご助言、戴ければ幸いです。宜しくお願い致します。

779766:2007/03/05(月) 01:33:35
名前入れ忘れた。
>>777=>>766です。
780デフォルトの名無しさん:2007/03/05(月) 01:34:40
>>777
mainの返り値型は必ずint
781デフォルトの名無しさん:2007/03/05(月) 01:48:37
>778
sum()内の変数minとmaxのアドレス。

アドレスaにある数値ととアドレスbにある数値を交換。交換それ自体に意味は無い。
なんで交換してるかはそれを呼び出した関数側の問題。
この場合は二つの数値で小さい順にするために条件付で交換している。

最小値から最大値までを合計するときに合計の値nに最初にminを入れてるから
二重にminを足さないためにmin+1からにしてる。
782766:2007/03/05(月) 02:12:20
>>780
int main(void)でおkですね?

それと、%dのままではまずいのでしょうか?
783デフォルトの名無しさん:2007/03/05(月) 02:23:58
別に%dがダメなんではなくて……


というか、まずは実行して見ればどうなるのか分かるのに
784766:2007/03/05(月) 02:33:18
すいません、今実行出来る環境が無いので・・・。
785デフォルトの名無しさん:2007/03/05(月) 02:56:58
ぱそこん、もってないのか。
786デフォルトの名無しさん:2007/03/05(月) 03:14:50
だったらなおさら、ココ見て考えるだけではどうしようもない気もするのだが……


多分、110 + 101 とかは
 x=110
 y=101
みたく入力したいのだろう、とは分かるけど
scanf("%d%d%d",&x3,&x2,&x1); のままやると、x3 に 110 とか格納される

あと、範囲チェックしてないので
 x=190 y=721
とかも計算してしまう
 x=a とか x=3.2
なんかすると、暴走することもある
バッファ溢れ……はまあいいか。


このレスの後半で何言ってるか分からんようなら、取り敢えず
scanf("%1d%1d%1d", &x3...);
ってやって、正確なデータ以外入力しなければ良い。
787774:2007/03/05(月) 04:19:43
>>781
むずかし過ぎます・・・・
788デフォルトの名無しさん:2007/03/05(月) 04:54:42
>787
どうでもいいけどちゃんと写せてる?
789デフォルトの名無しさん:2007/03/05(月) 05:02:39
>>774は、どういうレベルなんだ。こっちはそれが分からん
何を読んでそうなったんだ?
例えば「やさしい入門書」を謳っているもの等で、初心者が尻込みしないように用語の記述なんかを略した結果
必要なことすら書いてなくて、余計分かりにくくなったと言うモノもある。
それとも、単に>>781の内容が難しくて読めません、ということか?


例えば sum(10,5); と関数を呼んだ場合、
min = 10
max = 5 が入る。
もしこのままswap関数を呼ばないと、sum関数内のforループで
for (i=11; i<=5; i++) で、足し算をせずにループ終了してしまう。
そうならないように、swap関数で、min <= max となるように入れ替えている。
それ以上のポインタについて知りたいなら、ちゃんとした本読め

>for(i = min+1; i <= max; i++) の min+1;
コレに関しては、例えばすぐ上の行に
n = min; があるから。
n = 0; → for(i=min; i<=max; i++) でも一緒。
こういうことは、関数の一番上から適当なnなんかを入れて、順に手動で計算していけばどうなるのか分かる

とういか、そんな本は今すぐ窓から投げ捨てて
もうちょっと分厚い参考書買え、とか思うがなあ
790774:2007/03/05(月) 05:36:57
>>788
まだ、実行はしていません(内容を理解するのに時間を割いてしまっていて・・・・)

>>789
本は入門書を謳っている割には解説もなく(サンプル)
いきなりサンプルで高度になるんです。
しかも、説明も薄い内容だと思います。

解説ありがとうございました。
あとは自力と解説で何とかやってみます。
791デフォルトの名無しさん:2007/03/05(月) 07:18:16
プログラミングは実行してなんぼだ。
お前さんは勉強の仕方を間違えてる。
792デフォルトの名無しさん:2007/03/05(月) 07:35:47
>>790
>>791 は、まあ動けばいいや、
という姿勢に転んじゃうやつも問題あるんで注意しておくと、
動いているところを見たほうが、理解が進む、という意味だからね
793デフォルトの名無しさん:2007/03/05(月) 08:12:28
>>774はまだ入門書にケチつけられるレベルじゃないだろ…
794デフォルトの名無しさん:2007/03/05(月) 08:47:11
>>793
逆じゃね?
あふぉな入門書もあるから、>>774みたいなのの割合が増えるんだよ。

まあ、原因が分かってるのに本屋にも図書館にも行かない
っていうのはかなりどうかと思うけど菜
795766:2007/03/05(月) 09:37:54
>>786
わかしました。
ありがとうございます。
796デフォルトの名無しさん:2007/03/05(月) 09:50:41
ファイルをそのままコピーする標準関数ってない?
OSの機能か、バイナリーを自前で移すしかないの?
797デフォルトの名無しさん:2007/03/05(月) 09:52:59
週明け早々お聞きしたいのですが
配列で、効率的にメモリ確保をしたいのですが、どうやればいいでしょうか。
具体的には

   ・・・・・・・・・・・・・・・
・・・・・・・・・・・   ・・・・・・・・・・・・
   ・・・・・・・・・・・・・・・・・・・
      ・・・・・・・・・・・・

こういう座標群があったとして、それを配列に確保していきたいのです。
point[x][y]のように宣言して、左上から値がなかったら0 あったら1のように確保していくと
無い部分のメモリが無駄に取られてしまうので
座標がある部分だけ、確保したいのです。

図は二次元ですが、それを3次元でやりたくて、そこで詰まっています。
ご指南お願い致します
798デフォルトの名無しさん:2007/03/05(月) 10:09:13
座標値をもとにハッシュを作るとか、あとは、
sparse(スパース/疎な) arrayとかmatrixで探してみるといいかもしれない。
799デフォルトの名無しさん:2007/03/05(月) 10:14:52
ありがとうございます。ググってみます。わからなかったらまた伺うかもしれません…

それと同じように配列についてですが
BMPのように大きさが様々なデータを配列に読み込む場合に
その大きさちょうどのサイズを宣言したいのですが。。。どうすればいいのでしょうか
可変型の配列とかありますでしょうか
800デフォルトの名無しさん:2007/03/05(月) 11:00:37
>>799
C++ならvectorを使うと言う選択肢もあるけど、このスレ的には可変長配列はない。
厳密にはC99にならあるのだが画像処理には向かないし、
一般的にはmalloc()で適宜確保した一次元空間を二次元的に使うのが無難かな。
801 ◆Z4QrFDzwrY :2007/03/05(月) 11:01:29
必要になったときにalloc(),malloc()で動的に割り当てる
free()を忘れずに
802デフォルトの名無しさん:2007/03/05(月) 11:06:33
>>801
なかなか中途半端なコテだなぁ。
そもそもalloc()ってなんだよ。
803デフォルトの名無しさん:2007/03/05(月) 11:15:47
mallocとかでT array[W*H]確保して、
size_t at(size_t w, size_t h) { return W * h + w; }
とかは?
for (int w = 0; w < W; ++w) {
for (int h = 0; h < H; ++h) {
array[at(w, h)] = 0;
}
}
みたいに使う
804デフォルトの名無しさん:2007/03/05(月) 11:21:51
alloca()のことだな、たぶん。
いや、>>802はわかってるんだろうけど。
805デフォルトの名無しさん:2007/03/05(月) 11:23:42
>>803
普通はこうした方が引き数の名前が理解しやすいしパフォーマンスも期待できるな。
つーか、W固定じゃ可変長にできないじゃん。
int at(int x, int y, int width) {return x + y * width;}

for (int y = 0; y < height; ++y) {
for (int x = 0; x < width; ++x) {
array[at(x, y, width)] = 0;
}
}
size_tかintかは難しい問題だけどsize_tが64bitだと泣けるからunsignedで妥協とかもありかも。
806デフォルトの名無しさん:2007/03/05(月) 11:25:43
>>803
それだと結局2次元配列のCでの実装と同じことを手動でやってるという
落ちにならんか?

>>797のような、0でない要素が全体に対して少なめ(疎)と思われるデー
タに対しては、ナイーブな実装だとメモリ効率が悪くなる。
100×100×100の座標空間だけで100万要素だしな。
807デフォルトの名無しさん
ふむ、>799は>797のようなデータではなく画像データについての質問と解釈したのだが。
さてどっちかのう。