现在的位置: 首页 > 综合 > 正文

由《C缺陷和陷阱》上的一个例子想到的

2013年11月28日 ⁄ 综合 ⁄ 共 1095字 ⁄ 字号 评论关闭

 

为方便了解背景,如下图所示,为从《C缺陷和陷阱》书上截下的图片:

 

为了研究下这个问题,在code blocks上演示了下:

代码如下

#include <stdio.h>

#include <stdlib.h>

 

int main()

{

   // printf("Hello world!\n");

   int i;

   char c;

   for(i=0;i<5;i++){

        scanf("%d",&c);

        printf("%d ",i);

    }

    printf("\n");

    return 0;

}

 

然后编译,运行,结果却是如下图:

结果并不像书中所述的结果: 0 0 0 0 0 1 2 3 4

也许是编译器的事,这里暂时不管。

当时准备想接着往下看的,这里,我停了一下,想研究一下:

发现涉及到的问题还挺多的。

1.       大小端问题。

2.       int和char数据类型的大小(其实是操作系统的位数问题)

所以我重新修改代码如下:

#include <stdio.h>
#include <stdlib.h>

int main()
{
   // printf("Hello world!\n");
   int i;
   char c;
   printf("%d-%d\n",sizeof(int), sizeof(char));
   for(i=0;i<5;i++){
        scanf("%d",&c);
        printf("%d ",i);
    }
    printf("\n");
    return 0;
}

再次编译,运行,如下:

如果输入不是0到4,会出现如下情况:

代码如下:(为了便于观看结果我在第一个printf后面加了个\n)

#include <stdio.h>
#include <stdlib.h>

int main()
{
   // printf("Hello world!\n");
   int i;
   char c;
   printf("%d-%d\n",sizeof(int), sizeof(char));
   for(i=0;i<5;i++){
        scanf("%d",&c);
        printf("%d \n",i);
    }
    printf("\n");
    return 0;
}

运行,输入些数据,如下图:

重新输入如下图:

让我们重新分析下程序,虽然很小,但是仔细分析,还是有很多知识点在里面。

因为sizeof(int)=4, sizeof(char)=1

又因为局部变量存储在栈区,同时栈是向下生长(堆是向上生长,另提)

于是就有了,下面的图示:

当先分配i的时候,它占用4个字节,如图中ABCD四个部分,当输入c的时候,分配了4个字节,根据些x86小端存储原理,c要占用EDCB四个部分。

所以当输入小于1个字节时,都没有问题,当大于一个字节是就会覆盖掉i的低字节部分。

所以就出现了上述的几个结果.

聪明的你,看懂了吗?

 

抱歉!评论已关闭.