已阅读5页,还剩14页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
9.1存储单元的地址仅表明其首字节在内存中的位置,只有地址无法确定相关储存单元的大小及编码格式。只有知道了类型,才能确定相关存储单元的大小及编码格式,才能使用存储单元,因此,有类型的地址可以确定存储单元。9.2整型变量存储整数,指针变量存储地址。指针与内存地址的关系似乎更像整型与整数的关系。准确地说,指针变量存储的是存储单元的地址而并非简单的内存地址。简单的内存地址可以看成一个整数,但存储单元的地址应理解成具有类型的地址。9.3地址是整数,但整数不是地址。多次强调,存储单元的地址有类型,而指针变量也只能用规定类型的存储单元的地址赋值。更进一步,指针变量只能指向程序拥有的存储单元。因此,通常不能用整数给指针变量赋值。理论上不可以,只有同类型间的指针变量才可以相互赋值,但实际上C语言追求效率,不保证类型安全,有些C语言编译系统“允许”不同类型的指针变量之间相互赋值。即使单精度指针变量pf真的指向了整型变量i,通过*pf使用变量i的存储单元也没有太大的实际意义。9.4不等价。double *p = &lf;是初始化语句,定义了一个双精度指针变量p,并且它被赋值为变量lf的地址;语句*p=&lf;是赋值语句,把变量lf的地址赋值给指针变量p指向的存储单元,这条语句有两个问题,首先指针变量p没有指向合法的存储单元,不能以间接引用*p的方式使用非法的存储单元,其次,*p标识存储单元的类型为双精度,不能接受变量lf的地址,两者类型不匹配。double *p = &lf;的作用等同于double *p; p = &lf;。9.5程序的运行结果为:因为语句printf(“%x”, -5);的输出结果为fffffffb,所以变量i实际的内存状态和简化后的内存状态如下:变量pi与变量i的关系如下:9.6指针变量用于存储某类型存储单元的地址,而存储单元的地址在VC6.0中均为32位,因此,无论何种类型的指针变量,其长度均为4个字节。sizeof(pf)的值为指针变量pf本身的长度,长度为4个字节。sizeof(*pf)的值为指针变量pf指向的存储单元的长度,即双精度型存储单元的长度,为8个字节。9.7不能用整型变量给整型指针变量赋值。可修改为:pi=&i;或pi=(int*)i;。9.8程序中指针变量p1指向了整型变量i,而语句p2=p1;使得指针变量p2也指向了整型变量i。因为*p1和*p2也标识了变量i相关的存储单元,所以语句i = *p1 + *p2;相当于i = i + i;,语句执行后,变量i的值变为6。最终程序的输出结果为:6, 6, 6。9.9C语言中使用存储单元有直接引用和间接引用两种方法。对于指针变量p,语句p=&i;为指针变量p赋值为变量i的地址,实际上是使用直接引用的方式使用了指针变量p本身的存储单元。语句*p = 23;就是所谓的以间接引用的方式使用指针变量p指向的存储单元。理论上,只要指针变量指向了某存储单元,就可以通过间接引用的方式使用该存储单元,但实际上为避免出现错误,应保证通过间接引用方式只使用合法的存储单元。表达式p标识一个可以存储某类存储单元地址的存储单元,表达式*p标识p指向的存储单元。9.10pi不是空指针!程序的输出结果为:可见在VC6.0中,没有赋值的局部指针变量会被赋值为0xcccccccc。9.11(1)无问题。(2)无问题。(3)有问题,其中p2 = *p1;错误,不能用整型变量给指针变量赋值。(4)有问题,指针变量p1指向了非法的存储单元,语句*p1=*p2;中使用了非法的存储单元。(5)无问题。(6)有问题。指针变量p1只能用整型地址赋值,语句p1=&p2;中&p2的结果并非整型地址而是整型指针地址。9.12程序的运行结果为:a=1, b=7m=6, n=9分析如下:语句a=p1=&m;中p1=&m先求值,因为指针变量p1指向了整型变量m,故求值结果为真,值为1,原语句变为a=1;。在语句b=(+*p1)/(*p2)+5;中,*p1标识了变量m相关的存储单元,即其可与m互换,*p2可与n互换,原语句可变为b=(+m)/n+5;,变量b被赋值为7,且变量m自增1后变为6。语句n=*p1+*p2;可变为n=m+n;即n=6+3;。9.13(1) #includevoid main()int a,b,c,*pa=&a,*pb=&b,*pc=&c,t;printf(请输入三个整数!n);scanf(%d%d%d, pa, pb, pc);if(*pa *pb)t = *pa;*pa = *pb;*pb = t;if(*pb *pc)t = *pb;*pb = *pc;*pc = t;if(*pa *pb)t = *pa;*pa = *pb;*pb = t;printf(a = %d, b = %d, c = %dn,a,b,c);(2) #includevoid main()int a,b,c,*pa=&a,*pb=&b,*pc=&c,*t;printf(请输入三个整数!n);scanf(%d%d%d, pa, pb, pc);if(*pa *pb)t = pa;pa = pb;pb = t;if(*pb *pc)t = pb;pb = pc;pc = t;if(*pa *pb)t = pa;pa = pb;pb = t;printf(a = %d, b = %d, c = %dn,a,b,c);printf(%d%d y)*z = x;else*z = y;(2)#include #include 7_1.cvoid main()float m = 3.2, n = 2.3;int i;larger(m + n, m - n, &i);printf(%.1f 和%.1f中较大者为%dn, m + n, m - n, i);思考:可以定义一个单精度变量f(float f;)再用larger(m+n, m-n, &f);求出较大者吗?9.22void fac(int n, unsigned int *re)if(n=0 | n=1)*re = 1;elsefac(n-1, re);*re = n * *re;9.23(1)语句const double *pf = &m;中关键字const修饰的是double *可理解为指针变量pf指向的存储单元,也就是说指针变量pf可以通过赋值操作指向不同的存储单元,但它指向的存储单元不能被修改,即不能用类似*pf=3;的语句改变与变量m相关的存储单元。(2)语句double const *pf = &m;中关键字const修饰的是*,同上也可理解为指针变量pf指向的存储单元。(3)语句double * const pf = &m;中关键字const修饰的是指针变量pf,即不能通过赋值操作改变它指向的存储单元了,它只能指向变量m,但可以的用类似*pf=3;的语句改变与变量m相关的存储单元。(4)语句const double * const pf = &m;中,指针变量pf只能指向变量m,也不能用类似*pf=3;的语句改变与变量m相关的存储单元。函数的首部类似void test(cosnt int *pi)。9.24B和D均可以。9.25表达式*p+中优先级相同、右结合,自增操作符先求值,子表达式p+的结果为p,故原表达式实为*p,即a1,值为2,但具有左值性。该表达式求值过程中使指针变量p自增1,再使用指针变量p时,它已经指向了数组元素a2。表达式*-p中,子表达式-p先求值,指针变量p先减1,即指向了数组元素a0,故原表达式为a0,值为1,但具有左值性。9.26一维数组由地址连续的一组变量构成,只要获得了首元素的地址,就可以很容易地访问其余的数组元素,因此,一维数组的关键在于首元素地址。一维整型数组变量a的值为其首元素的值为其首元素地址,即它指向了数组的首元素;整型指针变量pi可以指向任意的整型存储单元,当然也可以指向数组的首元素。相同点:它们都存储了整型存储单元的地址。不同点:数组变量a只能存储固定的地址,不能通过赋值操作改变它指向的存储单元;所有的数组元素的存储单元都算作数组变量a的,故它的长度较大,但整型指针变量pi的长度只有4个字节,因为VC6.0中,地址有32位。9.276.5:#include#define N 10void main()int *pi, *pmax, temp;int arrN;printf(请输入%d个整数:n, N);for(pi=arr; piarr+N; +pi)scanf(%d, pi);printf(处理前数组为:n);for(pmax=pi=arr; pi *pmax)pmax = pi;for(temp=*pmax; pmaxarr+N-1; +pmax)*pmax = *(pmax + 1);*pmax = temp;printf(n处理后数组为:n);for(pi=arr; piarr+N; +pi)printf(%d , *pi);printf(n);6.6:#include#define N 10void main()int *pi, *p, temp;int aN=20,23,37,52,95;printf(请输入%d个整数:n, N-5);for(pi=a+5; pi=a &*ptemp; -p)*(p+1) = *p;*(p+1) = temp;printf(数组为:n);for(pi=a; pia+N; +pi)printf(%d , *pi);printf(n);6.7:#include#define N 20void main()int *pi, *p, temp;int aN;printf(请输入%d个整数:n, N);for(pi=a; pia+N; +pi)scanf(%d, pi);for(pi=a; pi=a&*ptemp; p-=2)*(p+2) = *p;*(p+2) = temp;printf(数组为:n);for(pi=a; pia+N; +pi)printf(%d , *pi);printf(n);9.28int strlen(char *str)int i=0;while(stri!=0)+i;return i;9.29int toInt(char *str)int sum,i,flag=1;sum = i = 0;if(*str = -)flag = -1;i = 1;if(*str = +)i = 1;while(stri!=0)sum = sum * 10 + (stri+-0);return sum * flag;9.30#include void main()char str100, temp, *p1, *p2, *p3;gets(str);for(p1=str; *p1!=0; +p1)p3 = p1;for(p2=p3+1; *p2!=0; +p2)if(*p3 *p2)p3 = p2;temp = *p1;*p1 = *p3;*p3 = temp;puts(str);9.31它们都是普通整型指针变量。数组变量作形参时会变成与之兼容的普通的指针变量。9.32函数逆序输出字符型指针变量ps指向的字符串。9.33test函数使用递归算法求出整型数组a中下标从i开始到n-1结束的最大的元素的下标,下标通过指针变量p指向的存储单元返回。使用函数test时形参p指向的存储单元的初值必须为下标i到n-1中的任一个下标。void main()int a5=2, 23, -9, 101, 52;int max = 0;test(a, 5, 0, &max);printf(%d, max);9.34分析:test函数输出形参i的值,形参a为一维整型数组,但它类型实际为普通的整型指针变量,因此,sizeof(a)的值为4。在main函数中,变量a是长度为5的一维整型数组,故sizeof(a)的值为20。数组a指向了其首元素,*a与a0可以互换,因此,sizeof(*a)的值为4。对于数组a,sizeof(a)/sizeof(*a)可以求出其“第一维”的长度。2020, 459.356.16:#include #define N 3void main() int mNN;int i, j, sum = 0;int *p;printf(请输入%d行%d列整型矩阵的元素n, N, N);p = &m00;for(i=0; iN; +i)for(j=0; jN; +j)scanf(%d, p);if(i = j | i + j = N - 1)sum += *p;+p;printf(两条主对角线上元素的和为:%dn, sum);6.17:#include #define N 3void main() int mNN;int i, j, sum = 0;int *p = (int*)m;printf(请输入%d行%d列整型矩阵的元素n, N, N);for(i=0; iN; +i)for(j=0; jN; +j)scanf(%d, p);if(i = j)sum += *p;+p;printf(上三角元素的和为:%dn, sum);9.36#includevoid main()int a32=1,2,3,4,5,6;int i,j;int *p=&a00;printf(按行输出:n);for(i=0;i3;+i)for(j=0;j2;+j)printf(%d ,*(p+i*2+j);printf(n);printf(按列输出:n);for(i=0;i2;+i)for(j=0;j3;+j)printf(%d ,*(p+j*2+i);printf(n);9.37#include#define N 3#define M 4void main()int aNM, k;int (*p1)M, *p2, *p;for(p=&a00; p(int*)(a+N); +p)scanf(%d, p);for(p1=a; p1a+N; +p1)p = *p1;/p指向了当前行的首元素for(p2=p; p2 *p)p = p2;/让p2指向最大值所在列的第0行元素p2 = a0 + (p - (int*)p1);/为简便没有用指针构造循环for(k=0;kN;+k)if(*p2 *p)break;p2 += N;if(k = N)printf(鞍点在%d行%d列!n, p1-a+1, p-(int*)p1+1);return;printf(没有鞍点!n);9.38程序的输出结果为:由程序的输出可知,在VC6.0中相同的字符串常量共用了同一个存储单元。9.39str是一维字符型数组变量,有四个元素,每个元素分别存储了字符H、i、!和0号字符。变量str1中一个普通的字符型指针变量,指向了字符串常量Hi!的首字符。语句scanf(%s, str);将向从变量str指向的存储单元开始的连续的多个存储单元中存入一串字符,可是变量str并没有通过赋值操作指向某个合法的存储单元。9.40#include#define N 3void main()int a,b,c,*arrN=&a, &b, &c;int i, j, t;printf(请输入%d个整数!n, N);for(i=0; iN; +i)scanf(%d, arri);for(i=1; i0&*arrj-1t; -j)*arrj = *arrj-1;*arrj = t;printf(a = %d, b = %d, c = %dn,a,b,c);9.41#include void swap(int *ppm, int *ppn)int *ppt;ppt = *ppm;*ppm = *ppn;*ppn = ppt;void main()int i, j, *pi=&i, *pj=&j;i = 2;j = 3;printf(%p,%p,%d,%dn, pi, pj, *pi, *pj);swap(&pi, &pj);printf(%p,%p,%d,%dn, pi, pj, *pi, *pj);9.42 1 2 3 4 5 67 8 9分析略。9.43#include#includevoid main()char *str3=Henan,Beijing,Guangzhou;char *pt;int i,j;for(i=0;i2;+i)for(j=0;j0)pt = strj;strj = strj+1;strj+1 = pt;printf(%s,%s,%sn,str0,str1,str2);9.44程序中少了三条语句。没有变量p的定义。在第一个循环中使用指针时没有对其赋值。在第二个循环中时没有调整指针变量p指向的存储单元。完整的程序如下。#include#includevoid main()int a=5,b=2,c=3;int *pa3=&a, &b, &c;int *pi, i;int *p;for(i=0; i3; +i)pi = pai;printf(%2d, *pi);printf(n);p = pa;for(i=0; i3; +i)printf(%2d, *p);+p;指针变量和数组变量的关系如图所示。9.45用命令test hello C!执行程序时,命令行参数只有一个hello C!,即双撇号中的字符串算一个命令行参数。测试程序如下:#includeint main(int argc, char *argv)while (argc- 1)puts(argvargc);return 0;9.46#includeint main(int argc, char* argv)char ca;if(argc 1)ca = argv11;switch(ca)case s:case S:printf(您使用了/s选项执行了程序!n);printf(5+3=%dn, 5+3);break;case p:case P:printf(您使用了/p选项执行了程序!n);printf(5-3=%dn, 5-3);break;case a:case A:printf(您使用了/a选项执行了程序!n);printf(5*3=%dn, 5*3);break;case ?:printf(您使用了/?选项执行了程序!n);printf(选项/s做加法、/p做减法、/a做乘法n);break;default:printf(选项有/s、/p、/a和/?n);elseprintf(请使用选项/s、/p、/a或/?执行程序!n);return 0;9.47#include#include/calDefInt参见例9-24double fun(double x)return 2*x*x+sin(x);int main()printf(%lfn,calDefInt(fun,0,3.1415926/2);return 0;9.48void型指针变量指向一个类型不确定的存储单元。因为无法确定void指针变量指向存储单元的类型,所以不能以间接引用的方式使用它指向的存储单元。与void型变量相关存储单元的类型不能确定,也就无法为其分配存储单元,所以不能定义void型变量。void型指针变量存储一个地址,占4个字节,因此,可以定义void型指针变量。9.49swap函数的形参为void型指针变量,因此可以使用任意类型存储单元的地址做实参调用此函数。swap函数中void型形参被强制类型转换成字符型指针变量,字符型指针变量指向了存储单元的最小单位,即字节。函数中把size大小字节的存储单元交换了数据,自然也就可以交换任意类型的存储单元了。测试程序略。9.50程序在堆空间中定义了一个3行2列的二维整型数组。9.51#include #include int main( ) int i, j; char str = Hello world!; char *ppa = (char *)malloc(3 * sizeof(char *); if(ppa != NULL) for(i=0; i3; +i) if(ppai = (char *)malloc(2 * sizeof(char *) = NULL)printf(分配内存空间失败!n);return 2; for(i=0; i3; +i)for(j=0; j2; +j)ppaij = &stri*2+j;
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年人工智能检测设备研发可行性研究报告及总结分析
- 2025时事政治测试题试卷及答案
- 2025年文化创意产业项目可行性研究报告及总结分析
- 2025年绿色旅游度假村建设项目可行性研究报告及总结分析
- 2025年互动娱乐内容开发可行性研究报告及总结分析
- 2025年新兴市场消费者行为研究可行性报告
- 在建工程抵押权转让合同(3篇)
- 2025年桌面云办公平台开发项目可行性研究报告及总结分析
- 2025年农产品农药残留检测协议
- 电测仪表专业技能复习题及答案
- 研究生实践考核表范文(篇一)
- 聚合物防水涂料外墙施工方案
- 2024年中国舞蹈史考研题库(含考研真题)
- 洞箫曲合集下册
- 电商直播带货培训课件
- 小麦高产的施肥技术
- 工程渣土接收证明(建筑垃圾消纳场接收证明)
- 低压配电柜培训ppt课件
- 中国医院质量安全管理 第4-9部分:医疗管理危急值管理 T∕CHAS 10-4-9-2019
- 《宋词》课件豪华宋词
- 抛物线焦点弦的性质(公开课)(20张)-完整版PPT课件
评论
0/150
提交评论