C语言指针 ゝ一纸荒年。 2023-07-19 10:46 46阅读 0赞 ### 文章目录 ### * 一、变量的地址 * 二、指针 * 三、对指针赋值 * 四、通过指针操作内存变量 * 五、再来讨论函数的参数传递 * 六、空指针 * 七、数组的地址 * 八、地址的运算 * 九、指针占用内存情况 * 十、指针的其它知识 * 十一、小结 * 十二、课后作业 * 十三、获取视频教程 * 十四、版权声明 # 一、变量的地址 # 内存变量简称变量,在C语言中,每定义一个变量,系统就会给变量分配一块内存,而内存是有地址的。如果把计算机的内存区域比喻成一个大宾馆,每块内存的地址就像宾馆房间的编号。 C语言采用运算符&来获取变量的地址。请看下面的示例。 **示例(book50.c)** /* * 程序名:book50.c,此程序用于演示获取变量的地址 * 作者:C语言技术网(www.freecplus.net) 日期:20190525 */ #include <stdio.h> int main() { int ii=10; char cc='A'; double dd=100.56; printf("变量ii的地址是:%p\n",&ii); printf("变量cc的地址是:%p\n",&cc); printf("变量dd的地址是:%p\n",&dd); return 0; } **运行效果** ![在这里插入图片描述][20200303163622948.png] 注意: 1)在printf函数中,输出内存地址的格式控制符是%p,地址采用十六进制的数字显示。 2)book50程序运行了两次,每次输出的结果不一样,原因很简单,程序每次运行的时候,向系统申请内存,系统随机分配内存,就像您去宾馆开房,如果您不提前预约指定房号,每次得到的房间编号大概率不会相同。 # 二、指针 # 指针是一种特别变量,全称是指针变量,专用于存放其它变量在内存中的地址编号,指针在使用之前要先声明,语法是: datatype *varname; datatype 是指针的基类型,它必须是一个有效的C数据类型(int、char、double或其它自定义的数据类型),varname 是指针的名称。用来声明指针的星号 \* 与乘法中使用的星号是相同的。但是,在这个场景中,星号是用来表示这个变量是指针。以下是有效的指针声明: int *ip; // 一个整型的指针 char *cp; // 一个字符型的指针 double *dp; // 一个 double 型的指针 # 三、对指针赋值 # 不管是整型、浮点型、字符型,还是其他的数据类型的内存变量,它的地址都是一个十六进制数,可以理解为内存单元的编号。我们用整数型指针存放整数型变量的地址;用字符型指针存放字符型变量的地址;用双精度型指针存放双精度型变量的地址,用自定义数据类型指针存放自定义数据类型变量的地址。 把指针指向具体的内存变量的地址,就是对指针赋值。 **示例book51.c** /* * 程序名:book51.c,此程序用于演示指针变量 * 作者:C语言技术网(www.freecplus.net) 日期:20190525 */ #include <stdio.h> int main() { int ii=10; char cc='A'; double dd=100.56; int *pii=0; // 定义整数型指针并初始化 char *pcc=0; // 定义字符型指针并初始化 double *pdd=0; // 定义双精度型指针并初始化 pii=ⅈ // 数型指针并指向变量ii pcc=&cc; // 字符型指针并指向变量cc pdd=ⅆ // 双精度型指针并指向变量dd // 输出指针变量的值 printf("pii的值是:%p\n",pii); printf("pcc的值是:%p\n",pcc); printf("pdd的值是:%p\n",pdd); } **运行效果** ![在这里插入图片描述][2020030316563339.png] # 四、通过指针操作内存变量 # 定义了指针变量,并指向了内存变量的地址,就可以通过指针来操作内存变量(在指针前加星号\*),效果与使用变量名相同。 **示例(book52.c)** /* * 程序名:book52.c,此程序演示指针的使用。 * 作者:C语言技术网(www.freecplus.net) 日期:20190525 */ #include <stdio.h> int main() { int ii=10; int *pii=0; // 定义整数型指针并初始化 pii=ⅈ // 数型指针指向变量ii // 通过指针操作内存变量,改变内存变量的值 *pii=20; // 同ii=20; printf("pii的值是:%p\n",pii); printf("*pii的值是:%d\n",*pii); printf("ii的值是:%d\n",ii); } **运行效果** ![在这里插入图片描述][20200303165713337.png] # 五、再来讨论函数的参数传递 # 在我们之前讲的函数的参数章节中,book49.c演示了函数的参数传递,主程序调用funcld函数的时候,传递的是变量的值,现在把它修改一下。 **示例(book55.c)** /* * 程序名:book55.c,此程序演示函数参数的传递和指针 * 作者:C语言技术网(www.freecplus.net) 日期:20190525 */ #include <stdio.h> // 声明funcld函数,p是一个指针变量 void funcld(int *p); int main() { int a=10; printf("位置一:a是一个变量,变量的地址是%p,a的值是 %d\n",&a,a); funcld(&a); // 调用函数,传递变量a的地址的值 printf("位置二:a是一个变量,变量的地址是%p,a的值是 %d\n",&a,a); } void funcld(int *p) { printf("位置三:p是一个指针 %p, 指向的内存的地址是 %d\n",p,*p); *p=20; printf("位置四:p是一个指针 %p, 指向的内存的地址是 %d\n",p,*p); } **运行效果** ![在这里插入图片描述][20200303165801592.png] book55.c演示了函数参数和指针的使用,主程序把变量a的地址传递给函数funcld,funcld函数的参数p是一个指针,接存放变量a的地址。在函数funcld中,根据指针中的地址直接操作内存,从而修改了主程序中变量a的值。 我们已经使用scanf函数很多次了,调用scanf函数的时候,需要在变量前面加符号&,其实就是把变量的地址传给scanf函数,scanf函数根据传进去的地址直接操作内存,改变内存中的值,完成了对变量的赋值。 # 六、空指针 # 空指针就是说指针没有指向任何内存变量,指针的值是空,所以不能操作内存,否则可能会引起程序的崩溃。 **示例(book56.c)** /* * 程序名:book56.c,此程序演示操作空指针引起程序的崩溃 * 作者:C语言技术网(www.freecplus.net) 日期:20190525 */ #include <stdio.h> int main() { int *pi=0; // 定义一个指针 printf("pi的值是 %p\n",pi); *pi=10; // 试图对空指针进行赋值操作,必将引起程序的崩溃 return 0; } **运行效果** ![在这里插入图片描述][20200303165839327.png] 段错误(Core Dump),就是程序崩溃掉了。 # 七、数组的地址 # 在C语言中,数组占用的内存空间是连续的,数组名是数组元素的首地址,也是数组的地址。 **示例(book57.c)** /* * 程序名:book57.c,此程序数组的地址 * 作者:C语言技术网(www.freecplus.net) 日期:20190525 */ #include <stdio.h> #include <string.h> int main() { char name[51]; strcpy(name,"C语言技术网(www.freecplus.net)"); printf("%p\n",name); printf("%p\n",&name); printf("%p\n",&name[0]); printf("%s\n",name); printf("%s\n",&name); printf("%s\n",&name[0]); } **运行效果** ![在这里插入图片描述][20200303165923151.png] 从以上的示例可以看出,数组名、对数组取地址和数组元素的首地址是同一回事。在应用开发中,程序员一般用数组名,书写最简单。 # 八、地址的运算 # 地址可以用加(+)和减(-)来运算,加1表示下一个存储单元的地址,减1表示上一个存储单元的地址,一般情况下,地址的运算适用于数组,对单个变量的地址运算没有意义。 **示例(book58.c)** /* * 程序名:book58.c,此程序演示地址的运算。 * 作者:C语言技术网(www.freecplus.net) 日期:20190525 */ #include <stdio.h> int main() { char cc[4]; // 字符数组 int ii[4]; // 整数数组 double dd[4]; // 浮点数组 // 用地址相加的方式显示数组全部元素的的址 printf("%p %p %p %p\n",cc,cc+1,cc+2,cc+3); printf("%p %p %p %p\n",ii,ii+1,ii+2,ii+3); printf("%p %p %p %p\n",dd,dd+1,dd+2,dd+3); } **运行效果** ![在这里插入图片描述][20200303170018581.png] 大家请注意,第一行输出的每个地址的增量是1,第二行的每个地址的增量是4,第三行的每个地址的增量是8,为什么会这样?因为数组cc是char型,一个存储单元是1个字节,数组ii是int型,一个存储单元是4个字节,数组ll是long型,一个存储单元是8个字节,地址加1指的是下一个存储单元,不是数学意义中的1。 在应用开发中,地址的运算很重要,主要用于字符串操作,在以后的字符串章节中我将详细介绍。 # 九、指针占用内存情况 # 指针也是一种内存变量,是内存变量就要占用内存空间,在C语言中,任何类型的指针占用8字节的内存(32位操作系统4字节)。 printf("sizeof(int *) is %d.\n",sizeof(int *)); // 输出:sizeof(int *) is 8 printf("sizeof(char *) is %d.\n",sizeof(char *)); // 输出:sizeof(char *) is 8 printf("sizeof(double *) is %d.\n",sizeof(double *)); // 输出:sizeof(double *) is 8 输出的结果都是8。 # 十、指针的其它知识 # 本章节介绍的知识已经包括了指针99%的用法,还有一些的知识点如指针的指针、函数指针等,这些概念难以理解,应用场景极少。学习的方法应该是循序渐进,等功力增长之后,那些复杂的概念其实也很容易。如果在这里就把人搞晕了,就没办法继续学习下去。 # 十一、小结 # 操作变量可以用变量名,也可以用变量的地址。 指针用一句话可以概括,就是用来存放变量的地址,是一种中间状态的变量。 变量的地址是变量的地址,指针是指针,地址和指针之间的关系像水与水桶的关系,表达的时候要严谨一些,不要把地址说成指针,也不要把指针说成地址。 指针就这么简单,您自己不要把自己晕了就行。 # 十二、课后作业 # 1、编写示例程序,把本章节的知识全部演示一遍,必须充分理解每一个细节,指针对C/C++程序员极其重要,没有指针,程序没法写。 2、系统会为变量分配内存,也会为常量分配内存,有内存就有地址,试试以下代码,如果不能理解就跳过。 char *pstr="西施"; printf("pstr=%p\n",pstr); printf("pstr=%s\n",pstr); // 不会出现段错误(Core dump) strcpy(pstr,"杨玉环"); // 会出现段错误(Core dump) # 十三、获取视频教程 # 百万年薪程序员录制,《C/C++高性能服务开发基础》视频教程已在CSDN学院发布,优惠价12元,地址如下: [https://edu.csdn.net/course/play/29402][https_edu.csdn.net_course_play_29402] # 十四、版权声明 # C语言技术网原创文章,转载请说明文章的来源、作者和原文的链接。 来源:C语言技术网(www.freecplus.net) 作者:码农有道 如果文章有错别字,或者内容有错误,或其他的建议和意见,请您留言指正,非常感谢!!! [20200303163622948.png]: /images/20230528/9a1740e0c79847ca9655a51ae4a9b660.png [2020030316563339.png]: /images/20230528/ea7e24f97b9d4b329cd74bed636e5f3c.png [20200303165713337.png]: /images/20230528/a6a45bab5da6468f9d2e8fd37a8794e9.png [20200303165801592.png]: /images/20230528/cd883931e0b34f3ba93b6fe02aa81462.png [20200303165839327.png]: /images/20230528/ad118e7966d14ebf8bff51fc02a9102e.png [20200303165923151.png]: /images/20230528/f65e87cc0aec4a1284e8017e9a6ce35f.png [20200303170018581.png]: /images/20230528/94253e6ee3f9466ea4c9c0ee11a73e25.png [https_edu.csdn.net_course_play_29402]: https://edu.csdn.net/course/play/29402
相关 C语言 - 指针 什么是指针 指针存储的是变量的内存地址。 申明指针的方式 通过`类型`进行声明,比如 int ip; / 一个整型的指针 / dou 偏执的太偏执、/ 2023年10月17日 16:56/ 0 赞/ 124 阅读
相关 C语言指针 文章目录 一、变量的地址 二、指针 三、对指针赋值 四、通过指针操作内存变量 五、再来讨论函数的参数传递 六、空指针 七、数组的 ゝ一纸荒年。/ 2023年07月19日 10:46/ 0 赞/ 47 阅读
相关 【C语言】指针 50、指针变量用来记录地址数据 51、只有记录了有效地址的指针变量才可以使用 52、声明指针变量时需要在变量名称前写\ 53、指针变量名称前加\可以表示指针所捆绑的存储区 亦凉/ 2022年06月12日 04:49/ 0 赞/ 264 阅读
相关 c语言指针 //指针怎么用 // (区分两个概念,指针变量和指向内容,指针变量只保存一个地址值,在这个地址值对应的内存中具体存放的东西叫做指向内内容) 用变量 ╰半夏微凉°/ 2022年06月04日 08:58/ 0 赞/ 279 阅读
相关 C语言指针 C语言中,指针尤为重要。 1可以把指针看作是一个数据类型。 ![SouthEast][] 打印结果: ![SouthEast 1][] 2 在指针声 今天药忘吃喽~/ 2022年05月31日 03:39/ 0 赞/ 268 阅读
相关 C 语言指针 1、CPU 访问内存,是通过内存地址来读写内存数据的,CPU 与内存条硬件之间有个地址总线,CPU 通过地址总线将要访问/写入的内存地址告诉内存条。 2、对于 CPU 而言地 拼搏现实的明天。/ 2022年05月29日 01:54/ 0 赞/ 303 阅读
相关 C语言指针 1、指针的基本知识 (1)定义 int \p; (2)赋值 1) int a;int p=&a 2) int a ;int p; 喜欢ヅ旅行/ 2022年03月26日 05:22/ 0 赞/ 314 阅读
相关 C语言:指针 今天研究了一下午终于把指针研究明白了 include<stdio.h> include<stdlib.h> int main() { 快来打我*/ 2022年03月25日 21:14/ 0 赞/ 328 阅读
相关 C语言-指针 1.指针和指针变量 > 内存区的每一个字节都有编号,这就是地址 > 如果在程序中定义了一个变量,在对程序进行编译和运行时,系统就会给这个变量分配内存单元,并确 àì夳堔傛蜴生んèń/ 2022年01月26日 11:17/ 0 赞/ 375 阅读
相关 C语言指针 变量的地址 我们已经知道,内存变量简称变量,在C语言中,每定义一个变量,系统就会给变量分配一块内存,而内存是有地址的。如果把计算机的内存区域比喻成一个 小咪咪/ 2021年11月10日 23:06/ 0 赞/ 487 阅读
还没有评论,来说两句吧...