福田欧曼服务站,无广告免费赚钱无门槛的游戏,怎么用txt做网站,做网站买完域名还需要什么hello#xff0c;各位小伙伴#xff0c;本篇文章跟大家一起继续深入学习指针#xff0c;感谢大家对我上一篇的支持#xff0c;如有什么问题#xff0c;还请多多指教
如果本篇文章对你有帮助#xff0c;还请各位点点赞#xff01;#xff01;#xff01; 话不多说各位小伙伴本篇文章跟大家一起继续深入学习指针感谢大家对我上一篇的支持如有什么问题还请多多指教
如果本篇文章对你有帮助还请各位点点赞 话不多说进入正题
1. 字符指针变量 一般我们有这两种方式来创建字符指针但是我们看到代码2中的字符指针用 const 修饰了也就是*pstr不能改变也就是字符串不能修改。因为代码2中字符指针存储的是常量字符串常量字符串是不能修改的。
这里有一个要注意的点在代码2中字符串指针pstr存的不是整个字符串而是字符串首字符的地址。看图解:
所以pstr存的是h的地址
《剑指offer》中收录了⼀道和字符串相关的笔试题我们⼀起来学习⼀下
#include stdio.h
int main()
{char str1[] hello bit.;char str2[] hello bit.;const char *str3 hello bit.;const char *str4 hello bit.;if(str1 str2)printf(str1 and str2 are same\n);elseprintf(str1 and str2 are not same\n);if(str3 str4)printf(str3 and str4 are same\n);elseprintf(str3 and str4 are not same\n);return 0;
}想必通过上面的讲解小伙伴们都知道答案了吧 这⾥str3和str4指向的是⼀个同⼀个常量字符串。C/C会把常量字符串存储到单独的⼀个内存区域 当⼏个指针指向同⼀个字符串的时候他们实际会指向同⼀块内存。但是用相同的常量字符串去初始 化不同的数组的时候就会开辟出不同的内存块。所以str1和str2不同str3和str4相同。
2. 数组指针变量
2.1 数组指针变量是什么
首先我们要搞明白的是数组指针变量是指针变量。举个例子红色苹果是苹果因为红色是形容词所以数组指针变量中的数组就是形容词用来修饰指针变量。
我们学过整型指针变量、还有刚那个字符指针变量 整型指针变量int * pint;存放的是整形变量的地址能够指向整形数据的指针。 浮点型指针变量 float * pf; 存放浮点型变量的地址能够指向浮点型数据的指针。 同理得数组指针变量存放的应该是数组的地址能够指向数组的指针变量。 我们来猜猜哪一个是数组指针变量
int *p1[10];
int (*p2)[10];
答案是p2
首先[ ]的优先级比 * 更高所以[ ]会优先与p1结合也就是p1是一个数组存放的是int *元素也就存放的是整型指针所以p1为指针数组
那么p2有括着*p2也就是p2是一个指针指向后面的[10]也就是指向数组大小为10个整型的数组而前面的int则是表示数组里存的元素为整型所以p2为数组指针变量 这⾥要注意[]的优先级要⾼于*号的所以必须加上来保证p先和*结合。 2.2 数组指针变量怎么初始化
知道数组指针变量存的是数组的地址那怎么存呢
在深入理解指针2有讲过数组名
int arr[10] {0};
arr;//取得arr的地址
那么同样的指针指向数组
int arr[10] {0};
int (*p)[10] arr; 可以看到arr和p的类型是完全一样的
数组指针类型解析 int (*p) [10] arr; | | | | | | | | p指向数组的元素个数 | p是数组指针变量名 p指向的数组的元素类型 3. ⼆维数组传参的本质
有了数组指针的理解我们就能够讲⼀下⼆维数组传参的本质了。 过去我们有⼀个⼆维数组的需要传参给⼀个函数的时候我们是这样写的
#include stdio.h
void test(int a[3][5], int r, int c)
{int i 0;int j 0;
for(i0; ir; i){for(j0; jc; j){printf(%d , a[i][j]);}printf(\n);}
}
int main()
{int arr[3][5] {{1,2,3,4,5}, {2,3,4,5,6},{3,4,5,6,7}};test(arr, 3, 5);return 0;
}我们知道二维数组就是一维数组里存放的是一维数组那么一维数组的传参我们是学过的呀
就是把数组的首元素地址传过去那么二维数组首元素不就是一维数组了吗那就意味着⼆维数组传参本质上也是传递了地址传递的是第一个一维数组的地址一维数组的地址类型就是数组指针类型----int(*)[5] 那么形参也是可以写成指针形式的
#include stdio.h
void test(int (*p)[5], int r, int c)
{int i 0;
int j 0;for(i0; ir; i){for(j0; jc; j){printf(%d , *(*(pi)j));// *(pi) :就是二维数组里的元素---一维数组} // *(*(pi)j)) 就是一维数组里的元素---整型变量printf(\n);}
}
int main()
{int arr[3][5] {{1,2,3,4,5}, {2,3,4,5,6},{3,4,5,6,7}};test(arr, 3, 5);return 0;
}总结⼆维数组传参形参的部分可以写成数组也可以写成指针形式。
不过写成数组形式更容易让人理解罢了
4. 函数指针变量
4.1 函数指针变量的创建
是不是和数组指针变量名字上有点相似对的函数指针变量也是指针存放的当然是函数啦
为了方便后面的理解我们下来看一段代码
#include stdio.h
void test()
{printf(hehe\n);
}
int main()
{printf(test: %p\n, test);printf(test: %p\n, test);return 0;
}
结果如下 嗯test和test在printf里打印地址的效果竟然一样这种操作是不是似曾相识没错我们的数组也是一样的等等函数竟然也有地址对函数也有地址函数名就是函数的地址
那我们把函数的地址存起来不就是创建了函数指针变量了嘛函数指针变量的写法其实和数组指针非常类似看
void test()
{printf(hehe\n);
}
void (*pf1)() test;
void (*pf2)() test;//都表示test函数的地址
int Add(int x, int y)
{return xy;
}
int(*pf3)(int, int) Add;
int(*pf3)(int x, int y) Add;//x和y写上或者省略都是可以的
我们来分析一下这个指针类型的写法 int (*pf3) (int x, int y) *表示pf3是一个指针 pf3表示指针的变量名 *pf3后面跟着的 ( ) 表示指针指向一个函数 该 ( ) 里面的int xint y表示这个函数所需传参的类型以及传参的个数 int表示这个函数的返回类型为整型int 4.2 函数指针变量的使用 既然我都存下了函数的地址那我肯定是要用的所以通过函数指针调用指针指向的函数。
#include stdio.h
int Add(int x, int y)
{return xy;
}
int main()
{int(*pf3)(int, int) Add;printf(%d\n, (*pf3)(2, 3));printf(%d\n, pf3(3, 5));return 0;
} 发现pf3指针不需要解引用也可以调用函数 得出结论pf3和test是一样的
我们来看看有趣的代码
代码1
(*(void (*)())0)(); void (*)()就是一个函数指针类型 (void (*)())0就是将0强制转换为该函数指针类型 *(void (*)())0就是将0解引用也就是函数的名字 (*(void (*)())0)()就是一个函数 代码2 void (*signal(int , void(*)(int)))(int); 这是一个函数声明用于声明一个名为signal的函数该函数接受两个参数一个整数类型的参数和一个指向函数的指针该函数的参数是整数类型且返回值为空。 函数signal的返回值是一个指向函数的指针该函数有一个整数类型的参数和返回值为空。 通常该函数用于注册信号处理程序以处理在程序运行过程中接收到的各种信号。它允许用户指定对特定信号的处理方式当接收到相应的信号时调用相应的函数来处理。 请注意这只是一个函数声明并没有给出具体的函数实现。在使用signal函数之前需要进行函数定义并提供相应的信号处理程序来实现具体的功能。 4.3.1 typedef关键字
⽐如你觉得 unsigned int 写起来不⽅便如果能写成 uint 就⽅便多了那么我们可以使⽤ typedef unsigned int uint; //将unsigned int 重命名为uint 如果是指针类型能否重命名呢其实也是可以的⽐如将 int* 重命名为 ptr_t ,这样写 typedef int* ptr_t; 但是对于数组指针和函数指针稍微有点区别 ⽐如我们有数组指针类型 int(*)[5] ,需要重命名为 parr_t 那可以这样写 typedef int(*parr_t)[5]; //新的类型名必须在*的右边 函数指针类型的重命名也是⼀样的⽐如将 void(*)(int) 类型重命名为 pf_t ,就可以这样写 typedef void(*pfun_t)(int);//新的类型名必须在*的右边 那么修改名字后代码可以这样写
typedef void(*pfun_t)(int);
pfun_t signal(int, pfun_t);
5. 函数指针数组
想必小伙伴们都知道函数指针数组是一个数组用来存放函数指针变量的
我们来猜猜哪一个是函数指针数组
int (*parr1[3])();
int *parr2[3]();
int (*)() parr3[3]; 答案是parr1 parr1[3]表示函数指针数组是一个数组 parr1[3]前的 * 表示该数组存的是函数指针也就是指针嘛 (*parr1[3])后面的( )表示该指针指向函数当然啦( ) 里面的参数就和函数指针里的意思一样 前面的int 表示该函数的返回类型 总的来说该数组的内容是int (*)() 类型的函数指针
好啦本篇文章对于指针就讲到这里如果有什么问题还请指教指教希望本篇文章能够对你有所帮助我们下一篇见
如你喜欢点点赞就是对我的支持感谢感谢 文章转载自: http://www.morning.mmtjk.cn.gov.cn.mmtjk.cn http://www.morning.rnzjc.cn.gov.cn.rnzjc.cn http://www.morning.wnhml.cn.gov.cn.wnhml.cn http://www.morning.niukaji.com.gov.cn.niukaji.com http://www.morning.lywpd.cn.gov.cn.lywpd.cn http://www.morning.hkcjx.cn.gov.cn.hkcjx.cn http://www.morning.djpgc.cn.gov.cn.djpgc.cn http://www.morning.wdply.cn.gov.cn.wdply.cn http://www.morning.kdldx.cn.gov.cn.kdldx.cn http://www.morning.bpmnc.cn.gov.cn.bpmnc.cn http://www.morning.rnrfs.cn.gov.cn.rnrfs.cn http://www.morning.gjmbk.cn.gov.cn.gjmbk.cn http://www.morning.gnwpg.cn.gov.cn.gnwpg.cn http://www.morning.rpkl.cn.gov.cn.rpkl.cn http://www.morning.pctsq.cn.gov.cn.pctsq.cn http://www.morning.nytqy.cn.gov.cn.nytqy.cn http://www.morning.hlhqs.cn.gov.cn.hlhqs.cn http://www.morning.plcyq.cn.gov.cn.plcyq.cn http://www.morning.fglyb.cn.gov.cn.fglyb.cn http://www.morning.gyxwh.cn.gov.cn.gyxwh.cn http://www.morning.fksdd.cn.gov.cn.fksdd.cn http://www.morning.sfwcb.cn.gov.cn.sfwcb.cn http://www.morning.yfphk.cn.gov.cn.yfphk.cn http://www.morning.rkbly.cn.gov.cn.rkbly.cn http://www.morning.xcdph.cn.gov.cn.xcdph.cn http://www.morning.kzslk.cn.gov.cn.kzslk.cn http://www.morning.jnhhc.cn.gov.cn.jnhhc.cn http://www.morning.gllhx.cn.gov.cn.gllhx.cn http://www.morning.jjhng.cn.gov.cn.jjhng.cn http://www.morning.rntyn.cn.gov.cn.rntyn.cn http://www.morning.lwnb.cn.gov.cn.lwnb.cn http://www.morning.wqsjx.cn.gov.cn.wqsjx.cn http://www.morning.tntqr.cn.gov.cn.tntqr.cn http://www.morning.zbqry.cn.gov.cn.zbqry.cn http://www.morning.nmfml.cn.gov.cn.nmfml.cn http://www.morning.lxngn.cn.gov.cn.lxngn.cn http://www.morning.knnc.cn.gov.cn.knnc.cn http://www.morning.bksbx.cn.gov.cn.bksbx.cn http://www.morning.npgwb.cn.gov.cn.npgwb.cn http://www.morning.rlwcs.cn.gov.cn.rlwcs.cn http://www.morning.jfymz.cn.gov.cn.jfymz.cn http://www.morning.msfqt.cn.gov.cn.msfqt.cn http://www.morning.fjmfq.cn.gov.cn.fjmfq.cn http://www.morning.qfwzm.cn.gov.cn.qfwzm.cn http://www.morning.qclmz.cn.gov.cn.qclmz.cn http://www.morning.brbmf.cn.gov.cn.brbmf.cn http://www.morning.wrtbx.cn.gov.cn.wrtbx.cn http://www.morning.mrkbz.cn.gov.cn.mrkbz.cn http://www.morning.tbwsl.cn.gov.cn.tbwsl.cn http://www.morning.wqngt.cn.gov.cn.wqngt.cn http://www.morning.yjmlg.cn.gov.cn.yjmlg.cn http://www.morning.ftntr.cn.gov.cn.ftntr.cn http://www.morning.pfggj.cn.gov.cn.pfggj.cn http://www.morning.gl-group.cn.gov.cn.gl-group.cn http://www.morning.grpbt.cn.gov.cn.grpbt.cn http://www.morning.tkflb.cn.gov.cn.tkflb.cn http://www.morning.sxbgc.cn.gov.cn.sxbgc.cn http://www.morning.dzgyr.cn.gov.cn.dzgyr.cn http://www.morning.knscf.cn.gov.cn.knscf.cn http://www.morning.lflnb.cn.gov.cn.lflnb.cn http://www.morning.rxkl.cn.gov.cn.rxkl.cn http://www.morning.kmwbq.cn.gov.cn.kmwbq.cn http://www.morning.bqqzg.cn.gov.cn.bqqzg.cn http://www.morning.ftzll.cn.gov.cn.ftzll.cn http://www.morning.mzqhb.cn.gov.cn.mzqhb.cn http://www.morning.qbgdy.cn.gov.cn.qbgdy.cn http://www.morning.sbjbs.cn.gov.cn.sbjbs.cn http://www.morning.mfmx.cn.gov.cn.mfmx.cn http://www.morning.fqnql.cn.gov.cn.fqnql.cn http://www.morning.c-ae.cn.gov.cn.c-ae.cn http://www.morning.yhsrp.cn.gov.cn.yhsrp.cn http://www.morning.cxryx.cn.gov.cn.cxryx.cn http://www.morning.qynnw.cn.gov.cn.qynnw.cn http://www.morning.qwnqt.cn.gov.cn.qwnqt.cn http://www.morning.rkdnm.cn.gov.cn.rkdnm.cn http://www.morning.fpngg.cn.gov.cn.fpngg.cn http://www.morning.yaqi6.com.gov.cn.yaqi6.com http://www.morning.fkmyq.cn.gov.cn.fkmyq.cn http://www.morning.ccphj.cn.gov.cn.ccphj.cn http://www.morning.xqgtd.cn.gov.cn.xqgtd.cn