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

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

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

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

Q&A

3回答

639閲覧

関数がアドレスを要求しているのにポインタを実引数として与えたら実行されるのはなぜか?

yuuuuuu_1216

総合スコア1

C

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

0グッド

0クリップ

投稿2022/10/30 06:59

編集2022/10/30 13:42

実現したいこと

配列aとbに共通して含まれる文字列をすべて表示するプログラムを作成しています.

発生している問題・エラーメッセージ

プログラムはうまく作動するのですが、関数はアドレスを要求しているのにポインタ渡しても動くんですか?
int compare(char p[], char q[]){→暗黙の型変換によりint compare(char *p, char *q){となり宣言時にはアドレスとなっているので関数の仮引数はアドレスを要求しており、char a[NUMBER_A][8] = {"red", "green", "blue"}; char b[NUMBER_B][8] = {"green", "yellow", "red", "purple"};と配列で宣言しているのでこの宣言以外では配列名を使うとそれはアドレスを示していてつまり配列名を実引数とすればいいのでは?と今頭の中で解釈しているんですが、それは違うんですか?

該当のソースコード

C

1#include <stdio.h> 2#define NUMBER_A 3 3#define NUMBER_B 4 4 5int compare(char p[], char q[]){ 6while (*p != '\0' || *q != '\0'){ 7 if (*p++ != *q++) 8 return 0; 9 } 10 return 1; 11} 12 13int main(void) 14{ 15 char a[NUMBER_A][8] = {"red", "green", "blue"}; 16 char b[NUMBER_B][8] = {"green", "yellow", "red", "purple"}; 17 for (int i = 0; i < NUMBER_A; i++){ 18 for (int j = 0; j < NUMBER_B; j++){ 19 if (compare(*(a + i),*(b + j)) == 1) 20 printf("%s\n",*(a + i)); 21 } 22 } 23 24 25 26 return 0; 27}

試したこと

ある学校の問題でif (compare(①,②) == ③),printf("%s\n",①);と空白を埋める問題でもともとアドレスを要求しているしていると思って(a + i)と(b + j)と空白を埋めて実行したのですがエラーが出てしまってもしかしたら二次元配列だから型がちがうのかなーと思って質問しています.

補足情報(FW/ツールのバージョンなど)

gdbオンラインで実行しています.

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

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

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

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

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

yuuuuuu_1216

2022/10/30 07:16

int compare(char p[], char q[]){→暗黙の型変換によりint compare(char *p, char *q){となり宣言時にはアドレスとなっているので関数の仮引数はアドレスを要求しており、char a[NUMBER_A][8] = {"red", "green", "blue"}; char b[NUMBER_B][8] = {"green", "yellow", "red", "purple"};と配列で宣言しているのでこの宣言以外では配列名を使うとそれはアドレスを示していてつまり配列名を実引数とすればいいのでは?と今頭の中で解釈しているんですが、それは違うんですか?
jimbe

2022/10/30 09:14

質問に対する追記は、質問本文を修正されたほうが良いと思います。
thkana

2022/10/30 11:03

> エラーが出てしまって動かなくて もしかしてC++としてコンパイルしているとか? (それが悪いとはいいませんが、もしそうならそうしていることは認識していたほうがよいかと思います) Cとしては、特に警告をエラーにするようなオプションを指定していなければ、「警告」にはなりますが動作するはずです。
guest

回答3

0

まず、エラーメッセージを読み、それを理解しましょう。

プログラムはうまく作動するのですが、関数はアドレスを要求しているのにポインタ渡しても動くんですか?

アドレスを格納している変数をポインタと呼びます

投稿2022/10/30 07:04

y_waiwai

総合スコア87719

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

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

0

すでに指摘がありますが、ポインタはアドレスを値として持つ変数です。アドレスを要求しているところにポインタを与えるのは正しいことです...が、ポインタはまた指す先の型の情報をも持っていますから、型が一致するためにはそちらの型もあっていなければいけません。

char a[NUMBER_A][8]; と宣言したとき、aが単独で記述れるとchar (*)[8]型、char8要素の配列へのポインタと解釈されます。これを、char*型を期待しているところに与えれば、型が異なりますからCはポインタ型の違いに鷹揚なので警告なるだけかも知れません(警告も出ないかも知れない)し、C++では型に厳密なのでエラーになります。(a+i)としても型は変わらないので話は一緒。
これを*a (あるいは*(a+i) )としたならば、aはchar8要素の配列へのポインタでしたからその参照しているも、つまりchar8要素の配列となり、値が配列そのものですからこれは配列の先頭要素へのポインタつまり&a[0][0](あるいは&a[i][0])という解釈され、つまりchar*型ですから期待される引数と型が一致します。

もちろん、char8要素の配列の格納されているアドレス(a+i)とchar8要素の配列の先頭要素が格納されているアドレス*(a+i)は結局同じアドレスを指しますから、エラーにさえならなければ動作はどちらでも変わらない、ということにはなります。

投稿2022/10/30 11:29

thkana

総合スコア7610

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

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

0

#include <stdio.h> #define NUMBER_A 3 #define NUMBER_B 4 int compare(char p[], char q[]){ while (*p != '\0' || *q != '\0'){ if (*p++ != *q++) return 0; } return 1; } int main(void) { char a[NUMBER_A][8] = {"red", "green", "blue"}; char b[NUMBER_B][8] = {"green", "yellow", "red", "purple"}; for (int i = 0; i < NUMBER_A; i++){ for (int j = 0; j < NUMBER_B; j++){ if ( compare(a[i], b[j]) == 1 ) // char a[][] なんだから a[] は char[] (bも同様) printf("a[%d] == b[%d] : %s\n",i, j, a[i]); } } return 0; }

投稿2022/10/30 07:37

episteme

総合スコア16614

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問