‘壹’ 操作系统和编译器是怎么识别全局变量和局部
操作系统,只管调度进程,线程编译器根据编程语言的定义,确定变量的作用于,存储类型,生命周期!
定义在函数外部的变量,只有文件静态变量,和外部变量
外部变量,是实实在在的全局变量,不论作用域还是生命周期。
静态变量是局部作用域的,生命周期为,程序的生命周期的变量。
自动变量和函数参数,是局部作用域的生命周期为函数结束的局部变量。
寄存器变量,用register定义,是局部变量;
函数内部的静态变量,语句组内部的静态变量,局部作用域的,生命周期为,程序的生命周期的变量。
静态变量,编译器,可以通过static关键字知道。
自动变量,1)函数内部定义的非静态变量,非寄存器变量是自动变量。
2)函数参数,只能是自动变量,不过也可能定义在寄存器中。
这和调用约定有关,因此不可以用register定义。
C语言没有全局变量这种数据类型。
只有4种存储类型,和变量的作用域与生命周期的概念。
C++同样没有全局变量这种数据类型。
有另外的两种作用域
1)namespace作用域。
2)类(类型)作用域。
C只有全局,文件,函数以及函数内部的语句组,4种逐渐缩小的作用域。
其中内层,对外部作用域,具有完全的遮蔽作用。
C++可以通过作用域限定符,区分不同作用域(类,名空间)的名字。
类作用域,可以通过访问权限,限制外部的访问权。
函数作用域(语句组作用域)是封闭的作用域,外部不可以使用函数内部定义的名字。
也不会和外部有命名冲突,只会遮蔽外部的名字。
类作用于,和名空间由于访问方式不同,命名冲突和遮蔽有些特殊。
函数和全局域,基本不会和类作用域有命名冲突,除非类方法内部。
命名空间,可以避免命名冲突。
类继承体系中,则有遮蔽现象。
还有访问权限问题。
实际上,全局变量,有两个概念可以判定
1)作用域(空间)===>由定义和声明位置,和定义和声明使用的关键字决定。
2)生命周期(时间)===>外部和静态变量,的生命周期是全局的,从初始化到程序结束。
函数参数,和函数局部非静态变量,是局部变量
函数参数的传递,是跨函数的(实参,变成形参);
函数内部定义的,局部变量,只有定义处可见,作用域是函数甚至语句组局部,
其中静态变量,生命周期是全局的,非静态是函数甚至语句组的。
全局变量,不是C,C++的概念。
而是,使用编程语言的程序员的概念。
所以,全局变量和C,C++的存储类型,作用域,生命周期等,不是一一对应的概念。
所以,可以有不同的理解。
所以这个概念是很模糊的,不清晰的。
比如局部静态变量,类的静态变量,是否全局变量,就不是可以清晰的说明的。
‘贰’ 问一下各位,c语言编译器是如何处理变量名的呢
编译器编译到int a;时就在内存中开辟一个两字节的内存空间,并且命名为a
‘叁’ 编译器对c语言中变量名怎么编译
对于变量名,会根据变量类型
开辟不同大小的内存空间
然后指定一个相对地址记录下来。
对于编译后, 不存在变量名,只有对应的相对地址。
‘肆’ c编译器将变量分配在 什么存储器
DEV C++TurboC2.0Visual studio 6.0Code::Blocks以上几款编辑器都可以在64位系统中运用。按照步骤如下:以Code::Blocks为例1首先下载下载Codeblocks这个软件,目前最新版本是13.12,2这个软件是英文的,所以软件是英文界面,建议读者使用英文版,不要去使用汉化版本,毕竟C语言是外国人开发的,所以用英文的界面会比较适合以后的能力提供,这个界面直接点击【I Agree】,进如下一步安装3这个是选择安装模式的界面,一般你的电脑是一个账户的,不是多人使用的电脑,所以这里选择Full就行了,就是给电脑所有用户安装4来到这个界面选择安装路径,这里强烈建议修改下安装路径,不建议使用默认的路径,默认的路径中【Program Files】中有一个空格,以后安装一个插件可能会出问题,所以建议自己建立一个文件作为该软件的安装路径,比如这里是在D盘建立了一个Develop的文件夹,作为开发软件的安装路径,然后安装路径就选择了D:\Develop\CodeBlocks,这里可以根据自己实际情况定义。5安装结束之后,弹出提示是否运行Code::Blocks,这里都可以选,选择运行6Code::Blocks的启动界面,这里是13.12版本,在上述经验有说到7这个直接选择Set as default就行了,因为此时你还没有安装其他的插件,所以其他的选项是灰色的,然后点击OK8紧接着看到的就是软件的这界面,这个界面就是Code::Blocks的界面
‘伍’ 编译器在编译的时候做了什么给申明的变量分配内存
第一是将java文件编译成字节码文件 就是class文件 给jvm执行
第二就是分配常量池 就是给你代码里面的变量和方法分配空间
‘陆’ 编译器对作为局部变量的数组是怎么管理的放在堆栈中
C语言的堆跟栈是有区别的,请大家不要混淆。
局部变量和函数调用时的实参是放在栈里。所以有大家常说函数调用时的入栈,出桟这个说话。
动态申请的内存放在堆里的。
全局变量和静态变量是放在另外的全局内存区。
‘柒’ 编译器怎么知道是全局变量还是局部变量
这个要细说,能说的很详细,我说一下,比较好理解的你就懂了!
我说之前先打个比方:小区人家,几十户,每家每户都有灯光自己用就是局部的
月亮..全局的.都能用懂了?
按照目前的面向对象来说如Java,C++,C#,Ruby中,由于变量都是封装在类里面的,对别的类不可见,所以已经几乎完全抛弃了全局变量的概念。然而,可以通过把一个类定义为public static,把类成员变量也定义为public static,使该变量在内存中占用固定、唯一的一块空间,来实现全局变量的功能。
说通俗点,你如果想理解,就假如在一个类中,看你定义的变量,位置!类中,方法外面,就属于全局,每个方法都能拿去用..方法里面定义的,就属于局部的,只能他自己用.懂了?
和你一样初学者,不足之处还请指点!
‘捌’ c 编译器如何半段 变量类型
编译器其实不会存储地址是什么类型。
只是根据代码, 向地址写入 或者读取的时候,根据读写的代码来判断是什么格式
比如
int p;
这样在读写p地址时,就是按照int型。
而如果
*((float*)&p) = 1.0;
这种就按照float读写了。
至于强制转换, 就是当系统没办法自动做转换的时候, 手动加一个强制转换。一般这种都是有一定风险的,比如char *转int*这样的。 系统也不是不能做,但由于有风险,就提示你强制转换下。 加了强制转换,就等于告诉系统, 我已经知道了风险,同时我知道我在做什么,系统就不管你了。
‘玖’ 现代C/C++编译器有多智能
最近在搞C/C++代码的性能优化,发现很多时候自以为的优化其实编译器早就优化过了,得结合反汇编才能看出到底要做什么样的优化。
请熟悉编译器的同学结合操作系统和硬件谈一谈现代c/c++编译器到底有多智能吧。哪些书本上的优化方法其实早就过时了?
以及程序员做什么会让编译器能更好的自动优化代码?
举个栗子:
1,循环展开,大部分编译器设置flag后会自动展开;
2,顺序SIMD优化,大部分编译器设置flag后也会自动优化成SIMD指令;
3,减少中间变量,大部分编译器会自动优化掉中间变量;
etc.
查看代码对应的汇编:
Compiler Explorer
【以下解答】
举个之前看过的例子:
int calc_hash(signed char *s){ static const int N = 100003; int ret = 1; while (*s) { ret = ret * 131 + *s; ++ s; } ret %= N; if (ret < 0) ret += N; //注意这句 return ret;}
【以下解答】
举个简单例子,一到一百求和
#include int sum() { int ret= 0; int i; for(i = 1; i <= 100; i++) ret+=i; return ret;}int main() { printf("%d\n", sum()); return 0;}
【以下解答】
话题太大,码字花时间…
先放传送门好了。
请看Google的C++编译器组老大Chandler Carruth的演讲。这个演讲是从编译器研发工程师的角度出发,以Clang/LLVM编译C++为例,向一般C++程序员介绍理解编译器优化的思维模型。它讲解了C++编译器会做的一些常见优化,而不会深入到LLVM具体是如何实现这些优化的,所以即使不懂编译原理的C++程序员看这个演讲也不会有压力。
Understanding Compiler Optimization - Chandler Carruth - Opening Keynote Meeting C++ 2015
演示稿:https://meetingcpp.com/tl_files/mcpp/2015/talks/meetingcxx_2015-understanding_compiler_optimization_themed_.pdf
录像:https://www.youtube.com/watch?v=FnGCDLhaxKU(打不开请自备工具…)
Agner Fog写的优化手册也永远是值得参考的文档。其中的C++优化手册:
Optimizing software in C++ - An optimization guide for Windows, Linux and Mac platforms - Agner Fog
要稍微深入一点的话,GCC和LLVM的文档其实都对各自的内部实现有不错的介绍。
GCC:GNU Compiler Collection (GCC) Internals
LLVM:LLVM’s Analysis and Transform Passes
========================================
反模式(anti-patterns)
1. 为了“优化”而减少源码中局部变量的个数
这可能是最没用的手工“优化”了。特别是遇到在高级语言中“不用临时变量来交换两个变量”这种场景的时候。
看另一个问题有感:有什么像a=a+b;b=a-b;a=a-b;这样的算法或者知识? - 编程
2. 为了“优化”而把应该传值的参数改为传引用
(待续…)
【以下解答】
推荐读一读这里的几个文档:
Software optimization resources. C++ and assembly. Windows, Linux, BSD, Mac OS X
其中第一篇:http://www.agner.org/optimize/optimizing_cpp.pdf
讲解了C++不同领域的优化思路和问题,还有编译器做了哪些优化,以及如何代码配合编译器优化。还有优化多线程、使用向量指令等的介绍,推荐看看。
感觉比较符合你的部分需求。
【以下解答】
一份比较老的slides:
http://www.fefe.de/source-code-optimization.pdf
【以下解答】
利用C++11的range-based for loop语法可以实现类似python里的range生成器,也就是实现一个range对象,使得
for(auto i : range(start, stop, step))
【以下解答】
我觉得都不用现代。。。。寄存器分配和指令调度最智能了
【以下解答】
每次编译poco库的时候我都觉得很为难GCC
【以下解答】
有些智能并不能保证代码变换前后语义是等价的
【以下解答】
诶诶,我错了各位,GCC是可以借助 SSE 的 xmm 寄存器进行优化的,经 @RednaxelaFX 才知道应该添加 -march=native 选项。我以前不了解 -march 选项,去研究下再来补充为什么加和不加区别这么大。
十分抱歉黑错了。。。以后再找别的点来黑。
误导大家了,实在抱歉。(??ˇ?ˇ??)
/*********以下是并不正确的原答案*********/
我是来黑 GCC的。
最近在搞编译器相关的活,编译OpenSSL的时候有一段这样的代码:
BN_ULONG a0,a1,a2,a3; // EmmetZC 注:BN_ULONG 其实就是 unsigned longa0=B[0]; a1=B[1]; a2=B[2]; a3=B[3];A[0]=a0; A[1]=a1; A[2]=a2; A[3]=a3;
【以下解答】
提示:找不到对象
【以下解答】
忍不住抖个机灵。
私以为正常写代码情况下编译器就能优化,才叫智能编译器。要程序员绞尽脑汁去考虑怎么写代码能让编译器更好优化,甚至降低了可读性,那就没有起到透明屏蔽的作用。
智能编译器应该是程序猿要较劲脑汁才能让编译器不优化。
理论上是这样的。折叠我吧。
【以下解答】
编译器智能到每次我都觉得自己很智障。
【以下解答】
虽然题主内容里是想问编译器代码性能优化方面的内容,但题目里既然说到编译器的的智能,我就偏一下方向来说吧。
有什么更能展示编译器的强大和智能?
自然是c++的模版元编程
template meta programming
简单解释的话就是写代码的代码,写的还是c++,但能让编译器在编译期间生成正常的c++代码。
没接触过的话,是不是听上去感觉就是宏替换的加强版?感觉不到它的强大呢?
只是简单用的话,效果上这样理解也没什么
但是一旦深入下去,尤其翻看大神写的东西,这明明看着就是c++的代码,但TM怎么完全看不懂他在干什么?后来才知道这其实完全是另外一个世界,可是明明是另外一个世界的东西但它又可以用来做很多正常c++能做的事....
什么?你说它好像不能做这个,不能做那个,好像做不了太多东西,错了,大错特错。就像你和高手考试都考了100分的故事一样,虽然分数一样,但你是努力努力再努力才得了满分,而高手只是因为卷面分只有100分.....在元编程面前,只有想不到,没有做不到。
再回头看看其他答案,编译器顺手帮你求个和,丢弃下无用代码,就已经被惊呼强大了,那模板元编程这种几乎能在编译期直接帮你“生成”包含复杂逻辑的c++代码,甚至还能间接“执行”一些复杂逻辑,这样的编译器是不是算怪兽级的强大?
一个编译器同时支持编译语法相似但结果不同却又关联的两种依赖语言,这个编译器有多强大多智能?
写的人思维都要转换几次,编译器转着圈嵌着套翻着番儿地编译代码的代码也肯定是无比蛋疼的,你说它有多强大多智能?
一个代码创造另外一个代码,自己能按照相似的规则生成自己,是不是听上去已经有人工智能的发展趋势了?
上帝说,要有光,于是有了光。
老子曰,一生二,二生三,三生万物。
信c++,得永生!
===
FBI WARNING:模板元编程虽然很强大,但也有不少缺点,尤其对于大型项目,为了你以及身边同事的身心健康,请务必适度且谨慎的使用。勿乱入坑,回头是岸。
【以下解答】
c++11的auto自动类型推断算么....
【以下解答】
智能到开不同级别的优化,程序行为会不同 2333
【以下解答】
这个取决于你的水平
‘拾’ 怎么添加编译器环境变量。。谢谢。
计算机->属性->高级系统设置->环境变量->“你的编译器的路径”