C语言错题库之<指针>

  1. 有以下程序:
#include <stdio.h>
int main()
{
	int a[]={1,2,3,4,5,6,7,8,9,10,11,12};
	*p=a+5;
	*q=NULL;
	*q=*p+5;
	printf("%d %d\n",*p*q);
}

程序运行后的输出结果是______。

  • A. 运行后报错
  • B. 5 10
  • C. 6 11
  • D. 6 6

答案:A
解析:*q初始化为NULL,没有指向地址,因此无法对*q指向的空间进行赋值操作,系统会报错。

  1. 若有定义:int aa[8]; 则以下表达式中不能代表数组元素aa[1]的地址的是_____.
  • A. &aa[0]+1
  • B. &aa[1]
  • C. aa+1
  • D. &aa[0]++

答案: D
解析:&aa[0]++中下标运算符的优先级最高,'&‘和’++‘优先级相同,从右往左计算,即先计算aa[0]++,aa[0]相当于一个变量,可以进行自加1,但是aa[0]++是一个常量,故不能进行’&'运算。

  1. 有以下程序:
#include <stdio.h>
int main()
{
	int a[5]={2,4,6,8,10};
	int *p;
	int **k;
	p=a;
	k=&p;
	printf("%d",*(p++));
	printf("%d\n",**k);
}

程序运行后的输出结果是______。

  • A.2 2
  • B. 2 4
  • C. 4 6
  • D. 4 4

答案:B
解析:*(p++) 首先小括号内的表达式优先级最高,但是p++是相当于先赋值再进行自加一,故表达式的值等于*p的值,即2;
k是二级指针,存放的的是一级指针p的地址,**k可以取到p指向的空间的值

  1. 有一个二维数组:int a[5][4],二维数组的首地址是100,int (*p)[4] = a,
    问 *(p+2)+3是______。

答案:144
解析:*(p+2)是第2行,*(p+2)+3即第2行第3列的地址,即距离首元素地址有2*4+3=11个元素大小的地址空间,int型占4个字节,则地址为0x144.

  1. 以下语句或者语句组中,能正确进行字符串赋值的是
  • A. char s[10]; *s=“right!”;
  • B. char *sp = “right!”;
  • C. char s[10];s=“right!”;
  • D. char *sp;scanf(“%s”,sp);

答案:B
解析:
A:s是指向数组第一个元素的指针,*s="right!"是对第一个元素进行赋值,且是试图将一个字符串赋值给一个字符型的变量。
C:s是数组名,数组名是一个地址常量,不能对其进行赋值
D:char *sp是定义了一个指针,且该指针没赋初值,是一个野指针,后面的表达式是在试图给一个野指针指向的空间赋值。

  1. 下面各语句行中,能正确进行赋字符串操作的语句行是 [单选题] [必答题]
  • A. char st[4][5]={“ABCDE”};
  • B. char s[5]={‘A’,‘B’,‘C’,‘D’,‘E’};
  • C. char *s; s=“ABCDE”;
  • D. char *s; scanf(“%s”,s);

答案:C
解析:
A:相当于有四个可以存放五个元素的数组,题目中在给0行第0个元素赋值,发生越界
B:没有’\0’,是字符数组而非字符串
C:定义了一个指针,指向了常量区的"ABCDE",常量区只能读
D:s是一个野指针,表达式试图向一个野指针指向的空间赋值。

  1. 有以下程序
int main()
{
	char str[][10] = {"China","Beijing"};
	char *p = str;
	printf("%s\n",p+10);
}

程序运行后的输出结果是:

  • A.ng
  • B.ing
  • C.China
  • D.Beijing

答案:D
解析:char *p = str; 会隐式的将str从char(*)[10]类型强制类型转换为(char*)类型。所以此时可以将其看作一个有20个元素的一维数组。

  1. 有以下程序
int main()
{
	char *p[10] = {"abc","aabdfg","dcdbe","abbd","cd"};
	printf("%d\n",strlen(p[4]));
}

执行后的输出结果是_____.

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

答案:A
解析:strlen函数会接收一个字符指针,统计指针指向的字符串的字符数量直到遇到’\0’停止。'\0’不会计入数量。

  1. 有以下程序
#include <string.h>
int main()
{
	char *p = "abcde\0fghjik\0"
	printf("%d\n",strlen(p));
}
  • A.12
  • B.5
  • C.6
  • D.15

答案:B
解析:strlen遇到’\0’就会停止,且不会对’\0’计数。

  1. 有以下程序
#include <stdio.h>
#include <string.h>
int main()
{
	char b1[8] = "abcdefg";
	char b2[8];
	char *pb = b1+3;
	while(--pb>=b1)
		strcpy(b2,pb);
	printf("%d\n",strlen(b2));
}
  • A.3
  • B.1
  • C.7
  • D.8

答案:C
解析:pb初始指向字符’d’的位置,进入while循环后会自减一,直到等于b1,即指向字符’a’的位置,此时b2指向的字符串就是"abcdefg",执行strlen函数返回就是7.

  1. 有以下程序
#include <stdio.h>
#include <string.h>
int main()
{
	char *p1,*p2,str[50]="ABCDEFG";
	p1 = "abcd";
	p2 = "efgh";
	strcpy(str+1,p2+1);
	strcpy(str+3,p1+3);
	printf("%s\n",str);
}
  • A. Abfhd
  • B. Afgd
  • C.AfghdEFG
  • D.Afghd

答案:B
解析:strcpy会将后一个参数的’\0’也复制过来
第一次复制:str::A f g h \0 F G
第二次复制:str:A f g d \0 F G
printf的控制格式是%s时,遇到’\0’停止打印,故输出Afgd

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

输出结果是:

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

答案:B
解析:s指向的是’c’,但是printf打印的是s的值,即c的地址,%ld打印长整型。

  1. *有以下程序
#include <stdio.h>
#include <string.h>
int main()
{
	char str[50]="xyz";
	char p1[128] = "abcd";
	char p2[128] = "ABCD";
	strcpy(str+2,strcat(p1+2,p2+1));
	printf("%s\n",str);
}
  • A. abcABz
  • B. xycdBCD
  • C.xyabcAB
  • D.ABabcz

答案:B
解析:strcat会会找到目标字符串的’\0’后,再将源字符串拼接过来,并返回目标字符串
首先strcat执行后:p1: abcdBCD\0 ,返回p1+2
strcpy(str+2,p1+2)执行后:str:xycdBCD\0

  1. 请读程序片段:
char str[] = "ABCD", *p = str; 
printf("%d\n", *(p + 4) ); 

上面程序的输出结果是

  • A. 68
  • B. 0
  • C. 字符"D"的地址
  • D. 不确定的值

答案:B
解析:str中有五个元素,最后一个元素是’\0’,(p+4)指向’\0’,以%d的格式打印,'\0’的ASCII值就是0

  1. 请读程序:
# include <stdio.h>
# include <string.h>
void fun(char *w,  int m)
{ 
    char s,*p1,*p2;
    p1 = w; 
    p2 = w + m - 1;
    while(p1 < p2)
    { 
        s = *p1++;
        *p1 = *p2--; 
        *p2 = s;
    }
}
int main()
{ 
    char a[] = "ABCDEFG";
    fun(a,  strlen(a));
    puts(a);
}

上面程序的输出结果是_____.

  • A) GFEDCBA
  • B) AGADAGA
  • C) AGAAGAG
  • D) GAGGAGA

答案:C
解析:初始时:ABCDEFG,p1指向A,p2指向G
只要p1<p2:
s= *p1 ; p1++;
*p1 = *p2; p2–;
*p2 = s;
第一轮:s=A; AGCDEAG
第二轮:s=G;AGADGAG
第三轮:s=A;AGAAGAG

  1. 请选出以下语句的输出结果:
    printf ( " %d \n “, strlen( “\t”\065\xff\n” ) );
  • A) 5
  • B) 14
  • C) 8
  • D) 输出项不合法,无正常输出

答案: A
解析:分别是\t " \065 \xff \n

  1. 有以下程序
# include <string.h>
void fun(char *s, int p, int k)
{ 
    int i;
    for(i = p; s[i] = s[i + 2]; i++);
}
int main()
{ 
    char s[] = "abcdefg";
    fun(s, 3 ,strlen(s));
    puts(s);
}

运行后的输出结果是_________.

答案: abcfg
解析:
for(表达式1;表达式2;表达式3) 代码;
先运行表达式1,然后是表达式2,满足判定条件后执行代码,再运行表达式3;之后运行表达式2-代码-表达式3-表达式2-…依次循环
s: a b c d e f g \0
i=3;s[3] = s[5];
s: a b c f e f g \0
i=4;s[4] = s[6]
s: a b c f g f g \0
i=5;s[5] = s[7]=‘\0’
s: a b c f g \0 g \0
puts是遇到’\0’停止,因此打印出 abcfg

  1. 有以下程序
#include <stdio.h>
void move(char *str, int n)
{ 
    char temp ; 
    int i;
    
    temp = str[ n - 1 ];
    for(i = n - 1 ; i > 0 ; i--) 
    	str[i] = str[ i - 1];   
    str[0] = temp;
} 

int main()
{ 
    char s[50]; 
    int n, i, z;
    
    scanf("%d, %s", &n, s);
    z = strlen(s);
    for(i = 1 ; i <= n ;  i++)
        move(s, z);
    printf("%s \n", s);
} 

运行后输入:3,abcde<回车>,则输出结果是 _________

答案:cdeab
解析:n=3, s=“abcde”, z=5 for(i=1;i<=3;i++)循环三次
move函数的功能是:将最后一位字符放到字符串首位,并且其他字符依次右移一位。
最开始
s: a b c d e
第一次调用move函数后
s: e a b c d
第二次调用move函数后
s: d e a b c
第三次调用move函数后
s: c d e a b
所以最后输出结果是cdeab

  1. 以下程序的功能是将字符串s中的数字字符放入 d 数组中,最后输出 d 中的字符串。例如,输入字符串:abc123edf456gh,执行程序后输出:123456。
#include <stdio.h>
int main()
{ 
    char s[80], d[80]; 
    int i, j;
    gets(s);
    for(i = j = 0 ; s[i] != ‘\0;  i++)
    	if(_________) 
    	{ 
        	d[j] = s[i]; 
        	j++;
     	} 
    d[j] = '\0';
    puts(d);
} 

答案:s[i]>=‘0’&&s[i]<=‘9’
解析:
先从键盘输入字符串,并存到s中;
之后遍历字符串,只要s[i]是数字就存到数组d中
并且给d的末尾加了’\0’
因此,应填 s[i]>=‘0’&&s[i]<=‘9’

  1. 下面程序的功能是:将字符数组a中下标值为偶数的元素从小到大排列,其它元素不变。
#include <stdio.h>
#include <string.h>
int main()
{ 
    char a[] = "clanguage", t;
    int i, j, k;
    k = strlen(a);
    for(i = 0 ; i <= k - 2 ; i += 2)
    	for(j = i + 2 ; j <= k ; _______) 
    		if(______) 
    		{ 
        		t = a[i] ; 
        		a[i] = a[j]; 
        		a[j] = t; 
    		}
    puts(a);
    printf("\n");
} 

答案:① j+=2 ② a[i]>a[j]
解析:选择排序的变种:
选择排序基本原理:只要最前面的数字比后面的任一数字大,就交换两个数字的值
现在只排序下标为偶数的数字
因此,步长应该为2 即①应该填 j+=2
此外,要确保前面的数字比后面的小,因此② a[i] > a[j]

  1. 以下程序的功能是:将无符号八进制数字构成的字符串转换为十进制整数。例如,输入的字符串为:556,则输出十进制整数366。
#include <stdio.h>
int main()
{ 
    char *p, s[6];
    int n;
    p = s;
    gets(p);
    n = *p - '0';    
    while(_______!= '\0')
        n = n * 8 + *p - '0';     
    printf("%d \n", n);
} 

答案:*(++p)
解析:首先从键盘输入一个字符串,并存放在s中,p指向s
n = *p - ‘0’; 是将p指向的第一个字符转成数字(通过算这个字符与’0’的距离)
首先结束条件肯定是*p的值是’\0’,即p指向字符串的结尾处时跳出循环
循环体内并没有p的loop条件,因此应当也在横线处体现,此时推断横线处应该有*p和p的loop语句,*p++或者是*++p
然后继续看循环体,n应该是数字最高位 ,假设s=“7”,此时n=7,如果继续进入循环势必是错误的,因此此时应该跳出循环,因此可以得知,此处应该是*(++p)

  1. 以下程序可以把从键盘上输入的十进制数(long型)以二至十六进制形式输出,请填空。
#include <stdio.h>
int main()
{ 
    char b[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
    int c[64], d, i = 0, base;
    long n;
    printf("enter a number:\n"); 
    scanf("%ld", &n);
    printf("enter new base:\n"); 
    scanf("%d", &base);
    do{ 
        c[i] = _____; 
        i++; 
        n = n/base;
    } 
    while(n != 0);
    printf("transmite new base: \n");
    for(--i ; i >= 0 ; --i)
    { 
        d = c[i];
        printf("%c", b____); 
    }
}

答案:①n%base ②[d]
解析:由程序可以看出,n是待转换的数字,base是转换的基数。两个值均由键盘输入。
第一个循环应当是在进行进制转换,因此势必是 n%base;并且转换后的数字存储在了int型数组c中,并且从上往下依次存储。
第二个循环在将int型的数字转换成char型的数字,i的值等于数组c最后一位的后面一位的下标,所以第二个循环刚好从下往上依次读出。
函数中定义了一个字符数组b,里面所存储的字符的下标刚好与数字相对应,因此只需要通过下标获取即可 b[d]

  1. 有下面程序:
#include <stdio.h>
void fun(char *a1, char *a2, int n)
{ 
    int k;
	for(k = 0;k < n;k++)
       a2[k]=(a1[k]-'A'-3 + 26)%26 +'A';
    a2[n] = '\0';
}
int main()
{ 
    char s1[5] = "ABCD", s2[5];
    fun(s1, s2, 4);
    puts(s2);
} 

输出结果是 ____________ 。

答案:XYZA
解析:分析fun函数的功能:
首先"%26"是为了保证可以在大写字母中循环;
如果先把"%26"去掉,代码就是a1[k]-‘A’-3 + 26 +‘A’ ,稍加整理,即a1[k]+23
因此可以看出该函数是为了找出距离a1[k]有23位的字母,并且遇到Z需要循环回A
A B C D E F G H I G K L M N O P Q R S T U V W X Y Z
可以看出a1[0] = A 时,对应的是X
BCD依次加1即可,所以是XYZA

  1. 设有下列程序:
#include <stdio.h>
#include <string.h>
int main()
{ 
    int i;
    char str[10], temp[10];
    gets(temp);
    for(i = 0 ; i < 4 ; i++)
    { 
        gets(str);
        if(strcmp(temp, str) < 0strcpy(temp, str);
    }
    printf(" %s \n ", temp);
}

上述程序运行后,如果从键盘上输入(在此代表回车符):
C++
BASIC
QuickC
Ada
Pascal
则程序输出结果是_____.

答案:QuickC
解析:stecmp函数会一个字符一个字符的进行比较。函数中当temp的字符串小于str的字符串时,就将其赋值给temp。循环执行4次。
temp = “C++”
第一轮:C>B 不赋值
第二轮:Q>C 赋值,temp=QuickC
第三轮:Q>A 不赋值
第四轮:Q>P 不赋值
因此结束时,temp中存放的时QuickC

  1. 下面的程序运行结果为( )。
char *RetMenory(void)
{
       char p[] = “hello world”;
       return p;
}

void Test(void)
{
	char *str = NULL;
    str = RetMemory();
    puts(str);
}
  • A 语法有错误,不能编译
  • B hello world
  • C 结果不可预知
  • D hello world+乱码

答案:C
解析:数组p[]为局部变量,存放在栈区。当执行完毕后,栈区的内存空间会自动释放。此时str指向的空间为栈区,故为随机值。

  1. 程序中若有如下的说明和定义语句
char fun(char *);
int main()
{
    char  *s = "one", a[5] = {0},(*f1)(char *)= fun, ch;
	......
}

以下选项中对函数fun的正确调用语句是 _________.

  • A) (*f1)(a);
  • B) *f1(*s);
  • C) fun(&a);
  • D) ch=*f1(s)

答案:A
解析:f1为函数指针,通过指针调用函数时,使用(f1)和f1来调用函数本质没有区别
B:参数错误
C:数组名本身就是一个地址
D:'()‘优先级高于’
',该表达式是在对f1函数的返回值进行取值操作

  • 16
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值