トップページ⇒tech
1001コメント309KB

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

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん2007/11/07(水) 06:24:18
C言語の入門者向け解説スレです。
・C++言語はスレ違いです。
・分からない事をなるべく詳しく書いて下さい。
・ソースコードを晒すと答えやすくなるかもしれません。
・質問者は最初にその質問をした時のレス番号を名前欄に書いて下さい。

前スレ
C言語なら俺に聞け(入門篇) Part 20
http://pc11.2ch.net/test/read.cgi/tech/1192455273/

教えて欲しいのではなく丸投げしたいならこちらへ
C/C++の宿題を片付けます 99代目
http://pc11.2ch.net/test/read.cgi/tech/1194262698/
0232デフォルトの名無しさん2007/11/12(月) 18:18:50
int main(argc, argv)
int argc;
char **argv;
{
return 0;
}
0233デフォルトの名無しさん2007/11/12(月) 18:20:30
#define begin {
#define end ;}
0234デフォルトの名無しさん2007/11/12(月) 18:25:55
size_t
ptrdiff_t
intptr_t
uintptr_t
0235デフォルトの名無しさん2007/11/12(月) 18:49:39
うわぁ予想外にいっぱいあるんですね。
>>231
[0]じゃなくてあえて[1]で。ってどういうことなんですか
すごく興味があります。
0236デフォルトの名無しさん2007/11/12(月) 19:16:10
struct e{
int value1,value2,value3;
};

void foo(e num[][size]){
e output1[size],output2[size];
double sum1, sum2, sum3;
double difference1,difference2,difference3;
for( i=0;i<size;i++){
for( j=0; j<size; j++){
sum1 = num[i][j].value1 + num[i][j+1].value1;
sum2 = num[i][j].value2 + num[i][j+1].value2;
sum3 = num[i][j].value3 + num[i][j+1].value3;

difference1 = num[i][j*2].value1 - num[i][j*2+1].value1;
difference2 = num[i][j*2].value2 - num[i][j*2+1].value2;
difference3 = num[i][j*2].value3 - num[i][j*2+1].value3;

output1[j].value1 = sum;output1[j].value2 = sum2;output1[j].value3 = sum3;
output2[j].value1 = difference1;output2[j].value2 = difference2;output2[j].value3 = difference3
} // end for j
} // end for i
}

このクソ汚いソースを直すのに、どなたか知恵をお貸しください。
2次元の構造体に3つの変数があって
それの隣接する和と差を求めるものの1部なのですが。

変数が多くなってあまりに汚いのでどうにかできないものかと
0237デフォルトの名無しさん2007/11/12(月) 19:25:30
>>236
それってsizeは関数に渡るのか?
0238デフォルトの名無しさん2007/11/12(月) 19:26:24
きっと #define size 10 に違いない
0239デフォルトの名無しさん2007/11/12(月) 19:30:53
>>235
昔は [0] が認められてなかった。
そのころからの古参ベテランだぞというアピール。
0240デフォルトの名無しさん2007/11/12(月) 19:32:21
sizeは#define sizeですが
関数に渡してもどっちでもいい状態であります。

どうしても構造体に3つのintが入ることになってしまって…
testで作っていたソースはvalue1個だけとかでやってていけて
いざ3つにしたら ぅわぁぁあぁ…という状況に…
0241デフォルトの名無しさん2007/11/12(月) 19:35:23
>>236
e add(e a, e b);
e sub(e a, e b);
のような関数を作ればおk
0242デフォルトの名無しさん2007/11/12(月) 19:38:09
>>236
i のループで、output1,output2が壊れてない?
output1, output2には、i = size - 1 のときの値しかassignされないように見える。
0243デフォルトの名無しさん2007/11/12(月) 19:39:35
>>236
配列の範囲外にアクセスしてるみたいだが、それはいいのかな?
0244デフォルトの名無しさん2007/11/12(月) 19:40:01
int add(int a, int b){
return a+b; }
0245デフォルトの名無しさん2007/11/12(月) 19:45:37
Cだし、マクロをうまく使えばどう?
#define SUM(x, m) x[j].m + x[j+1].m
みたいに。
0246デフォルトの名無しさん2007/11/12(月) 19:46:11
>>242-243
元のソースを少し変えてi jの2重ループだけにしてるので、ちょっとおかしいところ出てますが
そこは気にしないでください。

>>241
それは構造体を返す型の、関数ということですか。
やったことが無いのでイメージしづらいのですが…ためしに組んでみます。

マクロでやれるかとも思ったのですが、ヘッダがものすごいことになりそうで。。
0247デフォルトの名無しさん2007/11/12(月) 20:03:34
DEFINEって定数じゃなく式をも使えたのか!超勉強になるこのスレ!
0248デフォルトの名無しさん2007/11/12(月) 20:35:49
>>247
そんなあなたにこのマクロをどうぞ

#include<stdio.h>
int main(void){
printf("File:%s Line:%d\n", __FILE__, __LINE__);
return 0;
}
0249デフォルトの名無しさん2007/11/12(月) 20:42:32
246ですがとりあえず、マクロにして出来ました(その方が行が少なくできたので)

ただ行列(構造体)の横走査と
縦走査で同じようなことを2回書いて、あまり良くないソースになりました。

#define ADD(x, m) x[i][j*2].m + x[i][j*2+1].m  横走査
#define ADD_I(x, m) x[j*2][i].m + x[j*2+1][i].m 縦走査

for(i)
for(j)
ADD(); //横走査

for(i)
for(j)
ADD_I(); //縦走査

こんな感じに。。。
まだまだ修行不足です。アドバイスありがとうございました。
0250デフォルトの名無しさん2007/11/12(月) 22:21:46
行数を少なく書くというのも大事だけど、ソースの可読性ってのも大事だよ。
>241の言うような構造体eを足し引きする関数を作れば、
for(i){for(j){
out1[j] = e_sum ( num[i][j] , num[i][j+1] );
out2[j] = e_sub ( num[i][j*2] , num[i][j*2+1]);
}}
って感じになるんだけど、
これだとソースを見て何をやっているかが一目でわかる。
後々メンテする可能性のあるプログラムならこっちの方がいいかと。
0251デフォルトの名無しさん2007/11/13(火) 01:25:12
#include<stdio.h>
#define ROW 3
#define COLUMN 4
int main(void){

double a[ROW][COLUMN],b[COLUMN][ROW];
int i,j,k,l;
for(i=0;i<ROW;i++){
for(j=0;j<COLUMN;j++){
scanf("%lf",&a[i][j]);}}
l=k=0;
for(i=0;i<ROW;i++){
for(j=0;j<COLUMN;j++){
a[i][j]=b[k][l];
k++;}
l++;k=0;}
for(k=0;k<COLUMN;k++){
for(l=0;l<ROW;l++){
printf("b[%d][%d]=%lf\t",k+1,l+1,b[k][l]);}
printf("\n");}
return 0;}
a[3][4]の転置行列b[4][3]を表示したいんですがうまく表示されません。
どうすればよいですか?
0252デフォルトの名無しさん2007/11/13(火) 01:28:29
スカラってなんですか?
0253デフォルトの名無しさん2007/11/13(火) 02:01:40
>>251
代入文が逆ではないか?
× a[i][j]=b[k][l];
○ b[k][l]=a[i][j];
0254デフォルトの名無しさん2007/11/13(火) 02:46:03
>>252
ベクトルじゃないやつ。
0255デフォルトの名無しさん2007/11/13(火) 03:09:09
>>252
スカラーのことだろ?よく文字を見ればわかる。
ラーがついているということは、もともとスカルという意味で、
つまりはスカル人=スカラーだ。わかったか!?

あとは、マカセタ。
0256デフォルトの名無しさん2007/11/13(火) 03:37:42
ネットワークプログラミングを勉強しようとおもい、getaddrinfo等を使ってみようとしたのですが

program1.c:8:24: sys/socket.h: No such file or directory
program1.c:9:19: netdb.h: No such file or directory
program1.c:11:24: netinet/in.h: No such file or directory
以下、↑が読み込まれてないことが原因と思われるエラー複数


と、必要なヘッダファイルが見つからないようでコンパイルが出来ません・・
環境ですが
cygwinとwsbuilderというのをインストールして両方でgccしてみたのですが
同じようなエラーが出てダメでした。
どうすれば解決できるでしょうか・・
0257デフォルトの名無しさん2007/11/13(火) 08:15:45
>>253
いろいろやってるうちにそうなってました。
ありがとうございます
0258デフォルトの名無しさん2007/11/13(火) 09:33:13
>>256
cygwinはsys/socket.hじゃなくてcygwin/socket.hとかにあるんじゃなかったかな。
こういう質問はC言語のスレじゃなくてcygwinスレとかの方が答えてくれると思う。
0259デフォルトの名無しさん2007/11/13(火) 14:34:44
*a はポインタって当然分かるが、
今読んでるソースに**aみたいなのが、無数に出てきて、これが分からない
0260デフォルトの名無しさん2007/11/13(火) 14:36:08
>>259
ポインタの位置を指すポインタ。
0261デフォルトの名無しさん2007/11/13(火) 14:48:04
>>260
俺はアホだからよく分からない…

ぬこにも分かるようにお願いします><
0262デフォルトの名無しさん2007/11/13(火) 14:51:47
>>261

int* -> int (int*はint(の場所)を指す)

int** -> int* (int** は int*(の場所)を指す)
0263デフォルトの名無しさん2007/11/13(火) 17:24:52
int *p; → *p が int型
int **p; → **p が int型
0264デフォルトの名無しさん2007/11/13(火) 17:29:09
int* p; って書く奴アホだよな。
わざわざ判りにくくしてやがんのな。
0265デフォルトの名無しさん2007/11/13(火) 17:31:37
int* *p
0266sage2007/11/13(火) 17:42:23
void A(void){
unsigned short usWork[2];

usWork[0] = 0x0012
usWork[1] = 0x0000

B(usWork);
}

void B(unsigned short *Buff){
*(Buff+0) &= 0xffff
*(Buff+1) += 0x12345678
}


※上記の様な関数AとBが存在し、AからBをコールする際、
 Bで誤ってshort型に4バイトで計算してしまいました。
 その場合は、関数Aで指定した変数にはどのような値が入るのでしょうか?
 また、関数Aで指定した変数を超えてメモリを使用する恐れはありませんでしょうか?
0267デフォルトの名無しさん2007/11/13(火) 17:45:44
>>258
ありがとうございました、そちらのほうにいってみます
0268デフォルトの名無しさん2007/11/13(火) 18:31:36
>>266
引数がunsigned short *Buffだとわかっているので、
*(Buff+1) += 0x12345678;
もunsigned shortで行われる。
(正しくはintに拡張されて計算されてshortに丸められる)

その結果がshortに収まらなくてオーバーフローしても、
他の領域には影響は及ぼさないよ。
0269デフォルトの名無しさん2007/11/13(火) 18:43:07
ちなみに、usWork[1]の値は、0x5678になる。
0270デフォルトの名無しさん2007/11/13(火) 19:17:00
なんか
ポインタじゃなくて配列の代わりみたいなもん、って教え方した方が
俺の場合はすっきりした><

でもポインタなんだよね。
ポインタなんて死ねばいいのに
0271デフォルトの名無しさん2007/11/13(火) 19:38:38
むしろポインタ以外は死んで欲しい。
全部ポインタでメモリ確保しなきゃ使えないようにすれば混乱しなくていいのに。
0272デフォルトの名無しさん2007/11/13(火) 19:43:13
関数の引数はx[]と書いても*xと書いても意味は同じだからね。
文字列(char*)の配列なんかだと、char *argv[]やchar **argvになってしまう。

[]付きのほうが理解しやすいよね。
0273デフォルトの名無しさん2007/11/13(火) 20:30:05
すいません。

迷路でゴールを目指すプログラムを作りたいのですが、
左手法までたどり着き、その後がまったく分かりません。

どなたか、左手法の参考プログラムを教えていただけませんか?

ちなみに、Cを始めて3ヶ月です。
0274デフォルトの名無しさん2007/11/13(火) 21:31:05
>>273
進行方向というパラメータを持って、
左に壁があれば1歩直進(前が壁なら右回転)、
左に壁が無ければ左を向いて1歩直進。
これの繰り返しじゃないのかな。

int maze[100][100]={...}; /* 迷路。壁が1、通路が0 */
int x=1,y=1; /* 現在地 */
int direction=0; /* 向き */

while(x!=98 && y!=98)
{
if(existleft()){if(existfront()){turnright()}else{go()}}
else{turnleft();go();}
}
0275デフォルトの名無しさん2007/11/13(火) 21:37:30
すみません変な質問なのですが

tanak 170 60
satou 180 70
suzuki 162 55
…
onaka 192 80 (100行)

みたいなデータがあるのですが。
1行目読み込んで、任意の行(60行目とか)に飛ぶには
fseekでどうやるのでしょうか?

for文で回して、5行おきとか飛んだり、10行おきとかscanfで指定した分だけ飛んだり出来るような
ソースを最終的には考えているのですが、まずは指定した行だけ飛ぼうと思いまして
0276デフォルトの名無しさん2007/11/13(火) 21:41:15
>>275
>fseekで
そのデータじゃ無理
0277デフォルトの名無しさん2007/11/13(火) 21:41:59
嘘を教えるなよ
0278デフォルトの名無しさん2007/11/13(火) 21:45:31
文字列がどう入ってるかによるんじゃね?
0279デフォルトの名無しさん2007/11/13(火) 21:45:41
>>275
fseekはバイト単位で進んだり戻ったりする。データがテキストなら改行で数えたほうがラク。
0280デフォルトの名無しさん2007/11/13(火) 21:48:01
>>279
改行で数える、というのは具体的にはどうやればいいんでしょうか
0281デフォルトの名無しさん2007/11/13(火) 21:50:00
前に戻らないんなら、fgetsで読み捨てればいいんじゃないか。
0282デフォルトの名無しさん2007/11/13(火) 22:00:06
fgetsだと、文字列や数値を変数にもっていくのがよくわからなく
fseekで移動しfscanfで読み込むという作業をしようとしていました。

0283デフォルトの名無しさん2007/11/13(火) 22:01:07
>>282
sscanfでいいじゃね?
0284デフォルトの名無しさん2007/11/13(火) 22:07:36
C言語で簡単なプログラムを作りたいんですが・・・

 ビット位置------入力ポート--------
 0 ・・・ SW1 ON:0 OFF:1
 1 ・・・ SW2 ON:0 OFF:1
 2 ・・・ SW3 ON:0 OFF:1 
 3 ・・・ SW4 ON:0 OFF:1 ・・・ モータ回転 右:1 左:0
 4 ・・・ 未使用 ・・・ 0 1
 5 ・・・ 光SW 明:0 暗:1
0285デフォルトの名無しさん2007/11/13(火) 22:08:09
毎行fscanfしなくても、n行読み飛ばすなら、
for(i=0;i<n;i++)fgets(buff,buff_size,fp);
でいいんじゃないかってこと。
0286デフォルトの名無しさん2007/11/13(火) 22:09:36


main()
{
int cnt, data;
outport (3,0) /* モータを止める
outport (4,0)
printf ("SW××を押してください\n");
while (1) { /* 無条件に繰り返す
data = inport (1) /* inport関数からdataを受け取る
if (data==××) /* SW××が押された状態か
break; /* 繰り返しから抜け出る
}
outport (××, ××); /* モータを動作させる
for (cnt=1 ; cnt<100 ; cnt++); /* 暫く待つ
outport (3,0); /* モータを止める
outport (4,0);
}
 注:××はSWの番号やモータの右左のポートが入る

0287デフォルトの名無しさん2007/11/13(火) 22:11:06

上の条件やプログラムを参考にして
「SW1がONの時モータが右回転、
SW2がONの時モータが左回転、
SW3,4がONの時モータを止める、
光SWを暗くするとプログラム終了。」
というプログラムを教えて欲しいです。
他に何か必要な条件などがあったら教えてください。
0288デフォルトの名無しさん2007/11/13(火) 22:11:59
連投失礼しました
0289デフォルトの名無しさん2007/11/13(火) 22:15:41
SW1とSW2がONになったらどうするんだ?
SW1とSW3がONになったらどうするんだ?
0290デフォルトの名無しさん2007/11/13(火) 22:17:01
for文で待つとかwww
0291デフォルトの名無しさん2007/11/13(火) 22:19:11
0 = ON、1 = OFFが気になって夜も眠れない。
0292デフォルトの名無しさん2007/11/13(火) 22:33:05
>>291
モーターならドライバにFETとかが入るので、負論理は普通にありえる。

>>287
電気・電子板がいいとおもうぞ。
http://science6.2ch.net/denki/
0293デフォルトの名無しさん2007/11/13(火) 22:36:14
あ、スイッチもか。
スイッチならプルアップして、押下時に接地で負論理ってのは多いな。
0294デフォルトの名無しさん2007/11/13(火) 22:47:50
SWが2つ以上ONにして動作するのはSW3,4のみにしてそれ以外は動作しないものとします
0295デフォルトの名無しさん2007/11/13(火) 23:00:42
http://mbga.jp/AFmbb.S6kw4dbb1f/
モバゲーやっちゃお
ケータイでね
0296デフォルトの名無しさん2007/11/13(火) 23:05:15
>>294
>>284を見る限りビットで制御するようだが、outport()とinport()の引数は整数なのか?
0297デフォルトの名無しさん2007/11/13(火) 23:15:43
整数です
0298デフォルトの名無しさん2007/11/13(火) 23:18:03
readとfreadやっぱりreadの方が早いんですか?
おしえてえろい人
0299デフォルトの名無しさん2007/11/13(火) 23:26:45
>>297
outport()の第2引数はなんなの?
SW3とSW4が押されたとき、inport()でどうやって受け取るの?inport()を2回呼ぶの?
つーかそもそもinport()は実行すると入力があるまで待つの?
ハードの仕様も分からんし、不明な点が多すぎるよ。
0300デフォルトの名無しさん2007/11/13(火) 23:27:47
>>298
readって何?
0301デフォルトの名無しさん2007/11/13(火) 23:38:46
>>298
気にするな。お前が使えば、どっちでもそう変わりはしない。
0302デフォルトの名無しさん2007/11/14(水) 00:05:03
readvのほうがもっとはやい。
mmapならさらにはやいかもしれない。
0303デフォルトの名無しさん2007/11/14(水) 01:17:22
シスコと標準ファンクシャンヌの区別くらいできろよ。
0304デフォルトの名無しさん2007/11/14(水) 19:57:03
ユーザーに5桁の整数を入力してもらい、除算演算子と剰余演算子を使用して
それが回文かどうか判定するにはどうすればいいですか。
0305デフォルトの名無しさん2007/11/14(水) 19:58:45
配列に文字列で取得させて、
んで5ケタなら[0]と[4] [2]と[3]を比べてどっちも一致なら回文。
0306デフォルトの名無しさん2007/11/14(水) 19:59:32
C言語の自主勉強の仕方教えてください!
今は一応入門の本を買って手取り足とりでプログラムを組んでる最中です
0307デフォルトの名無しさん2007/11/14(水) 19:59:59
それを続ければいいじゃないの。
0308デフォルトの名無しさん2007/11/14(水) 20:01:54
>>306
基礎を学んだら適当に自分でソースかいて実際コンパイルの繰り返し。
ボーリングのスコア計算とか組めるようになってようやく超初心者卒業じゃないかな。
0309デフォルトの名無しさん2007/11/14(水) 20:06:51
>>306
独習Cだな。
あれを眠くならずに飽きもせずに最後まで練習問題こなせたら構文は卒業だよ。

とネタはさておき、何のためにCを勉強するかじゃないのか?
学校とか情報処理試験のためならそのレベルで十分だし、
何か作りたいソフトがあるなら、調べながらでも実際に作ってみればいい。
Cに限らずアルゴリズムやAPI、通信手順など学ぶものはいくつも出てくるから。
0310デフォルトの名無しさん2007/11/14(水) 20:08:31
そうですか〜
今一応簡単なのをしてるんですが楽しいです、本のまねをしてるだけですが
最初は仕組みを重点的に勉強した方がいいですか!?
0311デフォルトの名無しさん2007/11/14(水) 20:13:56
例えば
int main(void)
から始まるけど、このvoidってなんだい?とか説明できるようになるともっと面白くなるよ。
構造も大事だけど意味も知ったほうがなおよし
0312デフォルトの名無しさん2007/11/14(水) 21:06:21
>>310
ポインタと構造体の使いかたは理解しといたほうがいいと思うな
ソースが汚い人は大抵、構造体の使いかたが下手だよ

Cの本はあとあと読まないものが多いから、市立図書館を活用するのが一番のコツだと思う
0313デフォルトの名無しさん2007/11/14(水) 21:15:12
市立限定かよw
0314デフォルトの名無しさん2007/11/14(水) 21:17:39
区立図書館はダメですか?
0315デフォルトの名無しさん2007/11/14(水) 21:17:54
村のオラはどうしたら><
03163122007/11/14(水) 21:18:45
ごめん、なんでもいいよorz
0317デフォルトの名無しさん2007/11/14(水) 21:23:43
文系が得意な僕はプログラム系の仕事は向いていませんか?
ちなみにパソコンを触ることは大好きです
0318デフォルトの名無しさん2007/11/14(水) 21:28:59
プログラミングに理系の素養は多少はあった方がいいが、
クライアントとの意思疎通やドキュメントの作成など、
文系の方が有利といえる内容も多いので、
理系だ文系だというのは関係ない。

胸を張って「俺は体育会系だ」と言ってやれ。
0319デフォルトの名無しさん2007/11/14(水) 21:36:49
文系理系でどうこう言うやつって、血液型で性格をどうこう言うやつと同レベルだろ。
0320デフォルトの名無しさん2007/11/14(水) 21:56:04
整数の各桁の値を、配列もポインタも使わずに、
また文字(列)としても扱わずに、四則演算だけで求める方法を
教えてください。

たとえば、123234と入力されたら、
num1 == 1;
num2 == 2;
num3 == 3;
num4 == 2;
num5 == 3;
num6 == 4
という風に取得したいのです。
0321デフォルトの名無しさん2007/11/14(水) 22:23:02
>>320
% も使ったらいかんの?

num1 = n - (n / 10 * 10);
n /= 10;
num2 = n - (n / 10 * 10);
n /= 10;
num3 = n - (n / 10 * 10);
n /= 10;


0322デフォルトの名無しさん2007/11/14(水) 22:24:20
あ、%は使ってもいいです。
むしろ%と/を使って取得する方法が知りたいのです。
0323デフォルトの名無しさん2007/11/14(水) 22:28:48
num1 = n / 1 % 10
num2 = n / 10 % 10
num3 = n / 100 % 10
num4 = n / 1000 % 10
num5 = n / 10000 % 10

>>320 とは逆順だけど
0324デフォルトの名無しさん2007/11/14(水) 22:33:53
>>323
ありがとうございます
0325デフォルトの名無しさん2007/11/14(水) 23:04:57
ソースを読んでC言語を勉強したいのですが、お勧めのソースはありますでしょうか。
0326デフォルトの名無しさん2007/11/14(水) 23:10:47
ない
0327デフォルトの名無しさん2007/11/14(水) 23:40:27
>>319
世の中大概のことは非線形で
理系はそのことを理解していてなおかつ計算を楽にするために線形で近似する。
もちろん近似だからそれに限界があるのも知っている。
だが文系は最初から線形だ。
所詮は近似でしかない計算をバカはどこまでも頼みにしてバカでない者は経験で適当に我流の修正を加えていく。
計算が不完全なのを知っていて理論を新しく作ることも出来ないから理論を講じること自体を頭から否定して自分の経験に依存する。
物事のとらえかたに根本的な差があるのさ。
0328デフォルトの名無しさん2007/11/14(水) 23:58:06
>>325
ttp://www.ioccc.org/
0329デフォルトの名無しさん2007/11/15(木) 00:00:53
anderson.c がお薦め。
0330デフォルトの名無しさん2007/11/15(木) 11:43:39
聞きます!

変数Aに変数Bの特定ビットを読み込みたいのですが、
専用の命令はありますか?

変数Bの 01010101の 一番右の「1」だけ、とか 
右から4番目の「0」だけとか読みたいのです。

「>>」 と 「<<」でずらすのが一番処理が早いでしょうか?
0331デフォルトの名無しさん2007/11/15(木) 11:45:56
まあ普通はシフトするかな。
ビットフィールド使うこともあるけど。
■ このスレッドは過去ログ倉庫に格納されています