在C中,指针永远是我的痛苦。
我的问题:当我们向指针添加*时?
我看到了这两个代码:
第一个:
int x;
int *ptr;
ptr = &x;
第二个:
int x;
int *ptr;
*ptr = 5;
为什么第一个指针在指针前面有*,但第二个指针没有?
更新:
为什么我们不*pr = &x
和ptr = 5
?
答案 0 :(得分:3)
变量保存一个值,该值存储在内存中的某个位置(在地址处)。指针是一个变量,它将值保存为地址。
*
的一个用途是声明一个指针;在发布的代码中,int *ptr;
声明指向int
的指针。表达式&x
的计算结果为x
的地址,因此ptr = &x;
将变量x
的地址存储在(指针)变量ptr
中。如果单独使用变量ptr
,请执行以下操作:
printf("ptr = %p\n", (void *) ptr);
ptr
将评估ptr
中存储的值,即x
的地址。请注意,打印指针值需要%p
转换说明符,并且必须将其转换为(void *)
以避免未定义的行为。
如果要使用存储在指针所指向的变量中的值,则使用*
运算符取消引用指针。也就是说,如果您想使用ptr
获取x
中存储的值,请使用*ptr
:
printf("*ptr = x = %d\n", *ptr);
同样,如果要将值存储在指针指向的变量中,可以取消引用指针:
*ptr = 5;
printf("x is now %d\n", x);
现在请注意,在您的第一个代码段中,x
未初始化(包含不确定的值),但x
已定义,并且有一个地址,因此ptr
确实存在确定价值。但在第二个代码段中,ptr
未初始化,因此包含不确定值。使用不确定值是未定义的行为,因此在这种情况下行:
*ptr = 5;
导致未定义的行为。
以下是发布代码的一个版本,可以避免未定义的行为:
#include <stdio.h>
int main(void)
{
int x;
int *ptr;
ptr = &x;
printf("ptr = %p\n", (void *) ptr);
x = 1;
printf("*ptr = x = %d\n", *ptr);
*ptr = 5;
printf("x is now %d\n", x);
return 0;
}
答案 1 :(得分:1)
*
只是指定此变量是指针。
*
使用变量时(即声明以外的任何地方)意味着你想要访问指针指向的任何东西,而不是指针本身。
当你想让指针指向与之前指向的不同的对象时,请将*
保留(右边的任何内容应该是某个地址):
ptr = &thing_it_points_to;
当您希望指针保持指向同一个对象时使用*,但更改该对象的值:
*ptr = 5; // 5 is not an address here, it's the value I'm assigning to the int that this points to
所以,你的第一个:
int x;
int *ptr; // * while declaring the variable tells us this is a pointer type
ptr = &x; // Get a pointer that points to 'x', and store it in 'ptr'
第二个:
int x;
int *ptr; // * while declaring the variable tells us this is a pointer type
*ptr = 5; // * while using the variable means to get the thing this pointer points to, and set it to 5
BTW,这两个都是无效的代码; x
在第一个中初始化之前使用ptr
,在第二个中初始化之前使用wData
。
答案 2 :(得分:1)
指针可能会让人感到困惑。
首先,指针是一个存储另一个变量地址的变量。
声明指针时,需要使用*
声明它。 C是一种静态类型语言,您需要在分配变量之前定义变量的类型。
因此,int *ptr
声明一个整数指针。 char *string
是一个字符指针。
但是,在声明之后,当您再次使用*
时,它会取消引用指针。你基本上可以&#34;阅读&#34;那是&#34;&#34;的价值指针指向的内存地址。
示例:
int *ptr;
int x;
x = 10;
/*
* store the address of x in ptr
* so ptr is now pointing to x
*/
ptr = &x
/*
* this is printing the pointer
* which is pointing to the address of x
* so this will print you a memory address
* Output will be something like: 0x7fff9575c05f
*/
printf("%p\n", ptr);
/*
* this prints the value of the memory address
* save which is the value of x
* so in this case, this will print 10
*/
printf("%i\n", *ptr);
答案 3 :(得分:1)
如果*
出现在声明中,例如:
声明指针变量pt
, 不 指针变量*pt
。变量pt
指向int
类型,您可以使用它来存储地址。
int *ptr;
ptr = &x;
如果*
出现在赋值语句中,它取消引用指针,*ptr
实际上意味着 获取指针指向的内存中的数据/值< / EM> 强>
*ptr = 5;
这意味着将整数5
赋给指针变量`ptr。
为什么我们不做* pr =&amp; x和ptr = 5?
*pr = &x
和ptr=5
实际上(i)将x
的地址分配给指针的值(ii)将整数赋给指针变量
导致错误/未定义的行为。
答案 4 :(得分:0)
所以基本上C中的指针将地址存储到特定的内存中。
任何变量(例如上例中的x)都存储在内存中的某个位置,因此可以使用指针来表示位置。
在C中,在内存中获取变量位置的操作是使用运算符&amp;,所以ptr =&amp; x表示获取指向存储x的内存的指针并将位置存储到指针ptr中
在指针位置获取变量是指针前面的运算符*,因此* ptr = 5表示设置指针ptr指向5的内存的4个字节。
但是,第一个代码中的x未初始化,导致未定义的行为,并且第二个代码中的ptr也未初始化,并且语句* ptr = 5肯定会导致运行时错误,因为内存ptr表示无法修改通过该计划。严格来说,你的两个代码都是无效的。
答案 5 :(得分:0)
在您的代码中
int *ptr;
ptr =&x;
此处ptr
正在寻找存储int
类型整数的地址。
例如:0x77C79AB2
*ptr = 5;
此处ptr
查找整数,而不是地址。
例如:5 // (some number)
因为地址不被视为整数。 您需要将其强制转换为整数
在你的问题中
*ptr = &x and ptr =5
会抛出错误,因为它找不到第一个中的整数和第二个
中的地址答案 6 :(得分:0)
正如其他人所指出的那样,'*'可以用来告诉编译器和其他程序员你声明一个包含地址的变量。 在第一种情况下,您正在存储变量x的地址(使用'&amp;')并存储在ptr中。在第二种情况下,您将获取地址ptr存储的值。 所以你有这样的事情:
-------------- --------------
| ptr | | x |
|++++++++++++| |++++++++++++|
| xaddress |----->| xvalue |
|++++++++++++| |++++++++++++|
你说ptr指向x,因为ptr持有x的地址。
现在真的,指针只是该语言的一个便利功能。你没有 使用指针来存储地址,尽管你应该这样做。以下内容完全有效:
int x;
int ptr;
ptr = &x;
但是你的可读性和便利指针运算都会失败。如果你做了ptr + 1,那么如果你已经将ptr声明为指针,那么你只会提前1个字节而不是4个字节。此外,最终你会想要在整数变量中访问地址存储的内容,所以你必须做一个丑陋的演员,如:* (int*)ptr
你必须要特别小心,因为整数大小不是始终与整数指针大小相同。你的指针可能是8个字节,整数可能是4,所以你实际上必须声明long long ptr = &x;