C语言常见错误题

1.

#include<stdio.h>
void main(void)
{
    int a[5]={1,2,3,4,5};
    int *p=(int *)(&a+1);
    printf("%d,%d\n",*(a+1),*(p-1));
}

上述代码输出的结果是2,5。原因是在于&a是整个数组的地址,类型是int (*)[5],而a是代表的数组中第一个元素的地址&a[0],其类型是int *,因此,在(int*)(&a+1)代表的是将整个数组地址右移,此时假设a整个数组的地址是0x1000,那么(&a+1)代表的就是整个数组的地址再右移动一个同样的&a类型的字节大小,也就是a数组有5各元素,一个元素占用4各字节,所以a共占用20个字节,那么(&a+1)的地址就是0x0000+20=0x1014;但是它前边还有一个强制转换,转换成了int类型,然后再去p-1,这个时候p就减去4个字节,变成了0x1010,并且此时由于强制转换,对0x01000的解释有所不同,此时这个地址代表的是数组首元素的地址,如下图所示:

地址      值
0x1000    1
0x1004    2
0x1008    3
0x100C    4
0x1010    5

因此*(p-1)指向的就是a数组的最后一个元素5,因此会输出5。

2.

#include<stdio.h>

 

void func(int b[][3])

{

    ++b;

    b[1][2]+=2;

}

 void main(void)

 {

    int a[3][3]={{1,2,3},{4,5,6},{7,8,9}};

    func(a);

    printf("%d\n",a[2][2]);

 }上述代码输出的值是10,这是因为b是一个二维数组,二维数组就是一个一维数组里边的每个元素由多个元素组成,比如b[x][y],实际上是一个一维数组,里边的元素为b[0]...b[x-1],然后b[0]里边又有y个元素,相当于此时b[0]就是数组名,里边有b[0][0]...b[0][y]。然后先进行++b,这代表着先加一,后使用,因此就相当于b=b+1;而数组名又代表着地址,因此这里实际上相当于&b[0]=&b[0]+1=&b[1],因此,就相当于把b数组的行首地址赋值b[1]的行首地址,那么此时b[0][0]=4而不再是等于1,因此,b[1][2]=9+2=11;也就是a[2][2]=11;

3.

#include <stdio.h>

int main() {

    int a = 10, b = 20, c,d;

    d=a,b;//没有加括号,只将a的值赋给d

    c = (a, b);  // 使用逗号操作符连接a和b

    printf("c = %d,d=%d\n", c,d);  // 输出c的值

    return 0;

}上述代码需要注意的是c=(a,b);这是一个逗号操作符,逗号操作符的用法是计算并返回其右侧表达式的值,而不管左侧表达式的值。因此输出c=20;但是d=a=10,要注意看有没有括号。

4.

#include<stdio.h>

void main(void)

{

        int i,j;

        i=sizeof(char);

        j=++i + i++;

        printf("%d %d\n",i,j);

}该代码输出i=3,j=4(可能还存在争议);解析如下:首先sizeof是输出一个类型所占的内存,以字节为单位,所以得到i的初始值为1,然后++操作符优先级高于算数运算符,那么先算自增运算符之后,再去进行加法运算,然后++i代表的是先加1后使用,i++代表的是先使用,后加一。

5.

#include <stdio.h>

void fun(int a, int *b, int **c)

{

    int *p = &a; // p 指向 a 的地址(此处是局部变量 a)

    *p = 5; // 改变局部变量 a 的值为 5

    *c = b; // c(即主函数中 q 的地址)被赋值为 b 的地址

    **c = 6; // 改变 b 所指向的值为 6

}

int main()

{

    int x = 1, y = 2, z = 3; // 定义变量

    int *q = &z; // q 指向 z 的地址

    fun(x, &y, &q); // 调用 fun 函数

    printf("%d,%d,%d,%d\n", x, y, z, *q); // 输出 x, y, z, *q

    return 0;

}上述代码输出结果为1,6,3,6;对于为什么x输出值为1,即x的值未发生改变,这是因为c语言中函数参数的传递默认为按值传递,而不是按引用传递。实际上是将x的值复制了一份传递给函数参数a,但是现在a和x是两个独立的变量,不等价于a=x;因为并没有将x这个变量复制给a,只是将其值给了a。因此x并没有发生改变,如果想要改变x,应该调用fun(&x,…),改成引用传递。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值