C语言笔试例题_指针专练30题(附答案解析)
指针一直是C语言的灵魂所在,是掌握C语言的必经之路,收集30道C语言指针题目分享给大家,测试环境位64位ubuntu18.04环境,如有错误,恳请指出,文明讨论!!!
文章目录
- C语言笔试例题_指针专练30题(附答案解析)
- 1.笔试例题
- 2.结果与分析
- 总结
1.笔试例题
答案与解析在文末尾
1.char * p =“Hello”;是定义初始化指针变量,指针变量的值是一个字符串.说法是否正确
A :正确
B:不正确
2.以下代码printf 输出是什么?
void main (void)
{
int a[]={4,5,6,7,8};
int *p = a;
*p++ += 100;
printf(" %d %d \n" , *p,*(++p));
}
3.若定义:int a[2][3]={1,3,5,7,9,11},以下描述正确的是
A :*(a+1)为元素7的地址
B:(a[1]+1)的值是5
C:**(a +1)+2值是11
D:a[0]和a不同
4.以下代码printf 输出是什么?
int main()
{
int a[5] = { 1, 2, 3, 4, 5 };
int* ptr = (int*)(&a + 1);
printf("%d,%d", *(a + 1), *(ptr - 1));
return 0;
}
5.说出以下代码的错误之处,并说明原因
char *getmemory( void )
{
char p[] = "hello world";
return p;
}
void test( void )
{
char *str = NULL;
str = getmemory();
printf( str );
}
6.在上下文及头文件均正常的情况下,下列代码的输出是?(注:print已经声明过)
main()
{
char str[] = "Geneius";
print (str);
}
print(char *s)
{
if(*s)
{
print(++s);
printf("%c", *s);
}
}
A :suiene
B:neius
C:run-time error
D:suieneG
7.如下代码是否存在风险,并说明原因和修改方式
#include <stdio.h>
int main () {
//hello world 存放在常量区是不可以修改的
char * str = "hello world";
*str = 'a'; // error
return 0;
}
8.如下代码是否可行,说明原因
#include <stdio.h>
int main () {
char str[4];
str = "abc";
return 0;
}
9.如下代码输出是什么
#include <stdio.h>
#include <string.h>
int main(){
char *str = "baidu.com";
int i ;
str = "hello world!";
int len = strlen(str);
printf("%d \n",len);
printf("%c \n", *(str+4));
printf("%s \n",(str+6));
return 0;
}
10.以下程序的输出结果(32位机器上)是()
int main(){
char *p = "abcdefgh", *r;
long *q;
q = (long*)p;
q++;
r = (char*)q;
printf("%s\n", r);
}
A :abcd
B:bcde
C:cdef
D:efgh
11.对于char * pa[7]的描述中,正确的是( )
A :pa是一个指向数组的指针,所指向的数组是7个char型元素
B:pa是一个指向某数组中第7个元素的指针,该元素是char型变量
C:pa[7]表示数组的第7个元素的值,是char型的值
D:pa是一个具有7个元素的指针数组,每个元素是一个char型指针
12.如下代码输出是什么
#include <stdio.h>
void fun(char **p) {
int i;
for (i = 0; i < 4; i++)
printf("%s", p[i]);
}
main() {
char *s[6] = {"ABCD", "EFGH", "IJKL", "MNOP", "QRST", "UVWX"};
fun(s);
printf("\n");
}
A :ABCDEFGHIJKL
B:ABCD
C:AEIM
D:ABCDEFGHIJKLMNOP
13.test.c文件中包括如下语句,文件中定义的四个变量,哪个变量不是指针类型?
#define INT_PTR int*
typedef int* int_ptr;
INT_PTR a,b;
int_ptr c,d;
A :a
B:b
C:c
D:d
E:都是
F:都不是
14.有int s[2]={0,1}, * p=s; 则下列错误的C语句是 ()
A :s+=1;
B:p+=1;
C:*p++;
D:(*p)++;
15.请问下列代码的输出是多少()
#include <stdio.h>
int main() {
int m[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0};
int(*p)[4] = (int(*)[4])m;
printf("%d", p[1][2]);
return 0;
}
A :7
B:3
C:8
D:4
16.已知如下代码
int a[] = {1, 2, 3, 4, 5};
int*p[] = {a, a + 1, a + 2, a + 3};
int **q = p;
表达式*(p[0]+1)+**(q+2)的值是____。
A :5
B:6
C:7
D:8
E:9
F:10
17.如下代码输出是什么
#include<stdio.h>
void foobar(int a, int *b, int **c)
{
int *p = &a;
*p = 101;
*c = b;
b = p;
}
int main()
{
int a = 1;
int b = 2;
int c = 3;
int *p = &c;
foobar(a, &b, &p);
printf("a=%d, b=%d, c=%d, *p=%d\n", a, b, c, *p);
return (0);
}
A :a=1, b=2, c=3, *p=2
B:a=101, b=2, c=3, *p=2
C:a=101, b=101, c=2, *p=3
D:a=1, b=101, c=2, *p=3
18.如下代码输出是什么
void GetMemory(char **p, int num)
{
*p = (char *)malloc(num);
}
void Test(void)
{
char *str = NULL;
GetMemory(&str, 100);
strcpy(str, "hello");
printf("%s", str);
}
A :空
B:hello
C:出错
19.如下代码输出是什么
int main(){
int i = 10;
int j = 1;
const int *p1;//(1)
int const *p2 = &i; //(2)
p2 = &j;//(3)
int *const p3 = &i;//(4)
*p3 = 20;//(5)
*p2 = 30;//(6)
p3 = &j;//(7)
return 0;
}
A :1,2,3,4,5,6,7
B:1,3,5,6
C:6,7
D:3,5
20.在C++中,为了建立如图所示的存储结构(即每个结点含两个域,data是数据域,next是指向结点的指针域),则在[] 处应填入选项是(多选题)
struct link
{
char data;
[];
} node;
A :link next;
B:struct link * next;
C:link * next;
D:struct link next;
21.有以下语句:(多选)
char str[4][12] = {"aaa", "bbbb", "ccccc", "dddddd"}, *strp[4];
for (int i = 0; i < 4; i++)
strp[i] = str[i];
对字符串的正确引用是(),其中0≤k<4()
A :*strp
B:strp
C:str[k]
D:strp[k]
22.在64位系统下,分别定义如下两个变量:char ∗ * ∗p[10]; char( ∗ * ∗p1)[10];请问,sizeof( p p p)和sizeof (p1)分别值为____。
A :4,40
B:80,8
C:10,10
D:8,80
23.若有以下说明和定义,在必要的赋值之后,对fun函数的正确调用语句是()
int fun (int *c){ … }
int main(){
int (*a)(int*)=fun,*b(),w[10],c;
…
}
A :a=a(w);
B:(*a)(&c);
C:b=*b(w);
D:fun(b);
24.下列程序的打印结果是?
char p1[15] = "abcd", *p2 = "ABCD", str[50] = "xyz";
strcpy(str + 2, strcat(p1 + 2, p2 + 1));
printf("%s", str);
A :xyabcAB
B:abcABz
C:ABabcz
D:xycdBCD
25.对于下面的语句
int c[4][5], (*p)[5];
p = c;
A :p + 1
B:*(p + 3)
C:*(p + 1) + 3
D:*(p[0] + 2)
26.对于以下代码,char ∗ * ∗ p=new char[100];说法正确的是()
A :p和new出来的内存都在栈上
B:p和new出来的内存都在堆上
C:p在堆上,new出来的在栈上
D:p在栈上,new出来的在堆上
27.运行以下C语言代码,输出的结果是()
#include <stdio.h>
int main()
{
char *str[3] ={"stra", "strb", "strc"};
char *p =str[0];
int i = 0;
while(i < 3)
{
printf("%s ",p++);
i++;
}
return 0;
}
A :stra strb strc
B:s t r
C:stra tra ra
D:s s s
28.运行以下C语言代码,输出的结果是()
int main()
{
char c, s[20];
strcpy(s, "Hello,World");
printf("s[]=%6.9s\n", s);
return 0;
}
A :s[]=Hello,
B:s[]=Hello,World
C:s[]= Hello,
D:s[]=Hello,Wor
29.有以下语句定义,则能输出a[1][2]的值的语句是()
int a[2][3];
int (*p)[3]=a;
int *q=*a;
A:cout<< ∗ * ∗( ∗ * ∗(a+1)+2)
B:cout<<p[1][2];
C:cout<<*(q+5);
D:cout<<q[1][2];
30.若有定义语句: int year=1009 , ∗ * ∗p=&year ;以下不能使变量 year 中的值增至 1010 的语句是()
A:*p+=1;
B:(*p)++;
C:++(*p)
D:*p++
2.结果与分析
题目一:答案:错误 ,
原因:char * p =“Hello” 定义了一个指向字符串的指针变量 p,并将其初始化为字符串 “Hello” 的地址。所以指针变量的值为字符串的地址
题目二:答案:6,6:
原因:执行*p++ += 100语句之后,数组变成{104,5,6,7,8},p指针指向第个二元素:5,重点是考察的是变参函数printf,printf的参数入栈是从右到左执行的,所以先执行 ∗ * ∗(++p)输出6,再 执行 ∗ * ∗p输出6,输出的是同一个元素。此题答案之前出现分歧,可能是运行环境不一致导致的。
题目三:答案:A:
原因:在二维数组中, ∗ * ∗(a+1)表示第二列首元素地址,这里是7;(a[1]+1)表示第二列第二个元素的地址,这里应该是元素9的地址;**(a +1)表示第二列首元素求值,这里是7,+2得到的是9;a和a[0]其实是一样的。一维数组和二维数组运算关系可参见博客:https://blog.csdn.net/Yin_w/article/details/131731082
题目四:答案:2,5:
原因:因为&a是整个数组a的地址,所以&a+1指向的是整个数组a后面的一个位置(跨越了整个数组),也就是ptr指向的是数组a之外的下一个位置。而由于数组a是连续存储的,所以这个位置恰好是数组a最后一个元素的下一个位置。因此 ∗ * ∗(ptr-1)的值就是数组a中最后一个元素的值,即5
题目五:答案:运行结果:运行无误,但打印乱码:
原因:getMemory(void)中的p[]为函数内的局部自动变量,在函数返回后,内存已经被释放。如果一步步调试,会发现执行str=getMenory();后str不再是NULL了,但是str的内容并不是hello world,而是垃圾数据。
题目六:答案:A:
原因:主要考察递归思想,此题答案来自牛客网码友,鸣谢!
题目七:答案:运行会报错,:
原因:这种形式的字符串存储在常量区。常量区 字符串只有读取权限,没有写入权限,这就导致了字符数组 在定义后可读取和修改每个字符而 第二种形式(字符串常量) 一旦定义后便不可修改,对它的赋值都是错误的(可整体赋值),这种形式可修改:
char str[] = “hello world”;
char *pstr = str;
*str = ‘a’;
题目八:答案:赋值方式错误:
原因:字符数组 只有在定义时才可一次性赋值,一旦定义完就只能一个个赋值。这样写正确:str[0] = ‘a’; str[1] = ‘b’; str[2] = ‘c’;与上述第七题的联系和区别,可参见博客:https://blog.csdn.net/Yin_w/article/details/132426333
题目九:
答案:
12
o
world!
原因:字符数组是一个数组,关于指针和数组的规则同样也适用于字符数组.故输出字符串也可以用: ∗ * ∗(pstr+i)、pstr[i]、*(str+i) 、str[i]进行输出
题目十:答案:D:
原因:char* p = “abcdefgh”,每个字符占1个字节,那么总共是8个字节,此时p指向’a’。如果是p++,那么p将指向’b’。打印p会得到"bcdefgh"。 long* q = (long*)p 将p强制转换为long*类型,也就是用long类型去解释存储了"abcdefgh"的这一段内存,此时q指向’a’,由于long类型是4个字节,那么q++移动4个字节,q将指向’e’,打印q将得到"efgh"。
题目十一:答案:D:
原因,这里定义的是一个指针数组,本质是一个数组,数组元素为指针
题目十二:答案:D:
原因:以上语句定义了一个指针数组 s。本质是一个数组,数组元素为字符串指针,而数组名是指向第一个元素的常量指针,因此 s 是指向指针的指针,所以函数 fun 的形参定义是 char **。fun(s) 将指针 s 的值传递给形参 p,所以 p = s,因此for(i=0;i<4;i + + )printf(“% s”,p[i]);中 printf(“% s”,p[i]) 等价于 printf(“% s”,s[i])。注意, s[i] 中存储的不是字符串,而是字符类型的指针,但 printf 会输出 s[i] 存储的指针指向的字符串。所以最后输出为 D。
题目十三:答案:B:
原因:typedef 给已有类型声明一个别名,故c和d都是int_ptr类型也即都是int *类型;
#define宏定义,在预编译时直接进行简单替换,即原式变为:int ∗ * ∗ a,b; 这相当于是int *a, int b; 即a是指针,b是int型。参考博客:https://blog.csdn.net/Yin_w/article/details/134915018?spm=1001.2014.3001.5502
题目十四:答案:A
原因:数组名为指针常量,其值不可更改。
题目十五:答案:A
原因:int ∗ * ∗p[n] 表示的是指针数组;int ( ∗ * ∗p)[n] 表示的是一个指向有n个元素数组的指针;(int ( ∗ * ∗)[4])m 表示以数组指针重新组织数组m,将其每4位划为一组,这样一来,m为{{1,2,3,4},{5,6,7,8},{9,0, , }},p指向第一行故p[1][2]即 ∗ * ∗( ∗ * ∗(p+1)+2),表示第二行第三个元素,为7
题目十六:答案:A
原因:a[]是一个有5个元素的数组, ∗ * ∗p[]是一个指针数组,数组名p,其内部有4个元素,每个元素是一个指针,分别指向a,a+|,a十2,a十3。 ∗ * ∗(p[0]+1)表示数组p的第0行第1个元素的值,即a[l],值为2。 ∗ * ∗ ∗ * ∗q是一个二维指针,它是向p的首址,即p[0]+0,即a的首地址,a[0]。q+2表示指向&a的第2个元素,**表示取值3。所以答案5
题目十七:答案:A
原因:函数对a是值传递,所以int *p = &a得到的是形参的地址,不会改变a的实际值,“*p = 101”是把形参a的值变成了101;对**c,传入的是二级指针,所以“ ∗ * ∗c = b”改变了指针p的指向,现在p指针指向b,所以p取值是2,但c的值没有变,依旧是3;对于b =p;相当于改变指针的指向,对于一级指针来讲想在函数内部改变其指向是无效的,所以b的值其实也没变,整个过程下来其实改变的只有p的指向,所以选A。可以参考博客:https://blog.csdn.net/Yin_w/article/details/132478099
题目十八:答案:B
原因:这里对传入的参数是二级指针,但因为该函数形参p为实参的临时拷贝,在函数内部申请空间的地址,存放在p中,不会影响str,所以当函数返回之后,str会成功指向开辟的堆空间,但一定要记得释放,此题有区别于void GetMemory(char *p, int num)形式。
题目十九:答案:C
原因:
(1)const int ∗ * ∗p1:不能通过指针p1修改指向的内存的值,但p1本身指向可修改。
(2)int const ∗ * ∗p2=&i:与p1相同,即不能修改p2指向的内存单元的值,但是可以修改p2使其指向其它的内存单元。这里p2指向了整型变量i
(3)p2=&j:修改p2,使其指向整型变量 j ,由(2)可知(3)没错。
(4)int *constp3=&i:p3是指向整型变量的常指针,p3初始化后不能改变他的指向,但是可以修改p3指向的内存单元的值。
(5)*p3=20:通过p3将变量i的值修改为2,由(4)可知(5)没错。
(6)*p2=30:通过p2修改它所指向的内存单元的值,由(2)可知(6)错误。
(7)p3=&j:修改p3,使其指向j,由(4)可知(7)错误。
参考博客:https://blog.csdn.net/Yin_w/article/details/132394812
题目二十:答案:BC
原因:由链表的属性可知,第二个成员是指向数据储存数据的结构体类型的结构体指针,非常明显BC均符合。
题目二十一:答案:ACD
原因:for循环实现将每个字符串的首地址赋给指针数组中每一个元素。strp为指针数组首地址,不是字符串的引用。str[k]为第k个字符串的地址,表示第k个字符串的引用。strp[k]表示指针数组的第k个元素,为第k个字符串的地址,也是这个字符串的引用。*strp取指针数组第一个元素,即为第一个字符数组的地址,也即为第一个字符串的引用。选择A、C、D选项。
题目二十二:答案:B
原因:64位系统下一个指针占8字节。
(1)char ∗ * ∗p[10]指针数组:array of pointers,即用于存储指针的数组,也就是数组元素都是指针。如int* a[10]。
(2)char( ∗ * ∗p1)[10]数组指针:a pointer to an array,即指向数组的指针。如int (*a)[10]。
sizeof( p p p)计算的是10个char型指针的数组大小,sizeof(p1)计算的是一个char型指针p1的大小,所以答案为80 , 8。
题目二十三:答案:B
原因:int fun (int *c){ … }定义了一个参数为int类型指针的函数。int ( ∗ * ∗a)(int ∗ * ∗)=fun的意思是定义了一个函数指针,该指针指向了fun函数,所以可以通过对指针取值调用该函数,且函数的参数必须是个地址,只有B符合,注意调用函数指针有ret = (*p)(); 和ret = p(); 两种形式,参见博客:https://blog.csdn.net/Yin_w/article/details/129962775
题目二十四:答案:D
原因:本题考查数组和指针,在本题中c是二维数组,指针p指向二维数组c,p其实是指向c数组的第一行。因此选项A)中p+1指向c数组的第二行;选项B)中,p+3表示p指向c数组的第三行,因此 ∗ * ∗(p+3)表示取出c数组第三行首元素的地址:选项C)和选项B)类似,表示取出数组c第二行首元素地址然后加3;选项D)中p[0]+2表示数组第一行第三列元素的地址,因此 ∗ * ∗(p[0]+2)是取出该元素的值。 知识模块:函数和数组
题目二十五:答案:D
原因:动态分配在堆中,其它的内存分配都在栈上进行。
题目二十六:答案:B
原因:p是char ∗ * ∗类型,每次++,后移一位(char)
char ∗ * ∗p=str[0]相当于char ∗ * ∗p=“stra”,p先指向s,p++后,指向t,printf输出遇到空字符停止
题目二十七:答案:C
由链表的属性可知,第二个成员是指向数据储存数据的结构体类型的结构体指针,非常明显BC均符合。
题目二十八:答案:C
原因:%6.9s 表示显示一个长度不小于6且不大于9的字符串。若大于9, 则第9个字符以后的内容将被删除。%m.n表示场宽为m的浮点数, 其中小数位为n, 整数位为m-n-1,小数点占1位,不够m位,左右对齐。
题目二十九:答案:ABC
原因:由链表的属性可知,第二个成员是指向数据储存数据的结构体类型的结构体指针,非常明显BC均符合。
题目三十:答案:D
分析·: ∗ * ∗p++是先取出 ∗ * ∗p的值,然后让p++ ,( ∗ * ∗p)++是先取出*p的值,让这个值++,*p+=1也是先取值再让值++ 参考博客https://blog.csdn.net/Yin_w/article/details/132495312
总结
以上就是30道C语言指针测试题目,如有错误,恳请指出,收集不易,转载留名,谢谢!!!