题目原文链接:https://blog.csdn.net/zhanshen112/article/details/80783258
目录
指针,字符数组
若定义
char s[2][3]={“ab”, “cd”}, p=(char )s;
那么下列表达式语法正确,并且其值与 s[1][1]相等的表达式(并非一定与其等价)是
A. *(s+3)
B. p[1][1]
C. *(p+3)
D. *++p+2
思路:
① char s[2][3]={“ab”, “cd”}, p=(char )s;
声明了一个二维字符数组 s:
s[0][0] = 'a' s[0][1] = 'b' s[0][2] = '\0' (字符串结束标志)
s[1][0] = 'c' s[1][1] = 'd' s[1][2] = '\0' (字符串结束标志)
p 是一个字符指针,指向字符数组 s 的首地址。
这段代码的效果是将字符数组 s 的首地址赋给指针 p,使得 p 指向了第一个字符串 "ab" 的首地址。
② s[1][1]
表示二维数组 s 中第二行第二列的元素,即字符 'd'。
③ 分析选项
A. (s+3)
s 表示数组首元素地址,并不是一个指针变量,不能执行指针加法操作。该选项无意义。
B. p[1][1]
同样,p 是一个指向字符数组的指针,并不能像二维数组一样使用双重下标来访问元素。p[4] 才能访问 'd'。该选项无意义。
C. (p+3)
p表示的指针后移3位,为 'c'。
D. ++p+2
++p : &s[0][1]
++p : s[0][1] == 'b'
*++p + 2 : 'b' + 2,字符加数字用的是ASCII码,即得到 'd' 的ASCII码。
答案:D
类似的题目:
若定义 char a[3][3]={“ad”, “ce” , “fb”}, s = (char )a; 那么下列表达式语法正确,并且其值与 a[2][1]相等的表达式是___。
答案:D
指针的指针
有函数原型为
void f(int, int );
主函数中有变量定义:
int a=2, p=&a;
则下列函数调用正确的是
A. f(a,&p);
B. f(*p, p);
C. f(p,a);
D. f(*p, a);
思路:
p 是一个指向整型变量的指针
p = &a,所以 p == a(类型是int)
void f(int, int *),所以f第一个变量类型是 int,第二个是指针,它指向的元素类型为 int。
答案:B
宏定义
下列程序段的输出是___。
int s=5;
int k= DF(s+1,s-3);
printf("%d",k);
思路:
直接把 s + 1和s - 3代入(a+2b) 中的a b,不用括号!
(a+2b) → (s+1+2*s-3) == 13
答案:13
全局变量、局部变量、静态变量的生存期
以下代码的输出是:
{
static int w;
*y++; x++; w = x+*--y;
printf("%d#%d#%d#%d#",x,*y,z,w);
}
int main(void)
{
int x, y, z, w;
x=y=z=w=1;
do{
static int x;
p(&x, y);
printf("%d#%d#%d#%d#",x,y,z,w);
} while(0);
return 0;
}
思路:
作用域规则:
- 内部作用域可以访问外部作用域的变量,但外部作用域不能访问内部作用域的变量。
- 同名变量在不同作用域中的优先级是不同的。在内部作用域中声明的同名变量会优先于外部作用域中的同名变量.
- 对于嵌套作用域的情况,内部作用域中声明的变量只在自己的作用域内有效,不会影响外部作用域中的同名变量。
答案:2#0#0#2#0#1#1#1#
sizeof和数组
假设sizeof(int)的值为4,对数组定义:
int a[3][6];
则sizeof(a[0])的值为____.
思路:
定义int a[3][6];说明这是一个3行6列的二维数组。
a[0]表示第1行,有6个元素,故sizeof(a[0]) == 4 * 6 == 24
答案:24
条件表达式以及&&,||,!
写出表示“当 x 的取值在 [-10, 0] 的范围内,结果为真,否则为假”的C语言表达式,注意不要任何空格
答案:x>=-10&&x<=0 或 x<=0&&x>=-10 或 !(x<-10||x>0)
&&,||,!
若 int a = 6, b = 0, c = 3,则表达式 a && b || b - c的结果是(以1表示真,0表示假)
思路:
int → bool
0 在C语言中被视为假,而非 0 值被视为真。
&&:与(且),都非 0 为 1,有 0 为 0
||:或,有非 0 为 1 ,全 0 为 0
a && b || b - c → 6 && 0 || (-3) → 0 || (-3) → 1
答案:1
指针、字符串和数组
以下代码段的输出是:
char *s="fbla",*p;
int i, j;
for(p=s; *p; p++) {
j=0;
while (*p>=a[j] && a[j]!='\0') j++;
for(i=strlen(a); i>=j; i--) a[i+1] = a[i];
a[j]=*p;
}
printf("%s", a);
思路:
答案:abcefhiklnqtw
宏定义
根据下面的定义,F0(3+4)的输出结果是___(注意没有空格)
#define F1(var) printf("var=%d", var)
#define F0(var) F1(var * var)
思路:
F0(3+4) == F1(3 + 4 * 3 + 4) == var=19
答案:var=19
指针的指针
程序T1的代码如下,则运行T1 abc bcd cde aed的输出结果是___.
{
while(**argv++!='a');
printf("%s", *argv);
return 0;
}
思路:
argc 和 argv:
https://zhuanlan.zhihu.com/p/267822985
① argc表示参数的个数,此处参数为 T1 abc bcd cde aed,argv == 5
argv是一个指向指针的指针,用于存储命令行参数的字符串。
char* argv可以看成char argv[],即一个字符串数组,每个元素对应一个字符串,值为字符串的首地址。**argv就是字符串的首字母
以具体示例来解释:
假设我们在终端中执行了一个名为 program 的可执行文件,并给它传递了两个参数:hello 和 world。那么,argc 的值将是 3 (可执行文件本身也算作一个参数),而 argv 将会指向一个保存了 program、hello 和 world 的三个字符串的内存区域。
{
// argc = 3
// argv = ["program", "hello", "world"]
// 使用循环打印所有命令行参数
for (int i = 0; i < argc; i++)
{
printf("%s\n", argv[i]);
}
return 0;
}
在上述代码中,我们通过循环遍历 argv 数组,并使用 %s 占位符来打印出每个命令行参数的字符串。输出如下:
program
hello
world
② while(argv++!='a');
注意这里有;说明printf在循环之后才执行。
argv++每执行一次,指向下一个字符串,一直执行到遇到字符串首元素为a,即abc
由于有; 再执行一次,printf bcd。
答案:bcd
变量的指针
以下代码的输出是:
{
int pt;
pt = *pa, *pa = *pb, *pb = *pa;
}
int main(void)
{
int x=1, y=2;
swap(&x, &y);
printf("%d%d", x, y);
}
思路:
pt = pa == 1, pa = pb == 2, pb = *pa == 2
答案:22