C++学习(2)

来源:互联网 发布:java替换\ 编辑:程序博客网 时间:2024/06/01 20:01

一、什么是堆?什么是栈?堆和栈的区别是什么?

 

栈:由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。

 

堆:一般由程序员分配释放,若程序员不释放,程序结束时可能由OS 收。用malloc, calloc, realloc等分配内存的函数分配得到的就是在堆。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表。

 

//main.cpp    
  int   a   =   0;   全局初始化区    
  char   *p1;   全局未初始化区    
  main()    
  {    
   int   b;       
   char   s[]   =   "abc";       
   char   *p2;       
   char   *p3   =   "123456";   123456/0在常量区,p3在栈上。    
   static   int   c   =0   全局(静态)初始化区    
   p1   =   (char   *)malloc(10);    
   p2   =   (char   *)malloc(20);  

}  
  分配得来得1020字节的区域就在堆区。    
  strcpy(p1,   "123456");   123456/0放在常量区,编译器可能会将它与p3所指向的"123456"  
  优化成一个地方

 

堆和栈的区别:

栈是系统提供的功能,特点是快速高效,缺点是有限制,数据不灵活;而栈是函数库提供的功能,特点是灵活方便,数据适应面广泛,但是效率有一定降低。栈是系统数据结构,对于进程/线程是唯一的;堆是函数库内部数据结构,不一定唯一。不同堆分的内存无法互相操作。栈空间分静态分配和动态分配两种。静态分配是编译器完成的,比如自动变量(auto)的分配。动态分配由alloca函数完成。栈的动态分配无需释放(是自动),也就没有释放函数。为可移植的程序起见,栈的动态分配操作是不被鼓励的!堆空间的分配总是动态的,虽然程序结束时所有的数据空间都会被释放回系统,但是精确的申请内存/释放内存匹配是良好程序的基本要素。

 

二、什么是声明,什么是定义?

 

所谓定义就是创建一个对象,为这个对象分配一块内存,同时给这块内存取一个名字,这个名字就是我们常说的对象名或变量名。但是注意,这个名字一旦和这块内存关联起来,他们就是一个整体,生死相依,不离不弃。并且这块内存的位置也不能被改变。一个对象或者变量,在一个区域内(全局,文件,函数,循环等)只能被定义一次,如果定义多次,编译器会提示你重复定义同一个变量或对象。

 

所谓声明有两层含义:

第一层含义:告诉这个编译器,这个名字已经匹配到一块内存上路了,后面的代码用变量火女对象实在别的地方定义的。定义是原件,原件唯一有效,那么声明就像复印件,可以重复打印,可以多次声明。  

第二层含义:告诉编译器,这个变量或者对象的名字已经被占用了,别的地方,不能在使用这个名字作为其他的变量或者对象名;比如在电影票,你买了一张票后提示他人该位置已经被其他上占用了。  

这种声明最典型的例子就是函数参数的声明,

例如:  int funcint a, char b);   

举一个例子:  A),int aB),extern int a     

这一样一疏理后,应该能够区分出:A是定义,B是声明。   

定义和声明的根本区别:内存。  定义创建对象,并为这个对象分配了内存;而声明只是将与内存关联的对象名进行外域可见性的扩充,看不到,可以继续声明。

 

三、const关键字用法,在C++C中的区别?

 

const修饰的数据类型是指常类型,常类型的变量或对象的值是不能被更新的。

 

C语言中:

constC语言中保留的一个关键字,它用来限定一个变量是只读的,即不可变的。程序中使用const可以在一定程度上提高程序的健壮性,但是程序中使用过多的const,可能在对代码的阅读时增加一定的难度。 C中的const的意思是‘一个不能被改变的普通变量’,在C中,它总是占用内存,而且它的名字是全局符。C编译器不能把const看成一个编译期间的常量。

(1)用const修饰一般变量        

      注意在C语言中,用const修饰的变量必须在声明时进行初始化(用来修饰函数的形参 除外);           

void fun(const int n); 正确        

const char a; 错误        

char * const p;  错误        

const char *p;正确(注意这种为什么是正确的),因为这里const是修饰p指向的变量,而不 是指针变量p本身         

 

一旦一个变量被const修饰后,在程序中除初始化外对这个变量进行的赋值都是误 的。         

 

(2)const与指针搭配使用        

首先必须弄清楚两个基础概念:指针常量和常量指针        

指针常量:即指针本身的值是不可改变的,而指针指向的变量的值是可以改变的;        

常量指针:即指针指向的变量的值是不可改变的,而指针本身的值是可以改变的;

       

可以这样去理解:因为指针本身也是一个变量,只不过指针存放的是地址而已,而一旦 指针变成了常量,即指  针本身的值是不可变的,此时指针只能指向固定的存储单元;指针一般会指向一个变量,如果该变量成为一个常量,那么该变量的值就不能被修改,即常量指针,指针指向的是一个不可变的变量。   

总结:

(1)C语言中用const去修饰一个变量,表示这个变量是只读的,不可通过显式的调用a去修改a的值,并且此时a仍然是一个变 量,不能等同于常量;       

(2)要注意const在声明变量时所处的位置,位置不同,在意义上可能会有很大的不同。         

如果const'*'左边,则表示指针指向的变量的值不可变;         

如果const'*'右边,则表示指针的值是不可变的;

 

C++中:

C语言和C++中的const有很大区别。C语言中用const修饰的变量仍然是一个变量;而在C++中用const修饰过后,就变成常量了

1)C++,是否为const分配空间要看具体情况如果加上关键字extern或者取const变量地址,则编译器就要为const分配存储空间.

2)C++中定义常量的时候不再采用define,因为define只做简单的宏替换,并不提供类型检查.

C++编译器在通常情况下不为常量分配空间,而是将其值存放在符号表内.但当使用extern修饰常量时,则必须立即 为此常量分配空间(与之类似的情况还有取常量的地址等等).只所以必须分配空间,是因为extern表示"使用外部链  接",   这表明还会有其他的编译单元将会使用寻址的方法来引用它,因此它现在就必须拥有自己的地址.  ConstCC++中最大的不同是,在C中,const默认具有外部链接,而C++中则是内部链接。所以当你只在定义 const常量的文件中使用该常量时,c++不给你的const常量分配空间,此时const  int c = 0;相当于#define c 0;  而在C中,它会给每个const 常量分配内存空间。

 

四、static关键字用法,在C++C中的区别?

 

static主要有三个作用:  

(1)局部静态变量  

(2)外部静态变量/函数  

(3)静态数据成员/成员函数

前两种CC++都有,第三种仅在C++中有。

 

C+ +重用了这个关键字,并赋予它与前面不同的第三种含义:表示属于一个类而不是属于此类的任何特定对象的变量和函数这是与普通成员函数的最大区别也是其应用所在比如在对某一个类的对象进行计数时计数生成多少个类的实例就可以用到静态数据成员在这里面, static既不是限定作用域的也不是扩展生存期的作用而是指示变量/函数在此类中的唯一性这也是”属于一个类而不是属于此类的任何特定对象的变量和函数”的含义因为它是对整个类来说是唯一的,因此不可能属于某一个实例对象的. (针对静态数据成员而言成员函数不管是否是static, 在内存中只有一个副本普通成员函数调用时需要传入this指针, static成员函数