这篇文章主要介绍“C语言指针运算实例分析”,在日常操作中,相信很多人在C语言指针运算实例分析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C语言指针运算实例分析”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
指针-指针
指针的关系运算
#define VALUE 5 int main() { float values[VALUE]; float *vp; //指针+-指针,关系运算 for (vp = &values[0]; vp < &values[VALUE];) { *vp++ = 0;//通过这样完成初始化 } for (int i = 0; i < VALUE; i++) { printf("%d ", values[i]); } return 0; }
int main() { int arr[10] = { 0 }; printf("%d\n", &arr[9] - &arr[0]);//得到元素的个数 printf("%d\n", sizeof(arr)/sizeof(arr[0]));//计算元素个数 int* p0 = &arr[0]; int* p9 = &arr[9]; printf("%d\n", (p9 - p0));//得到元素的个数 return 0; }
通过数组首尾元素的地址相减,得出的就是数组元素的个数,
-int*表示指针指向的地址里面,存放的数据类型是整形,占用4个字节
数组元素地址+1,就是寻找下一个元素的地址,就会移动4个字节
通过调试更加清楚的观察到这一现象,int 数组每个元素占用四个字节:
&arr[0]: 0x005cf7f8
&arr[0]+1: 0x005cf7fc,地址移动1位,即int*指针移动1位,字节增加4个。
前提条件:两个指针必须指向同一块空间:
char ch[5]; int arr[6]; %arr[4]-&ch[3];//错误的
前面的文章介绍了字符串长度的方法两种方法:
循环
递归
这里介绍第三种方法, 指针
int mylen(char* pa)//传参是数组首元素的地址 { char* p = pa;//首元素地址 while (*pa)//元素不是‘0' { pa++;//通过地址访问字符串 } //结尾字符0的地址减首元素地址 return pa - p;//指针相减是元素的个数 } int main() { char arr[] = "abcdef"; int len = mylen(arr); printf("%d", len); return 0; }
标准规定:允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针比较,但是不允许与
指向第一个元素之前的那个内存位置的指针进行比较
int main() { // for (vp = &values[5]; vp > &values[0];) { *--vp = 0; } for (vp = &values[5-1]; vp >= &values[0];vp--)//不允许 //地址会指向首元素前面的地址,这是不允许的 { *vp = 0; } return 0; }
int main() { int arr[10] = {1,2,3,4,5,6,7,8,9,0}; printf("%p\n", arr); printf("%p\n", &arr[0]); int *p = arr;//p存放的是数组首元素的地址 return 0; }
数组名和数组首元素的地址是一样的。数组名表示的是数组首元素的地址。(2种情况除外,数组系列文章详细介绍了)
既然可以把数组名当成地址存放到一个指针中,我们使用指针来访问一个就成为可能
int main() { int arr[] = {1,2,3,4,5,6,7,8,9,0}; int *p = arr; //指针存放数组首元素的地址 int sz = sizeof(arr)/sizeof(arr[0]); for(int i=0; i<sz; i++) { printf("&arr[%d] = %p <====> p+%d = %p\n", i, &arr[i], i, p+i); } return 0; }
观察上图,所以 p+i 其实计算的是数组 arr 下标为 i 元素的地址。那就可以直接通过指针来访问数组:
int main() { int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; int* p = arr; int sz = sizeof(arr) / sizeof(arr[0]); for (int i = 0; i < sz; i++) { printf("%d ",*(p + i)); } printf("\n"); for (int i = 0; i < sz; i++) { printf("%d ", *(p++)); } printf("\n"); for (int i = 0; i < sz; i++) { printf("%d ", arr[i]); } return 0; }
指针变量也是变量,是变量就有地址,那指针变量的地址存放在哪里?这就是 二级指针
int main() { int a = 10; int* pa = &a; int** ppa = &pa; return 0; }
a的地址存放在指针pa中,pa是一级指针
pa的地址存放在ppa中,ppa是二级指针
对于二级指针的运算有:
*ppa 通过对ppa中的地址进行解引用,这样找到的是 pa , *ppa 其实访问的就是 pa .
int b = 20; *ppa = &b;//等价于 pa = &b;
**ppa 先通过 *ppa 找到 pa ,然后对 pa 进行解引用操作: *pa ,那找到的是 a
**ppa = 30; //等价于*pa = 30; //等价于a = 30;
指针数组是指针还是数组?
是数组。是存放指针的数组
在数组系列文章中,已经介绍了整形数组,字符数组:
int arr1[5];//占用20个字节 char arr2[5];//占用5个字节
指针数组:
int main() { int data1[] = { 1,2,3,4,5 }; int data2[] = { 2,3,4,5,6 }; int data3[] = { 3,4,5,6,7 }; //看成二维数组 int* arr[3] = { data1,data2,data3 }; for (int i = 0; i < 3; i++) { for (int j = 0; j < 5; j++) {//[]是操作符 printf("%d ", arr[i][j]);//不需要解引用 } printf("\n"); } return 0; }
arr3是一个数组,有五个元素,每个元素是一个整形指针,就是一个地址:
arr[0],为元素data1,是指针变量,本身也是一维数组 { 1,2,3,4,5 } 的数组名,代表首元素地址
arr[1],为元素data2,是指针变量,本身也是一维数组 { 2,3,4,5,6 } 的数组名,代表首元素地址
arr[2],为元素data3,是指针变量,本身也是一维数组 { 3,4,5,6,7 } 的数组名,代表首元素地址
通过调试也能发现:
指针数组首元素data,是指针变量,也是一维数组首元素的地址
通过数组名 + i 就能访问数组里的元素
指针数组可看成二维数组
arr[0]=data1;//指针数组首元素data,是指针变量,也是一维数组首元素的地址 arr[0][0]=data1[0];//看成一维数组 arr[0][1]=data1[1]; arr[0][2]=data1[2]; arr[0][3]=data1[3]; arr[0][4]=data1[4];
打印结果见下图:
代码换成下面这个效果一样,从地址的解引用角度去写:
int main() { int data1[] = { 1,2,3,4,5 }; int data2[] = { 2,3,4,5,6 }; int data3[] = { 3,4,5,6,7 }; //看成二维数组 int* arr[3] = { data1,data2,data3 }; for (int i = 0; i < 3; i++) { for (int j = 0; j < 5; j++) { printf("%d ", *(arr[i]+j));//地址访问解引用 } printf("\n"); } return 0; }
指针数组中元素都是指针变量,就是地址
int main() { int a = 10; int b = 11; int c = 12; int d = 13; int e = 14; int* arr[5] = { &a,&b,&c,&d,&e };//指针数组存放的元素是指针变量,就是地址 for (int i = 0; i < 5; i++) { printf("%d ", *(arr[i]));//地址解引用 } return 0; }
到此,关于“C语言指针运算实例分析”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。