C++的基础知识

来源:互联网 发布:傻强是不是卧底 知乎 编辑:程序博客网 时间:2024/06/05 16:28

1、C++和C的区别:

C是一个面向结构的语言,重点在于算法和数据结构。C程序的设计考虑如何通过一个过程,对输入进行运算处理得到输出
C++是一个面向对象的语言,重点在于如何构造一个对象模型,的核心是封装继承和多
  1. 类   struct是public继承,而class是private继承
  2. 引用
  3. 函数重载
  4. 操作符重载
  5. 继承,虚函数的实现
  6. new delete

1.1 struct和class的区别

C++中的struct对C中的struct进行了扩充,它已经不再只是一个包含不同数据类型的数据结构了,它已经获取了太多的功能。
struct能包含成员函数吗? 能!
struct能继承吗? 能!!
struct能实现多态吗? 能!!!
1)默认的继承访问权限。struct是public的,class是private的。
2)struct作为数据结构的实现体,它默认的数据访问控制是public的,而class作为对象的实现体,它默认的成员变量访问控制是private的。
做个总结,从上面的区别,我们可以看出,struct更适合看成是一个数据结构的实现体,class更适合看成是一个对象的实现体。


1.2 引用和指针

  1. 指针是一个实体,而引用是一个别名
  2. 引用只能在定义的时候初始化一次,之后不可以修改;指针可以修改
  3. 引用不能为空,必须初始化;指针不用
  4. 引用没有const,指针有const
  5. sizeof引用得到的是所指向变量(对象)的大小;sizeof指针得到的是4(指针本身大小)
  6. 指针和引用自增(++)含义不一样

1.3 TCP和UDP的差别

TCP与UDP区别总结:
1、TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接
2、TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付
3、TCP面向字节流,实际上是TCP把数据看成一连串无结构的字节流;UDP是面向报文的UDP没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如IP电话,实时视频会议等)
4、每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信
5、TCP首部开销20字节;UDP的首部开销小,只有8个字节
6、TCP的逻辑通信信道是全双工的可靠信道,UDP则是不可靠信道

typedef struct _TCP_HEADER 
{
 short m_sSourPort;              // 源端口号16bit
 short m_sDestPort;              // 目的端口号16bit
 unsigned int m_uiSequNum;         // 序列号32bit
 unsigned int m_uiAcknowledgeNum;  // 确认号32bit
 short m_sHeaderLenAndFlag;        // 前4位:TCP头长度;中6位:保留;后6位:标志位
 short m_sWindowSize;            // 窗口大小16bit
 short m_sCheckSum;              // 检验和16bit
 short m_surgentPointer;           // 紧急数据偏移量16bit
}__attribute__((packed))TCP_HEADER, *PTCP_HEADER;typedef struct _UDP_HEADER 
{
 unsigned short m_usSourPort;       // 源端口号16bit
 unsigned short m_usDestPort;       // 目的端口号16bit
 unsigned short m_usLength;        // 数据包长度16bit
 unsigned short m_usCheckSum;      // 校验和16bit
}__attribute__((packed))UDP_HEADER, *PUDP_HEADER;

1.3.1 TCP连接

server
  1. 创建一个新socket
  2. 设置socket属性,用函数sestsockopt()
  3. bind当前server的IP和port
  4. listen来监听是否有TCP连接请求信息
  5. accept从客户端上来的连接
  6. 收发数据,用函数send()/recv(),或者read()和write()
  7. 关闭网络连接
  8. 关闭监听 
Client
  1. 创建一个新socket    int socketfd = new socket()
  2. 设置socket属性,用函数sestsockopt()
  3. bind当前client的IP和port   bind(socketfd, ipaddr)
  4. 设置要连接的server的IP和地址addr
  5. connect发送消息到server,开始三次握手
  6. recv/send来接收和发送消息,或者read()和write()
  7. 关闭网络连接

1.3.2 UDP连接

server:
  1. 创建一个socket,用函数socket()
  2. 设置socket属性,用函数sestsockopt()
  3. 绑定当前服务器的IP地址和port
  4. 循环接收数据,用函数recvform()
  5. 关闭网络连接
client:
  1. 创建一个socket
  2. 设置socket属性,用函数sestsockopt()
  3. 绑定client的ip地址和server
  4. 设置要连接的server的IP地址和port
  5. connect该server
  6. recv/send来发送和接收数据

1.3.3 

1.4 STL中vector、list、deque和map的区别

  • 序列式容器
向量(vector) 连续存储的元素<vector>
列表(list) 由节点组成的双向链表,每个结点包含着一个元素<list>
双端队列(deque) 连续存储的指向不同元素的指针所组成的数组<deque>
  • 适配器容器
栈(stack) 后进先出的值的排列 <stack>
队列(queue) 先进先出的值的排列 <queue>
//优先队列(priority_queue) 元素的次序是由作用于所存储的值对上的某种谓词决定的的一种队列 <queue>
  • 关联式容器
集合(set) 由节点组成的红黑树,每个节点都包含着一个元素,节点之间以某种作用于元素对的谓词排列,没有两个不同的元素能够拥有相同的次序 <set>
多重集合(multiset) 允许存在两个次序相等的元素的集合 <set>
映射(map) 由{键,值}对组成的集合,以某种作用于键对上的谓词排列 <map>

多重映射(multimap) 允许键对有相等的次序的映射 <map>


  • vector
向量,x相当一个数组,在内存中分配一块连续的内存空间进行存储。支持不指定vecotr的大小来存储

优点:
  1. 不指定一块内存大小的数组的连续存储,既可以像数组一样操作,但可以对此数组进行动态操作,体现在push_back和pop_back上
  2. 随机访问方便,及支持下标[]和vector.at()
  3. 节省空间
缺点:
  1. 在内部进行插入删除操作效率低
  2. 只能在vector的最后进行push和pop,不能再头部进行
  3. 当动态添加的数组超过vector默认分配的大小时,要进行整体的重新分配、拷贝和释放。
  • list
双向链表,每一个结点多包括一个信息info,一个前驱pre,一个后驱next。可以不分配必须的内存大小方便进行添加和删除。使用的是非连续的内存空间进行存储
优点
  1. 不适用连续内存完成动态操作
  2. 在内部方便的进行插入和删除操作
  3. 可以在两端进行push和pop
缺点
  1. 不能随机访问,不支持下标
  2. 相对于vecotr占用的内存多
  • deque
双端队列double-end queue,deque合并了vector和list功能。
deque内部会维护一个map(不是stl那个map)一小块连续的空间,该空间中的每个元素都是指针,指向另一个较大的区域,这个区域是缓冲区,缓冲区用来保存deque中的数据。因此deque在随机访问和便利数据会比vecotr慢
优点
  1. 随机访问,支持下标
  2. 在内部方便插入和删除
  3. 可以在两端push和pop
缺点:
  1. 占用内存多

1.5 new delete和malloc free的区别

new delete是C++的函数,而malloc和free是c的操作符
new delete可以操作动态内存,而malloc必须制定需要分配的内存的大小
malloc不是C++的库函数,所以在free的时候没办法调用对象的析构函数。

相同:都可以用于申请动态内存和释放内存
不同:
1、操作对象不同
malloc和free是C++/c的标准库函数,而new、delete是C++的运算符。
对于非内部数据类的对象而言,光用malloc和free无法满足动态对象的要求。对象在创建的同时需要自动执行构造函数,消亡时要自动执行析构函数。由于malloc和free是库函数不是运算符,不在编译器的控制之内,malloc和free不能够把执行构造函数和析构函数的任务

2、差别
  • new自动计算需要分配的空间,malloc需要手动计算字节数
  • new是类型安全的,malloc不是
  • new operator由两步组成,分别是operator new和construct
  • operator new对应于malloc,但是operator new可以重载,可以自定义内存分配策略,malloc无能为力
  • new将调用constructor,malloc不能;delete将调用destructor,而free不能
  • malloc/free需要库文件支持,new delete不用
3、malloc free用法
void *malloc(size_t size)
用malloc申请一块长度为length的整数类型内存,为
int *p = (int *)malloc(sizeof(int)*length);
  • 类型转换    malloc返回的是void类型,所以在调用malloc的时候,需要显示的对类型进行转换
  • malloc函数并不知道申请的内存类型,只关心内存的总字节数
void free(void *memblock)
如果p不是NULL指针,那么连续free p两次会导致程序运行错误。

4、new/delete用法
运算符new使用起来比malloc简单
int *p2 = new int[length];
因为new内置了sizeof、类型转换和类型安全检查等功能。对于非内部数据类型对象,new在创建动态对象的同事完成了初始化工作,如果对象有多个构造函数,俺么new的语句也可以有多种类型.

delete []objects;        //不能丢掉了[]

(size_t       size_t是标准C库中定义的,应为unsigned int,在64位系统中为 long unsigned int

1.6 智能指针

智能指针smart pointer是存储指向动态内存分配(堆)对象指针的类,用于生存期控制,能保证自动正确销毁动态分陪得对象,防止内存泄漏。
一种技术是:使用计数器(reference count)auto_ptr 即是一种常见的智能指针。
实现:
将一个计数器与类指向的对象关联,引用计数跟踪类有多少个对象指向同一指针。
  • 每次创建类的新对象时,初始化指针并将引用计数置为1;
  • 当对象作为另一对象的副本而创建时,拷贝构造函数拷贝指针并增加与之相应的引用计数;
  • 对一个对象进行赋值时,赋值操作符减少左操作数所指对象的引用计数(如果引用计数为减至0,则删除对象),并增加右操作数所指对象的引用计数
  • 调用析构函数时,构造函数减少引用计数(如果引用计数减至0,则删除基础对象)。


1.7 fork()

fork通过系统调用创建一个与原来进城几乎完全相同的进程,也就是两个进程可以做完全相同的事



1.8 GCC编译器的参数

GCC最基本的用法是∶gcc [options] [filenames]

  • -c 只编译,不链接成为可执行文件,编译器只是由输入的.c等源代码文件生成.o为后缀的目标文件,通常用于编译不包含主程序的子程序文件。
  • -o output_filename,确定输出文件的名称为output_filename,同时这个名称不能和源文件同名。如果不给出这个选项,gcc就给出预设的可执行文件a.out。
  • -g,产生符号调试工具(GNU的gdb)所必要的符号资讯,要想对源代码进行调试,我们就必须加入这个选项。
  • -O,对程序进行优化编译、链接,采用这个选项,整个源代码会在编译、链接过程中进行优化处理,这样产生的可执行文件的执行效率可以提高,但是,编译、链接的速度就相应地要慢一些。

  • .c为后缀的文件,C语言源代码文件;
  • .a为后缀的文件,是由目标文件构成的档案库文件;
  • .C,.cc或.cxx 为后缀的文件,是C++源代码文件且必须要经过预处理;
  • .h为后缀的文件,是程序所包含的头文件;
  • .i 为后缀的文件,是C源代码文件且不应该对其执行预处理;
  • .ii为后缀的文件,是C++源代码文件且不应该对其执行预处理;
  • .m为后缀的文件,是Objective-C源代码文件;
  • .mm为后缀的文件,是Objective-C++源代码文件;
  • .o为后缀的文件,是编译后的目标文件;
  • .s为后缀的文件,是汇编语言源代码文件;
  • .S为后缀的文件,是经过预编译的汇编语言源代码文件。


1.9 malloc kmalloc cmalloc realloc和new的区别

相关原型:

#include <stdlib.h>void *malloc(*size_t size);void *calloc*size_t nmemb, size_t size);void free(void *ptr);void *realloc(void *ptr, size_t size);

  • malloc
用于动态申请存储空间,不是关键字,是一个内存函数
malloc返回一块内存地址的指针,否则会返回NULL;
char *str;
str = (char *)malloc(15*sizeof(char));
  • calloc
calloc函数有两个参数,分别为元素的数目和每个元素的大小,这两个参数的乘积就是要分配的空间内存

char *str = NULL;
str = calloc(15, sizeof(char));
  • realloc
重新分配空间,上面已经分配malloc str为15,重新分配为
 str = realloc(str, 20);

总结:
malloc:动态分配size_t字节空间
calloc:动态分陪n个连续的size字节空间,返回第一个指针,参数个数 大小
realloc:重新定义指针指向空间
free释放


1.10 size_t

size_t就是unsigned int类型,要注意,下面这段代码就会执行错误,因为for循环判断条件i>0 命名应该无限循环的,为什么这个循环会停止呢?
#include <iostream>#include <cstdint>#include <cstring> int main(){    size_t i= 10;    for(i = 10; i<0; i--) {        std::cout << i;    }}

1.11 sizeof和strlen
sizeof可以检测数组或者类的大小,但是strlen只能检测字符串的大小,并且strlen不包含'\0'
sizeof是运算符,strlen只是函数









原创粉丝点击