第8章 善于利用指针(1)
- 格式:pdf
- 大小:1.60 MB
- 文档页数:60
《高级语言程序设计》考试大纲
I.考试的性质
我校本科插班生考试(以下简称“插班生考试”)《高级语言程序设计》科目的考试,是普通高等学校(含高职班和各类成人高校从普通高考招生的普通班)应届和往届专科毕业生,以及通过自学考试、成人教育等国民教育系列获得大专毕业证书的人员,升入我校计算机科学与技术本科专业就读的必考科目。
II.考试内容及要求
《高级语言程序设计》课程主要任务是训练学生能灵活运用C语言的基本技能设计程序、编写程序和调试程序的能力,培养学生综合运用所学知识进行综合实验的能力,最终让学生提高分析问题、并运用计算机技能解决实际问题的能力。
Ⅲ.参考书目
考试主要参考书为《C程序设计(第四版)》,谭浩强,清华大学出版社,2013年4月。
第1章程序设计和C语言1第2章算法——程序的灵魂16第3章最简单的C程序设计——顺序程序设计第4章选择结构程序设计85第5章循环结构程序设计114第6章利用数组处理批量数据1426.1怎样定义和引用一维数组1426.1.1怎样定义一维数组1436.1.2怎样引用一维数组元素1446.1.3一维数组的初始化1456.1.4一维数组程序举例1466.2怎样定义和引用二维数组1486.2.1怎样定义二维数组1496.2.2怎样引用二维数组的元素1506.2.3二维数组的初始化1516.2.4二维数组程序举例1526.3字符数组1546.3.1怎样定义字符数组1546.3.2字符数组的初始化1556.3.3怎样引用字符数组中的元素1556.3.4字符串和字符串结束标志1566.3.5字符数组的输入输出1596.3.6使用字符串处理函数1616.3.7字符数组应用举例165习题168第7章用函数实现模块化程序设计1707.1为什么要用函数1707.2怎样定义函数1727.2.1为什么要定义函数1727.2.2定义函数的方法1737.3调用函数1747.3.1函数调用的形式1747.3.2函数调用时的数据传递1757.3.3函数调用的过程1777.3.4函数的返回值1787.4对被调用函数的声明和函数原型1797.5函数的嵌套调用1827.6函数的递归调用1847.7数组作为函数参数1927.7.1数组元素作函数实参1937.7.2数组名作函数参数1947.7.3多维数组名作函数参数1977.8局部变量和全局变量1997.8.1局部变量1997.8.2全局变量2007.9变量的存储方式和生存期2047.9.1动态存储方式与静态存储方式2047.9.2局部变量的存储类别2057.9.3全局变量的存储类别2087.9.4存储类别小结2127.10关于变量的声明和定义2147.11内部函数和外部函数2157.11.1内部函数2157.11.2外部函数215习题218第8章善于利用指针2208.1指针是什么2208.2指针变量2228.2.1使用指针变量的例子2228.2.2怎样定义指针变量2238.2.3怎样引用指针变量2248.2.4指针变量作为函数参数2268.3通过指针引用数组2308.3.1数组元素的指针2308.3.2在引用数组元素时指针的运算2318.3.3通过指针引用数组元素2338.3.4用数组名作函数参数2378.3.5通过指针引用多维数组2458.4通过指针引用字符串2558.4.1字符串的引用方式 2558.4.2字符指针作函数参数2598.4.3使用字符指针变量和字符数组的比较263 8.5指向函数的指针2668.5.1什么是函数指针2668.5.2用函数指针变量调用函数2668.5.3怎样定义和使用指向函数的指针变量268 8.5.4用指向函数的指针作函数参数2708.6返回指针值的函数2748.7指针数组和多重指针2778.7.1什么是指针数组 2778.7.2指向指针数据的指针2808.7.3指针数组作main函数的形参2828.8动态内存分配与指向它的指针变量2858.8.1什么是内存的动态分配2858.8.2怎样建立内存的动态分配2858.8.3void指针类型 2878.9有关指针的小结288习题291第9章用户自己建立数据类型2939.1定义和使用结构体变量2939.1.1自己建立结构体类型2939.1.2定义结构体类型变量 2959.1.3结构体变量的初始化和引用2979.2使用结构体数组3009.2.1定义结构体数组3009.2.2结构体数组的应用举例3019.3结构体指针3039.3.1指向结构体变量的指针3039.3.2指向结构体数组的指针3049.3.3用结构体变量和结构体变量的指针作函数参数306 9.4用指针处理链表3099.4.1什么是链表 3099.4.2建立简单的静态链表3109.4.3建立动态链表3119.4.4输出链表3159.5共用体类型3179.5.1什么是共用体类型3179.5.2引用共用体变量的方式3189.5.3共用体类型数据的特点3199.6使用枚举类型3239.7用typedef声明新类型名326习题330第10章对文件的输入输出33110.1C文件的有关基本知识33110.1.1什么是文件33110.1.2文件名33210.1.3文件的分类33210.1.4文件缓冲区33310.1.5文件类型指针33310.2打开与关闭文件33510.2.1用fopen函数打开数据文件33510.2.2用fclose函数关闭数据文件33710.3顺序读写数据文件33810.3.1怎样向文件读写字符33810.3.2怎样向文件读写一个字符串34110.3.3用格式化的方式读写文件34410.3.4用二进制方式向文件读写一组数据34510.4随机读写数据文件34910.4.1文件位置标记及其定位34910.4.2随机读写 35210.5文件读写的出错检测353习题354第11章常见错误分析355附录370附录A在Visual C++ 6.0环境下运行C程序的方法370附录B常用字符与ASCII代码对照表377附录CC语言中的关键字378附录D运算符和结合性378附录EC语言常用语法提要380附录FC库函数384参考文献390第4章选择结构程序设计854.1选择结构和条件判断854.2用if语句实现选择结构874.2.1用if语句处理选择结构举例874.2.2if语句的一般形式 894.3关系运算符和关系表达式914.3.1关系运算符及其优先次序914.3.2关系表达式924.4逻辑运算符和逻辑表达式924.4.1逻辑运算符及其优先次序934.4.2逻辑表达式944.4.3逻辑型变量964.5条件运算符和条件表达式974.6选择结构的嵌套1004.7用switch语句实现多分支选择结构1024.8选择结构程序综合举例106习题112第5章循环结构程序设计1155.1为什么需要循环控制1155.2用while语句实现循环1165.3用do…while语句实现循环1185.4用for 语句实现循环1215.5循环的嵌套1255.6几种循环的比较1265.7改变循环执行的状态1265.7.1用break语句提前终止循环1275.7.2用continue语句提前结束本次循环1285.7.3break语句和continue语句的区别1295.8循环程序举例132习题141第6章利用数组处理批量数据1436.1怎样定义和引用一维数组1436.1.1怎样定义一维数组1446.1.2怎样引用一维数组元素1456.1.3一维数组的初始化1466.1.4一维数组程序举例1476.2怎样定义和引用二维数组1496.2.1怎样定义二维数组1506.2.2怎样引用二维数组的元素1516.2.3二维数组的初始化1526.2.4二维数组程序举例1536.3字符数组1556.3.1怎样定义字符数组1556.3.2字符数组的初始化1566.3.3怎样引用字符数组中的元素156 6.3.4字符串和字符串结束标志1576.3.5字符数组的输入输出1606.3.6使用字符串处理函数1626.3.7字符数组应用举例166习题169第7章用函数实现模块化程序设计171 7.1为什么要用函数1717.2怎样定义函数1737.2.1为什么要定义函数1737.2.2定义函数的方法1747.3调用函数1757.3.1函数调用的形式1757.3.2函数调用时的数据传递1767.3.3函数调用的过程1787.3.4函数的返回值1797.4对被调用函数的声明和函数原型181 7.5函数的嵌套调用1837.6函数的递归调用1857.7数组作为函数参数1937.7.1数组元素作函数实参1937.7.2数组名作函数参数1957.7.3多维数组名作函数参数1987.8局部变量和全局变量2007.8.1局部变量2007.8.2全局变量2017.9变量的存储方式和生存期2057.9.1动态存储方式与静态存储方式205 7.9.2局部变量的存储类别2067.9.3全局变量的存储类别2097.9.4存储类别小结2137.10关于变量的声明和定义2157.11内部函数和外部函数2167.11.1内部函数2167.11.2外部函数216习题219第8章善于利用指针2218.1指针是什么2218.2指针变量2238.2.1使用指针变量的例子2238.2.2怎样定义指针变量2248.2.3怎样引用指针变量2258.2.4指针变量作为函数参数2278.3通过指针引用数组2328.3.1数组元素的指针2328.3.2在引用数组元素时指针的运算2338.3.3通过指针引用数组元素2348.3.4用数组名作函数参数2398.3.5通过指针引用多维数组2478.4通过指针引用字符串2578.4.1字符串的引用方式 2578.4.2字符指针作函数参数2618.4.3使用字符指针变量和字符数组的比较265 8.5指向函数的指针2688.5.1什么是函数指针2688.5.2用函数指针变量调用函数2688.5.3怎样定义和使用指向函数的指针变量270 8.5.4用指向函数的指针作函数参数2728.6返回指针值的函数2768.7指针数组和多重指针2798.7.1什么是指针数组 2798.7.2指向指针数据的指针2828.7.3指针数组作main函数的形参2848.8动态内存分配与指向它的指针变量2878.8.1什么是内存的动态分配2878.8.2怎样建立内存的动态分配2878.8.3void指针类型 2898.9有关指针的小结290习题293第9章用户自己建立数据类型2959.1定义和使用结构体变量2959.1.1自己建立结构体类型2959.1.2定义结构体类型变量 2979.1.3结构体变量的初始化和引用2999.2使用结构体数组3029.2.1定义结构体数组3029.2.2结构体数组的应用举例3049.3结构体指针3059.3.1指向结构体变量的指针3059.3.2指向结构体数组的指针3069.3.3用结构体变量和结构体变量的指针作函数参数3089.4用指针处理链表3119.4.1什么是链表 3119.4.2建立简单的静态链表3129.4.3建立动态链表3139.4.4输出链表3179.5共用体类型3199.5.1什么是共用体类型3199.5.2引用共用体变量的方式3209.5.3共用体类型数据的特点3219.6使用枚举类型3259.7用typedef声明新类型名328习题332第10章对文件的输入输出33310.1C文件的有关基本知识33310.1.1什么是文件33310.1.2文件名33410.1.3文件的分类33410.1.4文件缓冲区33510.1.5文件类型指针33510.2打开与关闭文件33710.2.1用fopen函数打开数据文件33710.2.2用fclose函数关闭数据文件33910.3顺序读写数据文件34010.3.1怎样向文件读写字符34010.3.2怎样向文件读写一个字符串34310.3.3用格式化的方式读写文件34610.3.4用二进制方式向文件读写一组数据34710.4随机读写数据文件35110.4.1文件位置标记及其定位35110.4.2随机读写 35410.5文件读写的出错检测355习题356第11章常见错误分析374附录390附录A在Visual C++ 6.0环境下运行C程序的方法390 附录CC语言中的关键字398附录D运算符和结合性398附录EC语言常用语法提要400附录FC库函数404参考文献410。
浙江农林大学硕士研究生入学考试《农业知识综合三》(农业信息化方向)考试大纲一、考试性质浙江农林大学硕士研究生入学考试《农业知识综合三》(农业信息化方向)是为招收农业工程与信息技术专业的硕士研究生而设置的具有选拔功能的水平考试。
其主要目的是测试考生掌握计算机程序设计、数据库及网络应用的情况,测试考生是否具备攻读农业工程与信息技术专业硕士所必须的基本素质、一般能力和培养潜能,以利于选拔具有发展潜力的优秀人才入学,为国家的经济建设培养具有较强分析与解决实际问题能力的高层次、应用型、复合型的农业工程与信息技术专业人才。
二、考试的基本要求要求考生掌握高级语言程序设计的基本方法和技能;掌握数据分析、组织等数据库的基本技能;熟悉计算机网络的基本原理,掌握网络应用的基本技能,了解农业信息技术的特点及应用并在此基础上具备计算机综合应用的基本能力。
三、考试方式和考试时间本试卷采用闭卷笔试形式,试卷满分为150分,考试时间为180分钟。
四、考试内容和考试要求《农业知识综合三》(农业信息化方向)考试内容包括:数据库技术、高级语言程序设计、计算机网络技术三部分内容。
各部分考试内容及要求如下:(一) 数据库技术 (50分)(一).绪论1. 数据库系统概述掌握数据库的4个基本概念、数据库系统的特点。
2. 数据模型两类数据模型、概念模型、数据模型的组成要素、关系模型。
3. 数据库系统的组成、结构掌握三级模式,两级映像,两级独立性;理解数据库系统的组成、结构及其各组成部分的内容。
4. 数据库管理系统 (DBMS)理解DBMS的主要功能;了解DBMS的组成。
(二).关系数据库1. 基本概念理解关系的候选码和主码;主属性和非主属性。
了解关系模型的组成:数据结构、关系的操作和完整性约束;关系的定义;关系的性质。
2. 外部码了解外部关系码;完整性约束:实体完整性、参照完整性、用户定义完整性。
3. 关系数据库模式与关系数据库。
了解关系模式和关系数据库模式的定义;关系与关系数据库的定义。
浙江师范大学硕士研究生入学考试初试科目考 试 大 纲科目代码、名称:886软件工程综合基础适用专业:083500软件工程(一级学科)、085400电子信息(软件工程领域)一、考试形式与试卷结构(一)试卷满分及考试时间本试卷满分为150分,考试时间为180分钟。
(二)答题方式答题方式为闭卷、笔试。
试卷由试题和答题纸组成;答案必须写在答题纸(由考点提供)相应的位置上。
(三)试卷题型结构(一)C程序设计部分,满分60分,其中:1、单项选择题:10小题,每小题3分,共30分2、程序设计题:3小题,每小题10分,共30分(二)软件工程基础部分,满分90分,其中:1、分析设计题:3小题,每小题15分,共45分2、综合论述题:3小题,每小题15分,共45分二、考查目标(复习要求)软件工程专业全日制学术型研究生入学考试科目《软件工程综合基础》的考试内容包括C程序设计和软件工程基础两部分。
其中:C程序设计部分要求考生掌握C语言的基本内容及程序设计的基本方法、常用算法与编程技巧,掌握结构化程序设计思想,选择适当的数据类型表示实际问题,能使用函数进行模块化程序设计,掌握应用计算机解决和处理实际问题的思维方法与基本能力。
软件工程基础部分要求考生掌握软件工程的基本概念、基本原理、基本方法和技术,理解规范化、文档化在软件生命周期过程中的重要性,并能运用相关理论和方法解决软件工程中的实际问题。
三、考查范围或考试内容概要C程序设计部分第一章程序设计与C语言1.了解计算机语言的基本概念。
2.了解C语言的背景、特点。
3.掌握C语言程序的结构。
第二章算法——程序的灵魂1.了解算法的概念、特性。
2.了解结构化程序设计方法。
3.掌握算法的描述方法。
第三章最简单的C程序设计——顺序程序设计1.掌握C语言的常量与变量;整型、浮点型、字符型数据。
c语⾔程序设计第五版课后答案谭浩强第⼋章课后答案c语⾔程序设计第五版课后答案谭浩强习题答案第⼋章善于利⽤指针本章习题均要求使⽤指针⽅法处理。
1. 输⼊3个整数,要求按由⼩到⼤的顺序输出。
解题思路:先获取到三个变量的地址,然后获取三个数据,通过指针进⾏⽐较转换即可答案:#include <stdio.h>void swap(int *p_a, int *p_b){int temp = *p_a;*p_a = *p_b;*p_b = temp;}int main(){int a, b, c, *p_a = &a, *p_b = &b, *p_c = &c; // 获取每个变量空间的地址printf("Please enter three numbers:");scanf_s("%d%d%d", p_a, p_b, p_c);if (*p_a > *p_b) {swap(p_a, p_b);//通过指针进⾏指向空间内的数据交换}if (*p_a > *p_c) {swap(p_a, p_c);}if (*p_b > *p_c) {swap(p_b, p_c);}printf("%d %d %d\n", *p_a, *p_b, *p_c);system("pause");return 0;}2. 输⼊3个字符串,要求按由⼩到⼤的顺序输出。
解题思路:字符串的⽐较可以使⽤strcmp函数,返回值>0表⽰⼤于,返回值⼩于0表⽰⼩于,返回追等于0表⽰相同。
其他的⽐较排序思路与数字的排序交换没有区别,逐个进⾏⽐较先找出最⼤的,然后找出第⼆⼤的。
答案:#include <stdio.h>int main(){char str[3][32];char *p[3];printf("Please enter three strings:");for (int i = 0; i < 3; i++) {p[i] = str[i];scanf_s("%s", p[i], 32);//后边的数字限制缓冲区边界,防⽌缓冲区溢出访问越界}//让p[0]和p[1]/p[2]分别进⾏⽐较,找出最⼤的字符串,i+1之后,则让p[1]和p[2]进⾏⽐较,找出第⼆⼤//i循环总个数-1次,最后⼀个是不需要⽐较的for (int i = 0; i < 2; i++) {for (int j = i + 1; j < 3; j++) {if (strcmp(p[i], p[j]) > 0) {char *tmp = p[i]; p[i] = p[j]; p[j] = tmp;}}}printf("%s %s %s\n", p[0], p[1], p[2]);system("pause");return 0;}3. 输⼊10个整数,将其中最⼩的数与第⼀个数对换, 把最⼤的数与最后⼀个数对换。
第八章指针的使用【学习目标】本章将详细介绍在C语言中如何使用指针。
学习要点包括如下几点:(1)掌握指针和指针变量的概念,了解指针变量的特点以及直接访问数据和间接访问数据的原理。
(2)掌握指针变量的定义、赋值方法及指针运算符的使用,熟练运用指针访问简单变量。
(3)熟悉指针和一维数组的关系,掌握指向一维数组的指针变量的定义方法,熟练使用指针变量访问一维数组元素。
(4)了解指针与字符串的关系,能熟练使用指针处理字符串。
(5)熟练掌握用指针变量作函数的参数时函数的定义和调用方法、数组名作函数的参数用法。
(6)指向指针的指针的运用。
【学习导航】本章的在整个课程中的位置如图5-1所示。
图8-1 本章学习导航在本书的第一章介绍C语言有一个灵活性的特点,那么它的灵活性具体体现在哪里呢?其实就是指针。
指针是C语言的精华部分,通过利用指针,我们能很好地利用内存资源,使其发挥最大的效率。
有了指针技术,我们可以描述复杂的数据结构,对字符串的处理可以更灵活,对数组的处理更方便,使程序的书写简洁,高效。
8.1 地址和指针指针是C语言的一种数据类型,类似于整型、字符型等。
既然指针也是一种类型,那么也可以定义该类型的变量,称为指针变量。
指针变量和其他类型的变量的区别是:指针变量存储的是地址。
所以要学好指针,就一定要明白数据在内存中是如何存储的。
计算机所有数据都是存储在存储器里,系统的内存可看作编了号的小房间,如果要取房间的东西(读取数据)就需要得到房间编号。
地址就是内存区中对每个字节的编号。
下面通过两个整型变量来说明。
整型变量x、y(基本整型需4个字节)在内存中的存储如图8-2所示(假设内存编号是从2000开始)。
把变量所占用的存储单元首字节的地址作为变量的地址。
C语言中利用取地址运算符“&”获取变量的存储地址。
例如,&c将返回c的首地址;&x将返回x的首地址。
2000H2004H2008H2012H...图8-2 变量x和y在内存中的存储图8-2中2000H和2004H就是内存单元的地址。
湖北工程学院2021年普通专升本:《高级语言程序设计(C语言)》考试大纲一、基本要求:考生应按本大纲的要求,正确理解C语言的结构、语法与环境;C语言的基本概念、函数及其调用;各类语句的语法,语义和各种数据类型的使用特点;问题的分析、设计及C语言实现及调试方法,并得到充分的程序设计训练。
本大纲对内容的要求由低到高,对概念和理论分为“了解”和“理解”两个层次;对运算和程序分为“掌握”和“应用”两个层次。
二、考试方法和时间:考试方法为闭卷考试,考试时间为120分钟。
三、考试题型大致比例:选择题:30分,填空题:20分,程序阅读:40分,程序填空:24分,程序设计:36分满分:150分。
四、考试内容和要求:第1章程序设计和C语言考试内容:(1)什么是计算机程序;(2)什么是计算机语言;(3)C语言的发展及其特点;(4)C语言程序的结构;(5)运行C程序的步骤与方法;(6)程序设计的任务。
考试要求:(1)了解:C语言的发展历史及其特点;(2)掌握:运行C程序的步骤和方法;(3)应用:用C语言编写简单的屏幕输出程序第2章算法----程序的灵魂考试内容:(1)算法的概念;(2)算法的特性;(3)算法的几种表示方法;(4)结构化程序设计方法;考试要求:(1)了解:最基本的算法;(2)理解:结构化程序设计方法第3章最简单的C程序设计----顺序程序设计考试内容:(1)数据的表现形式及其运算;(2)运算符和表达式;(3)C语句;(4)数据的输入输出;考试要求:(1)掌握:几种基本数据类型的表示形式,以及定义于基本数据类型之上的各种运算(算术、赋值、关系、逻辑、条件、逗号等);(2)掌握:常量的意义及几种基本数据类型的常量的表示形式,符合常量的定义与使用,变量的定义及自定义标识符的规范;(3)掌握:混合运算的表达式中各种运算符的优先级及结合方向;(4)掌握:输入、输出函数的使用规范第4章选择结构程序设计考试内容:(1)选择结构和条件判断;(2)关系运算符和关系表达式,逻辑运算符和逻辑表达式,条件运算符和条件表达式;(3)if选择控制语句;(4)switch选择控制语句。
内存管理指针的基本概念指针应用实例指针作函数参数第8章指针(1)复习回顾上次课的内容:◆局部变量和全局变量◆变量的作用域◆变量的生存期◆声明与定义◆内部函数◆外部函数◆你开始习惯写函数了吗?2012是如何实现的?假定造成世界末日的上帝是一个程序员,作为一名合格的程序员,他绝不应该写出类似于“摧毁地球”这样的程序,而应该写一个“摧毁(行星)”的函数,然后把地球作为参数传进去!C语言新手的晋级之路第一步:萧规曹随◆在这一步要求按照教材或讲义上的程序实例进行原样输入,运行一下程序看是否正确。
◆在这一步,掌握C语言编程软件的使用方法(包括新建、打开、熟练输入、编辑、保存、关闭C程序);初步记忆新学章节的知识点;养成良好的编程风格(是讲义提倡的而不是教材上的)◆难点:小心数字1和字母l,字母o和数字0,中英文标点符号的区别C语言新手的晋级之路第二步:移花接木◆在第一步输入的C程序的基础上进行试验性的修改,运行一下程序看一看结果发生了什么变化,分析结果变化的原因,加深新学知识点的理解。
◆可与第一步同步进行,“输入”可加深记忆,“修改”可加深理解,二者相辅相成,互相促进。
◆友提,一次进行一处修改即可,免得把自己改晕了。
C语言新手的晋级之路第三步:无中生有◆面对教材的例子题目,不参考教材,自己从头开始编写程序。
看能否写出正确运行的代码。
◆初学者易犯的错误:scanf格式控制和输入不匹配或把变量名当地址作参数,使用未定义的变量、漏掉或多写“;”、“{”与“}”、“(”与“)”不匹配,控制语句(选择、分支、循环)的格式不正确,调用库函数没有包含相应头文件,调用未声明的函数、调用函数时实参和形参不匹配、数组边界越界等等◆要学会看编程工具的错误信息提示:双击错误提示光标可跳转到发生错误的行,如果该行没有错误就往前查找。
错误要一个一个修改,每改完一次编译一下程序。
C语言新手的晋级之路第四步:欲擒故纵◆教材最后一章列出C语言初学者易犯的错误,可以按照易出错的类型,将教材中正确的程序改成错误的程序,运行一下看看出现的错误信息提示,并记下。
再将程序改成正确的,运行一下。
这样反复修改,就能熟悉C语言程序发生错误的原因和修改错误的能力。
◆注意:每次只改错一个地方,目的是现实发生该错误的真正原因,要避免一次改动多个地方。
带一个记录本记下英文错误提示信息和解决该错误问题的方法,积累程序调试经验。
要善于利用调试工具。
C语言新手的晋级之路第五步:海纳百川◆经过上述过程,我们应该已经熟悉C语言各种语句的语法和流程。
现在可以研读别人编写的C语言经典程序,看懂别人是如何解决问题的,学习解决问题的方法和程序设计技巧,提高自己的程序设计能力。
◆源程序的来源●教材和讲义的例子●图书馆里的C语言参考书●网络上搜索各种源代码●……C语言新手的晋级之路 学习方法可以使你事半功倍但是,除此之外你还需要:◆相信自己有能力学好C语言◆足够的耐心◆足够的责任心◆足够的细心欢迎来到内存管理的雷区!内存的概念 从物理上讲内存就是一块半导体存储材料任何需要被计算机执行的程序,包括指令和数据都要先从外部存储器(包括硬盘光盘等)调入内存后才能被执行CPU需要精准地从内存中找到需要的数据参与运算◆CPU如何找到想要的数据?C 语言编译器眼里的内存随着以下C 语句的编译运行,编译器做了哪些事情,内存会发生什么变化?20002001200220032004200520060x87654321301符号表变量名地址数据类型i c f200020040x87654321int chardoublei cfint i;char c;double f;i = 3;0x876543220x876543230x876543240x876543250x876543260x876543270x87654328变量名和地址建立了对应关系内存的管理方法与地址20002001200220032004200520060x87654321301if0x876543220x876543230x876543240x876543250x876543260x876543270x87654328i 的地址sizeof(int)=4执行"i=3;"会发生什么?1.找到i 的地址2000;2.确定i 所占的字节2000~2003;3.往这四个字节写入整型数值3(32位)。
接下来,分析"f=i;"发生了什么 由此可见,访问变量必须知道其地址和类型!务必弄清楚存储单元的地址和存储单元的内容这两个概念的区别◆地址:存储单元的编号◆内容:存储单元里存放的值存储单元内容和地址的区别2000200120022003200420052006301i指针是什么“指针就是地址!”内存区的每一个字节有一个“地址”。
数据存放在地址所标识的内存单元中由于通过地址能找到所需的内存单元,我们可以说,地址指向该内存单元。
所以我们将地址形象化地称为“指针”怎样定义指针变量定义指针变量的一般形式为:类型* 指针变量名;如:int *p;◆int是为指针变量指定的“基类型”◆基类型指定指针变量可以指向的变量类型●如p 可以指向整型变量,但不能指向浮点型变量取地址操作符&声明一个变量时,编译器自动为变量开辟内存空间,我们无需关心变量在内存中的位置。
当程序需要用到某个变量的地址信息,就需要取地址符号&。
◆例如,int num=0; &num就是num变量的地址指针变量定义举例我们可以将变量地址赋值给同类型的指针int a, b;int *ip=&a, *iq=&b;float *fp;char *cp;ip=&b; 正确*ip=&b; 错误,注意此处的*前面没有数据类型!指针变量定义注意事项下列定义实现了怎样的功能?int * a, b, c;结果是:定义了一个指针变量a,两个整型变量b, c;如果想将a,b,c都定义成指针变量,需要:int *a,*b,*c;或int *a; int *b; int *c;图解指针变量301int i; //四个字节,32位0x123443210x876543210x876543220x876543230x87654324int *p = &i四个字节,32位0x123443210x123443220x123443230x123443240x123443250x123443260x12344327如有雷同纯属巧合定义指针变量必须指定其类型某类型指针变量只能存放该类型变量的地址int a, b;int *p1 = &a, *p2 = &b;float *p3;p3 =&a; 错误,float类型指针不能指向整型变量指针变量仅能存放变量的地址 将一个整数复制给指针变量是错误的变量的地址必须通过一个已经被分配了存储空间的变量加上取地址符“&”来获得,而不能直接指定一个具体的地址◆如int *a; a=0x5050; 错误◆但是可以用常量0给指针赋值,表示不指向任何变量的空指针变量,如a=0; 正确指针变量的初始化在声明一个指针后,若没有经过初始化,指针的值是不确定的,直接使用未加初始化的指针变量可能会给程序带来各种内存错误。
因此指针变量的初始化很重要。
如果一开始不知该将此指针指向何处,最简单的方式是利用NULL将指针置0◆如:int *pInt = NULL;指针变量的值在32位计算机系统中,所有类型的指针的值都是32位的整数。
“一个指针的值是A”◆即“该指针指向了以A为首地址的一片内存区域”“一个指针指向了某内存区域”◆即“该指针的值是这块内存区域的首地址”显示指针变量所占空间的实例1.#include <stdio.h>2.int main()3.{4.char* pChar;5.int* pInt;6.double* pDouble;7.//以下sizeof关键字可以用来计算括号内的变量占的字节数8.printf("pChar=%d\n",sizeof(pChar));9.printf("pInt=%d\n",sizeof(pInt));10.printf("pDouble=%d\n", sizeof(pDouble));11.return0;12.}和指针有关的运算符要熟练掌握两个有关的运算符:(1) &取地址运算符。
&a是变量a的地址(2) * 指针运算符(“间接访问”运算符)若有p=&a,则*p就等价于ak=*p; (表示把a的值赋给k)*p=1; (表示把1赋给a)指针运算符代码实例double num = 3;double* pNum;pNum = #pNum:指向double类型的指针变量,其值是num的地址&num:返回变量num的地址,与pNum等价*pNum:返回pNum所指的变量,与num等价&(*pNum):与&num(即pNum)等价*(&num):与*pNum(即num)等价(&*p)和(*&p)的区别“*”和“&”具有相同的优先级,按照从右向左的方向结合◆对于&*p而言:首先进行一次*p运算,再取地址,相当于&(*p),此情况p必须是一个指针变量!◆对于*&p:相当于*(&p),就是先取地址再做”*”运算,结果等价于p,此情况p可以是任何类型变量。
一粒牛肉干与指针运算符C语言上机课,某女同学边写代码边偷偷吃起牛肉干有一粒牛肉干掉到了键盘上,卡在7和8键之间……女同学左手搭在shift键上,右手就在键盘上抠啊、抠啊……于是程序里某一行代码变成这个样子:int*pa=&*&*&*&*&*&*&*&*&*&a;女同学没有注意,继续完成程序,结果呢……————程序顺利通过编译,运行结果完全正确!指针变量综合举例1.#include <stdio.h>2.int main()3.{4.unsigned int a = 5;5.unsigned int * pint = NULL;6.printf("&a = %p\n a = %d\n", &a, a);7.printf(" &pint=%p\n pint=%p\n &(*pint)=%p\n",8.&pint, pint, &(*pint));9.pint = &a;10.printf("\n&a=%p\n a=%d\n", &a, a);11.printf(" &pint=%p\n pint=%p\n &(*pint)=%p\n",12.&pint, pint, &(*pint));13.printf(" *pint=%d\n", *pint);14.*pint = 10;15.printf("&a=%p\n a=%d\n", &a, a);16.printf(" &pint=%p\n pint=%p\n &(*pint)=%p\n",17.&pint, pint, &(*pint));18.printf(" *pint=%d\n", *pint);19.return0;20.}不考虑指针,数据只能这样访问 直接访问方式◆通过符号表获得变量名i对应的地址直接进行访问符号表变量名地址数据类型i a[]k200020042008int int[2]int3122000200420083020变量i变量a[]变量kint i=3,k;int a[2]={1,2};k = i + a[1];从这里取3将5送到这里从这里取220125指针带来了新的数据访问方式 间接访问方式◆通过变量p的值获得其所指向的变量的地址,再通过这个地址进行访问符号表变量名地址类型i j k200020042008int int int3692000200420084016变量i变量j变量kint i=3,j=6,k,*p,*q; p = &i;q = &k;*q = (*p)+j;将k的地址存到这里将i的地址存到这里302020002008p q30204016int *int *变量p变量q直接/间接访问类比:酒店找人直接访问:例如“i=3;”◆跟i 很熟,知道它住哪儿,所以可以直接去访问它间接访问:例如已知p=&i; 执行“*p=3;”◆跟i 不熟,只知道i 住在酒店里,i 的房间号放在前台(即p )那里,所以先询问前台(通过p 获得i 的地址),然后去访问它i200032000p*p20003指针的优点能完成一些直接访问无法实现的功能突破屏障去操作计算机底层,提供更大的编程灵活度类比一下,在绕过某人(在某人不知情)的情况下获得某人的地址并进行操作◆权力机关才允许做的事情◆坏人容易利用来做些不可告人的勾当使用指针变量的例子通过指针变量访问整型变量。