C中(&;)和间接(*)的地址
我有一个关于运算符的问题:C编程中(&)和间接(*)的地址 如果C中(&;)和间接(*)的地址,c,C,我有一个关于运算符的问题:C编程中(&)和间接(*)的地址 如果 var是类型为int ptr是指向int的指针,指向var 那么ptr的值是多少 结果是指示var的基址还是整个4字节(在我的平台中)?如果它只指向基址,那么为什么*ptr的计算结果是var的全部内容?它不应该只显示var的基址的内容吗 与任何其他类型一样,指针也是一种类型 符合取消引用条件的指针必须指向完整类型。每个类型都有一个已定义的大小(pre或user),因此取消引用将考虑指针指向的对象类型的大小 引用第§6.5.3.
是类型为var
int
是指向ptr
的指针,指向int
var
ptr
的值是多少
结果是指示
var
的基址还是整个4字节(在我的平台中)?如果它只指向基址,那么为什么*ptr
的计算结果是var
的全部内容?它不应该只显示var
的基址的内容吗 与任何其他类型一样,指针也是一种类型
符合取消引用条件的指针必须指向完整类型。每个类型都有一个已定义的大小(pre或user),因此取消引用将考虑指针指向的对象类型的大小
引用第§6.5.3.2章中的C11
一元*
运算符表示间接寻址。如果操作数指向函数,则结果为
函数指示符;如果它指向一个对象,结果是一个左值,表示
对象如果操作数的类型为“指向类型的指针”,则结果的类型为“类型”。如果
指针指定的值无效,一元*
运算符的行为无效
未定义
让我们看看下面的图形,以便更好地理解它
说
在这个平台上,sizeof(int)==4
现在,在记忆中,它看起来像
+-------------------------------------------+
| |
| int x = 10; |
| |
+-------------------------------------------+
0x1000 0x1004
+------------------------------------------+
| |
| pointer * px = &x; (0x1000) |
| |
+------------------------------------------+
- 现在,整个内存块,
到0x1000
(直到地址的开头0x1003
)被分配给0x1004
类型的变量int
x
是指针,指向该内存块的开头。另外,在定义px
时,我们告诉编译器它将指向一个px
,因此编译器知道,存储在int
的内存块有4个字节的存储空间,要在间接寻址期间获取数据(使用px
操作符),我们需要读取所有4个字节,然后返回结果*
因此,在编写
*px
时,编译器读取所有4个字节并返回值。与任何其他类型一样,指针也是一种类型
符合取消引用条件的指针必须指向完整类型。每个类型都有一个已定义的大小(pre或user),因此取消引用将考虑指针指向的对象类型的大小
引用第§6.5.3.2章中的C11
一元*
运算符表示间接寻址。如果操作数指向函数,则结果为
函数指示符;如果它指向一个对象,结果是一个左值,表示
对象如果操作数的类型为“指向类型的指针”,则结果的类型为“类型”。如果
指针指定的值无效,一元*
运算符的行为无效
未定义
让我们看看下面的图形,以便更好地理解它
说
在这个平台上,sizeof(int)==4
现在,在记忆中,它看起来像
+-------------------------------------------+
| |
| int x = 10; |
| |
+-------------------------------------------+
0x1000 0x1004
+------------------------------------------+
| |
| pointer * px = &x; (0x1000) |
| |
+------------------------------------------+
- 现在,整个内存块,
到0x1000
(直到地址的开头0x1003
)被分配给0x1004
类型的变量int
x
是指针,指向该内存块的开头。另外,在定义px
时,我们告诉编译器它将指向一个px
,因此编译器知道,存储在int
的内存块有4个字节的存储空间,要在间接寻址期间获取数据(使用px
操作符),我们需要读取所有4个字节,然后返回结果*
因此,在写入
*px
时,编译器读取所有4个字节并返回值。指针变量ptr
将包含var
开始的地址,即var
的第一个字节的地址。如果将ptr
作为*ptr
取消引用,则将得到var
的值
假设int
是4个字节,由于指针的类型,使用*ptr
“knows”读取接下来的4个字节。由于ptr
具有类型int*
,这意味着*ptr
具有类型int
,因此接下来的4个字节被读取为int
例如:
int var = 4;
int *ptr = &var;
printf("ptr = %p\n", (void *)ptr);
printf("*ptr = %d\n", *ptr);
printf("&var = %p\n", (void *)&var);
printf("var = %d\n", var);
输出:
ptr=0x7ffc330b4484
*ptr=4
&var=0x7ffc330b4484
var=4
指针变量ptr
将包含var
开始的地址,即var
的第一个字节的地址。如果将ptr
作为*ptr
取消引用,则将得到var
的值
假设int
是4个字节,由于指针的类型,使用*ptr
“knows”读取接下来的4个字节。由于ptr
具有类型int*
,这意味着*ptr
具有类型int
,因此接下来的4个字节被读取为int
例如:
int var = 4;
int *ptr = &var;
printf("ptr = %p\n", (void *)ptr);
printf("*ptr = %d\n", *ptr);
printf("&var = %p\n", (void *)&var);
printf("var = %d\n", var);
输出:
ptr=0x7ffc330b4484
*ptr=4
&var=0x7ffc330b4484
var=4
ptr
,作为一个int*
,指向整个int
,或者您所说的整个sizeof(int)
字节
(unsigned char*)ptr
指向您所说的“基址”
ptr
和(unsigned char*)ptr
在所有通用CPU体系结构上都具有相同的数值,这表明指向“整”整数和仅指向“基址”之间的差异完全取决于指针的类型。了解两个不同类型的变量可以
ptr 100 101 102 103
-------- var -------------------------
| &var |-------->| | | | |
-------- -------------------------
byte1 byte2 byte3 byte4
char *c_ptr = (char *)&var;
#include <stdio.h>
int main() {
int var = 50;
int *i_ptr = &var;
char *c_ptr = (char *)&var;
printf ("address of var: %p\n", (void *)&var);
printf ("i_ptr: %p\n", (void *)i_ptr);
printf ("i_char: %p\n\n", (void *)c_ptr);
printf ("value of var: %d\n", var);
printf ("value of *i_ptr: %d\n", *i_ptr);
for (size_t i = 0; i < sizeof(int); i++) {
printf ("Address of byte[%zu]: %p, ", i, (void *)&c_ptr[i]);
printf ("byte[%zu]: %c\n", i, c_ptr[i]);
}
return 0;
}
address of var: 0x7ffeea3ac9f8
i_ptr: 0x7ffeea3ac9f8 <========\
i_char: 0x7ffeea3ac9f8 <========/ the address pointing to is same
value of var: 50
value of *i_ptr: 50
Address of byte[0]: 0x7ffeea3ac9f8, byte[0]: 2 <========= 50th character of ascii
Address of byte[1]: 0x7ffeea3ac9f9, byte[1]:
Address of byte[2]: 0x7ffeea3ac9fa, byte[2]:
Address of byte[3]: 0x7ffeea3ac9fb, byte[3]:
address of var: ffbffbd0
i_ptr: ffbffbd0
i_char: ffbffbd0
value of var: 50
value of *i_ptr: 50
Address of byte[0]: ffbffbd0, byte[0]:
Address of byte[1]: ffbffbd1, byte[1]:
Address of byte[2]: ffbffbd2, byte[2]:
Address of byte[3]: ffbffbd3, byte[3]: 2
int var = 5;
int *ptr = &var;
ptr == &var // int * == int *
*ptr == var == 5 // int == int == int