目录
c语言的代码段、数据段、bss段
C++中为什么空类的大小为1?为什么成员函数不占大小?为什么有了成员变量之后就不用加1了?
如何理解面向对象(oop)
面向过程编程、OOP面向对象编程和泛型编程
typedef的作用
关于typedef的注意点
断言assert了解吗?
静态局部变量、静态全局变量、普通全局变量之间的区别
fopen文本模式和二进制模式的区别
对C++顶层const和底层const的区别
C++11有没有了解过?
智能指针
C++的内存分配\内存管理方式
C的内存管理方式
自由存储区和堆是两块不同的内存区域吗?它们有可能相同吗?
编译器在编译程序的时候,将程序中的所有的元素分成了一些组成部分,各部分构成一个段,所以说段是可执行程序的组成部分。
代码段:代码段就是程序的可执行部分,直观理解就是函数堆叠组成的。
数据段:数据段存放一些程序中的数据,初始化了的全局变量、静态变量都放在数据段。
bss段:未初始化的全局变量和静态变量都放在bss段。
面向对象有三大特性,封装、继承和多态。
封装就是将一类事物的属性和行为抽象成一个类,使其属性私有化,行为公开化,提高了数据的隐秘性的同时,使代码模块化。这样做使得代码的复用性更高。
继承就是一个类继承另一个类,实现了代码的复用,继承后子类自动拥有了父类的属性和方法,子类也可以写自己特有的属性和方法,目的是实现功能的扩展。
多态就是调用相同的方法,参数也相同时,但表现的行为却不同,这是由虚函数来实现的。
面向过程是一种以过程为中心的编程思想,考虑的是实际的实现过程,比如说c语言,以函数作为基本单元,就是通过函数来体现的。OOP是面向对象编程,把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数,通过封装、继承、多态来实现程序。
C++中还包括重载、多态、继承、输入输出流这些。
泛型编程就是提供了模板,将类型参数化,用template
第一,定义别名。可以定义一种类型的别名,也可以替复杂声明定义一个别名。可以用来同时声明多个指针。比如char* a,b;只是定义了一个指针和一个变量。如果有typedef char* PCHAR;就可以连续定义多个指针,PCHAR a,b,c,d; 和char*a,*b是等价的。typedef更直观。
第二,在结构体中用来省略struct,
typedef struct ListNode
{
struct ListNode *next;
int val;
}ListNode;
比如链表的结构体,ListNode就代替struct ListNode
第三,可以用来定义与平台有关的数据类型。当跨平台的时候,只需要修改typedef就行了。
typedef char* PSTR;
const PTSR p = “abc”;//这个地方const限制了p只读
p++;//错误×
记住const和 typedef一起出现时,绝不是简单的字符替换
typedef static int INT;//会报错
assert是一个宏,相当于一个if语句,在debug模式下使用的,assert中的表达式为真,程序正常运行,表达式为假,就会终止程序。频繁地调用assert会影响程序的性能。禁用assert,就是在include后面加#define NDEBUG。
#include
#define NDEBUG
#include
首先它们都存在内存的全局存储区。
一个程序由多个源文件组成。这三种变量的生命期都是整个程序。
静态局部变量的作用域是定义它的那个函数内部,且只能初始化一次。
静态全局变量的作用域是整个源文件,不可extern到别的源文件中使用。
普通全局变量的作用域是整个源文件,但是可以extern到别的源文件中使用。
FILE * fopen(const char * path,const char * mode);
首先文本文件是基于字符编码的文件,如ASCII码、Unicode等,包括xml文件、html超文本文件、c源程序文件等。二进制文件是基于值编码的文件,如word文件、图像格式文件JPG等。
fopen中二进制模式是原封不动的读写文件的全部内容。
文本模式下,你写进去、读出来的,和实际存储的数据,两者不一定相同;
二进制模式下,你写进去、读出来的,和实际存储的数据,两者一定相同。
以文本方式打开文件的话,当读取文件的时候,系统会将所有的"/r/n"(回车换行)转换成"/n"(换行);当写入文件的时候,系统会将"/n"转换成"/r/n"写入。
r 打开只读文件,该文件必须存在。
r+ 打开可读写的文件,该文件必须存在。
rb+ 读写打开一个二进制文件,只允许读写数据。
rt+ 读写打开一个文本文件,允许读和写。
w 打开只写文件,若文件存在则文件长度清为0,即该文件内容会消失。若文件不存在则建立该文件。
w+ 打开可读写文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则建立该文件。
wb 只写打开或新建一个二进制文件;只允许写数据。
wb+ 读写打开或建立一个二进制文件,允许读和写。
wt+ 读写打开或着建立一个文本文件;允许读写。
有 + 表示允许读写。
wb+和rb+都可以进行读写,区别在于wb+可以打开或者建立一个文件。
对于普通变量没有顶层底层的区别,对于指针来说才有区别。
顶层const指的是常量指针,也就是指针本身不可改变。*const
底层const指的是指向常量的指针,也就是指针指向的值不可改变。const* 就是底层。
C++11是C++编程语言的一个标准,之前的标准有C++98以及C++03。相比于C++03,C++11标准包含核心语言的新机能,而且扩展C++标准程序库。
例如:
for循环使用更简单
引入了空指针nullptr解决NULL二义性
void foo(int n);
void foo(char* cArr);
上面声明了两个重载函数,当我调用foo(NULL),编译器将会调用foo(int)函数,而实际上我是想调用foo(char*)函数的。为了避免这个歧义,C++11重新定义了一个新关键字nullptr,充当单独空指针常量。
引入了 auto 和 decltype 这两个关键字实现了类型推导,auto推导变量,decltype推导表达式。
auto会忽略掉顶层const,保留底层const。
const int i = 5;
auto a = i; //a是int类型而不是const int
const auto a = i;//a就是才是const int型
引入了智能指针
智能指针是对普通指针增加了一层封装机制,用来方便地管理一个对象的生命周期(及对象什么时候被删除或被析构由智能指针本身决定,不需要用户管理)
智能指针的作用:智能指针是为了避免内存泄露的问题,替代了new和delete。
关键字auto_ptr、unique_ptr、shared_ptr和weak_ptr,头文件是
auto_ptr
如果shared_ptr的两个指针b赋值给a,则两个指针的计数值都会增加。shared_ptr指针的计数值指的是指向这块内存的指针个数。
构造函数中计数初始化为1;
拷贝构造函数中计数值加1;
赋值运算符中左边的引用对象计数-1,右边的引用对象技术+1;
析构函数中引用计数-1,当减为0,就会自动delete释放掉对象空间。
C++中,内存区分为五个区,分别是堆、栈、全局存储区、常量存储区、自由存储区。
常量存储区:常量字符串等;
全局存储区:全局变量、静态变量,程序结束后由系统释放。
栈区:局部变量、函数的参数变量,由编译器自动分配释放(栈地址是向下增长的)。
堆区:由程序员分配释放,malloc在堆上分配的内存块,使用free释放内存。
自由存储区:是通过new和delete动态分配和释放对象的抽象概念,new所申请的内存区域在c++中称为自由存储区。
堆、栈、全局区、常量区。
自由存储区和堆是两个不同的概念,它们有可能指向同一块内存区域。
基本上,所有的C++编译器默认使用堆来实现自由存储,也就是new和delete也许会按照malloc和free的方式来被实现,这时藉由new运算符分配的对象,说它在堆上也对,说它在自由存储区上也正确,这时候他们就是相同的内存。而如果程序员也可以通过重载操作符,改用其他内存来实现自由存储,例如全局变量做的对象池,这时自由存储区就区别于堆了,这时候就是不同的内存区域。