C言語 - よくありそうな質問
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
検索
|
最終更新
|
ヘルプ
|
ログイン
]
開始行:
* C言語 - よくありそうな質問 [#t516e32a]
Cに関するよくありそうな質問。入門者向け。
#contents
**i++ と ++i の違いって何? [#zdadd7d3]
ただ単品で '''i++;''' や '''++i;''' と書くときには違いは...
次のようなコードで違いが生じます。
a = i++;
b = ++i;
前者は
a = i;
i = i + 1;
と同じで、後者は
i = i + 1;
b = i;
と同じです。~
(やや難しくいうと、i の値を評価してから1増やすか、1増やし...
**#define と typedef ってどっちを使ったらいいの? [#j199c...
typedef が使えるところではすべて typedef を使うべきです。~
#define で typedef の代用をすると、型名ではないところまで...
#define moji char
struct card{
int moji;
int suuji;
};
このようなとき、メンバの名前である moji まで '''char''' ...
// putmojiがputcharに置換されるという例だったが、cppはト...
**if( (cond=function()) != -1 ){ ... } ← これなんですか?...
これは次と同じ意味です。
cond = function();
if( cond != -1 ){ ... }
つまり、cond=function(); を実行して、値が変わった cond を...
while( (c=getchar()) != EOF ){ ... } なども同様です。~
( c=getchar(); を実行し、更新された c を EOF と比べる)
**printf(const char *format, ...) の const って何? [#zf9...
const とは constant の略で、「この変数はこの関数の中で変...
つまり、
char str[] = "This is a test.";
printf(str);
としたときに、「str の中身をprintf関数が勝手に変更したり...
**二次元配列を関数に渡したらコンパイルできません!! [#pd...
こんな風↓にしてませんか?
void function(int arg[][]){ ... }
main(){
int test[][] = {{0, 1, 2}, {1, 2, 3}, {2, 3, 4}};
function(test);
}
もしこうしているなら、function の引数を次のように直してく...
void function(int arg[][3]){ ... } // 要素数を後ろ側だけ...
main(){ ... }
こうすればコンパイルできるはずです。~
(両方指定して arg[3][3] としてもよいが、そうすると3×3配列...
なぜこうしないといけないかというと、二次元配列はメモリ上...
↓test[1][0]
[0][1][2][1][2][3][2][3][4]
↑test[0][0] ↑test[2][0]
つまり、呼び出された関数から見ると3×3配列は連続した9個のi...
後ろの3を指定してやることで、どこで区切ればいいのか分かる...
同様の理由で、3次元配列ならば後ろ2つ、4次元配列ならば後ろ...
** char array[n]; ってできないんですけど! [#zaff8516]
残念ながら、CおよびC++では配列を宣言するときの要素数の指...
ではどうするかというと、次のようにします。
#include <stdlib.h> // callocを使うのに必要
main(){
char* array = (char*)calloc(n, sizeof(char));
...
}
これで以後 array は要素数nのchar型配列とまったく同じよう...
(なぜこれでいけるのかは長くなるのでポインタと配列の関係と...
なお、C99(C言語の最新規格)では、char array[n];のような可...
** if(0 < a < 5){ ... } ってしたいんですけど! [#je0fd9d9]
''やめてください''~
このように書いてもコンパイルは通りますが、数学的に表され...
if(0 < a && a < 5){ ... }
としてください。~
↓まともな説明(分からん人はスルー可)~
a = -1 のときを例にとって、こう書くとどうなるのかやってみ...
0 < a < 5 の計算順序は (0 < a) < 5 なので、まず 0 < a を...
次に 0 < 5 を評価して、結局全体として真になってしまいます...
まとめると、0 < a < 5 の意味は「0とaを比較して、その結果(...
** if(a==b==c){ ... } ってしたらなんかおかしいんですけど...
これも上の質問と同じ原因で、見た目の意味(aとbとcが等しい...
if(a==b && b==c){ ... }
などとしてください。
** 『猫でも分かる〜』に書いてある メモリモデル とか FARポ...
昔の名残です。今では意味がありません。無視しましょう。~
(ただ今後64ビット環境と32ビット環境が入れ食い状態になると...
↓以下C++が分かる人向けの説明~
例えば、32ビット環境で64ビットのポインタを作ったとする
template <typename T> class ptr64{
private:
unsigned long long adr;
public:
T operator *(){ ... }
......
};
typedef ptr64<char> pchar64;
typedef ptr64<int> pint64;
......
このようなポインタ(実際には16ビット環境下での32ビットポイ...
** (a ? b : c) って何? [#ic8b7c01]
「aが真ならばb、偽ならばc」という意味。三項演算子と呼ばれ...
次のように使って、if よりも短く簡潔に書くことができる。
void func(int x){
int y;
y = (x>0 ? x : -1 * x); // yは、x>0ならx、そうでなけれ...
...
}
int even(int n){
return (n%2 ? 0 : 1); // n%2が1なら0を、0なら1を返す
}
ちなみに、ifとの違いは、ifが制御構文なのに対して、こちら...
** 「メモリがreadになることができませんでした」とかいって...
メモリのおかしな場所にアクセスした時にWindowsが出す警告で...
初心者がやりがちなミスで原因となりそうなものは、次のよう...
-配列添字に要素数以上の数を指定していませんか?~
char array[5]; のとき、使えるのはarray[0]〜array[4]の5つ...
-scanfなどの関数で、代入先の指定に & をつけ忘れていません...
× scanf("%d", a);
○ scanf("%d", &a);
-char *str; str[0] = 'a'; ... などとしていませんか?~
配列は自動的にポインタになりますが、ポインタは自動的に配...
char str[512]; // 充分な大きさの配列を用意
str[0] = 'a';
....
とするか、malloc, calloc等を使ってください。
-printfの書式指定を間違えていませんか?~
int a = 10;
× printf("%s\n", a);
○ printf("%d\n", a);
-終端文字(\0)の入っていない文字列を表示したり、文字列処理...
悪い例
char str[10];
str[0]='t'; str[1]='e'; str[2]='s'; str[3]='t';
printf("%s\n", str);
良い例1
char str[10] = "test"; // こうすると自動で最後に'\0'が入る
printf("%s\n", str);
良い例2
char str[10];
str[0]='t'; str[1]='e'; str[2]='s'; str[3]='t'; str[4]='...
printf("%s\n", str);
-リテラル領域に書き込んでいませんか?~
ダブルクォーテーションマークで囲んだ文字列は文字列「定数...
定数領域は弄っちゃいかんです。~
駄目な例
char *str = "VIP de yare";
str[5] = 'a';
良い例
char str[] = "VIP de yare";
str[5] = 'a';
上の例では、strにはリテラル領域のアドレスが入っているに過...
下の例では、strにはリテラル領域の中身がコピーされているか...
**「メモリがwrittenになることができませんでした」とかいっ...
同上
**むしろ何もメッセージが出ずに落ちるんですけど… [#bae6dec2]
何もエラーが出ずに落ちる場合でも、メモリアクセスが原因な...
(というより、「落ちる」という現象の原因はほぼ全部なんらか...
『「メモリがreadになることができませんでした」とかいって...
**関数ポインタの宣言が意味分かりません [#g9b39d4f]
Cの文法が腐ってるせいです。単純な場合は丸暗記しましょう。...
+単純な場合
int (*func)(char); //「char型の引数をとりint型を返す関数...
+複雑な場合
typedef int (*func_t1)(char);
//「char型の引数をとりint型を返す関数」へのポインタ
typedef func_t1 (*func_t2)(double);
//「double型の引数をとり、『char型の引数をとりint型を...
func_t2 test[];
//「double型の引数をとり、『char型の引数をとりint型を...
**排他的論理和ってなに? [#r919c70e]
論理演算(andとかorとか)の一種です。''二つ同じならfalse、...
AとBの排他的論理和
|A\B|true|false|
|true|false|true|
|false|true|false|
ただし、Cでは A^B は''ビットごとの排他的論理和''の意味に...
例:~
A = 10(2進数で&color(blue,white){0};&color(red,white){1...
B = 24(2進数で&color(blue,white){1};&color(red,white){1...
A^B = 18(2進数で&color(blue,white){1};&color(red,white)...
**標準ライブラリってなに?[#f5c7d4e0]
マイクロソフトのVisualStudio、やボーランドのBCC、オープン...
**じゃあ非標準ライブラリもあるわけ? [#w3fd34e0]
DirectX、OpenGL,HTTP,メールの送受信,グラフィック、正規表現...
終了行:
* C言語 - よくありそうな質問 [#t516e32a]
Cに関するよくありそうな質問。入門者向け。
#contents
**i++ と ++i の違いって何? [#zdadd7d3]
ただ単品で '''i++;''' や '''++i;''' と書くときには違いは...
次のようなコードで違いが生じます。
a = i++;
b = ++i;
前者は
a = i;
i = i + 1;
と同じで、後者は
i = i + 1;
b = i;
と同じです。~
(やや難しくいうと、i の値を評価してから1増やすか、1増やし...
**#define と typedef ってどっちを使ったらいいの? [#j199c...
typedef が使えるところではすべて typedef を使うべきです。~
#define で typedef の代用をすると、型名ではないところまで...
#define moji char
struct card{
int moji;
int suuji;
};
このようなとき、メンバの名前である moji まで '''char''' ...
// putmojiがputcharに置換されるという例だったが、cppはト...
**if( (cond=function()) != -1 ){ ... } ← これなんですか?...
これは次と同じ意味です。
cond = function();
if( cond != -1 ){ ... }
つまり、cond=function(); を実行して、値が変わった cond を...
while( (c=getchar()) != EOF ){ ... } なども同様です。~
( c=getchar(); を実行し、更新された c を EOF と比べる)
**printf(const char *format, ...) の const って何? [#zf9...
const とは constant の略で、「この変数はこの関数の中で変...
つまり、
char str[] = "This is a test.";
printf(str);
としたときに、「str の中身をprintf関数が勝手に変更したり...
**二次元配列を関数に渡したらコンパイルできません!! [#pd...
こんな風↓にしてませんか?
void function(int arg[][]){ ... }
main(){
int test[][] = {{0, 1, 2}, {1, 2, 3}, {2, 3, 4}};
function(test);
}
もしこうしているなら、function の引数を次のように直してく...
void function(int arg[][3]){ ... } // 要素数を後ろ側だけ...
main(){ ... }
こうすればコンパイルできるはずです。~
(両方指定して arg[3][3] としてもよいが、そうすると3×3配列...
なぜこうしないといけないかというと、二次元配列はメモリ上...
↓test[1][0]
[0][1][2][1][2][3][2][3][4]
↑test[0][0] ↑test[2][0]
つまり、呼び出された関数から見ると3×3配列は連続した9個のi...
後ろの3を指定してやることで、どこで区切ればいいのか分かる...
同様の理由で、3次元配列ならば後ろ2つ、4次元配列ならば後ろ...
** char array[n]; ってできないんですけど! [#zaff8516]
残念ながら、CおよびC++では配列を宣言するときの要素数の指...
ではどうするかというと、次のようにします。
#include <stdlib.h> // callocを使うのに必要
main(){
char* array = (char*)calloc(n, sizeof(char));
...
}
これで以後 array は要素数nのchar型配列とまったく同じよう...
(なぜこれでいけるのかは長くなるのでポインタと配列の関係と...
なお、C99(C言語の最新規格)では、char array[n];のような可...
** if(0 < a < 5){ ... } ってしたいんですけど! [#je0fd9d9]
''やめてください''~
このように書いてもコンパイルは通りますが、数学的に表され...
if(0 < a && a < 5){ ... }
としてください。~
↓まともな説明(分からん人はスルー可)~
a = -1 のときを例にとって、こう書くとどうなるのかやってみ...
0 < a < 5 の計算順序は (0 < a) < 5 なので、まず 0 < a を...
次に 0 < 5 を評価して、結局全体として真になってしまいます...
まとめると、0 < a < 5 の意味は「0とaを比較して、その結果(...
** if(a==b==c){ ... } ってしたらなんかおかしいんですけど...
これも上の質問と同じ原因で、見た目の意味(aとbとcが等しい...
if(a==b && b==c){ ... }
などとしてください。
** 『猫でも分かる〜』に書いてある メモリモデル とか FARポ...
昔の名残です。今では意味がありません。無視しましょう。~
(ただ今後64ビット環境と32ビット環境が入れ食い状態になると...
↓以下C++が分かる人向けの説明~
例えば、32ビット環境で64ビットのポインタを作ったとする
template <typename T> class ptr64{
private:
unsigned long long adr;
public:
T operator *(){ ... }
......
};
typedef ptr64<char> pchar64;
typedef ptr64<int> pint64;
......
このようなポインタ(実際には16ビット環境下での32ビットポイ...
** (a ? b : c) って何? [#ic8b7c01]
「aが真ならばb、偽ならばc」という意味。三項演算子と呼ばれ...
次のように使って、if よりも短く簡潔に書くことができる。
void func(int x){
int y;
y = (x>0 ? x : -1 * x); // yは、x>0ならx、そうでなけれ...
...
}
int even(int n){
return (n%2 ? 0 : 1); // n%2が1なら0を、0なら1を返す
}
ちなみに、ifとの違いは、ifが制御構文なのに対して、こちら...
** 「メモリがreadになることができませんでした」とかいって...
メモリのおかしな場所にアクセスした時にWindowsが出す警告で...
初心者がやりがちなミスで原因となりそうなものは、次のよう...
-配列添字に要素数以上の数を指定していませんか?~
char array[5]; のとき、使えるのはarray[0]〜array[4]の5つ...
-scanfなどの関数で、代入先の指定に & をつけ忘れていません...
× scanf("%d", a);
○ scanf("%d", &a);
-char *str; str[0] = 'a'; ... などとしていませんか?~
配列は自動的にポインタになりますが、ポインタは自動的に配...
char str[512]; // 充分な大きさの配列を用意
str[0] = 'a';
....
とするか、malloc, calloc等を使ってください。
-printfの書式指定を間違えていませんか?~
int a = 10;
× printf("%s\n", a);
○ printf("%d\n", a);
-終端文字(\0)の入っていない文字列を表示したり、文字列処理...
悪い例
char str[10];
str[0]='t'; str[1]='e'; str[2]='s'; str[3]='t';
printf("%s\n", str);
良い例1
char str[10] = "test"; // こうすると自動で最後に'\0'が入る
printf("%s\n", str);
良い例2
char str[10];
str[0]='t'; str[1]='e'; str[2]='s'; str[3]='t'; str[4]='...
printf("%s\n", str);
-リテラル領域に書き込んでいませんか?~
ダブルクォーテーションマークで囲んだ文字列は文字列「定数...
定数領域は弄っちゃいかんです。~
駄目な例
char *str = "VIP de yare";
str[5] = 'a';
良い例
char str[] = "VIP de yare";
str[5] = 'a';
上の例では、strにはリテラル領域のアドレスが入っているに過...
下の例では、strにはリテラル領域の中身がコピーされているか...
**「メモリがwrittenになることができませんでした」とかいっ...
同上
**むしろ何もメッセージが出ずに落ちるんですけど… [#bae6dec2]
何もエラーが出ずに落ちる場合でも、メモリアクセスが原因な...
(というより、「落ちる」という現象の原因はほぼ全部なんらか...
『「メモリがreadになることができませんでした」とかいって...
**関数ポインタの宣言が意味分かりません [#g9b39d4f]
Cの文法が腐ってるせいです。単純な場合は丸暗記しましょう。...
+単純な場合
int (*func)(char); //「char型の引数をとりint型を返す関数...
+複雑な場合
typedef int (*func_t1)(char);
//「char型の引数をとりint型を返す関数」へのポインタ
typedef func_t1 (*func_t2)(double);
//「double型の引数をとり、『char型の引数をとりint型を...
func_t2 test[];
//「double型の引数をとり、『char型の引数をとりint型を...
**排他的論理和ってなに? [#r919c70e]
論理演算(andとかorとか)の一種です。''二つ同じならfalse、...
AとBの排他的論理和
|A\B|true|false|
|true|false|true|
|false|true|false|
ただし、Cでは A^B は''ビットごとの排他的論理和''の意味に...
例:~
A = 10(2進数で&color(blue,white){0};&color(red,white){1...
B = 24(2進数で&color(blue,white){1};&color(red,white){1...
A^B = 18(2進数で&color(blue,white){1};&color(red,white)...
**標準ライブラリってなに?[#f5c7d4e0]
マイクロソフトのVisualStudio、やボーランドのBCC、オープン...
**じゃあ非標準ライブラリもあるわけ? [#w3fd34e0]
DirectX、OpenGL,HTTP,メールの送受信,グラフィック、正規表現...
ページ名: