1.引用和指针的区别:
(1)非空区别。引用在使用之前必须要初始化,在任何情况下都不能使用指向空值的引用。
(2)合法性区别。在使用引用之前不需要测试它的合法性。相反,指针则应该总是被测试,防止其为空。
(3)可修改区别。指针可以被重新赋值以指向另一个不同的对象。但是引用则总是指向在初始化时被指定的对象,以后不能改变,但是指定的对象其内容可以改变。
(4)使用区别。指针需要分配内存,引用不用;有const指针的修饰,引用没有。
2.结构体和类的区别:
c 与c++中结结构体的区别:
(1)C的结构体内不允许有函数存在,C++允许有内部成员函数,且允许该函数是虚函数。所以C的结构体是没有构造函数、析构函数、和this指针的。
(2)C的结构体对内部成员变量的访问权限只能是public,而C++允许public,protected,private三种。
(3)C语言的结构体是不可以继承的,C++的结构体是可以从其他的结构体或者类继承过来的。
C的结构体只是把数据变量给包裹起来了,并不涉及算法。而C++是把数据变量及对这些数据变量的相关算法给封装起来,并且给对这些数据和类不同的访问权限。
C++的结构体和C++类的区别
(1)C++结构体内部成员变量及成员函数默认的访问级别是public,而c++类的内部成员变量及成员函数的默认访问级别是private。
(2) C++结构体的继承默认是public,而c++类的继承默认是private。
3.malloc free 和new delete的区别
(1)操作对象不一样:malloc与free是C++/C 语言的标准库函数,new/delete 是C++的运算符。对于非内部数据类的对象而言,光用maloc/free 无法满足动
态对象的要求。对象在创建的同时要自动执行构造函数, 对象消亡之前要自动执行析构函数。由于malloc/free 是库函数而不是运算符,不在编译器控制权限之内,
不能够把执行构造函数和析构函数的任务强加malloc/free。
(2)使用new操作符申请内存分配时无须指定内存块的大小,编译器会根据类型信息自行计算。而malloc则需要显式地指出所需内存的尺寸。
(3)返回类型new操作符内存分配成功时,返回的是对象类型的指针,类型严格与对象匹配,无须进行类型转换,故new是符合类型安全性的操作符。而malloc内存
分配成功则是返回void * ,需要通过强制类型转换将void*指针转换成我们需要的类型。
(4)分配失败,new内存分配失败时,会抛出bac_alloc异常。malloc分配内存失败时返回NULL。
(5)自定义类型:new会先调用operator new函数,申请足够的内存(通常底层使用malloc实现)。然后调用类型的构造函数,初始化成员变量,最后返回自定义
类型指针。delete先调用析构函数,然后调用operator delete函数释放内存(通常底层使用free实现)。malloc/free是库函数,
只能动态的申请和释放内存,无法强制要求其做自定义类型对象构造和析构工作。
(6)重载:C++允许重载new/delete操作符,特别的,布局new的就不需要为对象分配内存,而是指定了一个地址作为内存起始区域,new在这段内存上为对象调用
构造函数完成初始化工作,并返回此地址。而malloc不允许重载。
(7)内存区域:new操作符从自由存储区(free store)上为对象动态分配内存空间,而malloc函数从堆上动态分配内存。自由存储区是C++基于new操作符的一
个抽象概念,凡是通过new操作符进行内存申请,该内存即为自由存储区。而堆是操作系统中的术语,是操作系统所维护的一块特殊内存,用于程序的内存动态分配,C
语言使用malloc从堆上分配内存,使用free释放已分配的对应内存。自由存储区不等于堆,如上所述,布局new就可以不位于堆中。
3.atoi函数的实现:
int my_atoi(char* pstr)
{
int Ret_Integer = 0;
int Integer_sign = 1;
/*
* 判断指针是否为空
*/
if(pstr == NULL)
{
printf("Pointer is NULL\n");
return 0;
}
/*
* 跳过前面的空格字符
*/
while(isspace(*pstr) == 0)
{
pstr++;
}
/*
* 判断正负号
* 如果是正号,指针指向下一个字符
* 如果是符号,把符号标记为Integer_sign置-1,然后再把指针指向下一个字符
*/
if(*pstr == '-')
{
Integer_sign = -1;
}
if(*pstr == '-' || *pstr == '+')
{
pstr++;
}
/*
* 把数字字符串逐个转换成整数,并把最后转换好的整数赋给Ret_Integer
*/
while(*pstr >= '0' && *pstr <= '9')
{
Ret_Integer = Ret_Integer * 10 + *pstr - '0';
pstr++;
}
Ret_Integer = Integer_sign * Ret_Integer;
return Ret_Integer;
}
4.冒泡排序:
void bubble_sort(int arr[], int len) {
int i, j;
for (i = 0; i < len - 1; i++) //外层循环控制趟数,总趟数为len-1
for (j = 0; j < len - 1 - i; j++) //内层循环为当前i趟数 所需要比较的次数
if (arr[j] > arr[j + 1])
swap(arr[j], arr[j + 1]);
}
5.int ,char,size_t在32/64位下分别占用
16位平台 最大2^16
char 1个字节8位
short 2个字节16位
int 2个字节16位
long 4个字节32位
指针 2个字节16位
32位平台 最大2^32
char 1个字节8位
short 2个字节16位
int 4个字节32位
long 4个字节32位
long long 8个字节64位
指针 4个字节32位
64位平台 最大2^64
char 1个字节
short 2个字节
int 4个字节
long 8个字节(区别)
long long 8个字节
指针 8个字节(区别)
size_t在32位系统中占4个字节,而在64位系统占8个字节
#define __SIZE_TYPE long unsigned int........................
typedef __SIZE_TYPE__ size_t;// 其实是无符号长整型
6.linux/window下的线程和进程怎么创建
对于windows来说,进程和线程的概念都是有着明确定义的,进程的概念对应于一个程序的运行实例(instance),而线程则是程序代码执行的最小单元。也就是说
windows对于进程和线程的定义是与经典OS课程中所教授的进程、线程概念相一致的。
提供API,CreateThread()用于建立一个新的线程,传递线程函数的入口地址和调用参数给新建的线程,然后新线程就开始执行了。
windows下,一个典型的线程拥有自己的堆栈、寄存器(包括程序计数器PC,用于指向下一条应该执行的指令在内存中的位置),而代码段、数据段、打开文件这些
进程级资源是同一进程内多个线程所共享的。因此同一进程的不同线程可以很方便的通过全局变量(数据段)进行通信,大家都可以对数据段进行读写,这很方便,也被
在安全性方面诟病,因为它要求程序员时刻意识到这些数据不是线程独立的。
对于linux来说,则没有很明确的进程、线程概念。首先linux只有进程而没有线程,然而它的进程又可以表现得像windows下的线程。linux利用fork()和exec函
数族来操作多线程。fork()函数可以在进程执行的任何阶段被调用,一旦调用,当前进程就被分叉成两个进程——父进程和子进程,两者拥有相同的代码段和暂时相同的数
据段(虽然暂时相同,但从分叉开的时刻就是逻辑上的两个数据段了,之所以说是逻辑上的,是因为这里是“写时复制”机制,也就是,除非万不得已有一个进程对数据
段进行了写操作,否则系统不去复制数据段,这样达到了负担最小),两者的区别在于fork()函数返回值,对于子进程来说返回为0,对于父进程来说返回的是子进程
id,因此可以通过if(fork()==0)…else…来让父子进程执行不同的代码段,从而实现“分叉”。
exec函数族的函数的作用则是启动另一个程序的新进程,然后完全用那个进程来代替自己(代码段被替换,数据段和堆栈被废弃,只保留原有进程id)。这样,如果在
fork()之后,在子进程代码段里用exec启动另一个进程,就相当于windows下的CreateThread()的用处了,所以说linux下的进程可以表现得像windows下的线程
。
然而linux下的进程不能像windows下线程那样方便地通信,因为他们没有共享数据段、地址空间等。它们之间的通信是通过所谓IPC(InterProcess
Communication)来进行的。具体有管道(无名管道用于父子进程间通信,命名管道可以用于任意两个进程间的通信)、共享内存(一个进程向系统申请一块可以被共
享的内存,其它进程通过标识符取得这块内存,并将其连接到自己的地址空间中,效果上类似于windows下的多线程间的共享数据段),信号量,套接字
创建线程:
#ifdef __GNUC__
//Linux
#include <pthread.h>
#define CreateThreadEx(tid,threadFun,args) pthread_create(tid, 0, threadFun, args)
#define CloseHandle(ph)
/*
int pthread_create(
//指向线程标识符的指针。
pthread_t *restrict tidp,
//设置线程属性。传入NULL表示使用默认。
const pthread_attr_t *restrict_attr,
//新线程所执行的线程函数地址。
void*(*start_rtn)(void*),
//传给线程函数的参数。
void *restrict arg
);*/
#else
//windows
#include <process.h>
#define CreateThreadEx(tid,threadFun,args) _beginthreadex(tid, 0, threadFun, args, 0, NULL)
/*
HANDLE WINAPI _beginthreadex(
//线程内核对象的安全属性,一般传入NULL表示使用默认设置。
LPSECURITY_ATTRIBUTES lpThreadAttributes,
//线程栈空间大小。传入0表示使用默认大小(1MB)。
SIZE_T dwStackSize,
//新线程所执行的线程函数地址,多个线程可以使用同一个函数地址。
LPTHREAD_START_ROUTINE lpStartAddress,
//传给线程函数的参数。
LPVOID lpParameter,
//指定额外的标志来控制线程的创建,为0表示线程创建之后立即就可以进行调度,如果为CREATE_SUSPENDED则表示线程创建后暂停运行,
//这样它就无法调度,直到调用ResumeThread()。
DWORD dwCreationFlags,
//返回线程的ID号,传入NULL表示不需要返回该线程ID号。
LPDWORD lpThreadId
);*/
#endif
7.multable的作用
在C++中,mutable 是为了突破 const 的限制而设置的。可以用来修饰一个类的成员变量。被 mutable 修饰的变量,将永远处于可变的状态,即使是 const 函数
中也可以改变这个变量的值。
8.http中的错误码分别代表是
https://blog.csdn.net/xiong9999/article/details/54138387
9.socket如何实现传输
https://blog.csdn.net/zhang___yong/article/details/78702559
10.TCP/IP协议有那几层
(1)应用层:应用程序通过这一层访问网络,常见 FTP、HTTP、DNS 和 TELNET 协议;
(2)传输层:TCP 协议和 UDP 协议;
(3)网络层:IP 协议,ARP、RARP 协议,ICMP 协议等;
(4)网络接口层:是 TCP/IP 协议的基层,负责数据帧的发送和接收。
https://blog.csdn.net/MXSKE/article/details/78279071
11.右值引用的用法,std::move
https://blog.csdn.net/booirror/article/details/45057689
12.char 和wchar_t的区别
char占一个字节,只能表示256个字符,类似与汉字这种字符char是无法表示的,wchar_t在我的64位机器上占4字节,用于表示更多的字符。
13.GBK,UTF-8,UTF-16一个字符占用多少个字节
https://www.cnblogs.com/wpcockroach/p/3907324.html
utf-8中文字符占三个字节,GB18030兼容GBK兼容GB2312中文字符占两个字节,ISO8859-1是拉丁字符(ASCII字符)占一个字节