繁体   English   中英

澄清C中的char指针

[英]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手册页,它会告诉我们:

每次调用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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM