我是C的新手,对指针有一些疑问。
问题1以下两项有何不同?初始化指针哪种方式更好?为什么?
int *p=NULL;
int *p;
#include <stdio.h>
void main()
{
char *s = "hello";
printf("%p\t%p",s);
//printf("%p\t%p",&s) it will give me unpredictable result every time
//printf("%p\t%p",(void *)&s) it will be fine
//Question3: why?
}
问题2:我尝试谷歌%p
正在做什么。根据我的阅读,它应该打印指针。这意味着它打印指针的地址?
答案 0 :(得分:1)
1)第一个是初始化(在这种情况下为NULL
)第二个只是p
的声明作为指向int
的指针,没有为{分配初始值{1}}在这种情况下。您应该始终更喜欢初始化以防止未定义的行为。
2)使用p
打印指针时应该转换为void*
(请注意您在格式说明符中使用了太多次)。打印%p
点的内存地址。
答案 1 :(得分:1)
问题1,这些是指针p
的定义。一个初始化指向NULL
的指针,另一个指针使其未初始化(如果它是函数中的局部变量,而不是全局变量,则默认情况下全局变量初始化为0)。使用NULL
初始化可能很好,或者可能很糟糕,因为编译器可以警告您使用未初始化的变量并帮助您找到错误。另一方面,编译器无法检测到未初始化变量的每种可能用途,因此初始化为NULL
几乎可以保证在使用时产生分段错误,然后您可以非常轻松地使用调试器捕获和调试。就个人而言,我总是在变量定义时始终初始化,如果可能的话,使用正确的值(如果初始化对于单个语句来说太复杂,则添加辅助函数来获取值)。
问题2,%p
打印传递给printf
的地址值。因此,printf("%p", pointer);
传递变量pointer
的值并打印出来,而printf("%p", &pointer);
(请注意额外的&
)获取传递的地址变量pointer
,并打印出来。 %p
的精确数字格式是实现定义的,它可能只是以普通数字打印。
问题3是关于未定义的行为,因为格式字符串的项目数多于实际传递给printf
的项目。简短的回答是,行为未定义,没有&#34;为什么&#34;。更长的答案是,使用机器代码调试器运行应用程序并在反汇编视图中跟踪执行以查看实际发生的情况,以了解原因。请注意,在不同的运行中结果可能会有所不同,并且在调试器下行为可能会有所不同并且正常运行,因为由于各种原因,内存可能在不同的运行中具有不同的字节值。
答案 2 :(得分:0)
1)
int *p = NULL
将指针'p'定义并初始化为NULL。这是初始化指针的正确方法,以便在以后忘记为此指针分配有效地址时获取“Seg Fault”。
int *p
仅定义具有未知地址的指针“p”。如果您在使用之前忘记为此指针分配有效值,则某些编译器会通知您有关此错误的信息,而其他编译器则不会,您可能会访问无效地址并获得运行时错误或程序的未定义行为
2)“%p”正在打印指针指向的地址。由于指针保存一个地址,因此“%p”将打印该地址。
printf("%p\t%p",s);
因此第一个“%p”将打印指针“s”指向的地址,该地址是存储字符串“hello”的地址。但是,请注意您使用了两次“%p”但是只提供一个指针来打印其地址!! 大多数编译器都不会为此而尖叫,因为它没有效果;但要尽量避免它。
答案 3 :(得分:0)
答案1:
int *p=NULL;
p是指向用NULL初始化的int变量的指针。这里NULL表示指针p没有指向任何有效的内存位置。
int *p;
p是指向int变量的指针。 p未初始化。读取未初始化的变量是未定义的行为。 (尝试使用的一种可能性是它会引发分段错误)
答案2:
打印指针的内容。我的意思是字符串&#34;你好&#34;
的基地址答案 4 :(得分:0)
主要区别在于,在*p = NULL
中,NULL是预定义且标准的地点&#39;指针指向的位置。
从维基百科阅读,
The macro NULL is defined as an implementation-defined null pointer constant,
which in C99 can be portably expressed as the integer value 0
converted implicitly or explicitly to the type void*.
这意味着&#39;存储单元&#39;名为p
的包含MACRO值为NULL。
如果您只是编写int *p
,则命名名为p
的内存单元格,但此单元格为空。