c语言之编译器引出的问题

c语言之编译器引出的问题

ID:8913179

大小:15.50 KB

页数:3页

时间:2018-04-12

c语言之编译器引出的问题_第1页
c语言之编译器引出的问题_第2页
c语言之编译器引出的问题_第3页
资源描述:

《c语言之编译器引出的问题》由会员上传分享,免费在线阅读,更多相关内容在教育资源-天天文库

1、草根编程网C语言之编译器引出的问题基本解释本节主要探讨C编译器下面两方面的特点所引发的一系列常见的编程问题。对C文件进行分别编译:C程序通常由几个小程序(.c文件)组成,编译器将这几个小程序分别编译,然后通过链接程序将它们组合在一起形成一个目标代码。由于编译器每次只能编译一个文件,因此它不能立即检查需要几个源文件配合才能发现的错误。对函数的参数和返回值建立临时变量C编译器会对函数的参数建立临时参数,也可能会对函数的返回值隐含传递一个指针。因为这些临时变量的隐含性存在,使得在某些情况下,特别是有指针存在的时候,会

2、引发一系列的问题。C文件中所包含的头文件会和C语言一同编译C语言中被包含的头文件是和.c文件一起编译的,头文件中的问题会反映到.c文件的编译中。问题:C文件的分别编译我有一个数组a定义在f1.c中,但是我想在f2.c中计算它的元素个数,用sizeof可以达到这个目的吗?答案与分析:答案是否定的,你没有办法达到目的,本质原因是sizeof操作符只是在“编译时(compiletime)”起作用,而C语言的编译单位是每次单个.c文件进行编译(其它语言也都如此)。因此,sizeof可以确定同一个源文件中某个数组的大小,

3、但是对于定义在另一个源文件中的数组它无能为力了,因为那已经是“运行时(runtime)”才能确定的事情了。一件事情要想做,总会有办法的,下面提供有三种可选的办法来解决这个问题:1)、定义一个全局变量,让它记住数组的大小,在另外一个.c文件中我们通过访问这个全局变量来得到数组的大小信息(好像有点小题大做得不偿失^_^)。2)、在某个.h文件中用宏定义数组的大小,例如#defineARRAY_SIZE50,然后在两个源文件中都包含这个.h文件,通过直接访问ARRAY_SIZE来得到定义在不同.c文件中的数组的大小。

4、3)、设置数组的最后一个元素为特殊值,例如0,-1,NULL等,然后我们通过遍历数组来寻找这个特殊的结尾元素,从而判断数组的长度(这个办法效率低,也是笨笨的)。问题:函数返回值隐含传递指针下面的代码可以正常工作,但是在程序结束时会有一个致命错误产生。究竟是什么原因呢?structlist{ char*item; structlist*next;}main(argc,argv){ ...}答案与分析:原因很简单,稍微注意一点不难发现,在定义结构list的右花括弧后面加一个分号就可以解决这个问题:structlis

5、t{ char*item; structlist*next;};//缺了这个分号可不行!好了,问题是解决了,但,你知道这个错误究竟导致了什么致命问题吗?问题不是表面上那么简单的,OK,让我们来看看事情背后的真相。首先看一看下面这段代码:VOIDFunc(structmy_structstX){ .......}structmy_structstY={...};Func(stY);当调用函数Func的时候,是把结构变量stY的值拷贝一份到调用栈中,从而作为参数传递给函数FUNC的,这个叫做C语言的参数值传递。我相

6、信这个你一定很清楚,那么,你应该知道:如果函数的返回值是结构变量的话,函数应该如何将值返回给调用者呢?且看下面这段代码:structmy_structFunc(VOID){ .......}structmy_structstY=Func();此时函数Func的返回值是一个结构类型的值,这个返回值被放在内存中一个阴暗恐怖的地方,同时安排了一个指针指向这个地方(暂时称为“神秘指针”),而这个指针会由C语言的编译器作为一个隐藏参数传递给函数Func。当函数Func返回时,编译器生成的代码将这个由隐藏指针指向的内存区的

7、值拷贝到返回结构stY中,从而完成将结构变量值返回给调用者。你明白了上述所讲的东东,那么今天问题的真正原因也就呼之欲出了:因为structlist{...}的定义后面没有加分号,导致主函数main(argc,argv)被编译器理解为是一个返回值为结构变量的函数,从而期望得到除了argc和argv以外的第三个参数,也就是我们上面提到的那个隐含传入的“神秘指针”。可是,大家知道,这里函数是main函数,main函数的参数是由程序中的启动代码(startupcode)提供的。而启动代码当然认为main()天生就应该只

8、得到两个参数,要“神秘指针”,当然没有,如此一来,main()在返回时自作主张地去调用栈中访问它的那个并不存在的第三个参数(即神秘指针),这样导致非法访问,产生致命问题。这才是这个问题的真正根源。建议:1)、尽量将结构变量的指针而不是结构本身作为函数参数,否则函数调用时内存拷贝的开销可不小,尤其是对那些调用频繁、结构体大的情况。2)、结构定义的后面一定要加分号,经过上面我的大段讲述,我

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。