- ベストアンサー
s[]とか *sとかの違い
C言語で 引数に s[]とか *sがありますが、 厳密にどう違うのでしょうか? あと書き方なのですが、int *sと int* sを見ますが、 正しいのはどちらでしょうか? 細かい話ですが、これらを知らないと、あとで困るような場面も知りたいです。 void test(int s[]) { } void test(int *s) { } void test(int* s) { }
- みんなの回答 (9)
- 専門家の回答
質問者が選んだベストアンサー
(s[]) と、(*s) が同等だったと記憶してますが、 省略できる括弧はしてもいいようです。 2次元以上の時に、配列のポインタを確保する時など覚えておかないと困ります。 2次元のときのサンプル #include <stdio.h> void test0(int count, char str[1][4]) { // ここに 1 などの整数を書けるが意味を持たないので注意。 int i; for (i = 0; i < count; i++) printf("%s", str[i]); printf("\n"); } void test1(int count, char (*str)[4]) { int i; for (i = 0; i < count; i++) printf("%s", str[i]); printf("\n"); } void test2(int count, char *str[1]) { // 同上 int i; for (i = 0; i < count; i++) printf("%s", str[i]); printf("\n"); } void test3(int count, char **str) { int i; for (i = 0; i < count; i++) printf("%s", str[i]); printf("\n"); } void test4(char str[1]) { // 同上 printf("%s", str); printf("\n"); } int main() { char foo[][4] = { "abc", "def", "ghi" }; char *bar[] = { foo[0], foo[1], foo[2] }; char **hoge = bar; test0(3, foo); test1(3, foo); test2(3, bar); test3(3, bar); test4(foo[0]); return 0; }
その他の回答 (8)
- php504
- ベストアンサー率42% (926/2160)
連続ですみませんが 配列とポインタは違うものですが関数の引数に配列を渡すとポインタとして扱われるのです。(関数の引数に限りs[]は*sと同じになる) #include <stdio.h> void func(char c[]) // 実際はchar* cとして扱われる { printf("%d\n", sizeof(c)); // 4(ポインタのバイト数) c++; // OK } int main(void) { char a[10] = "ABCDEFG"; func(a); return 0; }
- php504
- ベストアンサー率42% (926/2160)
s[] と *s は 配列とポインタで、関数の実引数でない場合に使い方が違います。 すみません、具体的な例をあげていただけますか。 ------------------- #include <stdio.h> int main(void) { char a[10] = "ABCDEFG"; char* b = "ABCDEFG"; printf("%d\n", sizeof(a)); // 10(配列の個数) printf("%d\n", sizeof(b)); // 4(ポインタのバイト数、環境により変わる) a++; // コンパイルエラー b++; // OK a[0] = 'Z'; // OK b[0] = 'Z'; // 実行時にアクセス違反になるかもしれない return 0; }
- asuncion
- ベストアンサー率33% (2127/6289)
>#5さん >s[] と *s は 配列とポインタで、使い方が違います。 関数の実引数でない場合、というただし書きがつきます。
- S117
- ベストアンサー率40% (18/45)
引数において空の[]はポインタと同じ意味になります。 int main(int argc, char *argv[]); int main(int argc, char **argv); は同じ型の関数です。 もちろん、これは関数の引数に書いたときだけの特別なルールなので、配列の宣言時に長さを省略し、初期化式に任せる方法とは無関係なので注意が必要です。 次に、*をどっちに書くかです。 char *p; char* p; Cとしては、どちらの場合も全く同じです。 型としてはchar*型になることから、後者を好んで使う人もいるでしょう。 ただし、 char* a, b; は char *a, b; と同じ意味で、bがchar*型にならず、char型になります。 文法上は*は変数名(識別子)につけるもので、たまたまchar* a;と書けるようになっているに過ぎないと考えた方がいいかもしれません。
- tsuduki999
- ベストアンサー率35% (6/17)
s[] と *s は 配列とポインタで、使い方が違います。 文法上、アクセスする手段が両者で同じになるので混同されがちですが メモリ配置の上で、異なってきますので別のものだと考えるようにしたほうがてよいです。 int *sと int* sも文法上は、同じものです。 ただ、もしも、C言語を学び始めたばかりなのだとすれば 「型」を意識する上で「int* s」と覚えた方がよいかもしれません。 「int *s」は、 「int *」という型であって「*s」 という変数ではないからです。 ポインタがわからないという人は、後者(「*s」という変数)で覚えている傾向があります。
- akayoroshi
- ベストアンサー率50% (46/91)
> あと書き方なのですが、int *sと int* sを見ますが、 > 正しいのはどちらでしょうか? 文法では、つづり(int、s、void、testなど)と記号(*、かっこ、区切りとしての空白など)との間には空白、タブ文字、改行をいくつ入れてもよいし、入れなくてもよいことになっています。 ということで、int *s でも、int* s でも、int * s でも正しいことになります。 慣習としてどちらか片方の書き方だけを採ることが多いようです。
- nda23
- ベストアンサー率54% (777/1415)
配列でないデータを考えると、広いメモリ中に1ヶ所だけ存在する、 言い換えると大海の中の孤島のようなもので、その前後(海)は別の 用途に使われていると考えられますね。これに対し、配列を考えると、 先頭の島は見えますが、その後ろに何個(島)あるかは定義した人しか 知りません。従って、「配列データを受け取る」と言っても最初の データ(島)の位置しか分からないのです。つまり、ポインタと同じ 扱いということです。一般に配列を引数とする時は別の引数で要素数を 示すとか、0なら最後の要素であるとか(文字列などはこれですね) 決めて使うようにしています。 int* s; int *s; この違いですが、古い書式は後者だった気がします。 解釈としては「intポインタ型の変数s」、「int型のポインタ変数s」 となるんでしょうか。好みですけど、最近は「×ポインタ型の変数」 とするやり方の方がメジャーな気がします。windows.h等では typedefにより「*」が付かないデータ型を定義して使っています。 【例】 #include<windows.h> char *p1; LPSTR p2; 上記 p1、p2 は同じ型です。
- php504
- ベストアンサー率42% (926/2160)
関数の引数の場合、s[]と*sはまったく同じ意味になりますのでわかりやすいほうでいいと思います。 int *sとint* sもどちらも正しいのでお好みで使い分けてください。
補足
ご回答ありがとうございます。すべて同じですが、 s[] と *s は 配列とポインタで、関数の実引数でない場合に使い方が違います。 すみません、具体的な例をあげていただけますか。