C语言指针练习题及答案
一、选择题
1. 变量的指针,其含义是指该变量的__B__.
a)值 b)地址
c)名 d)一个标志
解析:
“指针”与“指针变量”的区别:可以说i的指针变量是100,但不能说i的指针是100,“指针”是一个地址,“指针变量”是存放地址的变量。
2.若有语句int *point,a=4;和point=&a;下面均代表地址的一组选项是_D_ _.
a)a,point,*&a b)&*a,&a,*point
c)*&point,*point,&a d)&a,&*point ,point
解析:
*&p和&*p
根据运算优先级,*&p 等价于*(&p)。&*p 等价于&(*p)。
1、如果p是int *指针变量,那么*&p = p,&*p = p,都是p,但还没定义p指向哪,存的是谁的地址。
2、如果p是一个int变量,那么*&p = p;而&*p是非法的,因为*p非法。
比如int p =10;那么*&p = *(&p) = p = 10(即从p的地址取值),而&*p = &(*p) 则非法,因为p=10,*10是取内存地址为10的值,这在c语言中是不合法的。
3.若有说明;int *p,m=5,n;以下正确的程序段的是_D_.
a)p=&n; b)p=&n;
scanf("%d",&p); scanf("%d",*p);
c)scanf("%d",&n); d)p=&n;
*p=n; *p=m;
解析:
A:p是指针变量,存放的是n的地址即直接用scanf("%d",n);
B:同上
C:其中*p它没有指向某一个变量的地址所以无法解引用;
D:p存放的是n的地址,*p将m赋值给n;
4. 已有变量定义和函数调用语句:int a=25; print_value(&a); 下面函数的正确输出结果是____D__.
void print_value(int *x)
{ printf(“%d\n”,++*x);}
a)23 b)24 c)25 d)26
解析:
++*x=++(*x),(*x)是指变量a的值,因为前置++,即先++后使用;
5.若有说明:long *p,a;则不能通过scanf语句正确给输入项读入数据的程序段是A
A) *p=&a; scanf("%ld",p);
B) p=(long *)malloc(8); scanf("%ld",p);
C) scanf("%ld",&a);
解析:
A: 虽然将 a 的地址赋值给了指针 p ,但是在使用 scanf 函数时,没有使用 & 操作符来获取变量 a 的地址,而是直接将指针 p 传递给了 scanf 函数。这样会导致 scanf 函数尝试从指针 p 所指向的内存位置读取数据,而不是从变量 a 所在的内存位置读取数据
B:p=(long *)malloc(8)使用malloc函数动态分布了8个字节的内存空间,并将其地址赋值给了p,然后使用scanf函数将输入的数据存储到这个分配的内存空间;
6.有以下程序
#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);
}
程序运行后的输出结果是 B
A)1,2,1,2 B)1,2,2,1
C)2,1,2,1 D)2,1,1,2
解析:
(1)该算法不交换整型变量的值,而是交换了指针变量的值(即m与n的地址)
(2)若为void swap(int *p1,int*p2)
{ int temp;
temp=*p1;
*p1=*p2;
*p2=temp;
}
swap函数的函数体,使 *p1=*p2的值进行了互换,也就是m与n的值进行了互换(值互换)。
7. 有以下程序
int main()
{ int a,k=4,m=4,*p1=&k,*p2=&m;
a=p1==&m;
printf("%d\n",a);
}程序运行后的输出结果是(C)
A)4 B)1 C)0 D)运行时出错,无定值
解析:
a=p1==&m; 这个表达式首先算p1==&m,”==“这是一个比较运算符,题意知*p1=&k,则p1=k=4,&m是m的地址则不相等所以取值为0,然后把0赋值给a。
8. 在16位编译系统上,若有定义int a[]={10,20,30}, *p=&a;,当执行p++;后,下列说法错误的是( A)
A)p向高地址移了一个字节 B)p向高地址移了一个存储单元
C)p向高地址移了两个字节 D)p与a+1等价
解析:
由题意知在16位编译系统上,则为两个字节,执行p++后从首地址向后移动了一个单位。
- 有以下程序段
int a[10]={1,2,3,4,5,6,7,8,9,10},*p=&a[3], b; b=p[5]; b中的值是(D )
A)5 B)6 C)8 D)9
解析:
由题意知*p=&a[3],*p指向a数组的第4个元素(从0开始序号3), b=p[5]注意观察是p[5]即指的是在*p=&a[3]的基础之上(即首地址是在a[3])后的第5个元素为9。
10.若有以下定义,则对a数组元素的正确引用是___D.
int a[5],*p=a;
- *&a[5] b)a+2 c)*(p+5) d)*(a+2)
解析:
A:*&a[5]=a[5];
B:错误;
C:*(p+5)为引用数组第六个元素出现越界;
D:*(a+2)为引用数组第三个元素;
11.若有以下定义,则p+5表示_____A__.
int a[10],*p=a;
a)元素a[5]的地址 b)元素a[5]的值
c)元素a[6]的地址 d)元素a[6]的值
解析:
p+5其中p是指首元素(+5)是指向后移动5个单位即第六个元素(序号从0开始到5)则为元素a[5]的地址。
12.设已有定义: int a[10]={15,12,7,31,47,20,16,28,13,19},*p; 下列语句中正确的是( B)
A) for(p=a;a<(p+10);a++);
B) for(p=a;p<(a+10);p++);
C) for(p=a,a=a+10;p<a;p++);
D) for(p=a;a<p+10; ++a);
解析:
由于未进行指针*p的引用数组a,则A中的a++是指数组名(代表的一个地址,是一个常量)不能执行++;
13.有以下程序段
#include <stdio.h>
int main()
{ int x[] = {10, 20, 30};
int *px = x;
printf("%d,", ++*px); printf("%d,", *px);
px = x;
printf("%d,", (*px)++); printf("%d,", *px);
px = x;
printf("%d,", *px++); printf("%d,", *px);
px = x;
printf("%d,", *++px); printf("%d\n", *px);
return 0;
}
程序运行后的输出结果是( A )
A)11,11,11,12,12,20,20,20 B)20,10,11,10,11,10,11,10
C)11,11,11,12,12,13,20,20 D)20,10,11,20,11,12,20,20
解析:
int x[] = {10, 20, 30};
int *px = x;定义了一个指向整数的指针px,并使它指向数组x的第一个元素
printf("%d,", ++*px); ++(*px)=++x前置++先++后使用即*px为11
printf("%d,", *px);*px为11
px = x;引用上面的x还是为11
printf("%d,", (*px)++); (*px)++=x++后置++先使用后++,则输出11
printf("%d,", *px);由于上面进行了++则*px为12
px = x;将px重新指向数组x开始
printf("%d,", *px++); 基于上面*px为12,*px++先使用然后将px移动到下一位
printf("%d,", *px);由上面++可得将px移动到下一位即20
px = x;将px重新指向数组x开始
printf("%d,", *++px); *++px前置++位置先进行自增访问第二个元素
printf("%d\n", *px);基于上面继续访问第二个元素
return 0;
14.设有如下定义则程序段的输出结果为( D)
int arr[]={6,7,8,9,10};
int *ptr;
ptr=arr;
*(ptr+2)+=2;
printf ("%d,%d\n",*ptr,*(ptr+2));
A)8,10 B)6,8 C)7,9 D)6,10
解析:
int *ptr;
ptr=arr;
定义了一个指向整数的指针*ptr;,并使它指向数组arr的第一个元素
*(ptr+2)+=2--->{*(ptr+2)=*(ptr+2)+2}
*(ptr+2)访问了arr的第三个元素8进行表达式运算
- 有以下定义 char a[10],*b=a; 不能给数组a输入字符串的语句是(B)
A)gets(a) B)gets(a[0]) C)gets(&a[0]); D)gets(b);
解析:
B:gets(a[0]),a[0]是数组的一个元素不能输入字符串
16.下面程序段的运行结果是___ _C_.
char *s="abcde";
s+=2;
printf("%d",s);
a)cde b)字符'c' c)字符'c'的地址 d)无确定的输出结果
解析:
若想得到A即printf("%s",s);
若想得到B即printf("%c",*s);
若想得到C即printf("%d",s);
17.设已有定义: char *st="how are you"; 下列程序段中正确的是( )
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是数组名,是一地址常量,十+a是非法的,所以答案B错误;
C:因为数组a的大小为11,执行strcpy(a,st);,st字符串的结尾符10无法存放到数组a中,所以答案C也是错误的;
D:答案D中定义数组a 时未指定大小,所以也是错误的;
A:执行strcpy (p=a+1,&st[4]);,首先将数组a的第二个元素a[1]的地址赋给指针变量p,然后将st第5个元素开始直到字符串结束为止的字符复制到p所指向的内存单元中
18.有以下程序 输出结果是( )
main()
{
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));
}
- gm B)rg C)or D)ga
解析:
for(i=0;i<7;i++)
if(*(p1+i)==*(p2+i))
a数与b数组在第一个元素到第七个元素中相同的字符
19.以下正确的程序段是_C___.
a)char str[20]; b)char *p;
scanf("%s",&str); scanf("%s",p);
c)char str[20]; d)char str[20],*p=str;
scanf("%s",&str[2]); scanf("%s",p[2]);
解析:
- char str[20];
scanf("%s",&str);
应该指向数组的指针而不是数组本身
- char *p;
scanf("%s",&str);
未进行初始化,未分配空间
- char str[20];
scanf("%s",&str[2]);
从数组的第三个元素开始输入
d)char str[20],*p=str;
scanf("%s",p[2]);
p[2]是指数组的第三个元素
20.下面程序的运行结果是___.
#include <stdio.h>
#include <string.h>
main()
{ char *s1="AbDeG";
char *s2="AbdEg";
s1+=2;s2+=2;
printf("%d\n",strcmp(s1,s2));
}
- 正数 b)负数 c)零 d)不确定的值
解析:
strcmp(s1,s2));
strcmp函数是用来比较字符串的大小
若s1>s2则返回正数
若s1=s2则返回零
若s1>s2则返回负数
即ACSII码 值进行比较
‘a’--‘z’97-122
’A‘--‘Z’65-90