2.指针减去指针
指针减去指针得到的值的绝对值其实是两地址中间元素的个数
例如1:
#include<stdio.h> int main() { int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; printf("%d", &arr[9] - &arr[0]); //指针减去指针 }
结果:
分析:
例如2:
#include<stdio.h> int main() { int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; printf("%d", &arr[0] - &arr[9]); //指针减去指针 }
结果:
注意:指针减指针时,这两个指针必须是指向同一块空间的,比如:同一个数组。
应用
写一个函数模拟strlen函数的功能
#include<stdio.h> int my_strlen(char* str) { char* start = str; char* end = str; while (*end != '\0') { end++; } return end - start; //指针减指针 } int main() { char arr[] = "apple"; //存在数组中的元素为 'a','p','p','l','e','\0' int len = my_strlen(arr); printf("%d", len); }
结果:
3.指针的关系运算
指针关系运算就是指比大小
1.#include<stdio.h> #define N 5 //宏 int main() { int arr[N] = { 1,1,1,1,1 }; int* p; for (p = &arr[N]; p > &arr[0];) //进行指针大小比较 { *--p=0; } int i = 0; for (i = 0; i < N; i++) { printf("%d ", arr[i]); } return 0; }
结果:
分析:
四. 指针与数组
1.数组名是什么?
#include<stdio.h> int main() { int arr[5] = { 0 }; printf("%p\n", arr); //打印数组名地址 printf("%p\n", &arr[0]); //打印数组首元素地址 }
结果:
由结果看出,两个地址相同所以可以得出结论 :数组名绝大多数情况下指的是首元素地址
例外:
1.&arr ——&数组名 ,数组名不是首元素的地址-此情况下数组名表示整个数组,&数组名 取出的是整个数组的地址。
整个数组的地址与首元素的地址数值上相同,但表示的意义完全不同。分析如下:
2.sizeof(arr)——sizeof(数组名)此情况下数组名表示整个数组,sizeof(arr)计算的是整个数组的大小。
数字组可通过指针来访问
指针访问的是数组首元素地址
#include<stdio.h> int main() { int i = 0; int arr[5] = { 1,2,3,4,5 }; int* p = &arr; //访问首元素地址 for (i = 0; i < 5; i++) { printf("%d ", *(p + i)); } }
结果:
五. 二级指针
#include<stdio.h> int main() { int a = 3; int* pa = &a; int** ppa = &pa;//二级指针存放的是pa的地址,及存放a地址的地址 }
如上面例子,二级指针存放的是pa的地址,及存放a地址的地址
当然也有三级指针,四级指针等
#include<stdio.h> int main() { int a = 3; int* pa = &a; int** ppa = &pa;//二级指针存放的是存放pa的地址,及存放a地址的地址 int*** pppa = &ppa;//三级指针 int**** ppppa = &pppa;//四级指针 }
后面以此类推。
五.指针数组
指针数组本质是一个数组
是一个存放指针的数组
#include<stdio.h> int main() { int a = 3; int b = 5; int c = 8; int* arr[] = { &a,&b,&c };//指针数组,用来存放指针 }