TCP/IP 协议:赞
https://www.jianshu.com/p/9f3e879a4c9c
子网掩码:
https://baike.baidu.com/item/子网掩码/100207
路由:
https://blog.csdn.net/qq_29344757/article/details/78585296
https://blog.csdn.net/qq_37506868/article/details/79497433
socket编程:
https://www.cnblogs.com/jikexianfeng/p/5729168.html
new/delete和malloc、free的用法和区别:
https://www.cnblogs.com/maluning/p/7944231.html
函数指针和指针函数的区别
https://www.cnblogs.com/hwli/p/9831114.html
1、全局变量存在静态储存区,局部变量存在栈区,动态申请的变量存在堆区。
2、查看一个整数的二进制表达中有几个1,可用x&(x-1)。
每执行一次x = x&(x-1),会将x用二进制表示时最右边的一个1变为0,因为x-1将会将该位(x用二进制表示时最右边的一个1)变为0。
程序:
int func(int x)
{
int countx = 0;
while(x)
{
countx++;
x = x&(x-1);
}
return countx;
}
3、a++和++a的区别
a++是先执行,后自加1;++a是先自加1,再执行
int a=1, b=1;
printf("%d\n", a++); #输出1
printf("%d\n", ++b); #输出2
4、for循环执行顺序
for(a; b; c)
do_sth;
符合b条件,则执行循环体do_sth,执行完后,返回执行c操作;再判断c条件
eg:
解析:①初始化a=0, b=0;
②a<=1,x的非为1,符合循环条件
③x++后x自增为1.
④进入循环体,a++,a自增为1
⑤执行for循环中的a++操作,a自增为2
⑥a为2,a<=1不符合,所以&&后的“!x++”不执行,x还为1,不执行循环体
⑦所以最后,a=2,x=1
5、C中printf压栈顺序
输出结果为:3, 3, 1
C中printf计算参数时,是从右向左压栈的,从右向左运算,第一个是*(ptr++),先打印*ptr=1,然后ptr++后,*ptr=2;
然后是*(++ptr),ptr++后,打印*ptr=3;
最后打印*ptr=3。
6、逻辑左移、算术左移、逻辑右移、算术右移(优先级小于加法+)
如果操作数是无符号数即是逻辑移位,如果操作数是带符号数,是算术移位。
逻辑左移,算术左移,逻辑右移都是普通的补0;
算术右移的最右边需要补原符号位。
7、内核启动流程图
流程图来自:https://blog.csdn.net/perfect1t/article/details/81741531
8、预编译、编译、汇编、链接
预编译:gcc -E test_const.c -o test_const.i
编译:gcc -s test_const.c -o test_const.s
汇编:gcc -c test_const.c -o test_const.o
链接:gcc test_const.o -o test_const
预编译主要处理带“#”号的语句,①删除#define,展开宏定义;②处理条件预编译;
③处理#include,把包含的“.h”插到对应位置;④删除注释//,/* */;⑤添加行号和文件标识符;
⑥保留#programa编译器命令。设定编译器状态,指示编译器完成一些特定的动作。
9、malloc/free和new/delete区别
malloc/free是库函数,new/delete是C++运算符。
10、static关键字作用
在函数内定义的静态局部变量,该变量存在于静态存储区,即使函数运行结束,静态变量的值也不会被销毁。
在函数外定义的静态变量,他的作用域只能在定义该变量的文件中,不能被其他文件extern引用。
静态函数只能在声明它的源文件中引用。
11、const关键字作用
①修饰指定的变量不能被修改
const int a = 5;/*a的值一直为5,不能被改变*/
const int b; b = 10;/*b的值被赋值为10后,不能被改变*/
int const *ptr;
const int *ptr; /*ptr为指向整型常量的指针,ptr的值可以修改,但不能修改其所指向的值*/
int *const ptr;/*ptr为指向整型的常量指针,ptr的值不能修改,但可以修改其所指向的值*/
const int *const ptr;/*ptr为指向整型常量的常量指针,ptr及其指向的值都不能修改*/
总结:若const位于*号左侧,则const修饰的是指向的变量;若const位于*号右侧,则const修饰的是指针不可修改;
所以int const* ptr和const int *ptr情况一样。
②修饰函数形参,形参只能在调用时赋值,不能在函数体内修改。
③修饰函数返回值不能被修改。如键盘输入的值const *str=getstr();
④类的有些成员函数不改变成员变量,只获取成员变量,是“只读”函数,这时可把该成员函数加上const进行标识。
eg:
class Point
{
int xVal, yVal;
public:
int GetY() const;
}
int Point::GetY() const //实现时也必须一样的方式,后面加const
{
return yVal;
}
只读函数既不能改变yVal的值,也不能调用会改变yVal的函数,只能调用const函数。
不能把const放在前面,那样就返回值变成了固定的,意义不同了。
12、switch(表达式)…case语句
switch 后面括号内的“表达式”必须是整数类型。也就是说可以是 int 型变量、char 型变量,也可以直接是整数或字符常量,哪怕是负数都可以。但绝对不可以是实数,float 型变量、double 型变量、小数常量通通不行。
case语句后面若是不加break,当符合条件的case出现而后面没跟break,后面的case语句会一直执行完才会跳出break。
13、#define宏定义时注意加括号,否则可能会出错
eg:#define SUB(x,y) x-y SUB(3,3)*5预编译时展开为(3-3)*5
#define SUB(x,y) (x-y) SUB(3,3)*5预编译时展开为3-3*5
#define一下一年中的秒数,
#define SECONDS_PER_YEAR (60*60*24*365)UL (以防十六位的机器会整形溢出,用长整型L,无符号长整型UL)
14、内联函数inline和宏定义差别
内联函数使用场景:①一个函数被不断重复调用;②函数只有简单几行,且不包含for,while,switch语句。
inline关键字要放在函数的定义实现前,而不是函数声明前。
内联函数inline在编译的时候,直接嵌入到目标代码中,不需要中断调用跳转。宏只是简单的替换。
内联函数要做参数类型检查,宏不做类型检查,所以内联函数更安全。
内联函数和宏都是用增加空间消耗来换取效率的提高。
15、函数指针和指针函数
函数指针的实质是指向函数的指针;int (*pfun)(int x, inty)
指针函数的实质是一个返回指针的函数;int *pfun(int x, int y)
参考链接:https://blog.csdn.net/lincoln_2012/article/details/49179503