谷歌网站推广公司,上海松江做网站多少钱,wordpress信息填写,网站分享链接怎么做目录
1 指针的长度
2 指针与整数的加减运算
3 指针自增与自减
4 同类型指针相减
5 指针的比较运算
6 测试题 1 指针的长度 在 C 语言中#xff0c;sizeof 运算符可以用来计算指针的长度。指针的长度实际上与指针所指向的数据类型无关#xff0c;而是与系统的位数…目录
1 指针的长度
2 指针与整数的加减运算
3 指针自增与自减
4 同类型指针相减
5 指针的比较运算
6 测试题 1 指针的长度 在 C 语言中sizeof 运算符可以用来计算指针的长度。指针的长度实际上与指针所指向的数据类型无关而是与系统的位数即系统架构有关。具体来说
32 位系统无论指针指向什么类型的数据如 int、char、float 等指针的长度都是 4 个字节。64 位系统无论指针指向什么类型的数据指针的长度都是 8 个字节。 下面是一个示例展示了如何使用 sizeof 运算符来计算不同类型指针的长度
#include stdio.hint main()
{int *int_ptr;char *char_ptr;float *float_ptr;double *double_ptr;printf(int 指针的长度: %zu 字节\n, sizeof(int_ptr));printf(char 指针的长度: %zu 字节\n, sizeof(char_ptr));printf(float 指针的长度: %zu 字节\n, sizeof(float_ptr));printf(double 指针的长度: %zu 字节\n, sizeof(double_ptr));return 0;
} 在 32 位系统上运行上述代码输出可能是
int 指针的长度: 4 字节
char 指针的长度: 4 字节
float 指针的长度: 4 字节
double 指针的长度: 4 字节 在 64 位系统上运行上述代码输出可能是
int 指针的长度: 8 字节
char 指针的长度: 8 字节
float 指针的长度: 8 字节
double 指针的长度: 8 字节
结论
指针的长度与系统架构有关在 32 位系统中所有指针的长度都是 4 个字节在 64 位系统中所有指针的长度都是 8 个字节。指针的长度与指向的数据类型无关无论指针指向 int、char、float 还是 double指针本身的长度是固定的由系统的位数决定。 2 指针与整数的加减运算 指针与整数的加减运算表示指针所指向的内存地址的移动。具体来说
加法运算指针加一个整数表示指针所指向的内存地址向后移动。减法运算指针减一个整数表示指针所指向的内存地址向前移动。 指针移动的步长与指针指向的数据类型有关。每移动一个单位指针会移动相应数据类型所占的字节数。例如
如果指针指向 int 类型的数据int 通常占用 4 个字节那么指针加 1 会向后移动 4 个字节指针减 2 会向前移动 8 个字节。如果指针指向 char 类型的数据char 通常占用 1 个字节那么指针加 1 会向后移动 1 个字节指针减 2 会向前移动 2 个字节。 数组的元素在内存中是连续存储的因此通过数组元素可以很好地演示指针加减整数的情况。以下是一个示例
#include stdio.hint main()
{// 创建一个包含 5 个整数的数组int nums[] {10, 20, 30, 40, 50};// 创建一个指针并将其初始化为数组第一个元素的地址int *ptr nums[0];// int *ptr nums; 或者直接指向数组名 和上面等价// 打印指针的地址和指针所指向的值printf(初始状态: ptr%p, *ptr%d \n, (void *)ptr, *ptr);// 指针加 3指针指向 int 类型每个 int 占 4 个字节// 因此指针会向后移动 3 * 4 12 个字节ptr 3;printf(指针加 3 后: ptr%p, *ptr%d \n, (void *)ptr, *ptr);// 指针减 2指针会向前移动 2 * 4 8 个字节ptr - 2;printf(指针减 2 后: ptr%p, *ptr%d \n, (void *)ptr, *ptr);return 0;
} 输出结果如下所示 3 指针自增与自减 指针的自增和自减本质上是通过加减整数来实现的。自增会使指针向后移动自减会使指针向前移动。移动的步长与指针指向的数据类型有关。每移动一个单位指针会移动相应数据类型所占的字节数。例如如果指针指向 short 类型的数据short 通常占用 2 个字节那么指针自增 1 会向后移动 2 个字节指针自减 1 会向前移动 2 个字节。
#include stdio.hint main()
{// 创建数组元素都是 short 类型每个元素占据 2 个字节short nums[] {10, 20, 30, 40, 50};// 定义常量记录数组长度const int len sizeof(nums) / sizeof(nums[0]); // 5// 利用指针自增遍历数组元素// 创建指针并指向数组第一个元素的地址short *ptr nums[0];// short *ptr nums; 或者直接指向数组名 和上面等价// 循环遍历数组for (int i 0; i len; i, ptr){// 打印当前元素的索引、地址和值printf(元素索引%d, 元素地址%p, 元素值%hd \n, i, (void *)ptr, *ptr);// 指针自增向后移动一个 short 类型的单位2个字节// ptr; 可以放到循环变量迭代里面去}printf(\n);// 循环遍历数组从最后一个元素到第一个元素// 此时指针超出数组界限需先自减一次for (int i len - 1; i 0; i--){// 指针自减向前移动一个 short 类型的单位2个字节ptr--;// 打印当前元素的索引、地址和值printf(元素索引%d, 元素地址%p, 元素值%hd \n, i, (void *)ptr, *ptr);}return 0;
} 输出结果如下所示 在上述示例中当第一次循环正序输出数组元素结束后指针 ptr 已经超出了数组的边界指向了数组最后一个元素之后的位置如下图所示。因此在进行第二次循环倒序输出数组元素之前需要先将指针重置为数组最后一个元素的地址以确保能够正常输出。 可以使用 ptr-- 重置指针在第一次循环结束后指针 ptr 超出了数组的边界。可以通过 ptr-- 将指针向前移动一个单位使其指向数组的最后一个元素。如上述代码中的第二次循环一开始就使用 ptr-- 重置指针。 也可以直接修改指针的指向地址可以直接将指针 ptr 重新初始化为数组最后一个元素的地址这样可以确保指针指向正确的起始位置。如下代码所示
#include stdio.hint main()
{// 创建一个包含 5 个 short 类型的数组short nums[] {10, 20, 30, 40, 50};int n sizeof(nums) / sizeof(nums[0]); // 计算数组的长度// 创建指针并初始化为数组第一个元素的地址short *ptr nums[0];// 正序输出数组元素printf(正序输出数组元素:\n);for (int i 0; i n; i){printf(元素索引%d, 元素地址%p, 元素值%hd \n, i, (void *)ptr, *ptr);ptr; // 指针自增向后移动一个 short 类型的单位2个字节可以放到循环变量迭代里面去}printf(\n);// 重置指针使其指向数组最后一个元素的地址ptr nums[n - 1];// 倒序输出数组元素printf(倒序输出数组元素:\n);for (int i n - 1; i 0; i--){printf(元素索引%d, 元素地址%p, 元素值%hd \n, i, (void *)ptr, *ptr);ptr--; // 指针自减向前移动一个 short 类型的单位2个字节}return 0;
} 4 同类型指针相减 相同类型的指针可以进行减法运算返回它们之间的距离即相隔多少个数据单位。高位地址减去低位地址返回的是正值低位地址减去高位地址返回的是负值。同类型指针相减的结果是一个 ptrdiff_t 类型的数据ptrdiff_t 是一个带符号的整数格式输出中对应的格式占位符是 %td。 以下是一个示例演示了如何使用同类型指针相减来计算它们之间的距离
#include stdio.hint main()
{// 创建一个包含 5 个整数的数组int nums[] {10, 20, 30, 40, 50};// 创建指针并指向数组第一个元素的地址int *ptr1 nums[0];// 创建指针并指向数组第四个元素的地址int *ptr2 nums[3];// 打印查看原始内容printf(ptr1地址%p\n, ptr1);printf(ptr2地址%p\n, ptr2);// 计算两个指针之间的距离// ptr2 - ptr1 应该等于 3因为 ptr2 指向第四个元素ptr1 指向第一个元素printf(ptr2 - ptr1 %td \n, ptr2 - ptr1); // 输出 3// ptr1 - ptr2 应该等于 -3因为 ptr1 指向第一个元素ptr2 指向第四个元素printf(ptr1 - ptr2 %td \n, ptr1 - ptr2); // 输出 -3// 再连续创建两个变量double d1 1.0;double d2 2.0;// 创建指针并分别指向 d1 和 d2 的地址double *p1 d1;double *p2 d2;printf(p1地址%p\n, p1);printf(p2地址%p\n, p2);// 计算两个指针之间的距离// p1 - p2 应该等于 1因为 p1 指向 d1p2 指向 d2d1 和 d2 在内存中是相邻的printf(p1 - p2 %td \n, p1 - p2); // 输出 1// p2 - p1 应该等于 -1因为 p2 指向 d2p1 指向 d1d1 和 d2 在内存中是相邻的printf(p2 - p1 %td \n, p2 - p1); // 输出 -1return 0;
} 输出结果如下所示 5 指针的比较运算 指针之间可以进行比较运算如 、!、、、、。这些运算符比较的是指针所指向的内存地址的大小返回值是 int 类型的整数1 表示 true0 表示 false。 以下是一个示例演示了如何使用指针的比较运算
#include stdio.hint main()
{// 创建一个包含 5 个整数的数组int nums[] {10, 20, 30, 40, 50};double n 1.0;// 创建指针并指向数组第一个元素的地址int *ptr1 nums[0];// 创建指针并指向数组第四个元素的地址int *ptr2 nums[3];// 创建指针也指向数组第一个元素的地址int *ptr3 nums[0];// 创建指针指向变量 n 的地址double *ptr4 n;// 输出指针指向的地址printf(ptr1%p\n, (void *)ptr1);printf(ptr2%p\n, (void *)ptr2);printf(ptr3%p\n, (void *)ptr3);printf(ptr4%p\n\n, (void *)ptr4);// 进行比较// 比较 ptr1 和 ptr2 的地址printf(ptr1 ptr2: %d \n, ptr1 ptr2); // 比较 ptr1 是否大于 ptr2printf(ptr1 ptr2: %d \n, ptr1 ptr2); // 比较 ptr1 是否小于 ptr2// 比较 ptr1 和 ptr3 的地址printf(ptr1 ptr3: %d \n, ptr1 ptr3); // 比较 ptr1 是否等于 ptr3// 比较不同类型的指针ptr4 和 ptr1// 注意不同类型的指针进行比较会引发编译器警告printf(ptr4 ptr1: %d \n, ptr4 ptr1); // 比较 ptr4 是否大于 ptr1return 0;
} 注意不同类型的指针进行比较会引发编译器警告。如下所示 输出结果如下所示 6 测试题
1. 请写出下面程序的运行结果64 位操作系统。
int num 250;
int *p num;
printf(%zu \n, sizeof p);
printf(%zu \n, sizeof *p);
【答案】 8 4
【解析】 sizeof p 是计算指针本身的长度指针存储的是地址在 64 位操作系统下地址占 8 个字节。 sizeof *p 是计算指针指向的数据的长度指针 p 指向 int 类型变量 numint 类型长度是 4 个字节。 2. 请写出下面程序的运行结果。
int arr[] {10,20,30,40,50};
int *p arr;
printf(%d, *(p1) *(p2));
【答案】 50
【解析】 指针 p 指向数组 arr 的首元素地址。 p1 得到数组 arr 第二个元素的地址*(p1) 得到第二个元素的值 20。 p2 得到数组 arr 第三个元素的地址*(p2) 得到第三个元素的值 30。