这摘自 Yashavant P. Kanetkar 的Let Us "C"的第 9 章,应该澄清为什么你之前所做的没有奏效。
当我们使用二维字符数组时,我们可以自由地初始化我们声明数组的字符串,或者使用 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”中声明。因此我们有#included这个文件。但是为什么我们不使用数组来分配内存呢?这是因为对于数组,我们必须在编写程序时确定数组的大小。而且,在程序执行期间无法增加或减少数组大小。换句话说,当我们使用数组时,会发生静态内存分配。Chapter 9: Puppetting On Strings 353 与此不同的是,使用malloc()我们可以在执行期间动态分配内存。我们传递给 malloc() 的参数可以是一个变量,其值可以在执行期间改变。一旦我们使用 malloc() 分配了内存,我们就会将通过键盘接收到的名称复制到这个分配的空间中,最后将分配的块的地址存储在 names[] 的适当元素中,即指向字符串的指针数组。该解决方案在性能方面受到影响,因为我们需要分配内存然后进行复制 当我们使用数组时,会发生静态内存分配。Chapter 9: Puppetting On Strings 353 与此不同的是,使用malloc()我们可以在执行期间动态分配内存。我们传递给 malloc() 的参数可以是一个变量,其值可以在执行期间改变。一旦我们使用 malloc() 分配了内存,我们就会将通过键盘接收到的名称复制到这个分配的空间中,最后将分配的块的地址存储在 names[] 的适当元素中,即指向字符串的指针数组。该解决方案在性能方面受到影响,因为我们需要分配内存然后进行复制 当我们使用数组时,会发生静态内存分配。Chapter 9: Puppetting On Strings 353 与此不同的是,使用malloc()我们可以在执行期间动态分配内存。我们传递给 malloc() 的参数可以是一个变量,其值可以在执行期间改变。一旦我们使用 malloc() 分配了内存,我们就会将通过键盘接收到的名称复制到这个分配的空间中,最后将分配的块的地址存储在 names[] 的适当元素中,即指向字符串的指针数组。该解决方案在性能方面受到影响,因为我们需要分配内存然后进行复制 我们传递给 malloc() 的参数可以是一个变量,其值可以在执行期间改变。一旦我们使用 malloc() 分配了内存,我们就会将通过键盘接收到的名称复制到这个分配的空间中,最后将分配的块的地址存储在 names[] 的适当元素中,即指向字符串的指针数组。该解决方案在性能方面受到影响,因为我们需要分配内存然后进行复制 我们传递给 malloc() 的参数可以是一个变量,其值可以在执行期间改变。一旦我们使用 malloc() 分配了内存,我们就会将通过键盘接收到的名称复制到这个分配的空间中,最后将分配的块的地址存储在 names[] 的适当元素中,即指向字符串的指针数组。该解决方案在性能方面受到影响,因为我们需要分配内存然后进行复制