
volatile
易变值,防止编译器优化使用原值的临时备份,每次使用必须要重读原值。临时备份可能被放在工作寄存器中临时使用,而原值可能被中断修改,通常与中断相关变量使用
switch
struct
enum
可以用枚举代替的魔法数尽量用枚举代替,这不光有利于代码的可读性和移植性,还将在调试时带来可见的好处
[]结合方向:从左向右,如[2][3]表示两个元素,每个里面又包含三个子元素char ip[] = "hello";
int main(void)
{
char** a;
char* c;
char* d;
char*** g;
c = ip; //一级指针初始化
a = &c; //二级指针初始化
d = (char*)&a; //一级指向二级
g = (char***)&*d; //三级指向一级
printf("%s\r\n",*a);
printf("%s\r\n",**g);
return 0;
}
*号的位置并不敏感//以下定义等效
char* a;
char *a;
char * a;
char*a;
//单行声明多个指针变量
char *a,*b;
char **a,**b;
//声明只读的二级指针pp,其指向的一级指针和其一级指针指向的内容均为只读
//声明一个可读写的二级指针cc,其指向的一级指针可读写,其指向的一级指针指向的内容只读
//ss为任意的合法值初始化只读内容
char const*const*const pp=ss, **cc=ss;
特别的
ii,如果只用变量强转,解析一个uint16_t类型,则需要使用接收顺序的后一个字节;如果使用指针强转,则需要使用接收顺序的前一个字节,我感觉使用指针更符合常规思维方式。uint8_t ii[] = {0x00,0x00,0x02,0x00};
int main() {
printf("%d\r\n",(uint16_t)ii[1]); //向左结合
printf("%d\r\n",*(uint16_t*)&ii[1]); //向左结合
return 0;
}

允许重复声明,不建议这样做,应该没有任何好处
ASCII和gb2312编码的识别:从起始位置开始,第一个字节第一位为1则用gb2312解释,为0则用ASCII解释
GBK兼容gb2312,是gb2312字符集的扩充
%.*s, *表示可用一个额外参数指定最大输出宽度,如3,hello表示hello仅输出3位,*也可直接用数值代替%f,double类型不需要使用%lf,但默认输出会损失精度,需要使用格式输出参数指定小数位数printf("\033[2J")这个可以清空终端内容类似system("clear")使用方式和printf很想,因为要给数据赋值,所以传参的时候传地址
""内部添加\换行符是不行的,可以把一个""换成两个,""\""这样就可以换行了,两个字符串也会自动拼接#pragma pack(push, 1)和#pragma pack(pop)中间即可,这个例子是按一个字节对齐__packed,v6已弃用union,比如浮点转换