您的当前位置:首页正文

C语言教材 第七章 指针 实验

2020-03-22 来源:意榕旅游网
第七章 指针

第一部分 知识训练

【知识要点】

1. 地址与指针

指针变量的概念:用一个变量专门来存放另一个变量的地址。 2. 指向变量的指针变量

指针变量的形式:基类型 *指针变量名;&: 取地址运算符;*:指针运算符。 3. 指针与数组

引用一个数组元素可以用下标法和指针法;可以用数组名作函数的参数。 4. 指针与函数

函数指针变量定义的一般形式为:类型说明符 (*指针变量名)(); 一个函数的返回值可以是一个函数。

【典型习题与解析】

5. char * const p;

char const * p const char *p 上述三个有什么区别? 【解析】

char * const p; //常量指针,p的值不可以修改;

char const * p;//指向常量的指针,指向的常量值不可以改; const char *p; //和char const *p。 6. main()

{

int a[5]={1,2,3,4,5}; int *ptr=(int *)(&a+1);

printf(\"%d,%d\ }

输出结果是什么? 【解析】

答案:输出:2,5

*(a+1)就是a[1],*(ptr-1)就是a[4],执行结果是2,5。

&a+1不是首地址+1,系统会认为加一个a数组的偏移,是偏移了一个数组的大小(本例是5个int)。

int *ptr=(int *)(&a+1);则ptr实际是&(a[5]),也就是a+5。 原因如下:

1) &a是数组指针,其类型为 int (*)[5];而指针加1要根据指针类型加上一定的

值,不同类型的指针+1之后增加的大小不同。

2) a是长度为5的int数组指针,所以要加 5*sizeof(int),所以ptr实际是a[5],

但是prt与(&a+1)类型是不一样的(这点很重要),所以prt-1只会减去sizeof(int*) a,&a的地址是一样的,但意思不一样。

3) a是数组首地址,也就是a[0]的地址,&a是对象(数组)首地址,a+1是数组下

一元素的地址,即a[1],&a+1是下一个对象的地址,即a[5]。

【练习题】

一、填空题

1. 指针变量是把内存中另一个数据的 作为其值的变量。 2. 能够直接赋值给指针变量的整数是 。 3. 如果程序中已有定义:int k;

1) 定义一个指向变量k的指针变量p的语句是 。 2) 通过指针变量,将数值6赋值给k的语句是 。 3) 定义一个可以指向指针变量p的变量pp的语句是 。 4) 通过赋值语句将pp指向指针变量p的语句是 。 5) 通过指向指针的变量pp,将k的值增加一倍的语句是 。

4. 当定义某函数时,有一个形参被说明成int *类型,那么可以与之结合的实参类型可以是 、 等。

5. 以下程序的功能是:将无符号八进制数字构成的字符串转换为十进制整数。例如,输入的字符串为:556,则输出十进制整数366。请填空。 #include main( ) {

2

char *p,s[6]; int n; p=s; gets(p); n=*p-‵0‵;

while( != '\\0')

n=n*8+*p-‵0‵; printf(\"%d \\n\}

二、选择题

1.变量的指针,其含义是指该变量的( )。

A)值 B)地址 C)名 D)一个标志 2.下面程序的运行结果是( )。 #include #include main() {

char *s1=\"AbDeG\"; char *s2=\"AbdEg\"; s1+=2;s2+=2;

printf(\"%d\\n\ }

A)正数 B)负数 C)零 D)不确定的值 3.若有以下定义,则对a数组元素的正确引用是( )。

int a[5],*p=a;

A)*&a[5] B)a+2 C)*(p+5) D)*(a+2) 4.若有以下定义,则p+5表示( )。

int a[10],*p=a;

A)元素a[5]的地址 B)元素a[5]的值 C)元素a[6]的地址 D)元素a[6]的值

3

5. 以下Delblank函数的功能是删除字符串s中的所有空格(包括Tab、回车符和换行符)。 void Delblank(char *s) { int i,t; char c[80];

for(i=0,t=0; ① ;i++)

if(!isspace( ② ))c[t++]=s[i]; c[t]=‘\\0’; strcpy(s,c); }

① A) s[i] B) !s[i] C) s[i]=‘\\0’ D) s[i]==‘\\0’ ② A) s+i B) *c[i] C) *(s+i)=‘\\0’ D) *(s+i) 6. 以下conj函数的功能是将两个字符串s和t连接起来。 char *conj(char *s,char *t) { char *p=s; while(*s) ① ; while(*t) {

*s= ② ;s++;t++; }

*s=‘\\0’; ③ ; }

① A) s-- B) s++ C) s D) *s ② A) *t B) t C) t-- D) *t++ ③ A) return s B) return t C) return p D) return p-t 7. 下列程序的输出结果是( )。 #include main()

4

{

int **k,*a,b=100; a=&b; k=&a;

printf(“%d\\n”,**k); }

A) 运行出错 B) 100 C) a的地址 D) b的地址 8. 若定义了以下函数: void f(……) { ……

p=(double *)malloc(10*sizeof(double)); …… }

p是该函数的形参,要求通过p把动态分配存储单元的地址传回主调函数,则形参p的正确定义应当是( )。 A) double *p 三、编程题

1. 编写一个程序,将用户输入的字符串中的所有数字提取出来。

2. 通过指针处理下面的问题:利用随机函数模拟产生 300 个 1~12 月出生的人数,统计各月所占的出生率。

B) float **p C) double **p

D) float *p

【练习题参考答案】

一、填空题

1. 首地址 2. 0

3. 1)int *p=&k; 2)*p=6; 3)int **pp; 4)pp=&p; 5)(**pp)*=2; 4. 整型数组名、指向整型数据的指针值 5. *(p++) 二、选择题

1. B 2. B 3. D 4. A 5. BD 6. BAC 7. B 8. C 三、编程题

1. 编写一个程序,将用户输入的字符串中的所有数字提取出来。

5

#include #include void main()

{ char string[81],digit[81]; }

2. 通过指针处理下面的问题:利用随机函数模拟产生 300 个 1~12 月出生的人数,统计

各月所占的出生率。 #include #include #include

int main(int argc, char* argv[]) {

int month[12],*m_pt,i; m_pt=month;

srand( (unsigned)time( NULL ) ); //srand()函数产生一个以当前时间开始的随机 种子

char *ps; int i=0;

printf(\"enter a string:\\n\"); gets(string); ps=string; while(*ps!='\\0')

{if(*ps>='0' && *ps<='9') }

digit[i]='\\0';

printf(\"string=%s digit=%s\\n\

{ digit[i]=*ps; } ps++;

i++;

6

for (i=0;i<12;i++) *(m_pt+i)=0; for (i=0;i<300;i++) (*(m_pt+rand()%12)) ++;

printf(\"月份 出生人数 出生率 (总数300)\\n\"); for (i=0;i<12;i++)

printf(\"%3d %6d %2.1f℅ \\n\; getchar(); return 0; }

第二部分 上机实训

一、 目的要求

1.掌握指针的概念。

2.学会通过指针处理普通变量和一维数组。 3.学会通过指针处理动态分配的内存。

二、 预习内容

掌握指针变量的使用方法、“&”和“*”的用法、指针变量的赋值、指向数组的指针和指向函数的指针用法。

三、 实验内容及实验步骤

1.要求使用指针处理下面的问题,输入四个整数,按由小到大的顺序输出然后将程序改为:(1)将程序修改为由大到小顺序输出;(2)输入四个字符串,按由小到大顺序输出。 参考程序: 行号 程序代码

1 #include \"stdio.h\" 2 void main() 3 { int a,b,c,d,t;

4 int *pa=&a,*pb=&b,*pc=&c,*pd=&d; 5 printf(\"请输入四个整数:\"); 6 scanf(\"%d%d%d%d\;

7

7 if (*pa>*pb) //第一个数和第二个数比较 8 { t=*pa;*pa=*pb;*pb=t; } //两个数交换 9 if (*pb>*pc) //第二个数和第三个数比较 10 { t=*pb;*pb=*pc;*pc=t; }

11 if (*pc>*pd) //第三个数和第四个数比较 12 { t=*pc;*pc=*pd;*pd=t; }

13 if (*pa>*pb) //第一个数和第二个数比较 14 { t=*pa;*pa=*pb;*pb=t; }

15 if (*pb>*pc) //第二个数和第三个数比较 16 { t=*pb;*pb=*pc;*pc=t; }

17 if (*pa>*pb) //第一个数和第二个数比较 18 { t=*pa;*pa=*pb;*pb=t; } 19 printf(\"\\n 排序结果如下:\");

20 printf(\"%d,%d,%d,%d\\n\; 21 }

问题 1:将程序修改为由大到小顺序输出。

提示:将程序第 7、9、11、13、15、17 行的“<”号改为“>”号。 问题 2:完成题目的第二部分 提示:对上面的程序作如下修改: 1、打开字符串处理函数的头文件

在第 1 行下面增加 1 行 #include \"string.h\" 2、将整型变量改为字符串变量

第 3、4 行改为:

char a[100],b[100],c[100],d[100],t[100]; char *pa=a,*pb=b,*pc=c,*pd=d; 3、将输入整数改为输入字符串

第 6 行改为:

scanf(\"%s%s%s%s\; 4、将整数比较大小改为字符串比较大小

8

第 7、9、11、13、15、17 行中原比较整数大小使用字符串比较函数来比较,如第 7 行改为:if (strcmp(pa,pb)>0) 5、将整数赋值改为字符串拷贝

第 8、10、12、14、16、18 行中整数赋值改为使用字符串拷贝函数,如第 8行第 1 个赋值语句改为:strcpy(t,pa); 6、将整数输出改为字符串输出 第 20 行改为:

printf(\"\\n%s\\n%s\\n%s\\n%s\\n\\n\;

2. 完善程序,要求使用函数功能:将一个数字字符串转换成一个整数(不得调用C语言提供的将字符串转换为整数的函数)。例如,若输入字符串“-1234”,则函数把它转换为整数值-1234。 #include #include long fun(char *p) {

填写程序 }

void main() {

char s[6]; long n;

printf(\"Enter a string:\\n\"); gets(s); n=fun(s);

printf(\"%ld\\n\}

3. 分析下列程序

(1)#include

main() {

9

char a[10]=””,*p; p=a; puts(p); }

(2) #include

main() {

int max,x,y,*p1,*p2; printf(“Input x and y:”); scanf(“%d%d”,&x,&y);

p1=&x; p2=&y;

if(*p1>*p2) max=*p1; else max=*p2;

printf(“The max number is %d”,max); }

要求:输入程序,并调试、编译、连接、运行

输出结果 程序(1) 功能为 程序(2) p=&a[3] 你的输入是 输出结果 若将p=a改为输出结果 4. 输入10个整数,将其中最小的数和第一个数对换,把最大的数和最后一个数对换,即把最小数放到最前面,把最大数放到最后面。(用指针实现)

5. 用指向指针的指针的方法对n个整数排序并输出。要求将排序单独写成一个函数。整数和n在主函数中输入。最后在主函数中输出。

10

因篇幅问题不能全部显示,请点此查看更多更全内容