C语言程序设计(第3版)何钦铭 颜 晖 第8章 指针
- 格式:doc
- 大小:59.50 KB
- 文档页数:31
C语言知识点清单(杭电姚晔整理)第1章基本数据类型和表达式1.1 关键字和标识符标识符(p8)1.2 基本数据类型常用数据类型(p21,p122),字符型数据(p50,p123),原码反码补码(p120),实型数据的存储(p121)1.3 常量和变量常量和变量的定义(p21),整型字符型实型常量与变量(p123)1.4 输入和输出函数printf(p23),scanf(p27),字符型数据的输入和输出(scanf/printf/getchar/putchar/p51/p128),整型数的输入输出(scanf/printf格式控制p125),实型数的输入输出(scanf/printf格式控制p127) 1.5 常用库函数常用数学函数(p28)1.6 运算符和表达式算术运算(p22),赋值运算(p23),关系运算(p25),逻辑运算(p52),位运算(p140),长度运算符(p142),算术表达式(p131),赋值表达式(p133),关系表达式(p134),逻辑表达式(p136),条件表达式(p139),逗号表达式(p139),运算符的优先级与结合性(p142),复合语句(P33),自动类型转换(p130),强制类型转换(p130)第2章控制结构与语句2.1 结构化程序设计数据表达(p5),流程控制(p6),主要语法单位(p9),C语言的特点(p12)2.2 顺序结构顺序控制结构(p6)2.3 选择结构if-else语句(p26,p45),多分支else-if语句(p47,p60),switch语句(p57)2.3 循环结构for语句(p32),while语句(p69),do-while语句(p73),循环嵌套(p79),循环语句的选用(p82) 2.4 转向语句break语句(p59,p75),continue语句(p76)第3章函数3.1 函数的定义函数首部(p97),函数体(p98),函数原型声明(p100),问题分析思想(p105),模块化设计(p106/p239)3.2 函数的调用调用过程(p98),调用形式(p99),参数传递(p99),返回结果(p100,p104)3.3 嵌套与递归函数的嵌套调用(p238),递归函数基本概念(p241),递归程序设计(p244)3.4 函数与变量局部变量和全局变量(p108),变量生命周期(p112),变量存储的内存分布(p113),静态变量(p113),外部变量(p258),静态全局变量(p258),变量的存储类型及作用域(附录p340)第4章数组4.1 一维数组一维数组的定义和引用(p149),一维数组的初始化(p151),一维数组的编程(p152)4.2 二维数组二维数组的定义和引用(p160),二维数组的初始化(p161),二维数组的编程(p162)4.3 字符串字符数组(p167),字符串(p168),字符串处理函数(gets/puts/strcpy/strcat/strcmp/strlen/p203) 4.4 数组与函数数组名作为函数参数(p196),冒泡排序(p199),命令行参数(p273)第5章指针5.1 指针基本知识地址与指针(p181),指针变量的定义(p182),指针的基本运算(p184),指针变量的初始化(p186) 5.2 指针与数组指针、数组和地址的关系(p192)5.3 指针与字符串字符串与字符指针(p201),用指针数组操作多个字符串(p270)5.4 指针数组与多级指针指针数组的概念(p265),指向指针的指针(p266),二维数组的指针形式(p268),5.5 指针与函数指针作为函数参数(p188),指针实现动态内存分配(malloc/free/p209),指针作为函数返回值(p278),指向函数的指针(p278)第6章结构体6.1 结构体的概念结构的定义(p219),结构变量的定义和初始化(p221),结构变量的使用(p223)6.2 结构体数组结构数组操作(p226)6.3 结构体指针结构指针的概念(p229),结构指针做函数参数(p230)6.4 单向链表链表的概念(p285),单向链表的常用操作(p286)第7章文件7.1 文件概述文件的概念(p299),文本文件与二进制文件(p300),文件结构与文件类型指针(p301),文件处理步骤(p304)7.2 打开与关闭文件打开文件(p306),关闭文件(p308)7.3 文件读写函数字符方式读写函数fgetc/fputc(p309),字符串方式读写函数fgets/fputs(p311),格式化方式读写函数fscanf/fprintf(p314),数据块方式读写函数fread/fwrite(p315),文件定位函数rewind/fseek/ftell(p317),检测文件指针状态函数feof/ferror/clearerr(p317)第8章其他知识点8.1 编译预处理文件包含(p249),常用标准头文件(p251),宏基本定义(p247),带参数的宏定义(p248),条件编译(p252)8.2 共用体联合变量(附录p339)8.3 枚举枚举变量(附录p339)。
第4章循环结构【练习 4-1】在例 4-1 程序中,如果对 item 赋初值 0,运行结果是什么?为什么?如果将精度改为 10-3,运行结果有变化吗?为什么?解答:如果对item赋初值0,则程序运行结果是pi=0,因为item为0时不满足while 循环的执行条件,即不执行循环,故 pi 值为 0。
如果将精度改为 10-3,运行结果会有变化,因为精度改变意味着 while 循环的条件改变,精度变大使得while循环次数减少,必然影响到n的值。
【练习 4-2】运行例 4-2程序时,如果将最后一个输入数据改为-2,运行结果有变化吗?如果第一个输入数据是 -1,运行结果是什么?为什么?解答:如果将最后一个输入数据改为-2,运行结果没有变化,因为最后一个负数是一结束标志,不进行统计,故任意一个负数都可以。
如果第一个输入数据是-1,运行结果是:Grade averageis 0,因为第一个输入就是-1,则while循环条件不成立,不执行循环体。
【练习4-3】序列求和(1-1/4+1/7-1/10+1/13-1/16+…):输入一个正实数eps, 计算序列1-1/4+1/7-1/10+1/13-1/16+…的值,精确到最后一项的绝对值小于eps (保留6位小数)。
试编写相应程序。
解答:#include <stdio.h>#include <math.h>int main(void){int denominator, flag;double item, s,eps;printf(“Input eps:”);scanf(“%lf”,&eps);flag = 1;denominator = 1 ;item = 1.0;s = 0;while(fabs (item) >= eps) {item = flag * 1.0 / denominator;s = s + item;flag = -flag;denominator = denominator +3;}printf ( “s = %f\n”, s);return 0;}【练习4-4】如果将例4-3程序中的do-while语句改为下列while语句,会影响程序的功能吗?为什么?再增加一条什么语句,就可以实现同样的功能?while(number != 0){number = number / 10; count ++;}解答:会有影响,因为当输入数据 number 为 0时,上述 while 循环将不执行,count 值仍为 0,故输出为 0,不符合题目要求。
C语言程序设计第3版何钦铭颜晖第8章指针指针作为C语言中的一种数据类型,它存储的是一个变量或者对象的地址。
通过指针,可以直接访问或者修改存储在该地址上的数据。
指针的概念对于理解C语言的内存管理和数据结构至关重要。
本章首先介绍了指针的概念和初始化方式。
指针的声明和初始化方法与变量的声明和初始化类似,但在变量名前需要加上“*”符号,表示该变量是一个指针变量。
指针变量需要与具体的数据类型相匹配,以便正确地访问和修改数据。
其次,本章详细讨论了指针和数组之间的关系。
在C语言中,数组名可以看作是数组首元素的地址,所以可以通过指针对数组进行遍历和操作。
通过指针,可以实现指向数组的指针运算,例如指针的自增操作可以实现数组的遍历。
本章还介绍了指针和函数之间的关系。
在C语言中,可以通过函数参数传递指针来实现对函数外部变量的修改。
这种通过指针传递参数的方法,被称为按引用传递。
通过指针,可以在函数内部直接修改指针所指向的数据,从而实现对外部变量的修改。
本章接着讨论了指针和字符串之间的关系。
在C语言中,字符串实际上是存储在内存中的字符数组。
通过指针变量,可以访问字符串的每一个字符,并可以对字符串进行各种操作。
指针和字符串的关系在C语言的字符串处理中是非常重要的。
最后,本章简要介绍了指针和结构体之间的关系。
结构体是C语言中一种自定义的数据类型,可以包含不同类型的数据。
通过指针变量,可以访问结构体的成员,并实现对结构体的操作。
总之,本章通过详细讨论指针的各种用法,使读者对指针有了深入的理解。
指针作为C语言中的重要概念,对于理解和掌握C语言编程非常重要。
本章通过丰富的例子和深入的讲解,使读者能够掌握指针的基本概念,以及各种指针的用法。
对于初学者来说,指针可能是一个比较难理解的概念,但通过学习本章内容,读者可以逐步掌握指针的基本操作,并能够熟练地运用指针解决实际问题。
何钦铭《C语言程序设计》(第3版)课后习题参考答案习题11.对C 语言来说,下列标识符中哪些是合法的,哪些是不合法的?total, _debug, Large&Tall, Counter1, begin_解答:合法标识符:total, _debug, Counter1;不合法标识符:Large&Tall, begin_。
2.改写本章1.4 节中的流程图1.2,求1~100 中能被6 整除的所有整数的和。
解答:3.改写本章1.4 节中的程序,求1~100 中能被6 整除的所有整数的和,并在编程环境中验证该程序的运行结果。
解答:#include <stdio.h>int main(void){int i, sum = 0;for(i = 1; i <= 100; i++)if (i % 6 == 0)sum = sum + i;printf("%d", sum);return 0;}4.对于给定的整数n(n>1),请设计一个流程图判别n 是否为一个素数(只能被1 和自己整除的整数),并分析该流程图中哪些是顺序结构、哪些是分支结构与循环结构。
解答:在流程图中,分支结构和循环结构如图1.2 所示,自上而下的2 个实线框和2 个虚线组成了顺序结构。
习题21.求整数均值:输入4 个整数,计算并输出这些整数的和与平均值,其中平均值精确到小数点后1 位。
试编写相应程序。
解答:#include <stdio.h>int main (void){int num1, num2, num3, num4;double average, sum;scanf ("%d%d%d%d", & num1, & num2, & num3, & num4);sum = num1+ num2+ num3 + num4;average = sum / 4;printf ("Sum = %.0f; Average = %.1f\n", sum, average);return 0;}2.阶梯电价:为了提倡居民节约用电,某省电力公司执行“阶梯电价”,安装一户一表的居民用户电价分为两个“阶梯”:月用电量50 千瓦时(含50 千瓦时)以内的,电价为0.53 元/千瓦时;超过50 千瓦时的,超出部分的用电量,电价上调0.05 元/千瓦时。
c语言程序设计第三版C语言程序设计第三版是一本面向初学者和中级程序员的教材,它不仅涵盖了C语言的基础知识,还深入探讨了高级编程技巧和最佳实践。
这本书的第三版在前两版的基础上进行了更新和改进,以适应现代编程环境和教学需求。
第一章:C语言简介本章介绍了C语言的历史和特点,包括其结构化编程的特性和在操作系统、嵌入式系统等领域的广泛应用。
同时,也简要介绍了C语言的编译和运行过程。
第二章:C语言基础这一章是C语言编程的入门,涵盖了变量、数据类型、运算符和表达式等基本概念。
通过实例代码,读者可以学习到如何声明变量、进行算术运算和逻辑运算。
第三章:控制结构控制结构是程序流程控制的核心,本章详细介绍了条件语句(if、switch)、循环语句(for、while、do-while)以及跳转语句(break、continue、goto)的使用方法和应用场景。
第四章:函数函数是C语言模块化编程的基础,本章介绍了函数的定义、声明、调用以及参数传递。
此外,还探讨了递归函数和内联函数的概念。
第五章:数组和字符串数组是存储多个数据项的集合,而字符串则是特殊的字符数组。
本章讲解了一维数组、多维数组、字符串的声明、初始化和操作,以及字符串处理函数的使用。
第六章:指针指针是C语言中非常强大的特性,它允许程序员直接操作内存地址。
本章深入讲解了指针的基本概念、指针与数组的关系、指针的算术运算以及函数指针。
第七章:结构体和联合体结构体和联合体是C语言中用于创建复杂数据结构的工具。
本章介绍了如何定义和使用结构体、联合体以及枚举类型,以及它们在实际编程中的应用。
第八章:预处理器预处理器是C语言编译过程中的一个阶段,它处理源代码中的宏定义、文件包含和条件编译等指令。
本章解释了预处理器的工作原理和常用指令。
第九章:文件操作文件操作是程序与外部世界交互的一种方式。
本章介绍了文件的打开、关闭、读写和定位等操作,以及文件指针的使用。
第十章:动态内存分配动态内存分配允许程序在运行时分配和释放内存。
第8章指针【练习8-1】如果有定义”int m, n = 5, *p = &m;”与m = n等价的语句是B 。
A.m = *p; B. *p = *&n; C. m = &n; D. m = **p;解答:A:p是指向m的指针变量,所以*p等价于m。
即m=m。
B:&n是n的地址,*&n是n的值,即把n的值赋给p指向的值m。
即m=n。
C:&n是n的地址。
即把n的地址赋给m。
D:**p是指p指向的指针所指向的值,在此无意义。
故选B。
【练习8-2】调用函数求两个数的和与差:计算输入的两个数的和与差,要求自定义一个函数sum_diff(float op1,float op2, float *psum, float *pdiff),其中op1和op2是输入的两个数,*psum 和*pdiff 是计算得出的和与差。
解答:#include<stdio.h>void sum_diff(float op1,float op2,float *psum,float *pdiff);int main(void){float op1,op2,sum,diff;printf("Input op1 and op2: ");scanf("%f%f",&op1,&op2);sum_diff(op1,op2,&sum,&diff);printf("%f+%f=%f;%f-%f=%f \n",op1,op2,sum,op1,op2,diff);return 0;}void sum_diff(float op1,float op2,float *psum,float *pdiff){*psum=op1+op2;*pdiff=op1-op2;}【练习8-3】两个相同类型的指针变量能不能相加?为什么?解答:不能。
因为指针变量是一种特殊的变量,指针变量的值存放的是所指向变量的地址,两个地址相加并不能保证结果为一个有效的地址值,因而在C 语言中指针变量相加是非法的。
【练习8-4】根据表8.2 所示,这组数据的冒泡排序其实循环到第6 遍(即n-2)时就已经排好序了,说明有时候并不一定需要n-1 次循环。
请思考如何改进冒泡排序算法并编程实现(提示:当发现一遍循环后没有数据发生交换,说明已经排好序了)。
解答:设置一个标志变量flag,进入一轮循环前设置为0,在循环中有发生数据交换就改写flag 值为1。
当该轮循环结束后检查flag 值,如果变为1 说明发生了数据交换,还没有排好序,如果为0 说明没有发生交换,已经排好序。
#include<stdio.h>void bubble (int a[],int n);int main(void){int n,i,a[8];printf("Enter n (n<=8):");scanf("%d",&n);printf("Enter a[%d] : ",n);for(i=0;i<n;i++)scanf("%d",&a[i]);bubble(a,n);printf("After sorted, a[%d]=", n);for(i=0;i<n;i++)printf("%3d",a[i]);return 0;}void bubble(int a[], int n){int i,j,temp,flag;for(i=1;i<n;i++ ){flag=0;for(j=0;j<n-i;j++)if(a[j]>a[j+1]){temp=a[j];a[j]=a[j+1];a[j+1]=temp;flag=1;}if(flag==0)break;}}【练习8-5】重做例8-9,要求使用选择排序算法。
解答:#include<stdio.h>void bubble(int a[], int n);int main(void){int i,n,a[8];printf("Enter n (n<=8): ");scanf("%d",&n);printf("Enter a[%d] :",n);for(i=0;i<n;i++)scanf("%d",&a[i]);bubble(a,n);printf("After sorted, a[%d]=",n);for(i=0;i<n;i++)printf("%3d",a[i]);return 0;}void bubble(int a[],int n){int i,j,temp,index;for(i=0;i<n-1;i++){index=i;for(j=i+1;j<n;j++)if(a[j]<a[index]) index=j;temp=a[i];a[i]=a[index];a[index]=temp;}}8.4电码加密【练习8-6】在使用scanf( )函数时,输入参数列表需要使用取地址操作符&,但当参数为字符数组名时并没有使用,为什么?如果在字符数组名前加上取地址操作符&,会发生什么?解答:因为字符数组名的值是一个特殊的固定地址,可以看作是常量指针,因此不需要再使用取地址符来获取该数组的地址。
如果在字符数组名str 前加上取地址操作符&,那么对其取地址&str 可以看做是这个数组的第一个元素的地址,由于数组地址和数组第一个元素的地址相同,所以&str 表示地址值和str 表示的地址值是相等的。
对scanf()的变长参数列表的话,编译器只负责参数传递,怎么解释后边的几个地址的含义,是由前边的字符串确定的。
所以使用scanf(“%s”,str)和scanf(“%s”,&str)都能通过编译且正常执行。
【练习8-7】C 语言不允许用赋值表达式直接对数组赋值,为什么?解答:数组名可以看作是常量指针,因为不可以对一个常量进行赋值,所以不允许用赋值表达式直接对数组进行赋值。
【练习8-8】输入一个字符串,把该字符串的前3 个字母移到最后,输出变换后的字符串。
比如输入“abcdef”,输出为“defabc”。
解答:#include<stdio.h>#include<string.h>#define MAXLINE 100int main(void){char line[MAXLINE],str[4];int i;printf("Input the string:");gets(line);if(strlen(line)<3){printf("字符串长度小于3,不符合要求!\n");}for(i=0;i<3;i++)str[i]=line[i];str[i]='\0';for(i=3;line[i]!='\0';i++)line[i-3]=line[i];line[i-3]='\0';strcat(line,str);printf("%s%s\n","After changing: ",line);return 0;}【练习8-9】使用动态内存分配的方法实现例8-9 的冒泡排序。
解答:#include<stdio.h>#include<stdlib.h>void bubble(int a[],int n);int main(void){int n,j,*a,i,temp;printf("Enter n(n<=8):");scanf("%d",&n);if((a=(int*)calloc(n,sizeof(int)))==NULL){ printf("Not able to allocate memory.\n");exit(1);}printf("Ente a[%d]:",n);for(i=0;i<n;i++)scanf("%d",a+i);bubble(a,n);printf("After sorted,a[%d]=",n);for(i=0;i<n;i++)printf("%3d",*(a+i));free(a);return 0;}void bubble(int a[],int n){int i,j,temp;for(i=1;i<n;i++)for(j=0;j<n-i;j++)if(*(a+j)>*(a+j+1)){temp=*(a+j);*(a+j)=*(a+j+1);*(a+j+1)=temp;}}习题8一、选择题1.下列语句定义x 为指向int 类型变量 a 的指针,其中哪一个是正确的B 。
A.int a, *x = a; B. int a, *x = &a;C.int *x = &a,a; D.int a, x = a;2.以下选项中,对基本类型相同的指针变量不能进行运算的运算符是 A 。
A.+ B.- C.= D.==3.若有以下说明,且0<=i<10,则对数组元素的错误引用是 C 。
int a[ ] = {0,1,2,3,4,5,6,7,8,9}, *p = a,i;A.*(a+i) B.a[p-a+i] C.p+i D.*(&a[i])4.下列程序的输出结果是 B 。
int main(void){int a[10] = {0,1,2,3,4,5,6,7,8,9}, *p = a+3;printf(“%d”, *++p);return 0;}A.3 B.4 C.a[4]的地址D.非法5.对于下列程序,正确的是 A 。
void f(int *p){*p = 5;}int main(void){int a, *p;a = 10;p = &a;f(p);printf(“%d”, (*p)++);return 0;}A.5 B.6 C.10 D.11二、填空题1. 下列函数在一维数组a 中将x 插入到下标为i(i>=0)的元素前。