これは、Yashavant P. Kanetkar のLet Us "C"の第 9 章から取られたもので、以前に行ったことがうまくいかなかった理由を明確にする必要があります。
文字の 2 次元配列を使用している場合、配列を宣言する場所で文字列を初期化するか、または scanf( ) 関数を使用して文字列を受け取ることができます。ただし、文字列へのポインターの配列を使用している場合、配列を宣言している場所で文字列を初期化できますが、scanf( ) を使用してキーボードから文字列を受け取ることはできません。したがって、次のプログラムは決してうまくいきません。
main( )
{
char *names[6] ;
int i ;
for ( i = 0 ; i <= 5 ; i++ )
{
printf ( "\nEnter name " ) ;
scanf ( "%s", names[i] ) ;
}
}
プログラムが機能しない理由は次のとおりです。配列を宣言するときに、ガベージ値が含まれています。これらのガベージ値を、キーボードから受信した文字列を保持するアドレスとして scanf( ) に送信するのは間違いです。解決方法 scanf( ) を使用してキーボードから文字列を受け取り、それらのアドレスを文字列へのポインターの配列に格納することにこだわる場合は、以下に示すように、少しラウンド アバウトな方法で行うことができます。
#include "alloc.h"
main( )
352 Let Us C
{
char *names[6] ;
char n[50] ;
int len, i ;
char *p ;
for ( i = 0 ; i <= 5 ; i++ )
{
printf ( "\nEnter name " ) ;
scanf ( "%s", n ) ;
len = strlen ( n ) ;
p = malloc ( len + 1 ) ;
strcpy ( p, n ) ;
names[i] = p ;
}
for ( i = 0 ; i <= 5 ; i++ )
printf ( "\n%s", names[i] ) ;
}
ここでは、最初に文字列 n[ ] で scanf( ) を使用して名前を受け取りました。次に、strlen( ) を使用してその長さを調べ、この名前のコピーを作成するためのスペースを割り当てました。このメモリ割り当ては、malloc( ) と呼ばれる標準ライブラリ関数を使用して行われています。この関数は、割り当てられるバイト数を必要とし、割り当てたメモリ チャンクのベース アドレスを返します。この関数によって返されるアドレスは、常に void * 型です。したがって、型キャストと呼ばれる機能を使用して char * に変換されています。型キャストについては、第 15 章で詳しく説明します。この関数のプロトタイプは、ファイル 'alloc.h' で宣言されています。したがって、このファイルを #include しました。しかし、なぜ配列を使用してメモリを割り当てなかったのでしょうか? これは、配列の場合、プログラムの作成時に配列のサイズにコミットする必要があるためです。さらに、プログラムの実行中に配列サイズを増減する方法はありません。つまり、配列を使用すると、静的メモリ割り当てが行われます。これとは異なり、malloc( ) を使用すると、実行中にメモリを動的に割り当てることができます。malloc( ) に渡す引数は、実行中に値が変化する変数にすることができます。malloc( ) を使用してメモリを割り当てたら、キーボードから受け取った名前をこの割り当てられたスペースにコピーし、最後に割り当てられたチャンクのアドレスを、文字列へのポインターの配列である names[ ] の適切な要素に格納しました。このソリューションは、メモリを割り当ててからコピーする必要があるため、パフォーマンスが低下します 配列を使用すると、静的メモリ割り当てが行われます。これとは異なり、malloc( ) を使用すると、実行中にメモリを動的に割り当てることができます。malloc( ) に渡す引数は、実行中に値が変化する変数にすることができます。malloc( ) を使用してメモリを割り当てたら、キーボードから受け取った名前をこの割り当てられたスペースにコピーし、最後に割り当てられたチャンクのアドレスを、文字列へのポインターの配列である names[ ] の適切な要素に格納しました。このソリューションは、メモリを割り当ててからコピーする必要があるため、パフォーマンスが低下します 配列を使用すると、静的メモリ割り当てが行われます。これとは異なり、malloc( ) を使用すると、実行中にメモリを動的に割り当てることができます。malloc( ) に渡す引数は、実行中に値が変化する変数にすることができます。malloc( ) を使用してメモリを割り当てたら、キーボードから受け取った名前をこの割り当てられたスペースにコピーし、最後に割り当てられたチャンクのアドレスを、文字列へのポインターの配列である names[ ] の適切な要素に格納しました。このソリューションは、メモリを割り当ててからコピーする必要があるため、パフォーマンスが低下します malloc( ) に渡す引数は、実行中に値が変化する変数にすることができます。malloc( ) を使用してメモリを割り当てたら、キーボードから受け取った名前をこの割り当てられたスペースにコピーし、最後に割り当てられたチャンクのアドレスを、文字列へのポインターの配列である names[ ] の適切な要素に格納しました。このソリューションは、メモリを割り当ててからコピーする必要があるため、パフォーマンスが低下します malloc( ) に渡す引数は、実行中に値が変化する変数にすることができます。malloc( ) を使用してメモリを割り当てたら、キーボードから受け取った名前をこの割り当てられたスペースにコピーし、最後に割り当てられたチャンクのアドレスを、文字列へのポインターの配列である names[ ] の適切な要素に格納しました。このソリューションは、メモリを割り当ててからコピーする必要があるため、パフォーマンスが低下します