C语言基础知识:最核心的—指针!知识总结(第二部分)
yund56 2025-05-08 16:41 22 浏览
指针是C语言最重要也是最难理解的部分,它在我们平时的工作中无处不在。
今天我们继续来看看指针的剩下的知识总结吧!上一批的话可以在主页看到哦~
5 指针与结构体
一个指针,它指向的可以是一个结构体类型,这称为结构体指针。而一个结构体,它的成员中也可以有指针成员。
struct{
char *name; //姓名
int num; //学号
int age; //年龄
char group; //所在小组
float score; //成绩
} stu1 = { "Tom", 12, 18, 'A', 136.5 }, *pstu = &stu1;上面的代码中,定义了一个结构体变量stu1。这个变量中有一个指针变量name。还定义了一个结构体指针pstu。
我们想要通过结构体指针访问结构体成员一般有以下两种方式:
(*pstu).name;
pstu->name;6 指针与const:常量指针与指针常量
初学者常常对这两个概念搞错。首先,我认为需要理解这里说的常量是什么意思。常量就是只可读不可修改的。那常量指针和指针常量到底哪个是只可读不可修改的呢?是指针还是指针指向的内容?这里有一个方法,能让你迅速明白哪个是不可修改的。就是在声明时,以星号(*)为界,分成两部分,星号左边的和星号右边的。const在哪边,那个就是只可读不可修改的。以下面这个代码为例,我们来分析一下:以星号(*)为界,星号左边是char,没有const关键词,所以它指向的内容不是常量。然后,我们看星号的右边是const ptr,所以我们可以说ptr是一个常量。所以,这行代码声明了一个是常量的指针但是指向的内容不是常量。即这个是一个指针常量。
char* const ptr = "just a string";类似的,我们也可以分析下面的代码:
// Neither the data nor the pointer are const
//
char* ptr = "just a string";
// Constant data, non-constant pointer
//
const char* ptr = "just a string";
// Constant pointer, non-constant data
//
char* const ptr = "just a string";
// Constant pointer, constant data
//
const char* const ptr = "just a string";6.1 指针常量(Constant Pointers)
指针常量(Constant Pointers): 它的本质是一个常量,只不过这个常量是指针。由于指针是只可读不可修改的,所以这个指针不能指向别的地址了,但是该地址里的内容还是可以改变的。指针常量的声明格式如下:
<type of pointer> * const <name of pointer>
例如: int * const ptr;我们来看下序:
#include<stdio.h>
int main(void)
{
int var1 = 0, var2 = 0;
int *const ptr = &var1;
ptr = &var2;
printf("%d\n", *ptr);
return 0;
}上面这段程序中:
我们首先定义了两个变量var1,var2;
然后,定义了一个指针常量ptr,并且指向了var1
接着,试图让ptr指向var2
最后,打印出指针ptr指向的地址的内容
让我们来运行一下这个程序:
main.c: In function 'main':
main.c:6:9: error: assignment of read-only variable 'ptr'
ptr = &var2;
^我们看到这个程序编译报错了:试图对只读(read-only)变量ptr进行赋值。所以,一旦我们定义了指针常量,那这个指针就不能指向其他变量了。
但是我们还是可以修改指向的地址里的内容的:
#include<stdio.h>
int main(void)
{
int var1 = 0;
int *const ptr = &var1;
*ptr = 10; // OK
printf("%d\n", *ptr); // 10
return 0;
}6.2 常量指针(Pointer to Constants)
常量指针(Pointer to Constants):它的本质是一个指针,只不过它指向的值是常量(只可读,不可修改)。由于指向的是一个只可读不修改的值,所以指针不能通过它存储的地址间接修改这个地址的值,但是这个指针可以指向别的变量。
常量指针的声明格式如下:
const <type of pointer>* <name of pointer>
例如: const int* ptr;还是有一段程序:
#include<stdio.h>
int main(void)
{
int var1 = 0;
const int* ptr = &var1;
*ptr = 1;
printf("%d\n", *ptr);
return 0;
}我们还是来分析一下这个程序:
我们定义了一个变量 var1,并且初始化为0
然后我们定义了一个指针常量ptr,并且将它指向了var1
接着,试图通过指针ptr来改变var1的值
最后,打印出ptr指向的地址的内容。
我们进行编译:
main.c: In function 'main':
main.c:7:10: error: assignment of read-only location '*ptr'
*ptr = 1;
^编译报错也很明显: *ptr是一个只读的。所以不能通过ptr来修改var1的值。
但是,我们可以将ptr指向其他的变量:
#include<stdio.h>
int main(void)
{
int var1 = 0;
const int* ptr = &var1;
printf("%d\n", *ptr); // 0
int var2 = 20;
ptr = &var2; // OK
printf("%d\n", *ptr); // 20
return 0;
}6.3 指向常量的常量指针
理解了上面两种类型的话,理解这个就很容易了。指向常量的常量指针是指这个指针既不能指向其他的地址也不能通过地址修改内容。
它的声明格式如下:
const <type of pointer>* const <name of pointer>
例如: const int* const ptr;同样,下面一段程序,我想你一定知道哪里编译错误了。
#include<stdio.h>
int main(void)
{
int var1 = 0,var2 = 0;
const int* const ptr = &var1;
*ptr = 1;
ptr = &var2;
printf("%d\n", *ptr);
return 0;
}编译结果:
main.c: In function 'main':
main.c:7:10: error: assignment of read-only location '*ptr'
*ptr = 1;
^
main.c:8:9: error: assignment of read-only variable 'ptr'
ptr = &var2;
^7 指针与函数
7.1 函数指针
指针与函数相结合有两种情况:指针函数、函数指针。
指针函数,它的本质是一个函数,它的返回值是一个指针。
int * func(int x, int y);函数名本身就是一个指针(地址),这个地址就是函数的入口地址。
#include <stdio.h>
int sum(int a, int b)
{
return a + b;
}
int main()
{
printf("%p\n", sum);
return 0;
}输出:
0000000000401550
而函数指针,它的本质是一个指针。只不过它存的地址恰好是一个函数的地址罢了。
函数指针变量定义的格式一般是:
返回值 (*变量名)(参数列表)比如:
#include <stdio.h>
int sum(int a, int b)
{
return a + b;
}
int main()
{
printf("%p\n", sum);
int (*psum)(int, int); // 函数指针变量,参数名可以省略
psum = sum;
printf("%p\n", psum);
return 0;
}输出:
0000000000401550
0000000000401550可以发现,两者地址相等。
函数指针类型的定义:
typedef 返回值 (* 类型名)(参数列表);复制代码比如:
typedef int(*PSUM)(int, int);
PSUM pSum2 = sum;
PSUM pSum3 = sum;这样的好处就是,首先通过typedef定义一个函数指针类型PSUM,定义完后,PSUM就相当于一种新的类型,可以用此类型去定义其他函数指针变量,就不用每次都使用int(*pSum)(int, int);来定义一个函数指针变量。
#include <stdio.h>
int sum(int a, int b)
{
return a + b;
}
int func2(int a, int b)
{
return a - b;
}
typedef int (*PFUNC) (int, int);
int main()
{
int (*psum)(int, int);
psum = sum;
printf("psum(4, 5):%d\n", psum(4, 5));
PFUNC p2 = func2;
printf("p2(5, 2):%d\n", p2(5, 2));
p2 = sum;
printf("p2(5, 2):%d\n", p2(5, 2));
return 0;
}
输出:
psum(4, 5):9
p2(5, 2):3
p2(5, 2):77.2 回调函数
说到函数指针,那还有一个概念不得不提——回调函数。因为在实际的项目代码中实在是太常见了。
回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。
那为什么要使用回调函数呢?或者说使用回调函数有什么好处呢?回调函数允许用户把需要调用的方法的指针作为参数传递给一个函数,以便该函数在处理相似的事情时,可以灵活的使用不同的方法。
怎么使用回调函数:
#include <stdio.h>
int Callback_1(int a) ///< 回调函数1
{
printf("Hello, this is Callback_1: a = %d \n", a);
return 0;
}
int Callback_2(int b) ///< 回调函数2
{
printf("Hello, this is Callback_2: b = %d \n", b);
return 0;
}
int Callback_3(int c) ///< 回调函数3
{
printf("Hello, this is Callback_3: c = %d \n", c);
return 0;
}
int Handle(int x, int (*Callback)(int)) // 注意这里用到的函数指针定义
{
Callback(x);
}
int main()
{
Handle(4, Callback_1);
Handle(5, Callback_2);
Handle(6, Callback_3);
return 0;
}如上述代码:可以看到,Handle()函数里面的参数是一个指针,在main()函数里调用Handle()函数的时候,给它传入了函数Callback_1()/Callback_2()/Callback_3()的函数名,这时候的函数名就是对应函数的指针,也就是说,回调函数其实就是函数指针的一种用法。
8 二维指针
二维指针,或者二级指针。就是指向指针的指针。比如:
#include<stdio.h>
int main()
{
int a = 10;
int *pa = &a;
int **ppa = &pa;
printf("%p, %p, %p, %p, %p", a, pa, *pa, ppa, *ppa);
return 0;
}输出如下:
000000000000000A, 000000000061FE14, 000000000000000A, 000000000061FE08, 000000000061FE14从输出结果也可以看到,pa存的内容*pa= 000000000000000A,刚好与a的地址相同。而ppa存的内容*ppa= 000000000061FE14也刚好等于pa的地址。它们之间的内存关系可以用如下的图表示:
8.1 命令行参数
处理命令行参数是指向指针的指针的一个用武之地。
一般main函数具有两个形参。第一个通常称为argc,它表示命令行参数的数目。第2个通常称为argv,它指向一组参数值。由于参数的数目并没有内在的限制,所以argv指向这组参数值(从本质上来说是一个数组)的第一个元素。这些元素的每个都是指向一个参数文本的指针。如果程序需要访问命令行参数,main函数在声明时就要加上这些参数。
int main(int argc, char **argv)举例:
#include <stdio.h>
int main(int argc, char *argv[])
{
printf("argc: %d\n", argc);
// 打印参数,直到遇到NULL指针。程序名被跳过
while (*++argv != NULL) {
printf("%s\n", *argv);
}
return 0;
}在windows上执行: \test2.exe hello world
输出:
argc: 3
hello
world注意,如果命令行中传递的一个参数包括空格,就需要用 ""将参数括起来,比如:
.\test2.exe "hello word"
则上面的代码将输出:
argc: 2
hello word9 结束语
本文关于指针的讲解就结束了。我相信你一定对指针有更深入的了解。
对啦对啦!另外的话为了帮助大家,轻松,高效学习C语言/C++,我给大家分享我收集的资源,从最零基础开始的教程到C语言项目案例,帮助大家在学习C语言的道路上披荆斩棘!可以来我粉丝群领取哦~
编程学习书籍分享:
编程学习视频分享:
整理分享(多年学习的源码、项目实战视频、项目笔记,基础入门教程)最重要的是你可以在群里面交流提问编程问题哦!
对于C/C++感兴趣可以关注小编在后台私信我:【编程交流】一起来学习哦!可以领取一些C/C++的项目学习视频资料哦!已经设置好了关键词自动回复,自动领取就好了!
相关推荐
- SM小分队Girls on Top,女神战队少了f(x)?
-
这次由SM娱乐公司在冬季即将开演的smtown里,将公司的所有女团成员集结成了一个小分队project。第一位这是全面ACE的大姐成员权宝儿(BoA),出道二十年,在日本单人销量过千万,韩国国内200...
- 韩国女团 aespa 首场 VR 演唱会或暗示 Quest 3 将于 10 月推出
-
AmazeVR宣布将在十月份举办一场现场VR音乐会,观众将佩戴MetaQuest3进行体验。韩国女团aespa于2020年11月出道,此后在日本推出了三张金唱片,在韩国推出了...
- 韩网热议!女团aespa成员Giselle在长腿爱豆中真的是legend
-
身高163的Giselle,长腿傲人,身材比例绝了...
- 假唱而被骂爆的女团:IVE、NewJeans、aespa上榜
-
在韩国,其实K-pop偶像并不被认为是真正的歌手,因为偶像们必须兼备舞蹈能力、也经常透过对嘴来完成舞台。由于科技的日渐发达,也有许多网友会利用消音软体来验证K-pop偶像到底有没有开麦唱歌,导致假唱这...
- 新女团Aespa登时尚大片 四个少女四种style
-
来源:环球网
- 韩国女团aespa新歌MV曝光 画面梦幻造型超美
-
12月20日,韩国女团aespa翻唱曲《DreamsComeTrue》MV公开,视频中,她们的造型超美!WINTER背后长出一双梦幻般的翅膀。柳智敏笑容甜美。宁艺卓皮肤白皙。GISELLE五官精致...
- 女网友向拳头维权,自称是萨勒芬妮的原型?某韩国女团抄袭KDA
-
女英雄萨勒芬妮(Seraphine)是拳头在2020年推出的第五位新英雄,在还没有正式上线时就备受lsp玩家的关注,因为她实在是太可爱了。和其他新英雄不同的是,萨勒芬妮在没上线时就被拳头当成虚拟偶像来...
- 人气TOP女团是?INS粉丝数见分晓;TWICE成员为何在演唱会落泪?
-
现在的人气TOP女团是?INS粉丝数见分晓!现在爱豆和粉丝之间的交流方法变得多种多样,但是Instagram依然是主要的交流手段。很多粉丝根据粉丝数评价偶像的人气,拥有数百、数千万粉丝的组合作为全球偶...
- 韩国女团MVaespa Drama MV_韩国女团穿超短裙子跳舞
-
WelcometoDrama.Pleasefollow4ruleswhilewatchingtheDrama.·1)Lookbackimmediatelywhenyoufe...
- aespa师妹团今年将出道! SM职员亲口曝「新女团风格、人数」
-
记者刘宛欣/综合报导南韩造星工厂SM娱乐曾打造出东方神起、SUPERJUNIOR、少女时代、SHINee、EXO等传奇团体,近年推出的aespa、RIIZE更是双双成为新生代一线团体,深受大众与粉丝...
- 南韩最活跃的女团aespa,新专辑《Girls》即将发布,盘点昔日经典
-
女团aespa歌曲盘点,新专辑《Girls》即将发布,期待大火。明天也就是2022年的7月8号,aespa新专辑《Girls》即将发行。这是继首张专辑《Savage》之后,时隔19个月的第二张专辑,这...
- 章泽天女团aespa出席戛纳晚宴 宋康昊携新片亮相
-
搜狐娱乐讯(山今/文玄反影/图科明/视频)法国时间5月23日晚,女团aespa、宋康昊、章泽天等明星亮相戛纳晚宴。章泽天身姿优越。章泽天肩颈线优越。章泽天双臂纤细。章泽天仪态端正。女团aespa亮...
- Aespa舞台暴露身高比例,宁艺卓脸大,柳智敏有“TOP”相
-
作为SM公司最新女团aespa,初舞台《BlackMamba》公开,在初舞台里,看得出来SM公司是下了大功夫的,虽然之前SM公司新出的女团都有很长的先导片,但是aespa显然是有“特殊待遇”。运用了...
- AESPA女团成员柳智敏karina大美女
-
真队内速度最快最火达成队内首个且唯一两百万点赞五代男女团中输断层第一(图转自微博)...
- 对来学校演出的女团成员语言性骚扰?韩国这所男高的学生恶心透了
-
哕了……本月4日,景福男子高中相关人士称已经找到了在SNS中上传对aespa成员进行性骚扰文章的学生,并开始着手调查。2日,SM娱乐创始人李秀满的母校——景福高中迎来了建校101周年庆典活动。当天,S...
- 一周热门
- 最近发表
-
- SM小分队Girls on Top,女神战队少了f(x)?
- 韩国女团 aespa 首场 VR 演唱会或暗示 Quest 3 将于 10 月推出
- 韩网热议!女团aespa成员Giselle在长腿爱豆中真的是legend
- 假唱而被骂爆的女团:IVE、NewJeans、aespa上榜
- 新女团Aespa登时尚大片 四个少女四种style
- 韩国女团aespa新歌MV曝光 画面梦幻造型超美
- 女网友向拳头维权,自称是萨勒芬妮的原型?某韩国女团抄袭KDA
- 人气TOP女团是?INS粉丝数见分晓;TWICE成员为何在演唱会落泪?
- 韩国女团MVaespa Drama MV_韩国女团穿超短裙子跳舞
- aespa师妹团今年将出道! SM职员亲口曝「新女团风格、人数」
- 标签列表
-
- filter函数js (37)
- filter函数excel用不了 (73)
- 商城开发 (40)
- 影视网站免费源码最新版 (57)
- 影视资源api接口 (46)
- 网站留言板代码大全 (56)
- java版软件下载 (52)
- java教材电子课本下载 (48)
- 0基础编程从什么开始学 (50)
- java是用来干嘛的 (51)
- it入门应该学什么 (55)
- java线上课程 (55)
- 学java的软件叫什么软件 (38)
- 程序开发软件有哪些 (53)
- 软件培训 (59)
- 机器人编程代码大全 (50)
- 少儿编程教程免费 (45)
- 新代系统编程教学 (61)
- 共创世界编程网站 (38)
- 亲测源码 (36)
- 三角函数积分公式表 (35)
- 函数的表示方法 (34)
- 表格乘法的公式怎么设置 (34)
- sumif函数的例子 (34)
- 图片素材 (36)
