ここから本文です

C言語にて関数に渡す配列名に&を付けるのと付けないのとでの違いについて質問です...

アバター

ID非公開さん

2017/9/1615:57:47

C言語にて関数に渡す配列名に&を付けるのと付けないのとでの違いについて質問です。

以下の知恵袋回答のベストアンサーの内容に疑問が有ります。

配列名に&を付けるのと付けないのは何が

違う…
https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q111430255...

少なくとも私がコンパイルに使用する処理系では全く違いが有りません。
本当のことを教えていただけると嬉しいです。

閲覧数:
411
回答数:
7
お礼:
25枚

違反報告

ベストアンサーに選ばれた回答

s_h********さん

編集あり2017/9/1814:08:36

C言語にて関数に渡す配列名に&を付けるのと付けないのとでは,
アドレスは同じでも型が違います.

私の環境で確認したところ

char a[5] = "vwxyz";のとき
aと&aは同じアドレスでしたが

aは型が(char*),
&a は型がchar (*)[5],

でした



***

要素数が5個の配列 a があるとする
a[0]='v',a[1]='w',a[2]='x',a[3]='y',a[4]='z';
とする.

このとき,
aと&(a[0])と&aは同じアドレス.
aは型が(char*),
&(a[0])は型は(char*),
&a は型がchar (*)[5],
でした.

***

もし関数 test1(char (*p)[5]){};の場合,
サイズが5のポインタ配列のアドレス,(char (*)[5])を引数としているので,
test1(&a)と書く.

***

もし関数 test2(char* p){};の場合,
このとき,要素のアドレス(char *)を引数としているので,
test2(&a[0])とかtest2(&a[1])とかtest2(a)とか書く.

******

具体的に実験..

#include <stdio.h>

void test1(char (*p)[5]){
int i;
printf("%d ", sizeof *p);
for(i = 0;i < sizeof *p;i ++){
printf("%p ",&(*p)[i]);
printf("%c ",(*p)[i]);
}
printf("\n");
}

void test2(char* p){
printf("%d ", sizeof *p);
printf("%c\n",p[0]);
}

int main(void) {
char a[5] = "vwxyz";
char b[3] = "opq";
char c[7] = "abcdefg";

printf("a :%p, %d \n", a,sizeof(a));//sizeof(a)は配列aの大きさ
printf("&a:%p, %d %d\n", &a,sizeof(&a),sizeof(*(&a)));//sizeof(&a)はアドレスaの大きさ
printf("&(a[0]):%p, %d %d\n", &(a[0]),sizeof(&(a[0])),sizeof(*(&(a[0]))));
printf("&(a[3]):%p, %d %d\n", &(a[3]),sizeof(&a[3]),sizeof(*(&a[3])));

//aは型が(char*),&a は型がchar (*)[5],&(a[0])は型は(char*),適当に書いたらエラー欄に正しい型が説明された

printf("引数が(char (*)[5])の場合¥n");
//引数は,char (*)[5].
test1(&a);//char (*)[5]
//test1(&(a[0]));//&a[0]は(char*)となる
//test1(&b);//要素数3 char (*)[3],だからエラー//一方EasyIDECコンパイル通る
//test1(&c);//要素数7 char (*)[7],だからエラー//一方EasyIDECコンパイル通る

printf("引数が(char*)の場合\n");
//引数は,(char*).
test2(a);
test2(&a[0]);
test2(&a[1]);
test2(b);
test2(&(c[4]));
test2((c+4));

return 0;
}


******

出力結果

a :000000000061FE40, 5
&a:000000000061FE40, 8 5
&(a[0]):000000000061FE40, 8 1
&(a[3]):000000000061FE43, 8 1
引数が(char (*)[5])の場合
5 000000000061FE40 v 000000000061FE41 w 000000000061FE42 x 000000000061FE43 y 000000000061FE44 z
引数が(char*)の場合
1 v
1 v
1 w
1 o
1 e
1 e

ベストアンサー以外の回答

1〜5件/6件中

並び替え:回答日時の
新しい順
|古い順

her********さん

2017/9/1821:33:26

回答のベストアンサーは、言語を指定していないので、C++と思われます。
Cでは、VCでは警告でしか在りません。
多分 gcc では C でも C++ でも警告も出ない気がしますが、
今環境が無いので何ともいえません。
gcc も、Ver1.42 辺りまでは、無警告だったと思います。

昔のCは、配列に&付けても無視されます。
(sizeofに対しては1つだけ有効です)

aru********さん

2017/9/1821:16:27

第1として、そのベストアンサーが嘘を言っているような言い回しはやめてください。

違いの例を書くので、ここから先の深いところは頑張って調べて下さい。

char str[16] という配列があるとします。

test(char &a)

tes(char *a)

という引数が必要な関数があります。
使い方は

test( &str[3] )

tes( str )

です。

ここから察せというのは非常に苦なのはわかりますが、頑張って下さい。

j_c********さん

編集あり2017/9/1817:21:36

文字列以外の場合、&はデータが入っている先のアドレス。結局ポインタだけどね。受け取り側はポインタで受けないと固まっちゃう原因になるから気をつけて。
文字列の場合は文字列自体がポインタだから&はつけないでね。

tar********さん

2017/9/1701:01:47

&配列名
みたいな表記は
ちょっと気持ち悪い動作をするようなので
深入りしないほうがいいような気がします。

まったくなんの回答にもなっていませんが。

プロフィール画像

カテゴリマスター

qui********さん

2017/9/1623:33:52

ベストアンサー以外は読まないのかな?

少なくとも私は何が同じで何が違う、という話を書いたつもりだけれど。

人によって同じことでも少しずつ違う角度から説明をしたりもするから、BA以外のも読むと参考になることが結構ある。

この質問につけられたタグ

みんなで作る知恵袋 悩みや疑問、なんでも気軽にきいちゃおう!

Q&Aをキーワードで検索:

Yahoo! JAPANは、回答に記載された内容の信ぴょう性、正確性を保証しておりません。
お客様自身の責任と判断で、ご利用ください。
本文はここまでです このページの先頭へ

「追加する」ボタンを押してください。

閉じる

※知恵コレクションに追加された質問は選択されたID/ニックネームのMy知恵袋で確認できます。

不適切な投稿でないことを報告しました。

閉じる