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

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

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

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

過去スレ
Part 1 http://pc8.2ch.net/test/read.cgi/tech/1146700389/
Part 2 http://pc8.2ch.net/test/read.cgi/tech/1153818463/


関連スレ
くだすれC言語(初心者用)
http://pc8.2ch.net/test/read.cgi/tech/1153542424/

【ISO/ANSI/JIS】 C言語なら俺に聞け! Part 130
http://pc8.2ch.net/test/read.cgi/tech/1159613789/
0183デフォルトの名無しさん2006/11/13(月) 00:27:15
>>181
メンバー名をchar配列とかで決めるってことか?
0184デフォルトの名無しさん2006/11/13(月) 00:32:52
>>182
試したりしてるんですが、いかんせん勉強したてで...

>>183
まさにそれがやりたいんです
char配列で宣言したり、アクセスしたりしたいんですが...
0185デフォルトの名無しさん2006/11/13(月) 00:45:51
メンバー名は区別のための名前であって文字列じゃないから無理じゃね?
0186デフォルトの名無しさん2006/11/13(月) 00:51:53
>>185
やっぱ無理ですか...
無理だと分かるだけでもありがたいです。
どうもありがとう
0187デフォルトの名無しさん2006/11/13(月) 01:12:23
変数名を変数で指定できるか、みたいな感じだな。
0188デフォルトの名無しさん2006/11/13(月) 09:10:31
str_bの中身をstr_aにコピーするプログラムですが
上の関数の中身をs1=s2;にしたらコピーできない理由がわからないです
1文字ずつ比較しないとだめなのでしょうか

#include <stdio.h>
#include <string.h>

#define MAX 10


void str_copy(char *s1,char*s2)
{
while(*s2!='\0')
*s1++ = *s2++;

*s1 ='\0';
}

int main(void)
{
char str_a[MAX]="abcde";
char str_b[MAX]="fghi";

printf("str_a:%s, str_b=%s\n",str_a,str_b);

str_copy(str_a,str_b);

printf("str_a:%s,str_b=%s\n",str_a,str_b);

return 0;
}
0189デフォルトの名無しさん2006/11/13(月) 09:40:59
それだと、関数内でアドレスをコピーしたにすぎないし、
呼び出し元のstr_a, str_bには全く影響受けない
0190デフォルトの名無しさん2006/11/13(月) 10:08:05
ヘタレはC++でもやってろよ(プ
0191デフォルトの名無しさん2006/11/13(月) 11:37:54
ヘタレはC#でもやってりょ(ぷ
0192デフォルトの名無しさん2006/11/13(月) 12:04:00
struct aという構造体は自分と同じstruct a型の変数をメンバとすることができない理由がわかりません。教えてください
0193デフォルトの名無しさん2006/11/13(月) 12:07:12
>>192
構造体のサイズが無限大になるから
0194デフォルトの名無しさん2006/11/13(月) 12:20:43
#ifdef MODE

"モード1選択"
#else

"モード2選択"
#endif

#ifdefでどちらが選択されたかをコンパイル時にコンソールに表示したいのですが、
なにか方法はないでしょうか?
0195デフォルトの名無しさん2006/11/13(月) 12:30:46
コンパイラのヘルプ見ろ。
# 多分 #pragma で出ることが多い
0196デフォルトの名無しさん2006/11/13(月) 13:14:03
#pragma message("モード2")
#message モード2

でできました。有り難うございました。
C51を使用してますが、手持ちのヘルプには記載ありませんでした。
0197デフォルトの名無しさん2006/11/13(月) 16:16:07
>>195
「コンパイル時」
0198デフォルトの名無しさん2006/11/13(月) 16:17:20
C言語の質問なんですが、
double型の変数で整数の部分だけを出力するにはどうしたらいいですか?
0199デフォルトの名無しさん2006/11/13(月) 16:25:15
>>198
double val = 1234.5678;

printf("%.0f");
->1235
printf("%d", (int)val);
->1234
0200デフォルトの名無しさん2006/11/13(月) 17:03:08
>>199
ありがとうございます
切捨てと切り上げの両方できるんですね。

そしてsage忘れてすみません・・・。
0201デフォルトの名無しさん2006/11/13(月) 18:10:02
%0.fは切り上げではなく、丸めている。
切り上げはceil。
切り捨てのfloorもある。
0202デフォルトの名無しさん2006/11/13(月) 19:05:17
>>192
struct a(a1) に struct a(a2) を持たせるとその struct a(a2) もstruct a(a3) を持つのでその struct a(a3) はさらに struct a(a4) を持つので(ry
となってしまう

struct a へのポインタなら持たせられるにょ
0203デフォルトの名無しさん2006/11/13(月) 19:11:12
>>201
(VC++の場合)まるめの方向が0へ向かう四捨五入(?)っぽいね?
printf("%.0lf %.0lf %.0lf %.0lf", -123.5, -123.4, 123.4, 123.5);
→ -124 -123 123 124

このときの振る舞いは環境依存?
0204デフォルトの名無しさん2006/11/13(月) 19:13:50
>>203
C言語としては負数のとき丸め方向は定義されてないから
コンパイラの実装依存と思う

と調べずにカキコ
0205デフォルトの名無しさん2006/11/13(月) 19:21:42
CとC+とC++とC#の違いがわかりません。
素人なんですが、わりやすくどなたかおしえていただけないでしょうか?
0206デフォルトの名無しさん2006/11/13(月) 19:22:24
>>203
単に絶対値で丸めってだけじゃね

と便乗して調べずレス
0207デフォルトの名無しさん2006/11/13(月) 19:43:07
>>205
文法が似ているのと、ライブラリ関数が似ているだけで
まったく別の言語です
0208デフォルトの名無しさん2006/11/13(月) 20:08:42
>>207
ありがとうございます。
0209デフォルトの名無しさん2006/11/13(月) 20:18:27
>>208
Cを拡張、ベースにしたもの
まぁCをまねてC+やC++など作ったみたいな
結果的には別物...
0210デフォルトの名無しさん2006/11/13(月) 20:19:40
CとObjectCだけ覚えればOK
0211デフォルトの名無しさん2006/11/13(月) 20:30:36
>>209
>>210
とりあえずCを勉強すればC+やC++などの方にも応用がきくといった感じですか?
ありがとうございました。
0212デフォルトの名無しさん2006/11/13(月) 20:33:13
C+とかC++なんて覚えるだけ無駄。
限られた特定の環境でしか使わない。
覚えるなら Objective-C にしろ。
0213デフォルトの名無しさん2006/11/13(月) 20:40:04
偶にいるんだよな、敵作りの天才って
0214デフォルトの名無しさん2006/11/13(月) 20:41:16
これから流行るならって観点ならC#だろう。

それでもC++すきだけどな
0215デフォルトの名無しさん2006/11/13(月) 20:48:58
C++はCと微妙に互換性がないからなあ。
Objective-CはCとの互換性があるけど、現実的じゃない。
0216デフォルトの名無しさん2006/11/13(月) 20:53:03
皆さん色々なアドバイスありがとうございました。
とりあえずCを勉強してみようと思います。
0217デフォルトの名無しさん2006/11/13(月) 21:10:11
>>214
C#は流行るか?
何かすぐ消えそうな気がする
0218デフォルトの名無しさん2006/11/13(月) 21:17:20
JAVAと同じ運命をたどる
0219デフォルトの名無しさん2006/11/13(月) 21:30:27
>>217
同意。俺の周りにはC#やってる奴はいない
0220デフォルトの名無しさん2006/11/13(月) 21:53:19
毎日書きまくってますよ>C#
0221デフォルトの名無しさん2006/11/14(火) 01:49:25
C言語で10進数を2進数で表すにはどーすればいいですか??
0222デフォルトの名無しさん2006/11/14(火) 01:59:04
>>221
文字列を使う。
0223デフォルトの名無しさん2006/11/14(火) 01:59:55
んでstrtol()などで変換
0224デフォルトの名無しさん2006/11/14(火) 02:01:47
Cができないから毎日カキまくってますよ
0225デフォルトの名無しさん2006/11/14(火) 02:27:54
オブジェクティグCってWindowsで使える処理系あるの?
Mac専用でしょ?
0226デフォルトの名無しさん2006/11/14(火) 02:50:36
関数をマクロに上手く置き換えると、
戻り値や引数を展開しないので
動作が速くなると言うが、
戻り値void、引数なしの場合は早くなるんでしょうか?
(・・というかvoidも型か・・)

関数を実行するだけで、何か値が動くと思うので、
そのせいでマクロよりは多少遅いものなのでしょうか?
0227デフォルトの名無しさん2006/11/14(火) 02:53:57
指定されたファイルに書かれている整数を、逆順に表示するプログラムをつくるにはどのようにすればよいのでしょうか?
例えば、123 456 78
と入力されると、
78 456 123
と表示されるようなのです。
0228デフォルトの名無しさん2006/11/14(火) 03:02:11
>>227
ぱっと思いつくのは2通り。

1.全部配列に読み込んで逆順に出す
2.ファイルポインタをftell()で取得して配列に入れ、fseek()で逆順に出す
0229デフォルトの名無しさん2006/11/14(火) 03:50:16
何故、char str[] = "CAT" ; だけでポインタが付くと
char str*[] = {"CAT","DOG"}; になっていいのでしょうか?
0230デフォルトの名無しさん2006/11/14(火) 04:10:03
>>229
前者はchar型の配列
後者はchar型へのポインタ配列

意味が全然違う
0231デフォルトの名無しさん2006/11/14(火) 04:10:38
int total[6] = {1,2,3,4,5,6}; で添え字0から始まるので
予め -1 にしておくとは、どういう意味でしょうか?
0232デフォルトの名無しさん2006/11/14(火) 04:13:19
>>231
日本語で書いて
それだけじゃ意味わからんぞ
0233デフォルトの名無しさん2006/11/14(火) 04:37:06
>>230
サンクスです。
どうして、*が付くとそう書けるのかがわかりません
0234デフォルトの名無しさん2006/11/14(火) 04:37:49
変数を宣言したとき、
メモリはどうなるのか教えてください。

あと、絶対にほかのプログラムのメモリにはアクセスできない
のでしょうか?

というか、Cの質問じゃないですかね?
0235デフォルトの名無しさん2006/11/14(火) 04:46:40
*←肛門
0236デフォルトの名無しさん2006/11/14(火) 06:05:16
>>234
メモリが予約されるが、その中に何が入っているかは未定。
前そのメモリ空間を使っていた変数の値がその領域にのこったまま
だったらそれがそのままその領域に残ってる(初期化してくれない)
したがって宣言時に予約した領域に無意味な値を入れて安全にする
(初期化)ことが重要な場合が・・ある
0237デフォルトの名無しさん2006/11/14(火) 07:40:34
>>233
int foo = 5;と書いて
int fooz[] = {1, 2, 3, 4,};と書くが如く、
char * bar = "aho";と書いて
char * barz[] = {"tako", "ika", "kurage",};と書く。
0238デフォルトの名無しさん2006/11/14(火) 07:41:51
>>226
今時のコンパイラはインライン展開もするから、下手な小細工考えずに関数で書け。
そしてその関数だけでなくプログラム全体でプロファイリングしろ。
話はそれからだ。
0239デフォルトの名無しさん2006/11/14(火) 08:30:14
>>238
226です。ありがとうございます!
インライン展開、プロファイリングという言葉を初めて知り、
調べることが出来ましたyo
0240デフォルトの名無しさん2006/11/14(火) 08:35:34
�@printf()等の書式指定で
数値を指定桁数まで右スペース埋めしたいのですがどのように書けば良いのでしょうか?

左埋め… printf("%4d",10)→" 10"を出力
右埋め… printf("?",10)→"10 "を出力

�Aまた、上記の桁数(4)も動的に指定するにはどのように書式を指定すれば良いのでしょうか?

よろしくおねがいします。(性的な意味で)
0241デフォルトの名無しさん2006/11/14(火) 08:57:38
>>240
printf("%-*d", 4, 10);
0242デフォルトの名無しさん2006/11/14(火) 09:12:00
朝早くからありがとうございます!(性的な意味で)
0243デフォルトの名無しさん2006/11/14(火) 10:13:51
早くないよ・・・速いけど・・・(性的な意味で)
0244デフォルトの名無しさん2006/11/14(火) 15:37:33
整数nが与えられたとき、
n×nのサイズで螺旋状に0から(n二乗ー1)までの数が並ぶ行列を作成し、
画面に表示させるプログラムって配列を使って組むにはどうすればいいでしょうか?
ヒントだけでもいいので教えてください。お願いします。
0245デフォルトの名無しさん2006/11/14(火) 15:43:52
>>244
宿題スレにでも行ったら?
0246デフォルトの名無しさん2006/11/14(火) 18:29:28
typedefとdefineで書き方が逆になるのはなぜなんですか?
0247デフォルトの名無しさん2006/11/14(火) 18:35:33
typdef は複数の句をあつかうから だと思われる。
 typedef unsigned long (*function_ptr)(int, long, long);
のようにね。
0248デフォルトの名無しさん2006/11/14(火) 19:38:43
画面から16進数を入力して10進数に変換する処理ですがstrtol関数を使って
16進以外が途中に入力されたらエラーを出力したいのですが、何か良い方法はありますか?
0249デフォルトの名無しさん2006/11/14(火) 19:39:45
画面から入力ってどんな技術を使うんだよ?
0250デフォルトの名無しさん2006/11/14(火) 19:40:13
>>249
馬鹿だなぁ
タッチパネルに決まってるだろ?
0251デフォルトの名無しさん2006/11/14(火) 19:47:26
板検索しても最初ここが出てこなかったのですれ立てるまでもない質問スレに書き込んでしまったのですが、
改めて質問させて下さい。コピペになりますが、よろしくお願いします。

グーグル先生に質問してみたのですがよくわかりませんでした・・orz
宜しければ詳しく教えて欲しいのですが。

C++にて、テキストファイルに書き込まれたデータを構造体に格納する方法です。
データは一行につき1件で、カンマで区切られて4つの項目があります。
char型が2つとint型が2つになります。
データは10件(行)あります。

よろしくお願いします(´・ω・`)
0252デフォルトの名無しさん2006/11/14(火) 19:55:52
たったの10件程度なら手作業でやるのが早いよ。
0253デフォルトの名無しさん2006/11/14(火) 19:57:28
知識としても理解しておきたいので、どうか(´・ω・`)
0254デフォルトの名無しさん2006/11/14(火) 20:04:51
>>251
>C++にて
スレ違い。

>テキストファイルに書き込まれたデータ
>char型が2つとint型が2つ
それはテキストファイルではない。
0255デフォルトの名無しさん2006/11/14(火) 20:07:32
>254
すいません、Cでお願いします。
書き方が悪かったです。
文字列,文字列,数字,数字
という構造になっているので、構造体の宣言でchar型を2つとint型を2つ用意する必要があるという事を言いたかったんです
0256デフォルトの名無しさん2006/11/14(火) 20:08:12
>>251
man fscanf
0257デフォルトの名無しさん2006/11/14(火) 20:09:53
>>255
文字列は(char型)配列に格納してください。
0258デフォルトの名無しさん2006/11/14(火) 21:13:50
ペイピッポォ
0259デフォルトの名無しさん2006/11/14(火) 21:41:39
int main(){
struct xxx {int *x;} hoge;
struct yyy {void *x;};
struct yyy *piyo = (struct yyy *)&hoge;
return 0;
}
これはコンパイルが通ったのですが、四行目を
struct yyy piyo = (struct yyy)hoge;
とすると型変換できませんとエラーが出ます、何故でしょうか?
0260デフォルトの名無しさん2006/11/14(火) 22:02:56
>>259
(struct yyy)hoge
このキャストは無理
0261デフォルトの名無しさん2006/11/14(火) 22:03:16
struct xxxとstruct yyyは全く無関係の型だから。
02622592006/11/14(火) 22:05:21
>>260,261
構造体自体のキャストは出来ないんでしょうか?
検索するとC++とかではできるらしい?のでためしてみたんですが
0263デフォルトの名無しさん2006/11/14(火) 22:09:34
>>262
君は http://pc8.2ch.net/test/read.cgi/tech/1160893851/588 かな?
http://pc8.2ch.net/test/read.cgi/tech/1160893851/595
の左辺のキャストを よーーーく見よう C にはない文法の (struct hoge &) ってキャストしてっから。
これは 構造体自体のキャストでは無い
02642592006/11/14(火) 22:19:22
>>263
同じ日に…いえ、その人は別の方です
C++でも構造体をキャストできているわけでなないんですね
可能だとしても意味はほとんどないんでしょうけれど、疑問に思ったので…
(メンバーの数が違っても)構造体のポインタはキャスト可能ということは
領域破壊でバグの原因になったりしそうでどっちにしろ危険っぽいですね
ありがとうございました
0265デフォルトの名無しさん2006/11/14(火) 22:22:36
ふつう構造体のポインタのキャストで実際に使うのは

struct XXX *p <-> void *p

くらい
0266デフォルトの名無しさん2006/11/14(火) 22:36:41
どうもです、mallocの時〜は、自動でキャストしてくれるんでしたっけ
じゃあ自分のレベルではまだ使うこともなさそうですね
0267デフォルトの名無しさん2006/11/14(火) 22:38:38
>>266
まま、そうおっしゃらずに。
実はいける口なんでしょ?
0268デフォルトの名無しさん2006/11/14(火) 22:40:31
typedef struct{
int length;
char data[1];
}string;

struct{
int length;
char data[buf_size];
}a;

のとき

(string)a

のようにキャストするのもテクニックとしては知っておいたほうがいいかも
02692592006/11/14(火) 23:01:41
せいぜい数十行のコード書いて試す、を繰り返してる程度ですから…
>>268
すみません、どのように使うんでしょうか?
0270デフォルトの名無しさん2006/11/14(火) 23:02:25
すいません、先ほども質問しましたが、画面から配列に16進数を8桁入力して10進数に変換する処理ですがstrtol関数を使って
16進以外が途中に入力されたらエラーを出力したいのですが、何か良い方法はありますか?
気になって眠れません。
0271デフォルトの名無しさん2006/11/14(火) 23:07:29
>>270
どこまで変換したかってポインタが設定されるから、それを見たら?
途中で止まってたらおかしい。
0272デフォルトの名無しさん2006/11/14(火) 23:08:03
>>270
>249
0273デフォルトの名無しさん2006/11/14(火) 23:19:07
>>271さん
第一引数は配列名で第三引数は基数、第二引数をみるのですか?
0274デフォルトの名無しさん2006/11/14(火) 23:21:09
>>273
そう。
0275デフォルトの名無しさん2006/11/14(火) 23:49:34
>>269
268ではないが。
C言語ではコンパイル時に配列のサイズが決まっている必要があるが、
サイズを動的に変えられる(かのように扱える)構造体を使うためのテクニック。

配列のサイズは固定なので、基本的に最大の要素数を格納できるような
型を用意しておく必要がある。これでは、要素数の少ないデータしか
格納しない場合に無駄が多い。
よって、ケースバイケースで配列の要素数の異なる型が使えると嬉しい。

以下のようにすれば任意の要素数の配列として動的に確保できる。
string *p;
int size = 30;
p = (string *)malloc(sizeof(string) + sizeof(char)*(size - 1);
p->length = size;

この構造体を操作するときは、配列部分のサイズが固定じゃないから、
lengthメンバのようにどこかで配列サイズを保持しておき、
その分だけをアクセスするようにすればいい。

void func(string *pstr)
{
 int i;
 for(i = 0 ; i < pstr->length ; i++) {
  printf("%c", toupper(pstr->data[i]);
 }
}

当然、構造体の最後のメンバにしか適用できない。
0276デフォルトの名無しさん2006/11/14(火) 23:55:26
>>275
仕様書に違反している事には変わりがないけどな。
使うときは自己責任でって奴だ。
C99ではchar data[]って書き方が正式に許されたが。
0277デフォルトの名無しさん2006/11/15(水) 00:33:05
sizeof(char) は常に 1 なんだけど・・・


ま、いっか。
0278デフォルトの名無しさん2006/11/15(水) 02:04:53
2次元配列の意味がわかりません、簡単に言うと
どういう事なのでしょうか?入門書の説明が難しくて
わかりません。
あと、コメントが文字列なので2次元配列は、
どうして使えないのでしょうか?
0279デフォルトの名無しさん2006/11/15(水) 02:39:53
>>278
例えば学校で40人のクラスが5クラスあったとする。
その場合
int data [5][40];
とかになる

>あと、コメントが文字列なので2次元配列は、
>どうして使えないのでしょうか?

これは言ってる意味がわからない
0280デフォルトの名無しさん2006/11/15(水) 02:59:43
>>278
もしかして二次元配列とポインタの関係がわからなくて悩んでいるのか?
最初はポインタ無視していいよ。>>279の通りでいい。

>コメントが

これは俺も不明な質問だが、文字列の二次元配列という意味なら、文字列
そのものが既にchar型の一次元配列なので、1+2=3次元配列が必要になる。

例えば

char [][2][10] = {{"orange", "apple"}, {"banana", "pine"}};

のような感じで。
02812782006/11/15(水) 03:07:40
>>279
わkりました!!

>>280->>279
>>コメント
入門書にも詳しく書かれていないので、
自分でもよくわかりません、すんまそ。

>>char [][2][10] = {{"orange", "apple"}, {"banana", "pine"}};

のような感じで。


難しいです・・・まだここまで習っていないので参考にさせて
戴きます、頭が混乱するといけないので。

ありがとうございました。
0282デフォルトの名無しさん2006/11/15(水) 03:51:46
#include <stdio.h>
#include <time.h>
#include <stdlib.h>

//すごろくマップの構造体
struct board{
int p;//進む数
int h;//休む回数
char comment[128];
};

int p_position = 1; //プレイヤーの現在位置
int max = 10; //マップの全駒数
void writeBoard(void);

■ このスレッドは過去ログ倉庫に格納されています