在C中是否需要对char指针地址进行初始化? [英] Is char pointer address initialization necessary in C?

查看:100
本文介绍了在C中是否需要对char指针地址进行初始化?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在以自学成才的方式学习C编程.我知道必须始终以静态或动态方式初始化数字指针地址.

I'm learning C programming in a self-taught fashion. I know that numeric pointer addresses must always be initialized, either statically or dynamically.

但是,我还没有了解初始化char指针地址的强制性需求.

However, I haven't read about the compulsory need of initializing char pointer addresses yet.

例如,此代码是否正确,还是需要初始化指针地址?

For example, would this code be correct, or is a pointer address initialization needed?

char *p_message;
*p_message = "Pointer";

推荐答案

我不太确定数字指针"相对于字符指针"是什么意思.在C语言中, char 是整数类型,因此它是算术类型.无论如何,指针都不需要初始化,无论它是否是指向 char 的指针.

I'm not entirely sure what you mean by "numeric pointer" as opposed to "char pointer". In C, a char is an integer type, so it is an arithmetic type. In any case, initialization is not required for a pointer, regardless of whether or not it's a pointer to char.

您的代码有一个错误,它使用 * p_message 而不是 p_message 来设置指针的值:

Your code has the mistake of using *p_message instead of p_message to set the value of the pointer:

*p_message = "Pointer"          // Error!

这是错误的,因为假设 p_message 是指向 char 的指针, * p_message 应该是 char ,不是整个字符串.但是就首次声明时需要初始化 char 指针而言,这不是必需的.这样就可以了:

This wrong because given that p_message is a pointer to char, *p_message should be a char, not an entire string. But as far as the need for initializing a char pointer when first declared, it's not a requirement. So this would be fine:

char *p_message;
p_message = "Pointer";

我猜您部分困惑的原因在于这不合法:

I'm guessing part of your confusion comes from the fact that this would not be legal:

char *p_message;
*p_message = 'A';

但是,这与指针是否正确初始化无关.即使作为初始化,也会失败:

But then, that has nothing to do with whether or not the pointer was initialized correctly. Even as an initialization, this would fail:

char *p_message = 'A'; 

错误的原因与 int * a = 5; 错误的原因相同.那么,为什么会这样呢?为何起作用:

It is wrong for the same reason that int *a = 5; is wrong. So why is that wrong? Why does this work:

char *p_message;
p_message = "Pointer";

但这会失败吗?

char *p_message;
*p_message = 'A';

这是因为没有为'A'分配内存.当您具有 p_message ="Pointer" 时,您将为 p_message 分配字符串文字的第一个字符'P'的地址指针" .字符串文字生活在不同的内存段中,它们被认为是不可变的,并且不需要为它们的内存专门在堆栈或堆上分配.

It's because there is no memory allocated for the 'A'. When you have p_message = "Pointer", you are assigning p_message the address of the first character 'P' of the string literal "Pointer". String literals live in a different memory segment, they are considered immutable, and the memory for them doesn't need to be specifically allocated on the stack or the heap.

但是,像 int s这样的 char s需要在堆栈或堆上进行分配.您需要声明一个 char 变量,以便堆栈上有内存:

But chars, like ints, need to be allocated either on the stack or the heap. Either you need to declare a char variable so that there is memory on the stack:

char myChar;
char *pChar;
pChar = &myChar;
*pChar = 'A';

或者您需要在堆上动态分配内存:

Or you need to allocate memory dynamically on the heap:

char* pChar;
pChar = malloc (1); // or pChar = malloc (sizeof (char)), but sizeof(char) is always 1
*pChar = 'A';

因此,在某种意义上, char 指针与 int double 指针不同,因为它们可用于指向字符串文字,为此,您不必在堆栈上(静态地)分配内存,也不必在堆上(动态地)分配内存.我认为这可能是您的实际问题,与内存分配而不是初始化有关.

So in one sense char pointers are different from int or double pointers, in that they can be used to point to string literals, for which you don't have to allocate memory on the stack (statically) or heap (dynamically). I think this might have been your actual question, having to do with memory allocation rather than initialization.

如果您真正询问的是初始化而不是内存分配:指针变量与其他变量在初始化方面没有什么不同.正如未初始化的 int 变量在初始化之前将具有一些垃圾值一样,指针在初始化之前也将具有一些垃圾值.如您所知,您可以声明一个变量:

If you are really asking about initialization and not memory allocation: A pointer variable is no different from any other variable with regard to initialization. Just as an uninitialized int variable will have some garbage value before it is initialized, a pointer too will have some garbage value before it is initialized. As you know, you can declare a variable:

double someVal;    // no initialization, will contain garbage value

以及随后的代码中有一个分配其值的赋值:

and later in the code have an assignment that sets its value:

someVal = 3.14;

类似地,使用指针变量,您可以具有以下内容:

Similarly, with a pointer variable, you can have something like this:

int ary [] = { 1, 2, 3, 4, 5 };
int *ptr;          // no initialization, will contain garbage value
ptr = ary;

此处, ptr 未初始化为任何内容,但后来被分配了数组第一个元素的地址.

Here, ptr is not initialized to anything, but is later assigned the address of the first element of the array.

有人可能会说,初始化指针(至少指向 NULL )总是好事,因为您可能会无意间尝试在为指针分配任何实际(非垃圾)值之前取消引用,然后取消引用垃圾地址可能会导致程序崩溃,或者更糟的是,可能会损坏内存.但这与警告始终不变,例如,在声明变量时始终将 int 变量初始化为零并没有什么不同.如果您的代码在按预期方式设置其值之前错误地使用了一个变量,那么我不确定该值是否为零, NULL 或垃圾是不是很重要.

Some might say that it's always good to initialize pointers, at least to NULL, because you could inadvertently try to dereference the pointer before it gets assigned any actual (non-garbage) value, and dereferencing a garbage address might cause your program to crash, or worse, might corrupt memory. But that's not all that different from the caution to always initialize, say, int variables to zero when you declare them. If your code is mistakenly using a variable before setting its value as intended, I'm not sure it matters all that much whether that value is zero, NULL, or garbage.

修改.OP在一个注释中询问:您说字符串文字生活在不同的内存段中,它们被认为是不可变的,并且不需要为它们的内存专门在堆栈或堆上分配",那么如何会发生分配吗?

Edit. OP asks in a comment: You say that "String literals live in a different memory segment, they are considered immutable, and the memory for them doesn't need to be specifically allocated on the stack or the heap", so how does allocation occur?

这就是语言的工作方式.在C语言中,字符串文字是语言的元素.C11标准在第6.4.5节中规定,当编译器将源代码翻译成机器语言时,它应将双引号中的任何字符序列转换为 char (或 wchar_t(如果是宽字符),并附加一个 NUL 字符作为数组的最后一个元素.然后,将此数组视为不可变的.该标准说:如果程序尝试修改这样的数组,则行为未定义.

That's just how the language works. In C, a string literal is an element of the language. The C11 standard specifies in §6.4.5 that when the compiler translates the source code into machine language, it should transform any sequence of characters in double quotes to a static array of char (or wchar_t if they are wide characters) and append a NUL character as the last element of the array. This array is then considered immutable. The standard says: If the program attempts to modify such an array, the behavior is undefined.

因此,基本上,当您有如下语句时:

So basically, when you have a statement like:

char *p_message = "Pointer";

该标准要求将双引号字符指针" 实施为以 char 组成的静态,不可变, NUL 终止的数组在内存中的某个位置.通常,实现将此类字符串文字放置在内存的只读区域(如文本块)中(以及程序指令).但这不是必需的.给定实现处理此数组/以 code /string常量的 NUL 终止的序列的内存分配的确切方式取决于特定的编译器.但是,由于此数组存在于内存中的某个位置,因此您可以有一个指向它的指针,因此上述声明确实可以正常工作.

the standard requires that the double-quoted sequence of characters "Pointer" be implemented as a static, immutable, NUL-terminated array of char somewhere in memory. Typically implementations place such string literals in a read-only area of memory such as the text block (along with program instructions). But this is not required. The exact way in which a given implementation handles memory allocation for this array / NUL terminated sequence of char / string literal is up to the particular compiler. However, because this array exists somewhere in memory, you can have a pointer to it, so the above statement does work legally.

使用函数指针进行类比可能会有用.就像函数的代码以指令序列的形式存在于内存中的某个位置一样,您可以具有指向该代码的函数指针,但是您无法更改函数代码本身,所以字符串文字也以序列的形式存在于内存中 char 的字符串,您可以具有指向该字符串的 char 指针,但是您不能更改字符串文字本身.

An analogy with function pointers might be useful. Just as the code for a function exists somewhere in memory as a sequence of instructions, and you can have a function pointer that points to that code, but you cannot change the function code itself, so also the string literal exists in memory as a sequence of char and you can have a char pointer that points to that string, but you cannot change the string literal itself.

C标准仅针对字符串文字指定此行为,而不针对字符常量(例如'A')或整数常量(例如 5 )指定这种行为.预留内存来保存此类常量/非字符串文字是程序员的责任.因此,当编译器遇到如下语句时:

The C standard specifies this behavior only for string literals, not for character constants like 'A' or integer constants like 5. Setting aside memory to hold such constants / non-string literals is the programmer's responsibility. So when the compiler comes across statements like:

char *charPtr = 'A';    // illegal!
int *intPtr = 5;        // illegal!

编译器不知道如何处理它们.程序员尚未在堆栈或堆上预留这样的内存来保存这些值.与字符串文字不同,编译器也不会为它们预留任何内存.因此,这些陈述是非法的.

the compiler does not know what to do with them. The programmer has not set aside such memory on the stack or the heap to hold those values. Unlike with string literals, the compiler is not going to set aside any memory for them either. So these statements are illegal.

希望这更加清楚.如果没有,请再次发表评论,我会尽力澄清更多.

Hopefully this is clearer. If not, please comment again and I'll try to clarify some more.

这篇关于在C中是否需要对char指针地址进行初始化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆