暑期C++第一天复习

来源:互联网 发布:淘宝无线流量 编辑:程序博客网 时间:2024/06/06 14:36
今天从类开始复习 类和结构体一样,也是一个数据类型
那什么是数据类型呢? int double 这些都是数据类型。但是编译器是怎么理解的呢?这时候我们要站在
编译器的角度思考问题。
数据类型 是固定大小内存块的别名。当我们输入int double等数据类型关键词的时候,我们是在告诉
编译器要分配内存了。比如  int a是在告诉编译器要给a分配4个字节的内春空间。
但是 定义一个类 是一个抽象的概念 不会给你分配内存,只有用数据类型定义变量的时候 编译器才会
给变量分配内存。


如果你定义了多个对象,那么编译器是如何区分是哪个对象调用了类的方法.


下面我们来看一个初学者容易犯的典型错误 

#include<iostream>using namespace std;class circle {public:double r;//在初始化的时候 r的值就已经有了double pi = 3.1415926;double area = pi*r*r;//在初始化的时候  这个式子就已经执行了  };int main(void){circle c1;cout << "please enter a number:" << endl;cin >>c1.r;cout << c1.area << endl;
//乱码  因为这个area 在初始化的时候就已经有值了,现在操作只是从里面拿值,
//并没有执行该语句,只是从他的内存空间中取值//double = 10;cout << c1.area << endl;return 0;}
这是一个圆的类,我们可以通过输入他的半径来求圆的面积,但是我们可以试着运行这段代码,我们会发现c1.area始终是一段乱码。

这是为什么呢,首先我们知道 circle c1这个语句的意思是告诉c++编译器要我给我们分配内存了,这个时候c1里面的所有的变量都已经有值了,所以他的面积早已经固定好了,所以我们输入的c1.r并没有改变什么,我们读取c1的面积的时候 只是从他的内存空间中拿值。所以才会出现乱码。



然后我再看C++和C有什么不同

C++对C有着许多地方的加强 首先是bool类型

int main(void){bool b1 = true;cout << sizeof(bool) << endl;  //bool类型所占用内存空间b1 = 10;cout << "b1:" << b1 << endl;  //bool变量类型的值,不是0就是1b1 = 0;cout << "b1:" << b1 << endl;return 0;}
这是对bool类型的加强。


接下来看两个有趣的例子

#include<iostream>using namespace std;int main01(void){int a = 10;int b = 20;(a < b ? a : b) = 30;int c = 10;int d = 20;*(a < b ? &a : &b) = 30;
//这两个程序是一样的结果  但是在C中只能用这样的方法给a或b赋值//让表达式返回一个内存首地址   C++编译器帮我们程序员完成了刚才取地址的工作return 0;}//------------------------------------------------------------------int main02(void){const int a = 10;int *p = NULL;p = (int *)&a;          //在c++中, 当一个变量添加const后,这个变量就会被放到符号表中,不能被修改*p = 20;//当你调用这个变量的时候,就会自动从符号表中取出值,从而将这个变量变成常量cout << a << endl;// 当一个指针指向const变量的时候,cpu会在内存中给这个指针另外开辟一个空间,cout << *p << endl;//这个指针指向另外一个空间。return 0;}
首先看第一个例子第一个语句和第二个语句不同的地方在于 第二个返回的是一个地址然后对他解引用。

第一条语句在一般的C编译器是会报错的,为什么呢 因为第一条语句返回的是一个值 返回的是一个常量

常量=20,很明显常量是不能被修改的,那么我们如何才能实现这条语句呢。我们看第二条语句,他返回的是什么  返回的是一个地址然后对他解引用,所以他返回的是一个变量 返回的是a或者b。所以这条语句才能完成我们想要的。C++编译器会自动帮我们完成这些工作,所以在C++编译器第一条是可以使用的


在C++中const关键字也被加强了,通过运行我们可以发现a的值并没有发生改变 但是*p却发生了变化。

这是为什么呢,难道*p!=a么,可是p=&a啊。在C++编译器中,当我们对一个变量进行了const修饰以后

这个变量就会放到符号表里面,什么是符号表呢,一个值对应这一个变量,这就是符号表。当你调用这个变量的时候,就会自动从符号表中取出值,从而将这个变量变成常量。当一个指针指向const变量的时候,cpu会在内存中给这个指针另外开辟一个空间。所以这两个并不是同一个。



我们接下来看看引用这方面内容

int getAA1(){int a;a = 10;return a;}int &getAA2()//如果返回栈上的引用可能会有问题{int a;a = 20;return a;   //返回a的本身}int *getAA3(){int a;a = 20;return &a;}int main05(void){int a1 = getAA1();int a2 = getAA2();int &a3 = getAA2();//注意,如果返回栈变量,不能成为其他引用的初始值cout << a1 << endl << a2 << endl << a3 << endl;return 0;}

我们可以在relase 和debug两种环境下运行 我们会发现不一样的结果

第一个函数返回的是变量a的值,第二个返回的是a的引用,第三个返回的是a的地址。

不管返回什么 他们都是栈变量,这个函数运行结束以后他们就会被析构了,他们所占用的内存空间也将不会被电脑所管理。第一第二条语句没问题,我们看第三条语句。int &a3=getAA2().

他返回一个引用,然后用一个引用去接它。我们知道 引用就是一个const指针,只不过C++编译器帮我们做了这些工作 我们看不到而已。他返回一个引用要看我们怎么去接,如果是按照第二条语句去接的话,

那么他会自动将内存上的内容给a2,如果我们用一个引用去接,那么他返回的是一个内存地址。然后我们在读取a3  实际上就是*(&a)。但是a被析构了,但是他原来的内存是一直存在的,只不过内存里面的值没有了,变成了一堆乱码,所以我们对a3输出的结果可能是一堆乱码。



今天的复习内容就到这里了

。                                                           





原创粉丝点击