1.静态链表中指针表示的是数组下标
在某些语言中指针是不被支持的,只能使用数组来模拟线性链表的结构.在数组中每个元素不但保存了当前元素的值,还保存了一个”伪指针域”,一般是int类型,用于指向下一个元素的内存地址.
这种链表在初始时必须分配足够的空间, 也就是空间大小是静态的, 在进行插入和删除时则不需要移动元素, 修改指针域即可,所以仍然具有链表的主要优点(快速插入和删除).
有些高级语言中没有“指针”数据类型,只能用数组来模拟线性链表的结构,
数组元素中的指针“域”存放的不是元素在内存中的真实地址,而是在数组中的位置。这样的链表
称为静态链表。
静态链表:把线性表的元素存放在数组的单元中(不一定按逻辑顺序连续存放),每个单元不仅存放元素本身 ,而且还要存放其后继元素所在的数组单元的下标(游标)。
线性表的静态单链表存储结构 :
#define MAXSIZE 100;
typedef struct{
ElemType data;
int cur;
}component,SLinkList[MAXSIZE];
2.进程与线程
进程:
进程是一个具有一定独立功能的程序的一次运行活动,同时也是资源分配的最小单元;
进程是程序执行时的一个实例,即它是程序已经执行到某种程度的数据结构的汇集。
从内核的观点看,进程的目的就是担当分配系统资源(CPU时间、内存等)的基本单位。
线程是进程的一个执行流,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。
一个进程由几个线程组成(拥有很多相对独立的执行流的用户程序共享应用程序的大部分数据结构),线程与同属一个进程的其他的线程共享进程所拥有的全部资源。
"进程——资源分配的最小单位,线程——程序执行的最小单位"
进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。
线程有自己的堆栈和局部变量,但线程没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。
进程有独立的地址空间,线程没有单独的地址空间(同一进程内的线程共享进程的地址空间)。
3.TCP协议
TCP是重要的传输层协议,目的是允许数据同网络上的其他节点进行可靠的交换。它能提供端口编号的译码,以识别主机的应用程序,而且完成数据的可靠传输TCP 协议具有严格的内装差错检验算法确保数据的完整性TCP 是面向字节的顺序协议,这意味着包内的每个字节被分配一个顺序编号,并分配给每包一个顺序编号
UDP也是传输层协议,它是无连接的,不可靠的传输服务.当接收数据时它不向发送方提供确认信息,它不提供输入包的顺序,如果出现丢失包或重份包的情况,也不会向发送方发出差错报文.由于它执行功能时具有较低的开销,因而执行速度比TCP快
特点:
1.面向连接
双方必须先建立连接才能进行数据的读写,双方都必须为该链接分配必要的内核资源,以管理连接的状态和连接上的传输
TCP连接是全双工的,双方数据传输可以通过一个连接进行,完成数据交换后,双方必须断开连接,以释放系统资源,这种连接是一对一的,不适用于广播和多播的应用程序,基于多播和广播的应用程序适合使用UDP协议。
2.基于字节流
TCP字节流服务
(1)字节流:
发送端执行多次写操作时,TCP模块必须先把这些数据放入TCP发送缓冲区中,当TCP模块真正发送数据时,才把TCP发送缓冲区等待发送的数据封装成一个或多个TCP报文段发出
—TCP模块发出的报文的个数与应用程序的写操作的次数没有固定的数量关系
接收端收到报文段后,TCP模块必须把它们携带的应用数量按照TCP报文段的序号依次放入TCP接收缓冲区中,同时通知应用程序读取数据,接收端应用程序可以一次或多次读取数据(取决于用户指定的应用程序读缓冲区大小)
—应用程序执行读操作的次数和TCP模块接收到的TCP报文的个数没有固定的数量关系
*发送端执行的写操作次数与接收端执行的读操作次数没有数量关系
*应用程序对数据的发送和接收没有边界限定的,这也是字节流的概念
(2)数据报:
UDP数据报服务
UDP发送应用端程序执行一次写操作,UDP模块把它封装成一个UDP数据报并发送
接收端针对每一个数据报执行读操作,否则就会发生丢包,并且用户没有指定足够的应用程序缓冲区来读取数据报,则UDP数据报就会被截断
**通过以上可以理解:
字节流和数据报区别:通讯双方是否执行相同次数的读写操作
3.可靠传输
支撑TCP传输的可靠机制:
TCP采用发送应答机制。TCP发送的每个报文段都必须得到接收方的应答才认为这个TCP报文段传输成功
超时重传。发送端发出一个报文段之后就启动定时器,如果在定时时间内没有收到应答就重新发送这个报文段
TCP报文段最终是以IP数据报发送的。IP数据报到达接收端可能乱序重复,TCP协议对接收到的TCP报文段重排整理后再交给应用程序
**UDP数据报提供的是不可靠的服务,它们都需要上层协议处理数据的确认和超时重传
4.const的含义与作用
1.欲阻止一个变量被改变,可使用const,在定义该const变量时,需先初始化,以后就没有机会改变他了;
2.对指针而言,可以指定指针本身为const,也可以指定指针所指的数据为const,或二者同时指定为const;
3.在一个函数声明中,const可以修饰形参表明他是一个输入参数,在函数内部不可以改变其值;
4.对于类的成员函数,有时候必须指定其为const类型,表明其是一个常函数,不能修改类的成员变量;
5.对于类的成员函数,有时候必须指定其返回值为const类型,以使得其返回值不为“左值”。
5.const与#define相比,有何优点
1)const常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检查。而对后者只进行字符替换,没有类型安全检查,并且在字符替换可能会产生意料不到的错误。
2)有些集成化的调试工具可以对const常量进行调试,但是不能对宏常量进行调试。
6.什么是预编译,何时需要预编译
什么是预编译:
预编译又称为预处理 , 是做些代码文本的替换工作。
处理以# 开头的指令 , 比如拷贝 #include 包含的文件代码,#define 宏定义的替换 , 条件编译等,就是为编译做的预备工作的阶段。
主要处理#开始的预编译指令,预编译指令指示了在程序正式编译前就由编译器进行的操作,可以放在程序中的任何位置。
C 编译系统在对程序进行通常的编译之前,首先进行预处理。
c 提供的预处理功能主要有以下三种:
1 )宏定义
2 )文件包含
3 )条件编译
何时需要预编译:
总是使用不经常改动的大型代码体。
程序由多个模块组成,所有模块都使用一组标准的包含文件和相同的编译选项。在这种情况下,可以将所有包含文件预编译为一个“预编译头”
7.在c++程序中调用被c编译器编译后的函数,为什么要加extern "c"