试图弄清楚指针初始化和指针分配之间的区别。
C语言
int *p=0;
int *p;
*p=0;
我不知道两种方法之间有什么区别。一样吗?
答案 0 :(得分:7)
在功能内
int *p = 0;
等效于:
int *p;
p = 0;
即变量本身被初始化,声明的声明部分被忽略。相对于:
int *p;
*p = 0;
由于未分配指针的 target 被分配给它,因此导致未定义行为。
答案 1 :(得分:2)
int *p=0;
此行将声明int *
指针并使其指向0
。另外,请确保在取消引用之前使p
指向有效内存。
int *p;
*p=0;
是未定义的行为。由于p
没有指向任何地方。
答案 2 :(得分:1)
两者都不同。在这里
int *p=0;
整数指针p
被分配了0
,它与
int *p; /* first p is declared : uninitialized */
p = 0; /* then assigned with 0 */
尽管我不希望使用p = 0
。这个
int *p = NULL;
更好。 还有这里
int *p;
*p=0; /* p doesn't have any valid address, de-referencing it causes UB */
您正尝试为*p
分配0
,这是错误的,因为在这种情况下p
没有有效的地址。它调用未定义的行为。
答案 3 :(得分:1)
每个新的C程序员都难以使用指针的主要原因是指针声明和指针访问/取消引用之间的语法相似。
int *p;
是一个指向整数的指针的声明。 *p=0;
正在取消引用指针,访问其指向的位置,并尝试在其中写入值0。为此,必须先将指针设置为指向有效的内存位置。int *p = 0;
是一个带有初始化值的整数指针的声明。这将设置指针本身指向的位置。它不是取消引用。将值0
分配/初始化给指针本身是一种特殊情况,因为这会转换为“空指针常量”。基本上,指针指向明确定义的无处。最好改用stddef.h中的宏NULL
,这样我们才不会将其与整数值0
混在一起。
因为*p=0;
单独位于一行,所以0
就是一个纯整数值。
另请参阅Crash or "segmentation fault" when data is copied/scanned/read to an uninitialized pointer。
答案 4 :(得分:0)
int *p = 0;
这将创建一个整数指针,该指针将指向地址零,因此它是一个空指针。空指针仅表示该指针未指向任何东西,或者在某些语言中表示它所指向的对象是未知的。但是因为它是一个空指针,所以您知道这一点,代码也知道这一点,所以没有问题。
未初始化的指针变量通常称为悬挂指针,仅是因为您不知道其指向何处。表演
int *p;
*p=0;
具有不可预测的效果。
答案 5 :(得分:0)
快速解答
它们是不同的,因为在第一个示例int *p=0;
中,您将p声明为指针,然后将其设置为指向地址0x0。这一行示例等效于这两行代码int *p; p=0;
在第二个示例int *p; *p=0;
中,您在第一行声明了p,但尚未初始化...因此p指向的位置未定义。在第二行上,您将转到该未定义位置的地址,然后尝试将该地址的值设置为0。
您可以看到此示例与之前等价的2行示例之间的区别,因为一个示例使用p=0;
,而另一个示例使用*p=0;
示例
因此,在尝试访问* p之前,您需要定义p指向的位置。假设您知道要p指向的整数的地址为0x76543210。在代码运行之前,让我们看一下内存中的值:
// Dummy Memory Dump
// Offset: 0 4 8 C
// (0x76543200): 00000000 00000000 00000000 00000000
// (0x76543210): 00000000 00000000 00000000 00000000
// (0x76543220): 00000000 00000000 00000000 00000000
在此示例中,我将您的*p=0;
更改为*p=5;
,以便我们可以看到内存中的更改。现在,我们运行以下代码行:
int *p; // Declare a pointer p
p = (int*) 0x76543210; // Set p to point at the address 0x76543210 cast to (int*)
*p = 5; // Go to the address that p is pointing to, and set the value to 5
现在,如果我们回头看一下我们的内存,我们应该看到我们将5设置为p指向的地址:
// Dummy Memory Dump
// Offset: 0 4 8 C
// (0x76543200): 00000000 00000000 00000000 00000000
// (0x76543210): 00000005 00000000 00000000 00000000
// (0x76543220): 00000000 00000000 00000000 00000000
说明
通常,声明分为以下几个部分:
[type] [name];
并且可选地,可以这样中断在线初始化:
[type] [name] = [value];
在此示例中:
int *p=5;
这可能会造成混淆,因为声明中的*附加在名称上。声明中的*仅表示p是指针。 但是指针的名称仍然只是p。
现在我们知道了组成部分,可以这么说
int *p=5;
等同于
int *p;
p=5;
现在增加了混乱,在声明指针和访问指针地址时,*之间存在区别。 在访问期间使用*时,它将使用p中的值作为将被访问的地址。 在此示例中:
int *p; // This declares a pointer p with no value
*p=5; // This line wants to go to the address that p is pointing to and set it to 5
// At this point, p is undefined because p was just declared and hasn't been set
// So it is trying to go to an unknown location to set the value 5.
答案 6 :(得分:-1)
指针初始化和指针分配没有什么区别,除了可以将指针声明及其初始化放置在全局名称空间中,而作为表达式语句的赋值只能在函数内部使用。
因此,通常,这两个代码段具有相同的效果。
int *p = 0;
和
int *p;
p = 0;
您错误地将指针指向的对象分配视为指针本身的分配。
在此声明中
*p=0;
指针被取消引用,并且指针所指向的对象被分配值为0。
int *p;
*p=0;
由于指针本身未初始化,因此它具有一些不确定的值,并且带有赋值表达式的expression语句具有未定义的行为。
请考虑以下代码段
int x;
int *p;
p = &x; // pointer assigment
*p = 0; // object assignment pointed to by the pointer
为指针类型使用typedef将有助于避免指针分配和指针所指向的对象的分配之间的混淆
例如
typedef int * Pointer;
Pointer p;
p = 0;
因此,在声明中,符号'*'
用于声明指针。
在表达式中,符号'*'
表示表示间接的一元运算符。将此运算符应用于指针的结果是一个左值指定了对象。
答案 7 :(得分:-1)
没有区别。 只有一点。
int *p = 0;
是带有初始化的合并声明的示例
同时
int *p;
*p = 0;
是先声明然后初始化的示例。
赞
int a = 0;
与
相同int a;
a = 0;