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

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

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

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

ポインタ

ポインタはアドレスを用いてメモリに格納された値を"参照する"変数です。

再帰

情報工学における再帰とは、プログラムのあるメソッドの処理上で自身のメソッドが再び呼び出されている処理の事をいいます。

Q&A

解決済

1回答

1495閲覧

C言語 配列ポインタ型の引数と同名の配列を関数内で再定義することについて

qazwsx_0000

総合スコア6

C

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

ポインタ

ポインタはアドレスを用いてメモリに格納された値を"参照する"変数です。

再帰

情報工学における再帰とは、プログラムのあるメソッドの処理上で自身のメソッドが再び呼び出されている処理の事をいいます。

0グッド

0クリップ

投稿2020/01/20 17:21

前提・実現したいこと

 C言語初心者です。
ポインタと再帰の勉強のため、配列ポインタを引数として受け取り、同名の配列を関数内で定義して引数の配列をコピーしてその配列の先頭のポインタを表示した後再びその関数を呼び出すvoid operator()関数を作成しました(コード1)。引数の配列ポインタ名と同名の配列を関数内で再定義していますが、プログラムはエラーなく動作して配列のポインタを返します(結果1)。
しかしこのコードを改変して、配列ポインタを引数として受け取り関数内で同名の配列を定義してポインタを返すコード(コード2)を実行すると
redefinition of 'result' with a different type: 'int [20]' vs 'int *' int result[20];
とエラーがでます。引数名と同じ変数名を同じ関数内で定義しているのでエラーがでるのは納得できるのですが、なぜコード1はエラーを返さず動作するのでしょうか?

(コード1)
#include <stdio.h>

void operator(int result[],int n)
{
if(n>0){
int result[5];
for(int i=0;i<5;i++) result[i]=result[i];
printf("result:%p\n",result);
n--;
operator(result,n);
}

}

int main(void){
int result[5];
int i;
for(i=0;i<5;i++){result[i]=0;}
operator(result,10);
return 0;

}

(結果1)
result:0x7ffdd0abb830
result:0x7ffdd0abb800
result:0x7ffdd0abb7d0
result:0x7ffdd0abb7a0
result:0x7ffdd0abb770
result:0x7ffdd0abb740
result:0x7ffdd0abb710
result:0x7ffdd0abb6e0
result:0x7ffdd0abb6b0
result:0x7ffdd0abb680

(コード2)
#include <stdio.h>

void operator(int result[])
{

int result[5]; for(int i=0;i<5;i++) result[i]=result[i]; printf("result:%p\n",result);

}

int main(void){
int result[5];
int i;
for(i=0;i<5;i++){result[i]=0;}
operator(result);
return 0;

}

(コード2に対するエラーメッセージ)
Main.c:6:9: error: redefinition of 'result' with a different type: 'int [5]' vs 'int *'
int result[5];
^
Main.c:3:19: note: previous definition is here
void operator(int result[])
^
1 error generated.

実行環境はpaiza ioというオンライン実行環境です。
よろしくお願いいたします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

スコープが違います.

コード1の int result[5] は if の {} の中にあります.
ですので, この {} 内に限り result という名前の変数は全てこの宣言の変数となり, パラメータの result は見えなくなります.
従いまして, for で行っているのは パラメータからのコピーではありません.

投稿2020/01/20 18:15

編集2020/01/20 19:16
jimbe

総合スコア12646

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

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

rubato6809

2020/01/21 03:33

> for で行っているのは パラメータからのコピーではありません その if 文中に割り当てた配列から読みだした値を、まだ同じ場所に書き戻している格好なので、何も変化しない・無意味な処理になっています。従って最適化を深くかけると for 文ごと無視されて、何もコードが生成されない可能性があります。 おそらくここが質問者にとって重大な誤解になっていると思います。
qazwsx_0000

2020/01/21 14:04

条件文のスコープを理解していませんでした。 回答ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問