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

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

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

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

ポインタ

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

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

5回答

4055閲覧

ポインタ配列を引数にとる関数について

退会済みユーザー

退会済みユーザー

総合スコア0

C

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

ポインタ

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

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

0クリップ

投稿2020/03/21 08:19

編集2020/03/21 08:48

C言語初学者です。このような場で質問するのは恐れ多いですが、させていただきます。

以下のコードはコンパイル、実行できました。

C

1#include <stdio.h> 2 3int main() 4{ 5 char* a[] = {"cat"}; 6 printf("%s",*a); 7 return 0; 8}

しかし、以下のコードはコンパイルできませんでした。

C

1#include <stdio.h> 2 3void print(char* a[]) 4{ 5 printf("%s",*a); 6} 7 8int main() 9{ 10 print({"cat"}); 11 return 0; 12}

複数の文字列を渡し、それらを出力する関数はどうしたら作れるのでしょうか?

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

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

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

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

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

guest

回答5

0

関連するルールを挙げるとすると

  • 配列は一部の例外を除いて配列の先頭要素を指すポインタに暗黙に型変換される
  • 関数の仮引数に配列形式で書くとその配列の要素の型を指すポインタ型に調整される (char* a[]char** a と書くのと全く同じに解釈される。 ちなみに char* a[10] などといったように配列の大きさを書いても無視されてポインタに調整されます)
  • 配列の大きさは型の一部である (配列型がポインタに型変換されると大きさの情報は脱落してしまう)
  • 配列に & を適用すると「配列の先頭要素を指すポインタ」ではなく「配列を指すポインタ (配列の大きさの情報を保持するポインタ)」を作れる
  • 配列のリテラルをそのまま関数に渡したいのであればコンパウンドリテラルを使える

といったものがあります。

これらを踏まえればこのように書けなくもないです。

#include <stdio.h> void print(const char* (*a)[3]) { for(size_t i=0; i<sizeof(*a)/sizeof(**a); ++i) printf("%s\n",(*a)[i]); } int main(void) { print(&(const char*[3]){"cat", "dog", "penguin"}); return 0; }

ただ、このようなデザインにはすることはあまりないと思います。

  • 受け取る側 (この場合は print 関数) も配列の大きさを明示しなければならない (様々な場合を処理しづらい)
  • 文法がややこしい! (たぶん初心者が見ても何が何やらよくわからないでしょう)
  • コンパウンドリテラルは C++ には無い文法なので後に C++ に移行することがあったら面倒くさいかも?

otn さんの案が C では最も定番 (常識的) な書き方だと思います。

投稿2020/03/21 11:48

SaitoAtsushi

総合スコア5684

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

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

otn

2020/03/21 12:05

> コンパウンドリテラルを使える これは知りませんでした。
退会済みユーザー

退会済みユーザー

2020/03/22 19:23

ご回答ありがとうございました。遅れましたが、お礼申し上げます。ベストアンサーが1つしか選べないのが残念で仕方ありません。
guest

0

ベストアンサー

{ }は初期化の時だけ使えます。
・配列のサイズは、呼び出した関数には伝わらないので、サイズを別途渡す必要があります。
・別の方法としては、終わりの目印を付けておく方法もあります。文字列はcharの配列ですが0を終わりの目印にしています。

案1:サイズを別途渡す。

C

1#include <stdio.h> 2 3void print(char *a[], int size) 4{ 5 int i; 6 for(i=0; i<size; i++){ 7 printf("%s\n",a[i]); 8 } 9} 10 11int main() 12{ 13 char *list[] = {"cat", "dog", "mouse"}; 14 print(list,3); 15/* print(list,sizeof list/sizeof list[0]); と、数を明示せずに書くことも出来る */ 16 return 0; 17}

案2:終わりの目印としてNULLを付ける。

C

1#include <stdio.h> 2 3void print(char *a[]) 4{ 5 int i; 6 for(i=0; a[i]; i++){ 7 printf("%s\n",a[i]); 8 } 9} 10 11int main() 12{ 13 char *list[] = {"cat", "dog", "mouse", NULL}; 14 print(list); 15 return 0; 16}

投稿2020/03/21 09:33

otn

総合スコア85901

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

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

退会済みユーザー

退会済みユーザー

2020/03/22 19:21

ご回答ありがとうございました。遅れましたが、お礼申し上げます。
guest

0

printf関数には、複数の文字列を保有する配列からその要素すべてを出力する機能はありません。なので、面倒ですがループを利用して1要素ずつprintf関数で順に出力する必要があります。

問題は、関数の内部で、要素数をどのように取得するかです。というのも、関数に渡されるのは配列の先頭アドレスのみで、要素数は自動的には渡されないからです。方法は2つありまして、1つ目は要素数を別の引数として渡す方法、もう1つは配列の最後にヌルポインタ(番兵)を置く方法です。番兵方式の場合、番兵を置き忘れると暴走するというデメリットがあるので、1つ目の方式が優れていると個人的には考えています。

投稿2020/03/21 08:57

majiponi

総合スコア1722

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

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

退会済みユーザー

退会済みユーザー

2020/03/22 19:20

ご回答ありがとうございました。遅れましたが、お礼申し上げます。
guest

0

{"cat"}の記法は、初期化専用なので、引数に書いたり、ふつうの式の途中に書いたりすることはできません。

投稿2020/03/21 08:25

maisumakun

総合スコア146018

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

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

退会済みユーザー

退会済みユーザー

2020/03/22 19:20

ご回答ありがとうございました。遅れましたが、お礼申し上げます。
guest

0

print({"cat"});

引数は配列になってません

んでついでに言うと、

void print(char* a[])

引数は、charの配列、のアドレス、です。

投稿2020/03/21 08:24

編集2020/03/21 08:29
y_waiwai

総合スコア88042

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

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

otn

2020/03/21 09:35

> 引数は、charの配列、のアドレス、です。 *より[]の方が結合優先度が高いので、「charへのポインタ」の配列です。
退会済みユーザー

退会済みユーザー

2020/03/22 19:19

ご回答ありがとうございました。遅れましたが、お礼申し上げます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問