|
寥寥数笔,记录我的C语言盲点笔记,只为曾经经历过,亦有误,可交流。
1.implict declartion of function 指的是在预处理时没有函数的申明,但该函数在别的函数中进行了编译与调用,编译可以完成链接但是会给出warning,需要提前申明
2. sizeof是一个operand操作符,不能直接对其进行&取地址操作。是一个编译器自动算大小的函数,在预处理时。和宏定义有所类似。sizeof当然不是函数,它是编译的时候处理的
编译时,编译器推断出sizeof参数的类型,sizeof根据这个类型确定一个整数,所以它可以当常量使用
函数肯定不能当常量使用,函数只能运行时求值
3.1.C语言中,对结构体指针赋值为NULL时,在未对其进行再次修改前,不允许对该结构体取值,因为NULL=0,取0处的内容,程序运行时会出现段错误Segmentation fault,不要对NULL地址取值。这个错误使得在调用需要指针的函数的最好不要传入指针变量,除非自带获取过一个地址如malloc,calloc等,不然这个地址默认是0,一旦在函数内部发生取值赋值时,就会出现段错误。段错误往往是有对内存的不正当操作引起,使的程序在运行是侵占内存,系统检测到后强制终止程序运行,以防止系统死机。
2.在使用malloc使要确定是否分配所需的内存大小,不然程序访问超出的那些内存时往往不在是你原本想象的数值,系统已经将这些内存自我实现了回收机制,只留下你申请的那部分。也许你能再次访问到这块内存,但是最终的结果肯定是内存已经回收清空,系统这样做的好处就是看不是堆内存链表中的区域,自行回收,使系统更高效。
4.C语言中优良的
编程习惯#ifndef _H_FINGER_API_H_
#define _H_FINGER_API_H_
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
extern "C" }
#endif
这样的好处在于定义的头文件在一个c源文件中出现多次时,也不会出现重复的函数申明,同时这个也可以将c很方便的移植到c++去中去。
5 C语言中,对结构体指针赋值为NULL时,在未对其进行再次修改前,不允许对该结构体取值,因为NULL=0,取0处的内容,程序运行时会出现段错误Segmentation fault,
不要对NULL地址取值。
6,for(n = 0 ; n < nLen ; n++)和for(int n = 0 ; n < nLen ; n++)这两个的区别在与后者的n只能在for这个区域中生效,前者在整个函数域内有效。后者的n不能在for外部使用。c中前者的使用较为理想。C99的标准
7,函数间数据的传递也可以考虑使用memcpy来对临时缓存进行拷贝。但是要记得不能在函数内部把一个临时缓存区的地址覆给一个传入的指针变量。因为结束后这部发内容被清空,无意义(除非用malloc申请的内容)
8.全局变量可不可以定义在可被多个.C文件包含的.,h头文件中?为什么?恩,不可以在多个.c文件使用含有全局变量(已经定义即初始化)的.h文件,因为每个文件域都有了这个全局变量后。在编译连接时,编译器识别到两个全局变量并且都要分配地址,这样的话在放入全局变量区之前就出现连接报错。解决方法:1.在.h中申明为extern int a 或者在其他。c文件文件中声明extern int a。这样这个全局变量编译时就不会报错但是这个如果只有在一个.c文件中出现定义define或者初始化时,而其他.c只是申明的话,那么这个全局变量就不会报错。一般如果变量定义了就会分配内存的。出现多个申明,默认找已经定义的那个作为全局数值。2.对两个相同的变量都加static,就可以。因为只在自己的文件域内有效,在函数的用法也类似
关键是不允许在.h中定义的全局变量两赋初值(即定义)!,因为.h中赋值后,多个文件一旦使用,就相当与重复了两次变量的初始化赋值。这个不允许。
9.在编码中。在.h的头文件中养成只做函数和变量的申明。在.c文件中来具体实现,以及全局变量的定义等等。
10所有未加static前缀的全局变量和函数都具有全局可见性,其它的源文件也能访问
11Linux下面的文件换行符为\n(0x0a),区别于window下面的\n\r(两个字节)
Linux下面EOF 为-1二进制文件为0xff.(-1补码)EOF是文本文件结束的标志。window下在文本文件中,数据是以字符的ASCⅡ代码值的形式存放,普通字符的ASCⅡ代码的范围是32到127(十进制),EOF的16进制代码为0x1A(十进制为26),因此可以用EOF作为文件结束标志文本方式 和 二进制方式 的不同在于。
1. 文本方式只能读取不包括控制字符(换行除外)的文件 (<32)
2. 文本方式会对换行执行翻译。比如windows下,把文件中的/r/n翻译为/n,把写入文件的/n翻译为/r/n;unix下,把文件中的/n翻译为/n,把写入文件的/n翻译为/n。
12.传入函数的指针如果是需要使用的有必要对其进行NULL检测。13.C语言中的申明不一定只是申明,int a;
系统会给默认的定义值。但是定义int a=1,一定是定义。还有extern int a;则一定是申明,定义在其他地方,这里只是引用而已。加extern关键字的声明不是定义并且不分配内存(实际上声明是不分配内存的)。实际上,它只是宣称了已经在其它文件中定义的变量的名称和类型。一个变量可以声明多次,但是只能定义一次。声明只有在他同样是定义时才能初始化,因为只有定义才会分配内存
14。在使用数组或者某些结构体前,最好完成对其的初始化{0}.memset或者bzero等,因为在局部函数内部,编译器分配的栈空间,初始数值并不是为0.需要先初始化为需要的默认值,不然有可能对你后续程序有影响,而造成比如Segmentation fault(常常是对内存操作出现的错误比较操作的内容块小于分配的大小等等)
15missing braces around initialize该问题是在结构提中有多个数组在初始化时,没有对每一个进行初始化,从而会出现这个错误如typedef struct Usr_Info{
unsigned char ID[ID_LEN];
unsigned char Finger[FMD_LEN];
unsigned int finsih_flag;// 1:one usr info get finsihed
}USR_INFO;初始化USR_INFO one = {0},会出现警告,需要对每一部分的数组进行初始化,就这样{{0}.{0}.0}。C99的特点
16ANSI C说明了三个用于存储空间动态分配的函数
(1) malloc 分配指定字节数的存储区。此存储区中的初始值不确定
(2) calloc 为指定长度的对象,分配能容纳其指定个数的存储空间。该空间中的每一位(bit)都初始化为0
(3) realloc 更改以前分配区的长度(增加或减少)。当增加长度时,可能需将以前分配区的内容移到另一个足够大的区域,而新增区域内的初始值则不确定
17 a[]用作函数参数,会退化成指针,即和*a一样,这样写看上去上更明确一点
18,static申明的函数被同一文件内的函数调用后,这个非static的函数照样可以被其他文件的函数调用,从而可以说是间接的进行了调用static函数。
19,怎样打印long long型数 :printf("%I64u\n",a);或者%I64x.lld打印64位数据 |