• 售前

  • 售后

热门帖子
入门百科

C语言:指针的第二层(进阶篇)

[复制链接]
13471756666 显示全部楼层 发表于 2022-1-16 13:16:53 |阅读模式 打印 上一主题 下一主题
目次
1. 字符指针
 2.指针数组
3.数组指针 
3.1 数组指针的界说
3.2 &数组名VS数组名 
3.3 数组指针的利用
4.数组参数、指针参数
4.1 一维数组传参
4.2 二维数组传参
4.3 一级指针传参
5.函数指针
6.函数指针数组
7.指向函数指针数组的指针
8.回调函数


   我们在开端学习C语言时,就已经开端的打仗过指针这个东西的存在,也对指针有了大概的相识
          1.指针就是个变量,是用来存放内存地点的,内存中地点唯一标识一块内存空间!
          2.指针的巨细是固定的4/8个字节(32位体系平台/64位体系平台)
          3.指针是有具体范例的,指针的范例决定了在 + / - 整数时指针所偏移的步长(或称跨度),            以及指针解引用时访问多少个字节的权限
          4.可以用来指针运算
  这一篇中,继续来探索新的指针更深入条理的主题 

1. 字符指针


在初识指针之后都知道指针中有一种范例叫字符指针 - char*;
对于指针一样寻常的利用:
  1. int main()
  2. {
  3.         char ch = 'W';//创建char变量ch
  4.         char* pc = &ch; //取出变量ch的内存地址,将其放进字符指针变量pc中,pc的内容就是ch的地址
  5.         *pc = 'A';//通过指针解引用找到ch 将其内容值修改
  6.         return 0;
  7. }
复制代码
对字符指针另有一种利用:
  1. int mian()
  2. {
  3.         char* pc = "hello word";//一个思考,这是把一个字符串给放到pc指针中去了吗?
  4.         printf("%s\n", pc);
  5.         return 0;
  6. }
复制代码
第二个代码块中,char* pc = "hello word"; 是特殊容易让各人以为是把一个字符串hello word放到字符指针pc中去了,但是实在这个代码本质上只是把 hello word 首字符 的地点放到了pc中
来看一道风趣的标题
  1. #include <stdio.h>
  2. int main()
  3. {
  4.         char str1[] = "hello word";
  5.         char str2[] = "hello word";
  6.         char* str3 = "hello word";
  7.         char* str4 = "hello word";
  8.         if (str1 == str2)
  9.                 printf("str1 and str2 are same\n");
  10.         else
  11.                 printf("str1 and str2 are not same\n");
  12.         if (str3 == str4)
  13.                 printf("str3 and str4 are same\n");
  14.         else
  15.                 printf("str3 and str4 are not same\n");
  16.         return 0;
  17. }
复制代码
在每个人看到的第一眼,都会以为输出的结果为 str1 and str2 are same /str3 and str4 are not same     但实在,结果却大大相反!! 先看看结果

这里终极输出的是:

应该会有许多人很惊讶, 为什么str1 和str2是不相称的?
实在很简单,str1和str2 两个是数组,数组中存储的字符串 是一样的,但是各人不要忘记了,数组名代表数组首元素地点,既然是两个数组那么肯定就拥有着两块差别的空间,固然存储的内容一样,但是它们的地点 那但是完全不一样,下面的判断语句则是地点与地点是否相称,很显然 输出的结果肯定是else
那如果按这么说,那么str3为什么会和str4相称?  是由于str3和str4它们不是数组,它们是指针变量,只不外指向的是同一个字符串hello word,那么这个字符串是常量字符串,常量字符串的特性:可以访问,可以利用,但不可修改 那么既然都不可修改 内存中就没须要存储两份千篇划一的常量字符串,那么str3和str4 存储的都是这一个常量字符串中h的地点 颠末if语句判断 输出的结果为 same~


 2.指针数组


在开端熟悉指针中,也学习了一下指针数组,指针数组本质上就是一个用于存放多个同范例指针聚集的数组
  1.         int* arr1[10]; //整形指针的数组
  2.         char* arr2[4]; //一级字符指针的数组
  3.         char** arr3[5];//二级字符指针的数组
复制代码
指针数组利用起来还好坏常简单的:
  1. int main()
  2. {
  3.         //int* arr1[10]; //整形指针的数组
  4.         //char* arr2[4]; //一级字符指针的数组
  5.         //char** arr3[5];//二级字符指针的数组
  6.         //创建三个数组
  7.         int a[] = { 1,2,3,4,5 };
  8.         int b[] = { 6,7,8,9,10 };
  9.         int c[] = { 11,12,13,14,15 };
  10.         //创建指针数组 并且把存进三个数组的指针
  11.         int* tmp[3] = { a,b,c };
  12.         //利用指针数组,打印这三个指针指向的空间内容
  13.         int i = 0;
  14.         for (i = 0; i < 3; i++)
  15.         {
  16.                 int j = 0;
  17.                 for (j = 0; j < 5; j++)
  18.                 {
  19.                         printf("%d ", * (tmp[i] + j));//写法1;
  20.                         //printf("%d ", *(*(tmp + i) + j));//写法2;
  21.                         //printf("%d ", tmp[i][j]);//写法3;
  22.                 }
  23.                 printf("\n");
  24.         }
  25.         return 0;
  26. }
复制代码
  在这段代码中,我创建了3个int范例数组,而且都存储5个元素
  再而创建了一个指针数组,用于存放这三个数组的指针,那么在之前的学习中我们都知道,数组名代表着首元素的地点,那么既然代表着首元素的地点,它就是个地点 地点实在就是指针,也就可以明白为数组名实在就是一个一级指针, 创建指针数组时 tmp先和[ ]联合,代表它是个数组,数组中有3个元素,每个元素范例为int* 足以证实它是个指针数组,那么再把三个数组的数组名放进去,实在存放的就是三个一级指针
  在下面的打印中,printf实在有三种写法,第一种写法中 tmp实在等价于*(tmp+i)拿到了tmp数组中某个指针指向的那块空间,然后在表面又举行了 +j 解引用 就是拿到了谁人位置的元素 将其打印  这也就等价于写法2: *(*(tmp + i) + j 写法2又等价于写法3:tmp[j]
  


3.数组指针 


3.1 数组指针的界说

数组指针到底是指针?照旧数组?
答案是:指针.
我们已经熟悉:
整形指针: int * pint; 可以大概指向整形数据的指针。
浮点型指针: float * pf; 可以大概指向浮点型数据的指针。
那数组指针应该是:可以大概指向数组的指针。
下面代码哪个是数组指针?
   
  1. int *p1[10];
  2. int (*p2)[10];
  3. //p1, p2分别是什么?
复制代码
表明:
     int *p1[10]; 在我们学过的优先级中,[ ]的优先级是高于*的 以是p1先和[ ]联合,这时间p1是个数组,它有10个元素,每个元素的范例是int* 以是它是个指针数组!
   int (*p)[10] ; 这里 ( )的优先级是最高的,那么p先和*举行联合,这时间p是个指针, 把p拿掉后还剩下 int  [10]; 证实指针指向一个数组,数组有10个元素,每个元素是int范例; 
   //这里要留意: [ ] 的优先级是要高于*的,以是必须加上( )来包管p先和*联合.
    3.2 &数组名VS数组名 

对于下面的数组:
  1. int arr[10];
复制代码
arr 和 &arr 分别是什么?
此中,arr是数组名,数组名表现的是首元素的地点.
那&arr数组名到底是什么?  看一段代码:
  1. #include <stdio.h>
  2. int main()
  3. {
  4.    int arr[10] = {0};
  5.    printf("%p\n", arr);
  6.    printf("%p\n", &arr);
  7.    return 0;
  8. }
复制代码
运行结果如下: 

可见数组名和&数组名打印的地点是一样的。
岂非两个是一样的吗?
我们再看一段代码:
  1. #include <stdio.h>
  2. int main()
  3. {
  4. int arr[10] = { 0 };
  5. printf("arr = %p\n", arr);
  6. printf("&arr= %p\n", &arr);
  7. printf("arr+1 = %p\n", arr+1);
  8. printf("&arr+1= %p\n", &arr+1);
  9. return 0;
  10. }
复制代码
 它的运行结果如下


根据上面的代码我们发现,实在&arr和arr,固然值是一样的,但是意义应该不一样的。
现实上: &arr 表现的是数组的地点,而不是数组首元素的地点。
数组的地点+1,跳过整个数组的巨细,以是 &arr+1 相对于 &arr 的差值是40


3.3 数组指针的利用

那数组指针是怎么利用的呢?
既然数组指针指向的是数组,那数组指针中存放的应该是数组的地点。
看代码:
  1. #include <stdio.h>
  2. int main()
  3. {
  4.    int arr[10] = {1,2,3,4,5,6,7,8,9,0};
  5.    int (*p)[10] = &arr;//把数组arr的地址赋值给数组指针变量p
  6.    //但是我们一般很少这样写代码
  7.    return 0;
  8. }
复制代码
为什么我说一样寻常很少如许写代码? 由于数组指针用在一维数组上,实在并不是那么得当, 最得当一维数组的指针,就是一级指针,而非数组指针,不信的话 看看下面代码数组指针对于一维数组的打印:
  1. #include <stdio.h>
  2. int main()
  3. {
  4.         int arr[10] = { 1,2,3,4,5,6,7,8,9,0 };
  5.         int(*p)[10] = &arr;//把数组arr的地址赋值给数组指针变量p
  6.         int* a = arr; //把数组首元素地址付给一级整形指针a;
  7.         int i = 0;
  8.         for (i = 0; i < 10; i++)
  9.         {
  10.                 printf("%d ", *((*p) + i));//数组指针打印一维数组的方式
  11.                 printf("%d ", *(a + i));//一级指针打印一维数组的方式
  12.         }
  13.         return 0;
  14. }
复制代码
在这段代码中,显着用一级指针来举行一维数组打印,岂论是誊写,照旧可读性 都会更加的好,用数组指针也是可以,只不外显得有点杀鸡焉用牛刀 一样寻常数组指针,都是用于二维数组身上
一个数组指针的利用:
[code]#include void print_arr1(int arr[3][5], int row, int col) {    int i = 0;    for(i=0; i

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x

帖子地址: 

回复

使用道具 举报

分享
推广
火星云矿 | 预约S19Pro,享500抵1000!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

草根技术分享(草根吧)是全球知名中文IT技术交流平台,创建于2021年,包含原创博客、精品问答、职业培训、技术社区、资源下载等产品服务,提供原创、优质、完整内容的专业IT技术开发社区。
  • 官方手机版

  • 微信公众号

  • 商务合作