質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

2回答

1788閲覧

C言語 ポインタと配列 *vとv[]の違いについて

aya0

総合スコア16

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2020/03/05 06:43

問題
要素型がint型で要素数がnの配列を受け取って、全要素に添え字と同じ値を代入する関数を作成せよ。

c

1#define _CRT_SECURE_NO_WARNINGS 2#include <stdio.h> 3 4void set_idx(int *v, int n) 5//なぜ、v[]にする場合*をつけず、 6//vにする場合*をつけるのか分からない 7//vとv[]の違いを知りたい 8{ 9 int i; 10 for (i = 0; i < n; i++) 11 v[i] = i; 12} 13 14int main(void) 15{ 16 int i; 17 int a[] = { 1,2,2,4,5 }; 18 19 set_idx(a, 5); 20 21 for (i = 0; i < 5; i++) 22 printf("a[%d] = %d\n", i, a[i]); 23 24 return 0; 25}

参考書にはvoid set_idx(int v, int n)の部分のvはv[]にしてもよいと書かれていました。
なぜ、v[]にする場合をつけず、vにする場合をつけるのか分からないです。
vとv[]の違いを知りたいです。
宜しくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

vとv[]の違いを知りたいです。

仮引数についてだけは、int v[]と書いたものはint *vに読み替えられるので、全く違いはありません。

なぜ、v[]にする場合をつけず、vにする場合をつけるのか分からないです。

書いてのとおり、int v[]は「intの配列」、int *vは「intのポインタ」という意味です。一部の場面を除いて、式の中では配列はポインタとして扱われるので、引数でこの2つは等価となります。int vは「int型の値」、int *v[]は「intへのポインタの配列」となり、意味が異なることは明らかです。

投稿2020/03/05 06:48

編集2020/03/05 06:53
maisumakun

総合スコア146018

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

aya0

2020/03/05 21:37

回答ありがとうございます! 関数でv[]を受け取るときはv[]がポインタ変数になり、関数でvを受け取るときはvがint型の値(v[0]のアドレス)になるってことだったのですね! すごく助かります!
guest

0

関数でv[]を受け取るときはv[]がポインタ変数になり、

関数でvを受け取るときはvがint型の値(v[0]のアドレス)になる

う~ん...

そもそも「配列」と「ポインタ」がなぜこんなに絡まっているのかから考えてみた方がよさそうな。

Cの配列は、要素(変数)が密に並んでいるもの、です。一方、ポインタは変数の位置を示します。なので、配列上の要素の一つをポインタで示したならば、そこを足がかりにして配列の隣の要素も、あるいはn離れた要素にもアクセス出来るわけです。

上記を取り込んで、C言語には2つの決まりがあります。
一つは、一部の例外を除き、「配列が単独で記述されたときは配列の先頭要素へのポインタと解釈される」ということ。
int a[N];
があったとき、以降プログラム中に登場するaは&a[0]と解釈されるのです。
(例外はaがsizeof演算子または&演算子のオペランド:対象になるとき)

もう一つは、まさに配列とポインタの絡みの極み?ですが
CではT型の配列aとT型のポインタp、整数Nがあって、p=&a[0]としたら
a[N]と*(p+N)は等価、ということ。先の規則とあわせて、p[N]とか*(a+N)も等価です。(余談:さらにはN[a]という記述方法もあり、ということになります)

この仕組みを前提に、Cは関数が配列を受け取る際に、ポインタ一つを受け取ることで「配列を受け取った」とすることにしました。それで配列の各要素にアクセスできるので。このとき、配列全体の要素数の情報を切り捨てる、という犠牲を払っています。要素数が必要であれば配列(ポインタ)とは別に受け取る必要があります。
また、「配列を渡しているんだ」というプログラマの意図を明示するために(別に開発者に聞いたわけじゃないですけどそういうことでしょう)配列の形式で記述することも可にしています。これにより、配列の形式で(int v[])と記述しても実際には(int* v)として解釈します。

それと、「*をつけず」「をつける」と言っていますが、宣言の際は変数に'をつけている'わけではなく、あくまでint型の変数vを宣言している、ということです。アクセスのときはは演算子なので変数に「つける/つけない」なのですが...(C言語の文法の紛らわしいところの一つです)

投稿2020/03/05 22:59

編集2020/03/05 23:01
thkana

総合スコア7703

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

aya0

2020/03/07 06:34 編集

回答ありがとうございます! p=a p=&a[0] *p=a[0] ↓ *(p+N)=a[N] 上の仕組みがあって*の有無が決まってたのですね! また、*は指しているオブジェクトをアクセスするためにも使われるが今回の質問の部分はint*型の変数を宣言するっていうことが目的で使われてたのですね! このままでは勘違いのまま終わるところでした! すごく助かります!
rubato6809

2020/03/07 09:34

<関数が配列を受け取る際に、ポインタ一つを受け取ることで「配列を受け取った」とする> ここに集約されると思います。
aya0

2020/03/07 13:29

回答ありがとうございます! より理解が深まりました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問