指针所占内存
指针所占内存与指针指向的内容和内容的大小无关。在不同的操作系统及编译环境中,指针类型占用的字节数是不同的。
指针本身占了多大的内存?对于某一个具体的环境,可以用下面的语句精确地知道指针类型占用的字节数:`printf("%d\n", sizeof(int *));`。在32位平台里,指针本身占据了4个字节的长度。指针所占内存这个概念在判断一个指针表达式是否是左值时很有用。
指针的算术运算
指针的算法运算包括指针与整数的运算和指针与指针的运算。指针与整数的运算的意义与通常的数值加减运算的意义是不一样的。
指针与整数的运算
C指针算术运算的第一种形式是:
指针 ± 整数
标准定义这种形式只能用于指向数组中某个元素的指针。
并且这类表达式的结果类型也是指针。这种形式也适用于使用`malloc()`函数动态分配获得的内存。
数组中的元素存储于连续的内存位置中,后面元素的地址大于前面元素的地址。因此,我们很容易看出,对于一个指针加1使它指向数组的下一个元素,加5使它向右移动5个元素的位置,依此类推。将一个指针减去3使它向左移动3个元素的位置。对整数进行扩展保证对指针执行加法运算能产生这种结果,而不管数组元素的长度如何。
对指针执行加法或减法运算之后如果指针所指的位置在数组第1个元素的前面或在数组最后一个元素的后面,那么其效果就是未定义的。让指针指向数组最后一个元素后面的那个位置是合法的,但对这个指针执行间接访问可能会失败。
例如:
`p+n`、`p-n`。
将指针p加上或者减去一个整数n,表示p向地址增加或减小的方向移动n个元素单元,从而得到一个新的地址,使其能访问新地址中的数据。每个数据单元的字节数取决于指针的数据类型。
例题:指针变量自身的运算
#include <stdio.h>
int main()
{
int a = 1, b = 10;
int *p1, *p2;
p1 = &a; // 指针赋值
p2 = &b;
printf("p1地址是%p, p1存储的值是%d\n", (void*)p1, *p1);
printf("p2地址是%p, p2存储的值是%d\n", (void*)p2, *p2);
printf("p1-1地址存储的值是%d\n", *(p1-1)); // 地址-1后存储的值
printf("p1地址的值-1后的值是%d\n", *p1-1); // 值-1后的值
printf("*(p1-1)的值和*p1-1的值不同\n");
return 0;
}
说明:
- `p1 = &a;` 和 `p2 = &b;` 是将变量 `a` 和 `b` 的地址赋给指针变量 `p1` 和 `p2`。
- `printf` 打印地址和地址存储的值,注意这里使用了`%p`来格式化输出指针地址,并通过强制转换为`(void*)` 确保跨平台的一致性。
- `*(p1-1)` 是指针偏移操作,根据内存布局的不同可能会输出意料之外的结果。
- `*p1-1` 则是对指针指定位置的内容减1。
最后两个打印说明了指针偏移和简单算术计算的不同,请谨慎使用指针运算以避免未定义行为。
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。 |