ページ 11

ポインタについて

Posted: 2016年4月21日(木) 23:32
by kloud

コード:

#include "stdio.h"

void Input ( int* );
void Output ( int* );

void main ( void )
{
	int eData [20];
	
	Input ( &eData [0] ); 
	Output ( &eData [0] );
	
	rewind ( stdin );
	getchar ();
}

void Input ( int* pData )
{
	for ( int nCount = 0; nCount < 20; nCount++ )
	{
		scanf ( "%d" , &pData [nCount] );
	}
}

void Output ( int* pData )
{
	for ( int nCount = 0; nCount < 20; nCount++ )
	{
	    printf ( "nData[%d] : %d \n" , nCount , pData [nCount] );
	}
}

///////////////   EOF   ///////////////

ポインタの学習として、「scanfで数字を入力させ、それをeData[20]の配列に入れて出力させる」というプログラムを作っています。
プログラム結果は大丈夫なのですが、プログラムの書き方としては合っているのでしょうか?
また、どこがダメなのか教えてください。
よろしくお願いします。

Re: ポインタについて

Posted: 2016年4月21日(木) 23:38
by box
kloud さんが書きました:

コード:

#include "stdio.h"
ここは、ふつう

コード:

#include <stdio.h>
と書くんでしょうね。なぜなら、stdio.hは処理系が標準で用意しているヘッダーだから。
kloud さんが書きました:

コード:

	Input ( &eData [0] ); 
	Output ( &eData [0] );
単に

コード:

	Input (eData); 
	Output (eData);
で十分なはずです。なぜなら、配列名は、当該の配列の先頭要素へのポインターと同義だから。
kloud さんが書きました:

コード:

	rewind ( stdin );
まあこれはなくてもいいのかな、と。

Re: ポインタについて

Posted: 2016年4月22日(金) 00:01
by みけCAT
scanfの戻り値を無視している、すなわち入力をきちんと読み込めたかを確認していないのはよくないですね。
box さんが書きました:なぜなら、配列名は、当該の配列の先頭要素へのポインターと同義だから。
配列名は、当該の配列の先頭要素へのポインターと同義ではありません。
単項&演算子やsizeof演算子のオペランドなどの例外を除いて、式中で用いられる配列はその配列の先頭要素へのポインタに変換されます。

N1570 6.3.2.1 Lvalues, arrays, and function designatorsより引用
3 Except when it is the operand of the sizeof operator, the _Alignof operator, or the
unary & operator, or is a string literal used to initialize an array, an expression that has
type ‘‘array of type’’ is converted to an expression with type ‘‘pointer to type’’ that points
to the initial element of the array object and is not an lvalue. If the array object has
register storage class, the behavior is undefined.
box さんが書きました:
kloud さんが書きました:

コード:

	rewind ( stdin );
まあこれはなくてもいいのかな、と。
これがなくていいとすれば、その下のgetchar();もなくていいでしょう。

この2行が欲しいと感じるのは、IDEなどから実行していて終了した直後に実行結果が消える状況であると考えられるので、
そのような場合に入力がリダイレクトで与えられるとか考えにくいです。
そうすると、入力はキーボードを通して行われ、典型的には数字を入力した後Enterキーでバッファからプログラムに入力を渡すでしょう。
すると、入力された改行コードが取り込まれるため、getchar();単体で実行結果が消えるのを防ぐことはできません。

終了後に実行結果が消えるのを防ぐ機能が付いたIDEおよびその機能をつかうか、端末ソフトウェアから実行すればこの2行は必要ないでしょう。

Re: ポインタについて

Posted: 2016年4月24日(日) 00:27
by kloud

コード:

#include <stdio.h>

void Input ( int* );
void Output ( int* );

void main ( void )
{
	int eData [20];

	Input ( eData );
	Output ( eData );
}

void Input ( int* pData )
{
	for ( int nCount = 0; nCount < 5; nCount++ )
	{
		scanf ( "%d" , &pData [nCount] );
	}
}

void Output ( int* pData )
{
	for ( int nCount = 0; nCount < 5; nCount++ )
	{
	    printf ( "nData[%d] : %d \n" , nCount , pData [nCount] );
	}
}

///////////////   EOF   ///////////////

解答ありがとうございます。非常に勉強になりました。

Re: ポインタについて

Posted: 2016年4月24日(日) 08:20
by box
みけCAT さんが書きました: 配列名は、当該の配列の先頭要素へのポインターと同義ではありません。
単項&演算子やsizeof演算子のオペランドなどの例外を除いて、式中で用いられる[/b]配列はその配列の先頭要素へのポインタに変換されます。
いちいち細かいね、ホント。

そんだけ細かいのに、main関数の型がvoidになっていることを
突っ込まないのはなぜだ?