gpt4 book ai didi

c - 在C中是否需要对char指针地址进行初始化?

转载 作者:太空狗 更新时间:2023-10-29 15:52:35 25 4
gpt4 key购买 nike

我在自学C编程。我知道数字指针地址必须始终初始化,无论是静态的还是动态的。
然而,我还没有读到初始化字符指针地址的必要性。
例如,这段代码是正确的,还是需要指针地址初始化?

char *p_message;
*p_message = "Pointer";

最佳答案

我不太清楚“数字指针”和“字符指针”是什么意思。在c中,achar是整数类型,因此它是算术类型。在任何情况下,指针都不需要初始化,不管它是否指向char
您的代码错误地使用*p_message而不是p_message来设置指针的值:

*p_message = "Pointer"          // Error!

这是错误的,因为考虑到 p_message是指向 char的指针, *p_message应该是 char而不是整个字符串。但就第一次声明时初始化 char指针的需要而言,这不是必需的。所以这没关系:
char *p_message;
p_message = "Pointer";

我猜你的部分困惑是因为这是不合法的:
char *p_message;
*p_message = 'A';

但是,这与指针是否正确初始化无关。即使是初始化,也会失败:
char *p_message = 'A'; 

这是错误的,原因与 int *a = 5;是错误的相同。那为什么是错的?为什么这样做:
char *p_message;
p_message = "Pointer";

但这次失败了?
char *p_message;
*p_message = 'A';

这是因为没有为 'A'分配内存。当您有 p_message = "Pointer"时,您将 p_message分配给字符串文本 'P'的第一个字符 "Pointer"的地址。字符串文本存在于不同的内存段中,它们被认为是不可变的,不需要在堆栈或堆上专门为它们分配内存。
但是需要在堆栈或堆上分配 chars,比如 ints。您需要声明一个 char变量以便堆栈上有内存:
char myChar;
char *pChar;
pChar = &myChar;
*pChar = 'A';

或者需要在堆上动态分配内存:
char* pChar;
pChar = malloc (1); // or pChar = malloc (sizeof (char)), but sizeof(char) is always 1
*pChar = 'A';

因此,在某种意义上, char指针不同于 intdouble指针,因为它们可以用来指向字符串文本,而不必在堆栈(静态)或堆(动态)上分配内存。我想这可能是你的实际问题,与内存分配而不是初始化有关。
如果您真正询问的是初始化而不是内存分配:指针变量在初始化方面与任何其他变量没有区别。正如未初始化的 int变量在初始化前会有一些垃圾值一样,指针在初始化前也会有一些垃圾值。如您所知,您可以声明一个变量:
double someVal;    // no initialization, will contain garbage value

在代码的后面有一个设置其值的赋值:
someVal = 3.14;

类似地,使用指针变量,可以有如下内容:
int ary [] = { 1, 2, 3, 4, 5 };
int *ptr; // no initialization, will contain garbage value
ptr = ary;

这里, ptr没有初始化为任何内容,但稍后会被分配给数组的第一个元素的地址。
有些人可能会说,初始化指针总是很好的,至少是初始化到 NULL,因为在给指针分配任何实际(非垃圾)值之前,您可能会无意中尝试取消对指针的引用,而取消对垃圾地址的引用可能会导致程序崩溃,或者更糟,可能会损坏内存。但这与声明变量时总是将变量初始化为零的警告并没有太大区别。如果您的代码在按预期设置变量值之前错误地使用了某个变量,那么我不确定该值是0、 int还是垃圾值有多重要。
编辑。op在评论中问道:您说“字符串文本存在于不同的内存段中,它们被认为是不可变的,并且它们的内存不需要在堆栈或堆上专门分配”,那么如何分配呢?
这就是语言的工作原理。在C语言中,字符串文字是语言的一个元素。C11标准在第6.4.5节中规定,当编译器将源代码翻译为机器语言时,它应将双引号中的任何字符序列转换为 NULL的静态数组(如果它们是宽字符,则转换为 char),并附加一个 wchar_t字符作为数组的最后一个元素。这个数组被认为是不可变的。标准规定: NUL
所以基本上,当你有这样的陈述时:
char *p_message = "Pointer";

标准要求将双引号字符序列 If the program attempts to modify such an array, the behavior is undefined.实现为内存中某个位置的以 "Pointer"结尾的静态、不可变数组。通常,实现会将此类字符串文本放在内存的只读区域中,例如文本块(以及程序指令)。但这不是必需的。给定实现处理此数组/ NUL终止的 char/string文本序列的内存分配的确切方式取决于特定的编译器。但是,因为这个数组存在于内存中的某个地方,所以可以有指向它的指针,所以上面的语句确实是合法工作的。
类似于函数指针可能有用。正如函数的代码存在于内存中的某个指令序列中,并且可以有一个指向该代码的函数指针,但不能更改函数代码本身,因此字符串内存也存在于 NUL的序列中,并且可以有指向该字符串的 char指针,但不能更改字符串文本本身。
C标准仅为字符串文本指定此行为,而不是为字符常量(如 char或整数常量(如 char)指定此行为。留出内存来保存这些常量/非字符串文本是程序员的责任。所以当编译器遇到如下语句时:
char *charPtr = 'A';    // illegal!
int *intPtr = 5; // illegal!

编译器不知道如何处理它们。程序员没有在堆栈或堆中留出这样的内存来保存这些值。与字符串文本不同,编译器也不会为它们预留任何内存。所以这些声明是非法的。
希望这更清楚。如果没有,请再次评论,我会尽量澄清一些。

关于c - 在C中是否需要对char指针地址进行初始化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18560060/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com