C指针练习-选择题解析

昨天做c指针的编程题,脑子快干废了,今天做几个简单的选择题!

1.变量的指针,其含义是指该变量的(B)
A、值
B、地址
C、名
D、一个标志

解析:指针变量存储的是地址,而指针就是地址,这两个概念要分清
2.若有int *p, a=4; p=&a;下面均代表地址的一项是(D)
A、a,p,*&a
B、&*a,&a,*p
C、*&p,*p,&a
D、&a,&*p,P

解析: A中,a是个int变量,错。B中第一个&*a是个什么玩意,都没见过,测试后直接编译就报错了,
不确定的话看*p,*p=a,故B错,C也错。D中的&*p=&(a)=p
3.若有int *p, a=4, n;下面正确的程序段是(D)
A、p=&n; scanf("%d", &p);
B、p=&n; scanf("%d", *p);
C、scanf("%d", &n); *p=n;
D、p=&n; *p=m;

解析: scanf("%d", &x);中第二参数是变量的地址,所以A,B错,
C中p还没初始化呢,*p是什么呀,D中结果就是n=m
4.int a=25; p_val(&a);输出结果是(D)
void p_val(int *x)
{
	printf("%d\n", ++*x);
}
A、23
B、24
C、25
D、26

解析: 看到++*x,值只能大不能小吧,那不就是D嘛!
其实真正的是++*x = ++(a),就是26。该结果经过我的测试,木得问题
5.有以下程序,输出结果是(B)
#include<stdio.h>
int main()
{
	int m=1, n= 2, *p=&m, *q=&n, *r;
	r=p; p=q; q=r;
	printf("%d, %d, %d, %d\n", m,n,*p,*q);
	return 0;
}
A、1,2,1,2
B、1,2,2,1
C、2,1,2,1
D、2,1,1,2

解析:int *p=&m, *q=&n则*p=m=1, *q=n=2,
而r=p,p=q,q=r交换了p和q的存储地址,所以*p=2*q=1。
结果就是1221
6.有以下程序,输出结果是(C)
#include<stdio.h>
int main()
{
	int a=1, b=3, c=5;
	int *p1=&a, *p2=&b, *p=&c;
	*p=*p1*(*p2);
	printf("%d\n", c);
	return 0;
}
A、1
B、2
C、3
D、4

解析:p存放c地址,所以*p=c,同理*P1=a=1*p2=b=3,
故*p=*p1*(*p2);等价于c=a*b; c=1*3=3
7.16位编译系统上,有int a[]={10,20,30},*p=&a;当执行p++后,
系列说法错误的是(A)
A、p向高地址移了一个字节
B、p向高地址移了一个存储单元
C、p向高地址移了二个字节
D、p与a+1等价

解析:选项D,a是数组名,也是第一个元素的地址,则有*a = a[0],那地址+1
不就是a[0]后的元素吗,就是a[1]啊,所以*(a+1) = a[1] = 2,a+1就是a[1]
的地址。p=&a在测试的时候是有警告的,因为p是int *型,而a是个数组啊,这
样取地址不兼容,改成p=&a[0]就没问题了,以下我都测试了,结果一样的
	int a[]={10,20,30},*p=&a[0];
    p++;
	printf("%d, %d\n", *p,*(a+1));
    printf("%p, %p\n", p,a+1);


系统是16位的,指针大小是2字节,所以p++后,移动了2字节,即一个存储单元。
不同位数系统的存储单元大小不一样哦!

8.int a[10]={1,2,3,4,5,6,7,8,9,10},*p=&a[3],b; b=p[5];b的值是(A)
A、5
B、6
C、8
D、9

解析:学过c指针时,应该都知道指针和数组可以共用,在指针p指向数组首地址
的时候,则有a[n] = *(p+n)。本题中p指向了a[3],此时a[3]就是p的第一个元
素,所以p[5] = a[3+5] = 9;
9.int a[10]={6,7,8,9,10},*p=a; 
  *(p+2) += 2;printf("%d, %d\n", *p, *(p+2));的值是(D)
A、8,10
B、6,8
C、7,9
D、6,10
解析:这题很简单,根据a[n] = *(p+n),则*p=a[0]=6*(p+2) = *(p+2)+2
等价于a[2] = a[2] + 2 = 10;
9.对数组int a[2][3]的第i行第j列元素地址的引用正确的是(D)
A、*(a[i]+j)
B、(a+i)
C、*(a+j)
D、a[i]+j

解析:像BC两选了一看就是错的,连ij都凑不够。选项A,a[i]就是第几行的意思,当i=0时
是{1,2,3},i=1时是{4,5,6},其实直接打印a[0]的话,结果是1,因为a[0]就等于a[0]
[0],不写第二个参数默认为0。
那a[i]就是第i行首地址,a[i]+j不就跟一维数组+j是一样的吗,参考第7题的a+1可知
a[i]+j=&a[i][j];

数组a[2][3]随便赋值,可以写成int a[2][3]={{1,2,3},{4,5,6}};更直观的写法:
int a[2][3]={
		     {1,2,3},
			 {4,5,6}
			 };
两行三列

测试代码:
	int a[2][3]={
		     {1,2,3},
			 {4,5,6}
			 };
             
	printf("%p,\n", a[1]+2);
    printf("%p,\n", &a[1][2]);
    
    printf("%d,\n", *(a[1]+2));
	printf("%d,\n", a[1][2]);

测试结果:
0x7ffec1107b54,
0x7ffec1107b54,
6,
6,

10.以下声明指针数组的是(AC)
A、int *p[2];
B、int (*p)[2]
C、typedef int *ptr; ptr p[2];

解析:指针数组:数组中存放的是指针,本质是数组
		数组指针:是一个指向数组的指针,本质是指针

int *p[2];这个东西写成(int *)(p[2]);容易理解一些,平时定义int a[5];时,表明a是
一个数组,数组中的元素是int类型,同理p是一个数组,存放的类型是int *型元素,即指针。

注意,这种定义int *p[2]中p的结合顺序都是先结合右边再结合左边的,p先结合[2]形成p[2]
数组,所以p是个数组,右边没有符号了,就结合左边的int *,这个表明数组中的元素类型

选项B,(*p)中,右边碰到括号,先运算括号中的东西,说明p是个指针,指针指向“int [2]”
,即数组,所以p是一个数组指针
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值