1.?若有以下定义,说法错误的是()
int a = 100, *p = &a;
A:声明变量p,其中*表示p是一个指针变量
B:变量p经初始化,获得变量a的地址
C:变量p只可以指向一个整形数据
D:变量p的值为100
本题考查的是指针
ABC都正确,这里说一下C,C正确的原因是p是一个int*类型的,所以p只能指向整型数据
2. 有以下代码段,向内存申请到的内存空间中存入整数123的语句为( )
int *p = (int *)malloc(sizeof(int));
A:scanf("%d", p);
B:scanf("%d", &p);
C:scanf("%d", *p);
D:scanf("%d", **p);
p是一个指向malloc的空间的指针,所以p也就是这个空间的地址,那向空间输入数据,直接用p就行。
3.?程序运行后的输出结果是()
#include <stdio.h>
#include <stdlib.h>
void fun(int *p1, int *p2, int *s)
{
s = (int *)malloc(sizeof(int));
*s = *p1 + *(p2++);
}
int main()
{
int a[2] = {1, 2};
int b[2] = {10, 20}
int *s = a;
fun(a, b, s);
printf("%d \n", *s);
return 0;
}
A:11
B:10
C:1
D:2
本题考查的是函数的传值是不会影响实参的,所以在函数fun里对指针s的操作,不会影响实参s,实参s还是指向的a的首元素地址,所以依旧是1.
4.?程序运行后的输出结果是()
#include <stdio.h>
int main()
{
char s[]="ABCD", *p;
for (p = s + 1; p < s + 4; p++)
printf("%s ", p);
return 0;
}
A:ABCD BCD CD D
B:A B C D
C:B C D
D:BCD CD D
p最开始指向的是B的地址,printf会自动打印字符串,直到遇到\0停止;
所以第一次循环打印BCD,第二次打印CD,第三次打印D。
5. 下面代码的输出结果是()
#include<stdio.h>
int main()
{
int a[2][2][3] = {{{1, 2, 3}, {4, 5, 6}}, {{7, 8, 9}, {10, 11, 12}}};
int *ptr = (int *)(&a + 1);
printf("%d %d", *(int*)(a + 1), *(ptr - 1));
}
A:7 12
B:1 6
C:1 3
D:7 9
本题考查的是对指针的加法和解引用具体拿多少字节的知识
首先要知道管他几维数组,物理存储都是连续的。
数组名就是首元素地址,但是&数组名代表的是整个元素的地址;
所以&a + 1;跳过的就是整个三维数组,指向的是最后一个元素的下一个位置;但是此时已经被强转为int*类型了;
所以*(ptr - 1)就是向前移动4字节,因为ptr类型是int*,那就是12;
而(a + 1)的a是数组名,是首元素地址,记住数组名代表首元素地址的时候,就已经是首元素的类型了,所以a的首元素其实是一个二维数组类型,a的数据类型就是int [2][3],那a + 1就是跳过一个二维数组的大小,也就是到7的位置;但是a + 1被强制转换为int*,在解引用的时候就只能解引用出4字节了,也就是7;