空类编译器做了哪些操作
‘壹’ C++中的空类编译器默认隐式声明哪些成员函数
如果你只是声明一个空类,不做任何事情的话,
编译器会自动为你生成四个函数:
一个默认构造函数、
一个拷贝默认构造函数、
一个默认拷贝赋值操作符
一个默认析构函数
‘贰’ java编译器的功能是什么编译过程中主要完成哪些操作
主要是把.java文件编译成.class文件,在编译的过程中,初始化static成员,
‘叁’ 请问抛砖:VS的编译器到底做了什么
最近在学习并发程序设计,其中有个很重要的概念叫原子操作。网上有很多文章论述原子操作的,其中大部分文章不约而同的都使用到了这个例子++操作,来例证很多高级语言中的一条语句并非是不可拆分的原子操作。出于好奇,本人对++操作的原子性在VS2012下写了一个小程序以测试之,于是乎发现了下面的问题。//测试代码TEST(ConcurrenceTest, Atomic){ std::vector
<std::thread
threads; threads.push_back(std::thread(std::ref(thread))); threads.push_back(std::thread(std::ref(thread)));for(auto &
t : threads) { t.join(); } std::cout<<"total值:"<<total<<
std::endl;}//线程voidthread(){for(inti =0; i <50000; i++) { total++; }}以上代码在release下结果都是100000,但在debug下会小于100000。
了解原子操作的朋友应该知道,debug下小于100000的结果应该属正常现象,因为++操作并不具有原子性,所有在并发的过程中会出现数据竞跑的现象。但是在release下所得到的结果却总是正确的(为了避免偶然性,本人用更多的线程,更大的数据类型同样做过测试,结果依然正确),这不得不怀疑编译器在release下对代码是否做过一定的优化? 那么这种优化对于程序员来说是一件好事么? 他会不会给一些对此了解不深的程序员造成一种正确的假象?本人是个初学者,写这些的目的只是抛个砖,以上的观点也仅是本人的一些小想法,希望有兴趣的朋友能来一起讨论。
‘肆’ 初学C语言用TC/VC迷糊中。教材哪里找
初学用TC就可以 上手容易教材资料丰富 稍微入行点就换VC6.0+Visual.Assist.X插件
‘伍’ 编译器做什么工作
1. 词法分析 词法分析器根据词法规则识别出源程序中的各个记号(token),每个记号代表一类单词(lexeme)。源程序中常见的记号可以归为几大类:关键字、标识符、字面量和特殊符号。词法分析器的输入是源程序,输出是识别的记号流。词法分析器的任务是把源文件的字符流转换成记号流。本质上它查看连续的字符然后把它们识别为“单词”。 2. 语法分析 语法分析器根据语法规则识别出记号流中的结构(短语、句子),并构造一棵能够正确反映该结构的语法树。 3. 语义分析 语义分析器根据语义规则对语法树中的语法单元进行静态语义检查,如果类型检查和转换等,其目的在于保证语法正确的结构在语义上也是合法的。 4. 中间代码生成 中间代码生成器根据语义分析器的输出生成中间代码。中间代码可以有若干种形式,它们的共同特征是与具体机器无关。最常用的一种中间代码是三地址码,它的一种实现方式是四元式。三地址码的优点是便于阅读、便于优化。 5. 中间代码优化 优化是编译器的一个重要组成部分,由于编译器将源程序翻译成中间代码的工作是机械的、按固定模式进行的,因此,生成的中间代码往往在时间和空间上有很大浪费。当需要生成高效目标代码时,就必须进行优化。 6. 目标代码生成 目标代码生成是编译器的最后一个阶段。在生成目标代码时要考虑以下几个问题:计算机的系统结构、指令系统、寄存器的分配以及内存的组织等。编译器生成的目标程序代码可以有多种形式:汇编语言、可重定位二进制代码、内存形式。 7 符号表管理 符号表的作用是记录源程序中符号的必要信息,并加以合理组织,从而在编译器的各个阶段能对它们进行快速、准确的查找和操作。符号表中的某些内容甚至要保留到程序的运行阶段。 8 出错处理用户编写的源程序中往往会有一些错误,可分为静态错误和动态错误两类。所谓动态错误,是指源程序中的逻辑错误,它们发生在程序运行的时候,也被称作动态语义错误,如变量取值为零时作为除数,数组元素引用时下标出界等。静态错误又可分为语法错误和静态语义错误。语法错误是指有关语言结构上的错误,如单词拼写错、表达式中缺少操作数、begin和end不匹配等。静态语义错误是指分析源程序时可以发现的语言意义上的错误,如加法的两个操作数中一个是整型变量名,而另一个是数组名等。
‘陆’ 谁知道C++编译器会为类添加哪些成员函数
条款45: 弄清C++在幕后为你所写、所调用的函数
一个空类什么时候不是空类?当C++编译器通过它的时候。如果你没有声明下列函数,体贴的编译器会声明它自己的版本。这些函数是:一个拷贝构造函数,一个赋值运算符,一个析构函数,一对取址运算符。另外,如果你没有声明任何构造函数,它也将为你声明一个缺省构造函数。所有这些函数都是公有的。换句话说,如果你这么写:classEmpty{};和你这么写是一样的:classEmpty{public:Empty();// 缺省构造函数Empty(constEmpty& rhs);
// 拷贝构造函数~Empty();// 析构函数Empty&operator=(constEmpty& rhs);
// 赋值运算符Empty*operator&();// 取址运算符constEmpty*operator&()const;};对于这个问题,好像早有读者向书的作者Scott Meyers提出了疑问,Scott Meyers也认为上边的答案是有问题的.正确的结果应该是:classEmpty{public:Empty();Empty(constEmpty&);
~Empty();
Empty&operator=(constEmpty& rhs);}另外,需要注意的是只有当你需要用到这些函数的时候,编译器才会去定义它们。
声明一个空类,大家都认为会生成
构造函数、拷贝构造函数、析构函数、赋值运算符号;
其实对于这样的一个空类来说,是完全没有必要的,而编译器也不是这样做的。是我们太低估编译器给我们做的工作了,我们用VC编译器来说明一下。
classA{};对于单独申明的一个空类A来说,编译器编译过程中,并没有发现创建A实例。所以对于空类A来说,编译器是不会给类A生成任何函数的;如果我们在代码中需要生成一个A的实例,比如A a;编译器就会根据上面的实例,给类A生成构造函数和析构函数。 当使用A b(b);编译器就会生成类A的拷贝构造函数;A c;c = a;编译器生成赋值运算符函数;
A &d = a;
编译器生成取地址运算符函数。
经过分析可以这样理解:
对于一个没有实例化的空类,编译器是不会给它生成任何函数的,当实例化一个空类后,编译器会根据需要生成相应的函数。这条理论同样适合非空类(只声明变量,而不声明函数)。
‘柒’ C++中的空类,编译器默认可以产生哪些成员函
6个成员函数都会默认产生 然后编译过程中根据需求再去实例化
‘捌’ C++中编译时遇到函数的定义,编译器做了哪些事,
程序在内存中分为四部分
代码段 (程序代码,比如你的函数)
静态段 (存放静态变量和全局变量,还有用到的字面值常量)
堆 (由程序员自己管理的内存,动态分配用的就是这部分内存) //动态分配的数组在这里
栈 (由操作系统管理,局部变量和临时变量存在这里) //自己定义的数组在这里
现在你应该知道自己定义的普通数组在哪里,动态分配的数组又在哪里了吧.
调用函数时都是值传递,就是把变量的值复制一份给函数这时就会新分配一块内存给函数中
接收这个值的那个变量,当函数结束时,这个变量被释放
引用调用不是值传递,而是让函数直接操作你传递的实参
高级一点: 引用其实也是值传递这种方式,只不过编译器偷偷给你变成了指针
‘玖’ C++中的空类,编译器默认可以产生哪些成员函数
一个空的class在C++编译器处理过后就不再为空,编译器会自动地为我们声明一些member function,如果你写
class Empty{};
就相当于:
class Empty
{
public:
Empty();
Empty(const Empty&);
~Empty();
Empty& operator=(const Empty& rhs);
Empty* operator&();
const Empty* operator&() const;
};
需要注意的是只有当你需要用到这些函数的时候,编译器才会去定义它们。
‘拾’ C语言里一个变量给另一个变量赋值时编译器进行了哪些操作
把a所占据的内存空间拷贝一份复制到b所占据的空间。
看上去就像执行了b.a= a.a, b.b = a.b, b.c = a.c;