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
,比如浮点转换