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

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

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

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

ポインタ

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

配列

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

Q&A

解決済

4回答

4588閲覧

C言語 ポインタと配列に関する質問です

yusukee345

総合スコア31

C

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

ポインタ

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

配列

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

0グッド

1クリップ

投稿2016/10/20 14:03

###質問したいこと
「発生した乱数:
1 5 2 8 9
2倍した値:
2 10 4 16 18」

というような実行結果を得たい。長さ5の整数型の配列変数aに、すべての成分に0から100の乱数の値を代入して表示し、以下の条件を満たす数値を表示するプログラムを作りなさい。
(1) 5つの整数の値は、グローバル変数ではない配列変数に入れること
(2) 配列への値の表示、値の二倍は、それぞれ専用の関数を用いること。
(3) 専用の関数の引数として、整数型ポインタをを用いること。(問題文ここまで)

という問題に取り組んでいます。
以下のようなソースコードで書いてvisualstudio2013で実行したのですが望む通りの実行結果が得られません。
###発生している問題・エラーメッセージ
コンパイルは成功します。実行時、画面に表示されるのは
「発生した乱数:
2倍した数:」
だけです。printfにポインタpが格納されてないか、関数を呼び出せていないかだと思います。
更に実行するとエラーメッセージが出て、「Run-Time Check Failure#2-Stack around the variable 'a' was corrupted.」と表示されデバックを中断せざるを得なくなります。

###該当のソースコード
#include<stdio.h>
#include<stdlib.h>
#include<time.h>

void show(int*);
void two(int*);//どちらの関数もアドレスの形を引数にとる

void main(){
int a[5];
int i;
int* p = NULL;
p = a; //pにaのアドレスを代入
srand((unsigned)time(NULL));
printf("発生した乱数:");
for (i = 0; i < 5; i++){
*p = rand() % 101;
void show(p);//発生した乱数をshow関数を用いて表示(pをアドレスの形で引数にする)
p++;
}
printf("\n2倍した値:");
for (i = 0; i < 5; i++){
*p = rand() % 101;
void show(p);//発生した乱数を2倍したものをtwo関数を用いて表示(pをアドレスの形で引数にする)
p++;
}
printf("\n");
getchar();
}

void show(int *n){
printf("%d ", *n);//ポインタnが示す数値を表示
}

void two(int *m){
printf("%d ", (*m) * 2);//ポインタmが示す数値を2倍したものを表示
}

###試したこと
関数の引数を入れる場所をアドレスではなく値型にした( void show(int) というプロトタイプで引数を代入する時は void show(p) とした)が「」の場所に「型指定子が必要です」と出てエラーになる。

###補足情報(言語/FW/ツール等のバージョンなど)
C言語
コンパイラはVisualStudio2013

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

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

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

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

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

guest

回答4

0

mainでaを参照するのにわざわざアドレス参照する必要はないと思います。
普通に配列を使えばよろしいかと。
ただこれは問題ではなく、問題点はshowの呼び方と、twoを呼んでいないことと、2倍にする前にまた乱数で初期化してしまっていることですね。
ということを踏まえて修正したのが以下です。

c

1#include <stdio.h> 2#include <time.h> 3void show(int*); 4void two(int*);//どちらの関数もアドレスの形を引数にとる 5 6int main(void){ 7 int a[5]; 8 int i; 9 srand((unsigned)time(NULL)); 10 printf("発生した乱数:"); 11 for (i = 0; i < 5; i++){ 12 a[i] = rand() % 101; 13 show(&a[i]);//発生した乱数をshow関数を用いて表示(pをアドレスの形で引数にする) 14 } 15 printf("\n2倍した値:"); 16 for (i = 0; i < 5; i++){ 17 two(&a[i]);//発生した乱数を2倍したものをtwo関数を用いて表示(pをアドレスの形で引数にする) 18 } 19 printf("\n"); 20 getchar(); 21 22 return 0; 23} 24 25void show(int *n){ 26 printf("%d ", *n);//ポインタnが示す数値を表示 27} 28 29void two(int *m){ 30 printf("%d ", (*m) * 2);//ポインタmが示す数値を2倍したものを表示 31}

ただ、質問文を読むと、関数化すべきなのは「配列の値の表示」と「値の二倍」なので、答えはこうじゃないでしょうか。

c

1#include <stdio.h> 2#include <time.h> 3void show(int*,int); 4void two(int*,int); 5 6int main(void){ 7 int a[5]; 8 int i; 9 srand((unsigned)time(NULL)); 10 for (i = 0; i < sizeof(a)/sizeof(int); i++){ 11 a[i] = rand() % 101; 12 } 13 14 printf("発生した乱数:"); 15 show(a,sizeof(a)/sizeof(int)); 16 printf("\n"); 17 18 // 2倍 19 two(a,sizeof(a)/sizeof(int)); 20 21 printf("2倍した値:"); 22 show(a,sizeof(a)/sizeof(int)); 23 printf("\n"); 24 getchar(); 25 26 return 0; 27} 28 29void show(int *n, int len){ 30 int i; 31 for(i = 0; i < len; i++){ 32 printf("%d ", *n);//ポインタnが示す数値を表示 33 n++; 34 } 35} 36 37void two(int *m, int len){ 38 int i; 39 for(i = 0; i < len; i++){ 40 *m = *m * 2; 41 m++; 42 } 43} 44

投稿2016/10/21 00:08

ttyp03

総合スコア16998

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

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

0

ベストアンサー

ご参考として

c

1#include<stdio.h> 2#include<stdlib.h> 3#include<time.h> 4 5void show(int*); 6void two(int*);//どちらの関数もアドレスの形を引数にとる 7 8void main(){ 9 int a[5]; 10 int i; 11 srand((unsigned)time(NULL)); 12 printf("発生した乱数:"); 13 for (i = 0; i < 5; i++){ 14 *(a+i) = rand() % 101; 15 show(a+i);//発生した乱数をshow関数を用いて表示(pをアドレスの形で引数にする) 16 } 17 printf("\n2倍した値:"); 18 for (i = 0; i < 5; i++){ 19 two(a+i);//発生した乱数を2倍したものをtwo関数を用いて表示(pをアドレスの形で引数にする) 20 } 21 printf("\n"); 22} 23 24void show(int *n){ 25 printf("%d ", *n);//ポインタnが示す数値を表示 26} 27 28void two(int *m){ 29 printf("%d ", (*m) * 2);//ポインタmが示す数値を2倍したものを表示 30}

投稿2016/10/20 16:05

A.Ichi

総合スコア4070

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

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

yusukee345

2016/10/21 03:23

質問に答えて下さった方々ありがとうございます。皆様のアドバイスを元にこう改良したら望み通りの結果が得られました。自分では大丈夫と思ってても抜けがたくさんあり、勉強になりました。 #include<stdio.h> #include<stdlib.h> #include<time.h> void show(int*); void two(int*);//どちらの関数もアドレスの形を引数にとる void main(){ int a[5]; int i; int* p = NULL; srand((unsigned)time(NULL)); printf("発生した乱数:"); for (i = 0; i < 5; i++){ a[i] = rand() % 101; } p = a; for (i = 0; i < 5;i++){ show(p);//発生した乱数をshow関数を用いて表示(pをアドレスの形で引数にする) p++; } p = a; printf("\n2倍した値:"); for (i = 0; i < 5; i++){ two(p);//発生した乱数を2倍したものをtwo関数を用いて表示(pをアドレスの形で引数にする) p++; } printf("\n"); getchar(); } void show(int *n){ printf("%d ", *n);//ポインタnが示す数値を表示 } void two(int *m){ printf("%d ", (*m) * 2);//ポインタmが示す数値を2倍したものを表示 }
A.Ichi

2016/10/21 04:34

少しはお役に立ててよかったです。
guest

0

Pを5つ増やした後、リセットされていないですね。
関数twoも呼ばれていないような。。。

投稿2016/10/20 14:27

maiko0318

総合スコア876

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

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

0

関数の呼び出し時は
void show(p);
はなく
show(p);
で大丈夫です

投稿2016/10/20 14:16

hiim

総合スコア1689

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

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

hiim

2016/10/20 14:29

追記ですが、最初pにはaのアドレスをセットしており、またaはサイズはintの5つ分確保、 2倍した値の時には、pを初期化していないので、aの確保以降のアドレスに踏み込んでいってますね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問