C语言指针经典练习题

题目原文链接: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+2
b) → (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;
}

思路

作用域规则

  1. 内部作用域可以访问外部作用域的变量,但外部作用域不能访问内部作用域的变量。
  2. 同名变量在不同作用域中的优先级是不同的。在内部作用域中声明的同名变量会优先于外部作用域中的同名变量.
  3. 对于嵌套作用域的情况,内部作用域中声明的变量只在自己的作用域内有效,不会影响外部作用域中的同名变量。

答案: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

发表评论