[英]Clarification of char pointers in C
我正在研究K&R第二版,第5章。
在页87,引入字符数组的指针如下:
char *pmessage;
pmessage = "Now is the time";
如何知道pmessage
是指向字符数组的指针,而不是指向单个字符的指针?
要扩展,请在第94页上定义以下函数:
/* month_name: return the name of the n-th month */
char *month_name(int n)
{
static char *name[] = {
"Illegal month",
"January", "February", "March",
...
};
return (n < 1 || n > 12) ? name[0] : name[n];
}
如果只提供了上面的函数声明,那么如何知道是返回单个字符还是字符数组?
如果假设从month_name()
返回是一个字符数组并迭代它直到遇到NULL
,但返回实际上是单个字符,那么是否有可能出现分段错误?
有人可以演示一个指向单个字符与字符数组的指针的声明和赋值,它们对函数的使用以及已经返回的标识?
所以你拥有的是一个字符串文字,它是一个具有静态存储持续时间的char数组:
"Now is the time"
在大多数情况下,数组会衰减成指向第一个元素的指针,这是在这里发生的事情:
pmessage = "Now is the time";
您需要以这样一种方式设计和记录您的界面,使您知道输入和输出的期望。 没有运行时信息来说明所指出的内容的性质。
每次调用strtok()都会返回一个指向包含下一个标记的以null结尾的字符串的指针。
因此程序员确切地知道预期的结果并相应地处理结果。
如果你有一个指向单个字符的指针而不是像C样式字符串,那么你将有未定义的行为,因为你将访问超出范围的内存。 分段错误是一种可能,但未定义仅意味着结果是不可预测的。
是什么
char *pmessage;
pmessage = "Now is the time";
意思?
char *pmessage;
表示您将pmessage
声明为char
的指针
pmessage = "Now is the time";
意味着pmessage
现在指向字符串文字的第一个字符 Now is the time
。
从函数返回pmessage
时,将返回指向字符串文字的指针。
如果您将使用%c
说明符打印pmessage
,那么它将打印N
,如果您将使用%s
打印它,那么它将打印整个字符串文字。
printf("%c\n", *N); // 'N' will be printed
printf("%s\n", N); // "Now is the time" will be printed
看起来很奇怪,C信任程序员的智慧。 如果我看到如下功能:
/* month_name: return the name of the n-th month */
char *month_name(int n)
{
static char *name[] = {
"Illegal month",
"January", "February", "March",
...
};
return (n < 1 || n > 12) ? name[0] : name[n];
}
我查看文档并读取它返回一个NUL终止的字符串,该字符串是指向静态分配的内存的指针。 这足以让我按照自己的意愿对待回报值。
如果函数的创建者将未来版本中的返回值更改为不同类型的字符串,则他们最好大声喊出它,更改函数名称,或者使其非常清楚,否则它们的行为非常糟糕。
另一方面,如果我没有正确处理返回值,即使它被正确记录,那么我也不会那么聪明,也许可能会成为一名Java开发人员。
最后,如果没有记录该功能,找到它的主人并烧毁他的房子。 1
1 如果它在库中,则会被释放 ! 一旦他们开始编写图书馆,就不要烧人的房子! ^ _ ^
如何知道pmessage是指向字符数组的指针,而不是指向单个字符的指针?
你没有。 至少,没有办法从指针值本身告诉它是指向单个char
还是char
数组的第一个元素。 它可以任何一种方式使用。
您必须依赖上下文或明确指定如何使用指针。 例如, scanf
使用不同的转换说明符来确定指针是否指向单个char
:
char single_char;
scanf( " %c", &single_char );
或char
数组:
char array_of_char[N];
scanf( "%s", &array_of_char[0] );
请记住,当它不是sizeof
或一元&
运算符的操作数或用于在声明中初始化另一个数组的字符串文字时,将转换“N元素数组T
”的表达式(“衰减”)表达式为“指向T
指针”,表达式的值将是数组第一个元素的地址,因此最后一行也可以写入
scanf( "%s", array_of_char );
由于该转换规则,无论何时将数组表达式传递给函数,函数实际接收的是指针值。 实际上,函数声明
void foo( char str[N] );
和
void foo( char str[] );
相当于
void foo( char *str );
这三个都将str
视为指向char
的指针。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.