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

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

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

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

プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

Q&A

解決済

2回答

1707閲覧

配列のポインタ渡しで苦戦しています

L4zy

総合スコア18

C

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

プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

0グッド

1クリップ

投稿2020/04/28 03:04

10までの素数を求めたくて、関数sqrSosuで配列sosu[]に代入しているつもりなのですが、
printf("%d\n", sosu[i]);が(0のため)出力されません。
配列では、ポインタは渡せないのでしょうか?

C

1#include <stdio.h> 2#include <math.h> 3 4void sqrSosu(int sqr, int num[], int *sosu[]); 5// 1から100までの素数を表示する関数 引数:なし 戻り値:0 6int main() 7{ 8 double number = 100; 9 int num[100] = {1}; 10 int sosu[100] = {}; 11 12 // 素数を求める 13 sqrSosu((int)sqrt(number), num, &sosu); 14 15 16for(int i = 2; sosu[i] != 0; i++) 17{ 18 printf("%d\n", sosu[i]); 19} 20 21 return 0; 22} 23 24// 平方根以下の素数を代入する関数 引数:平方根、1から100までの配列、素数配列 戻り値:なし 25void sqrSosu(int sqr, int num[], int *sosu[]) 26{ 27 int i; 28 for(i = 2; i < sqr; i++) 29 { 30 for(int j = 3; j < sqr; j++) 31 { 32 // i以外のiの倍数だったら素数ではない 33 if(j % i == 0) num[j] = 0; 34 } 35 } 36 for(i = 2; i < sqr; i++) 37 { 38 // 素数だったら 39 if(num[i] == 1) *sosu[i] = i; 40 } 41}

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

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

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

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

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

guest

回答2

0

ベストアンサー

C言語では、配列名そのものが要素0番目へのポインタ=配列自身へのポインタになります。

どういうことかというと、

c

1int arr[4] = {1, 2, 3}; 2 3printf("%d %d\n", arr[1], *(arr + 1)); // → 2 2

つまり、arr&arr[0] は同じ意味で、*arrarr[0] は同じ意味になります。
宣言は配列ですが、arr が(*arr と宣言していないけれども)ポインタとして振る舞っていることに注目してください。

このことを使うと、次のような記述が許されることになります。

c

1// arr は上記のまま 2int *ap = arr; 3 4printf("%d %d\n", ap[1], ap[2]); // → 2 3

ここまで理解したら、本題です。

上記 *ap = arr を参照してください。
int 配列へのポインタを格納するには、int * で事足ります。

そこで、プロトタイプ宣言はこのようになります。

c

1void sqrSosu(int sqr, int num[], int *sosu);

呼び出しのときには、int * を渡してあげればいいわけですから、

c

1sqrSosu((int)sqrt(number), num, sosu);

と呼びます。あとは、sosuint * であることを踏まえて、sqrSosu 関数内の処理を書き換えてみてください。

通常変数を扱うときと配列を扱うときでポインタ関係の表記が異なるのが C言語のやっかいなところですが、ソースを見る限りポインタの理解は合っているように見受けられます。
あとは配列独特の表記を覚えるだけです。頑張ってください。

投稿2020/04/28 03:50

plageoj

総合スコア65

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

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

L4zy

2020/04/28 04:17

大変分かりやすい回答ありがとうございます。 ですが、mainの方だと、値が0のまま変わっていません。
plageoj

2020/04/28 04:30

書き換えた後の `sqrSosu` 関数はどのようになっていますか?
episteme

2020/04/28 04:34

件の問題とは別のバグが潜んでいるからでしょう。
L4zy

2020/04/28 04:48

void sqrSosu(int sqr, int num[], int *sosu) { int i; for(i = 2; i < sqr; i++) { for(int j = 3; j < sqr; j++) { // i以外のiの倍数だったら素数ではない if(j % i == 0) num[j] = 0; } } for(i = 2; i < sqr; i++) { // 素数だったら if(num[i] == 1) sosu[i] = i; } } 何がいけないのか、考えても全然分かりませんでした。
L4zy

2020/04/28 05:02

解決しました。ありがとうございました。
guest

0

int *sosu[]

では、ポインタの配列になってますよ。
*が余計なのでは

投稿2020/04/28 03:08

y_waiwai

総合スコア88042

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問