C程序设计教程与实验(第3版)习题解答--第7章

第七章 指针

1.选择题

(1)设已定义“int  a, *p;”,下列赋值表达式中正确的是(C)。

        A.*p=a  
        B.p=*a   
        C.p=&a 
        D.*p=&a

        指针变量的值是地址,* 为指针运算符,选择C。

(2)若已定义“int a[]={1,2,3,4},*p=a;”, 则下面表达式中值不等于2的是(C)。

        A.*(a+1)
        B.*(p+1)
        C.*(++a)
        D.*(++p)

        a表示数组所在地址,并非可修改的左值,不可进行++a,C错误。

(3)若已定义“int a[]={1,2,3,4},*p=a+1;”则p[2]的值是(C)。

        A.2
        B.3
        C.4 
        D.无意义

        因为*p = a+1,p[2]同于a[1+2],即4,C正确。

(4)设已定义“char s[]="ABCD";”,printf("%s", s+1)的值为(C)。

        A.ABCD1         
        B.B      
        C.BCD              
        D.ABCD

        &s等于&s[0],s+1表示s[1]的地址,从s[1]始即从'B'开始输出。

(5)下面对字符串变量的初始化或赋值操作中,错误的是(C)。     

        A.char a[]="OK";       
        B.char *a="OK";
        C.char a[10]; a="OK";  
        D.char *a; a="OK";

        数组名无法接收对数组元素的整体赋值,C错误。

(6)设已定义 char *ps[2]={"abc","1234"}; 则以下叙述中错误的是(A)。

        A.ps为指针变量,它指向一个长度为2的字符串数组
        B.ps为指针数组,其两个元素分别存储字符串"abc"和"1234"的地址
        C.ps[1][2]的值为'3'
        D.*(ps[0]+1)的值为'b'

        A中,该数组为二维数组,不能因为只有根据下标简单判断,A错误。

(7)以下程序运行后,输出结果是(C)。

#include<stdio.h>
int main(void)
{ 
    char *s="abcde";
    s+=2;
    printf("%ld\n",s);
}

        A.cde                   
        B.字符c的ASCII码值    
        C.字符c的地址    
        D.出错

        s储存的是数组"abcde"的首地址,s+2则是'c'的地址,以long int输出则为其地址,C正确。

(8)下面程序的输出是(D)。

#include<stdio.h>
#include<string.h>
int main(void)
{    
   char p1[10]="abc", *p2="ABC", str[50]="xyz";
   strcpy(str+2,strcat(p1,p2));
   printf("%s\n",str);
}

        A.xyzabcABC    
        B.zabcABC    
        C.yzabcABC     
        D.xyabcABC

        strcpy()函数作用是将字符串2复制到字符数组1中。strcat()函数作用是将字符串2连接在字符串1后。strcat(p1,p2)值为"abcABC",s+2地址上的值为str[2],即从'z'处开始延续"abcABC",D正确。

(9)执行以下程序后,y的值是(C)。

#include<stdio.h>
int main(void)
 {
    int a[] = { 2,4,6,8,10 };
    int y = 1, x, * p;
    p = &a[1];
    for (x = 0; x < 3; x++)
        y += *(p + x);
    printf("%d\n", y);
}

        A.17    
        B.18    
        C.19    
        D.20

        y依次加上a[1],a[2],a[3],y = 1+4+6+8,故y值19,C正确。

(10)设已有定义: “char* st="how are you";”, 下列程序段中正确的是(A)。

        A.char a[11], *p;  strcpy(p=a+1,&st[4]);
        B.char a[11];       strcpy(++a, st);
        C.char a[11];       strcpy(a, st);
        D.char a[], *p;     strcpy(p=&a[1],st+2);

        B中,a并非可修改的左值,语法错误;C中,a为数组名,无法给数组整体赋值;D中,数组a未完成初始化。

(11)若有说明“int i, j=7, *p=&i;”,则与“i=j”;等价的语句是(B)。

        A.i=*p;    
        B.*p=*&j;    
        C.i=&j;    
        D.i=**p;

        指针p的值即i的地址。A、D都未涉及j,B中,*p = *&j,即*p = 7,使地址p上的值为7,B正确;C中,i值为j的地址,显然不为7。

(12)以下程序的输出结果是(D)。

#include <stdio.h>
int main(void)
{
    char a[] = "programming", b[] = "language";
    char* p1, * p2;
    int i;
    p1 = a;      
    p2 = b;
    for (i = 0; i < 7; i++)
        if (*(p1 + i) == *(p2 + i))
            printf("%c", *(p1 + i));
    return 0;
}

        A.gm     
        B.rg     
        C.or     
        D.ga

        代码意在通过地址寻找数组a、b中相同的字符,其为ga,D正确。

(13)执行以下程序的输出结果是(A)。

#include <stdio.h>
#include <string.h>
int main(void)
{
    char * p[10] = { "abc","aabdfg","dcdbe","abbd","cd" };
    printf("%d\n", strlen(p[4]));
    return 0;
}

        A.2       
        B.3     
        C.4      
        D.5

        strlen()函数计算字符串的长度,直到空字符。p[4]值为"cd",A正确。

(14)下面程序段的输出结果是(C)。

int a[][3]={1,2,3,4,5,6,7,8,9,10,11,12},(*p)[3];
p=a;
printf("%d\n",*(*(p+1)+2));

        A.3      
        B.4     
        C.6     
        D.7

        (*p)[3]表示的是数组长度为3的行变量指针,*(*(p+1)+2)表示第二的第3个元素,即a[1][2],6,C正确。

(15)设有如下函数定义:

int f(char *s)
{   
    char *p=s;
    while(*p!='\0')
          p++;
    return(p-s);
}

如果在主程序中用下面的语句调用上述函数,则输出结果为(C)。|
printf("%d\n",f("goodbey!"));

        A.3     
        B.6     
        C.8     
        D.0

        s指向"goodbey!",p也指向该字符串。p指针的移动直到空字符,p和s的差值实际是计算该字符串的有效长度,其为8,C正确。

2.填空题

(1)若有语句int a[10], *p; p=a;,在程序中引用数组元素a[1]的形式还可以是:  *(p+1) *(a+1)    p[1]  

        p=a 同于 p=&a[0]

(2)若有语句:int a[4]={1,2,3,4},*p; p=&a[1];,则printf("%d\n", *p++);的结果是 2  

        p++,先参与运算再自增。

(3)若有定义“int w[10]={23,54,10,33,47,98,72,80,61}, *p=w;”,则不移动指针p,且通过指针p引用值为98的数组元素的表达式是 *(p+5)  

        *p == a[0]

(4)函数sstrcmp()的功能是对两个字符串进行比较。当s所指字符串与t所指字符串相等时,返回值为0;当s所指字符串大于t所指字符串时,返回值大于0;当s所指字符串小于t所指字符串时,返回值小于0。

int sstrcmp( char *s, char *t)

{  while (*s && *t && *s==  *t  )

   { s++;    t++;  }

   return   *s-*t  ;

}

        入口条件处需判断两字符串同一位置的字符是否相等。返回值反映两字符串大小。

(5)执行下面的语句后,程序的输出是  5, 3  

int m[]={1,2,3,4,5,6,7,8}, *p1=m+7, *p2=&m[2];
p1-=3;
printf("%d,%d\n",*p1,*p2);

初始化时,*p 等于 &m[7],p1-=3后,*p1值为5,*p2值同m[2],即3。

(6)已知“int a[5] = { 2, 3, 4, 5, 6 }; int *p = a+2;”,表达式 *p*a[3] 的值是  20  

        *p值同a[2],即4,4*5,故结果为20。

(7)以下fun函数的功能:累加数组元素中的值,n为数组元素个数,累加的和放入x所指的存储单元中。

fun(intb[], int n, int *x)
{
        int k,r=0;
        for (k=0;k<n;k++)
        r=   r+b[k]   ;
           *x   =r;
}

        r = r+b[k];负责累加元素,*x = r;负责存放累加和。

(8)已有定义char *names[]={"Wang","Li","Chen"};语句“printf("Second%sFirst%s",names[1], names[0]);”的运行结果为   SecondLiFirstWang   

        以names[1],names[0]代入即可。

(9)设有变量定义:“int a[]={1,2,3,4,5,6},*p=a+2;”,则计算表达式*(p+2)*p[2]的值是 25 

        *p值同于a[2],*(p+2)值同于a[4],即 5,p[0]同于a[2],p[2]同于a[4]。

(10)判断输入的字符串是否是“回文”,(顺读和倒读都一样的字符串称为“回文”,如level)。

#include "stdio.h"
#include "string.h"
int  main(void)
{
        char s[80], *t1, *t2;
        int m;
        gets(s)   ;
        m=strlen(s);
        t1=s; 
        t2=  s+m-1  ;
        while(t1<t2)
        {
                if(*t1!=*t2)  break;
                else
                {
                        t1++;
                        t2--  ;
                }
        }
        if (t1<t2)  printf("NO\n");
        else printf("YES\n");
        return 0;
}

        第一处获取输入的字符串;第二处,将最后一个有效元素的地址赋给t2;第三处,向头部移动指针。

3.编程题

(1)输入2个字符串,每个字符串的长度均不超过80字符,用自己实现的cmpstr()函数完成这两个字符串的大小比较,cmpstr()函数的功能和字符串比较函数strcmp()的功能相同。

#include<stdio.h>
#include<string.h>
int cmpstr(char* s1, char* s2);
int main(void)
{
	int res;
	char s1[81], s2[81];
	printf("输入字符串1:");
	gets(s1);
	printf("输入字符串2:");
	gets(s2);
	res = cmpstr(s1, s2);
	if (res > 0)
	{
		printf("字符串2大于字符串1");
	}
	else if (res < 0)
	{
		printf("字符串2小于字符串1");
	}
	else
	{
		printf("字符串2等于字符串1");
	}
    return 0;
}

int cmpstr(char* s1, char* s2)
{
	while (*s1 != 0 && *s2 != 0)
	{//指针遍历比较
		if (*s1 == *s2)
		{
			s1++;
			s2++;
		}
		else return *s2 - *s1;
	}//返回字符串2与字符串1在不同时对应字符的差值
	return 0;
}

(2)定义一个函数float reverse(int p[], int n),该函数有两个参数,第一个参数p为形参数组名,第二个参数n为该数组中的元素个数,要求使用reverse()函数将该数组中的所有元素逆序排列,并返回该数组中所有元素的平均值。

float reverse(int p[], int n)
{
	int k;
	float res = 0;
	for (int i = 0; i < n - 1; i++)
	{//选择排序
		k = i;
		for (int j = i + 1; j < n; j++)
		{
			if (p[j] > p[k])
			{
				if (p[j] > p[k]) k = j;
			}
		}
		if (k != i)
		{
			p[k] += p[i];
			p[i] = p[k] - p[i];
			p[k] -= p[i];
		}
		res += p[i];
	}
	res += p[n-1];//加上未取到的最后一个数
	res /= n;
	return res;
}

(3)定义一个函数delSubstr(),删除字符串中第k个字符开始的m个字符,例如删除字符串abcde第2个字符开始的3个字符,则删除后结果为ae;又如删除字符串abcde第4个字符开始的5个字符,则删除后结果为abc。

int delSubstr(char* s, int k, int m)
{
	char* p = s;
	int i;
	if ((k + m - 1) > strlen(s))
	{//移动不符合要求时,返回0
		return 0;
	}
	for (i = k - 1; i < strlen(s) - 1; i++)
	{//从第i个字符开始,将后面的值移动到前面
		*(p + i) = *(p + i + m);
	}
	*(p + i) = '\0';
	return 1;
}

(4)定义一个函数delSpechar(),使用字符指针删除字符串中的所有指定字符(如把字符串“I love you!”中的o字符删除,得到“I lve yu!”)。

char* delSpechar(char* s, char c)
{
	char* p = s, * q = "";
	while (*p != '\0')
	{
		if (*p == c)
		{
			q = p;
			while (*q != '\0')
			{
				*q = *(q + 1);
				q++;
			}
		}
		else p++;
	}
	return s;
}

(5)求整型二维数组a[M][N]中的最大元素值及最大元素的位置(用指针法引用数组元素)。

void f(int* p, int m, int n)
{//m为二维数组行数,n为列数
    int k1 = 0, k2 = 0, r = *p;
    for (int i = 0; i < m; i++)
    {
        for (int j = 0; j < n; j++)
        {
            
            if (*p < *(p + n * i + j))
            {
                k1 = i;
                k2 = j;
                *p = *(p + n * i + j);
                printf("%d\t%d\n", k1, k2);
            }
        }
    }
    printf("最大值为:%d,a[%d][%d]", *p, k1, k2);
    *p = r;//归还*p原值
}

(6)已知字符串str[80],编写函数lstrchar(),实现在数组str中查找字符ch首次出现的位置,如果字符串中找不到该字符,则返回-1。

int lstrchar(char* p, char c)
{
    int i = 0, res = -1;
    while (*(p  + i) != '\0')
    {
        if (*(p + i) == c)
        {
            res = i;
            return res;//返回该字符下标
        }
        i++;
    }
    return res;//找不到则返回原值 -1
}

(7)定义一个整型二维数组并初始化,编程求该数组所有元素的和。要求:分别用数组下标法、一级指针法、二级指针法实现。

#include <stdio.h>
int f1(int s[3][4])
{
    int sum = 0;
    for (int i = 0; i < 3; i++)
    {
        for (int j = 0; j < 4; j++)
        {
            sum += s[i][j];
        }
    }
    return sum;
}

int f2(int* p)
{
    int sum = 0;
    for (int i = 0; i < 3 * 4; i++)
    {
        sum += *(p + i);
    }
    return sum;
}

int f3(int (*p)[4])
{
    int sum = 0;
    for (int i = 0; i < 3; i++)
    {
        for (int j = 0; j < 4; j++)
        {
            sum += *(*(p + i) + j);
        }
    }
    return sum;
}

int main(void)
{
    int a[3][4] = { {4,2,7,9},{1,3,13,0},{-5,6,-11,10} };
    printf("数组下标法:%d\n", f1(a));
    printf("一级指针法:%d\n", f2(a[0]));
    printf("二级指针法:%d\n", f3(a));
    return 0;
/*运行结果
数组下标法:39
一级指针法:39
二级指针法:39*/
}

(8)输入一行数字字符存入字符数组str[80]中,用num[10]中的数组元素作为计数器来统计每个数字字符的个数。用下标为0的元素统计字符“0”的个数,用下标为1的元素统计字符“1”出现的次数,……。输出每个奇数字符出现的次数。

#include <stdio.h>
void f(char* p)
{
    int num[10] = {0}, sum = 0;
    while (*p != '\0')
    {
        num[*p - '0']++;
        p++;//移动指针来实现遍历
    }
    for (int i = 1; i < 10; i += 2)
    {
        printf("%d出现的次数:%d\n", i, num[i]);
    }
}

int main(void)
{
    char str[80];
    gets(str);
    f(str);
    return 0;
}

(9)在主函数中输入10个不等长字符串,用另一函数sort()对它们排序,然后在主函数中输出已排好序的字符串。要求:每个字符串长度均不超过30字符,用指针数组进行处理。

#include <stdio.h>
#include <string.h>
void sort(char * p[10])
{
    char* t;
    for (int i = 0; i < 9; i++)
    {//冒泡
        for (int j = 0; j < 10 - i - 1; j++)
        {
            if (strcmp(p[j], p[j + 1]) > 0)
            {
                t = p[j];
                p[j] = p[j + 1];
                p[j + 1] = t;
            }
        }
    }
}

int main(void)
{
    char s[10][81], *sp[10];
    for (int i = 0; i < 10; i++)
    {//指针数组存放二维字符数组的一维地址
        gets(s[i]);
        sp[i] = s[i];
    }
    sort(sp);
    printf("排序后:\n");
    for (int i = 0; i < 10; i++)
    {
        printf("%s\n", sp[i]);
    }
    return 0;
}

(10)输入一个字符串,内有数字字符和非数字字符如123a345bcd567,将其中连续的数字作为一个整数,依次存放到整型数组a中,例如,123放在a[0],345放在a[1]中,567放在a[2]中,……,统计共有多少个整数,并输出这些整数。

#include <stdio.h>
int main(void)
{
    char ch[64], * p = ch;
    int a[64] ={ 0 }, * q = a, count = 0;
    gets(ch);
    while (*p != '\0')
    {
        if (*p >= '0' && *p <= '9')
        {
            *q = *q * 10 + (*p - '0');
            if (*(p + 1) < '0' || *(p + 1) > '9')
            {//如果后一个字符不是数字,说明当前字符为该数最后一位
                q++;
                count++;//记录数的个数
            }
        }
        p++;
    }
    printf("一共有%d个整数\n", count);
    for (int i = 0; i < count; i++)
    {
        printf("%d\n", a[i]);
    }
    return 0;
}

如有错误不足之处,恳请批评指正。

题目来源:C程序设计教程与实验(第3版)        吉顺如主编

答案参照微信公众号:程序设计及信息技术学习平台

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值