01.C / CPP
C
一、文件操作函数,头文件为:stdio.h
1、fopen:FILE *file = fopen("file", "options"); options有" r / r+ / rb / rb+ / w / w+ / wb / wb+ / a / a+ / ab / ab+ / ab "。
2、fclose:int fclose(file); 关闭成功返回 0,否则返回EOF(-1)。
3、fgetc:int fgetc(FILE *file); 成功返回字符的ASCII码,失败或读到文件尾,返回EOF。
4、fputc:int fputc(int char, FILE *file); char为字符的ASCII码。
5、fgets:char* fgets(char *str, int (size+1), FILE *file); 成功返回str字符串,失败返回null。读取(size+1)-1个字符。
6、fputs:int fputs(const char *str, FILE *file);
7、getw:int getw(FILE *file); 成功返回读取的值,失败返回-1。读取数字,非ANSI标准函数。
8、putw:int putw(int num, FILE *file); 返回输出整数。如果出错,返回EOF。
9、fread:int fread(void *buf, size_t size, size_t num, FILE *file); size是单个类型大小(通常用sizeof计算),num是类型的个数(通常计算得出)。
10、fwrite:int fwrite(const void *buf, size_t size, size_t count, FILE *file);
11、fscanf:int fscanf(FILE *file, const char *format, ... ); 成功返回读取数据个数,失败返回 EOF,匹配失败返回0。
12、fprintf:int fprintf(FILE *file, const char *format, ... ); 类似printf。
13、ftell:long ftell(FILE *stream ); 获取文件指针的当前位置相对文件首的偏移字节数。文件大小不得大于2^31-1。
14、fseek:int fseek(FILE *file, long offset, int origin); offset小于0表示向前偏移。origin参数有三种:
①、SEEK_SET:从文件的开始位置定位,此时offset必须大于0
②、SEEK_CUR:从文件的当前位置定位
③、SEEK_END:从文件的结束位置定位,此时offset必须小与0
15、rewind:rewind(FILE *file); 等价于fseek(file, 0, SEEK_SET);
16、feof:int feof( FILE *fike); 程序到达文件末尾会返回非零值(真)。其判断标准通过读取函数fread/fscanf等返回错误来识别,判断位置应该在读取函数之后。
17、ferror:ferror(FILE *file); 检查调用输入输出函数中的错误。返回值为0表示未出错。
18、clearerr:void clearerr(FILE *file); 清除文件错误标志。
二、结构体与链表
结构体三连要注意链表节点的分配与销毁。
三、数组和指针
1、指针数组:int *(arr[num]); []优先级高于*,所以括号可省略。本质是数组。
存放指针的数组。通过使用数组,达到调用指针的目的。
2、数组指针:int (*arr)[num]; 指向数组的指针。同样使用(*ptr)[num]调用。
3、指针函数:int *(func(param)); 本质是函数,括号可省略。其返回值是指针。
4、函数指针:int (*func)(param); func就是指向函数的指针,用于调用函数、做函数的参数。函数的返回类型此时为int。
指针类型必须和其指向的函数类型一致。一般用typedef定义函数指针,否则当其作为参数或返回值时,可能编译不过。
typedef void(*ptrfunc)(int);
ptrfunc ptr = funcA; //调用函数
funcB(int a, void(* funcname)(int)) //做函数参数,以供回调。funcname一般与ptrfunc同名方便书写。
char (*a[3])(int); a[3]:数组 => (*a[3]):指针数组 => (*a[3])(int):存放指向函数的指针的,指针数组 => char (*a[3])(int):返回值为char的,存放指向函数的指针的指针数组。
四、内存申请
1、malloc/free:申请使用完毕,使用free(ptr)释放。
2、malloc:void *malloc(size_t total_size); 申请长度为size的内存并返回起始地址。
3、calloc:void *calloc(size_t num, size_t size); malloc + memset,分配+清零。
4、realloc:void *realloc(void* ptr, unsigned newsize); 重新分配已分配了空间的指针,ptr不为空,newsize是重新申请的长度。
五、宏:先替换成符号,再计算
1、宏函数:__FILE__(宏所在文件的源文件名)。__FUNCTION__ (宏所在函数名)。__LINE__(宏所在行的行号)。__DATE__(代码编译的日期)。__TIME__(代码编译的时间)。
2、参数中的#与##:
①、用" # "作参数前缀:直接用传入参数的字符串,替换#修饰的参数,不进行计算。即便是另一个宏也不展开,仍作为字符串输出。
②、用" ## "参数连接:连接两个参数并去除参数间的空格和制表符。循环调用宏来替换时,仅替换最外层,其内所有的宏都属于未定义,输出时直接使用传入的字符串。
3、宏定义使用do{...}while(0)格式构造。构造后的宏定义不会受到大括号、分号等的影响,总是会按你期望的方式调用运行。不会发生语法或逻辑错误,增强了适应性、扩展性、灵活性。
六、__attribute__
1、语法:__attribute__((attr_list)) 。可参考 https://www.jianshu.com/p/e2dfccc32c80 和 https://www.cnblogs.com/XuChengNotes/p/10397528.html
2、是编译器指令,告诉编译器声明的特性,或让编译器进行更多的错误检查和高级优化。其可分为:函数属性(Function Attribute )、变量属性(Variable Attribute )和类型属性(Type Attribute)等。
①、函数属性:noreturn / noinline / always_inline / pure / const / nothrow / sentinel / format / format_arg / no_instrument_function / section / constructor / destructor / used / unused / deprecated / weak / malloc / alias / warn_unused_result / nonnull 。下面列举出常见属性:
format(archetype, string-index, first-to-check):按照参数表格式规则对该函数的参数进行检查。例如linux源码里的函数device_create()和class_device_create() 。
archetype:格式( printf / scanf / strftime / strfmon)。
string-index:指定传入函数的第几个参数是格式化字符串。
first-to-check:指定从函数的第几个参数开始按上述规则进行检查。
noreturn:该属性通知编译器函数从不返回值。当遇到函数需要返回值却还没运行到返回值处就已退出来的情况,该属性可以避免出现错误信息。
constructor / destructor:自动执行该函数在(main() 函数执行之前 / exit() 函数调用之后) 被自动的。被修饰的函数经常隐式的用在初始化程序。
②、变量属性:address / aligned / boot / deprecated / fillupper / far / mode / near / noload / packed / persistent / reverse / section / secure / sfr / space / transparent_union / unordered / unused / weak 。
③、类型属性:aligned / packed / transparent_union / unused / deprecated / may_alias 。
CPP
一、命名空间:
1、虽然C++标准程序库中的所有标识符都被定义于一个名为std的namespace中,但尽量不要使用using namespace std,而使用std::xxx或者using std::xxx代替。有关using编译命令和using声明。他们增加了名称冲突的可能性。
2、const:C++编译器碰见常量声明时,在符号表中放入常量。编译过程中若发现使用常量,则直接以符号表中的值替换,但编译过程中若发现对const使用了extern或者&操作符,则给对应的常量分配存储空间(兼容C)。
一些语法:
C:
C++:
1、在字符串前加字母 'L' 作用:表示将ANSI字符串转换成unicode字符串,即每个字符占用两个字节。
2、 __cplusplus 用来表示是否C++编译器,而 __STDC__ 用来表示是否支持 ANSI C,当要求程序严格遵循 ANSIC 标准时,就会赋值标识符 __STDC__ 为1。一些C++编译器中预先定义了__STDC__,但是处值设置为0。(和编译器相关,我试了一下,在VC2003中没有预订义__STDC__)。在C++里面写C要加上 extern "C " {}进行说明,它指示编译器生成符号表时不改变标识符的名字。