易截截图软件、单文件、免安装、纯绿色、仅160KB

谈C中scanf陷阱

原文地址:http://westsoftware.blog.163.com/blog/static/2609410920091953456841/
      最近一直在看Andrew Koening写的书籍,可以说学习C/C++或者从事这方面的开发的人员非常值得一看的书籍,这里我推荐看看《C陷阱与缺陷》与《C/C++沉思录》。
      这里先来看看《C陷阱与缺陷》一段代码。
#include <stdio.h>
int main()
{
int i;
char c;
//printf("i address:%ld\n",&i);
//printf("c address:%ld\n",&c);
for(i=0 ; i<5; i++)
{
scanf("%d",&c);
printf("%d ",i);
}
return 0;
}

这么精小的一段代码,看看运行结果将会是什么?请看清楚C是字符变量。
刚开始的时候,对他讲的东西不是很明白,为了更加清楚,分析相关内存结构。
由于scanf指向的是一个整形指针,此时C接收字符录入,所以在给C输入数据的数据的时候,会将i的一些内存地址进行覆盖,怎么覆盖的呢?在FC6下,会将i的低端地址覆盖成C的高端地址,不知道这么说能不能明白?就是说C实际接收了一个整形变量,但是C存不下,多出的那部分怎么办呢?就将C的高端地址位覆盖成I的低端地址位了,所以I的值一直都是0,所以在运行此程序是一个死循环状态。
上面注释掉那两段,可以打印看看C与I的地址。我这里打印的地址是连续的。
但是在VC6中,是可以正常运行的,这就是我说的内存地址覆盖方式不一样,换句话说,怎么覆盖是有编译器决定,这里我是这么猜想,VC覆盖内存的时候是C的左彻的那段内存而不覆盖I的内存地址,所以在VC中能正常。
这也是一个猜想,怠于证实。而在FC中是“往右”进行覆盖。
所以开发的时候,一定要注意,这种陷阱一旦走进去的,就很难调试,有时候也有一种“凑巧”来避开这个问题,差错就更加不好查。希望在以后开发的时候能给大家有一定的参考。


相关文档:

(转)C程序的编译过程

编译,编译程序读取源程序(字符流),对之进行词法和语法的分析,将高级语言指令转换为功能等效的汇编代码,再由汇编程序转换为机器语言,并且按照操作系统对可执行文件格式的要求链接生成可执行程序。
C源程序头文件-->预编译处理(cpp)-->编译程序本身-->优化程序-->汇编程序-->链接程序--> ......

将Win32 C/C++应用程序迁移到Linux

本文的内容是 Win32 API(特别是进程、线程和共享内存服务)到 POWER 上 Linux 的映射。本文可以帮助您确定哪种映射服务最适合您的需要。作者向您详细介绍了他在移植 Win32 C/C++ 应用程序时遇到的 API 映射。
概述
有很多方式可以将 Win32 C/C++ 应用程序移植和迁移到 pSeries 平台。您可以使用免费软件或者第三方工具来 ......

C/C++中Static的作用详述


C/C++中Static的作用详述
 
1.先来介绍它的第一条也是最重要的一条:隐藏。
当我们同时编译多个文件时,所有未加static前缀的全局变量和函数都具有全局可见性。为理解这句话,我举例来说明。我们要同时编译两个源文件,一个是a.c,另一个是main.c.
下面是a.c的内容:
char a = 'A'; // global variable
void ......

C/C++ 字节对齐问题

VC中下面几个结构体大小分别是多少呢
struct MyStruct
{
    double m4;
    char m1;
    int m3;
};
struct MyStruct {
    char m1;
    double m4;
    int m3;
};
#pragma pack(push)   ......
© 2009 ej38.com All Rights Reserved. 关于E健网联系我们 | 站点地图 | 赣ICP备09004571号