memcpy须确保没有重叠区域,memmove无此规则。
restrict可用于指针,表明指针是访问一个数据对象的唯一且初始的方式。
例子:
int ar[10];
int* restrict restar = (int )malloc (10*sizeof(int));
int *par = ar;
int n;
for(n=0;n<10;n++){
par[n]+= 5;
restar[n]+= 5;
ar[n] *= 2;
par[n] += 3;
restar[n] +=3;
}
restar是访问它所指向数据块的唯一初始方式,编译器可以用具有同样效果的一条语句来代替包含restar的两个语句:
restar[n] += 8;
而将两个par语句精简为一个语句将导致计算错误。
int *risks[10]; //具有10个元素的数组,每个元素是一个指向int的指针
int (*rusks)[10]; //一个指针,指向具有10个元素的int数组
int *off[3][4]; //一个3*4的数组,每个元素是一个指向int的指针
int (*uuf)[3][4]; //一个指针,指向3*4的int数组
int (*uof[3])[4]; //一个具有3个元素的数组,每个元素是一个指向具有4个元素 //的int数组的指针
位字段:在结构体中声明每个字段的宽度。只能是signed,unsigned,int类型。
如果有位字段的数据类型是signed,第一位符号位,以补码的形式读出数据。
可变宏:...和_ _VA_ARGS_ _
例:#define PR(...) printf(_ _VA_ARGS_ _)
#undef指令取消定义一个给定的#define
预定义宏:
__DATE__:日期
__FILE__:当前源代码文件名的字符串文字
__LINE__:当前源代码文件中的行号的整数常量
__TIME__:时间
__func__:当前函数名
在绝大多数机器里,程序将使用一个运行时堆栈,它用于存储函数的局部变量和返回地址。
注释会被预处理器拿掉,取而代之的是一空格。
如果内层代码块有一个标识符的名字与外层代码块的一标志符同名,内层的那个标识符就将隐藏外层的标识符,外层的标识符无法在内层代码块中通过名字访问。
如果某个操作符的各个操作属于不同类型,那么除非其中一个操作数转换为另外一个操作数的类型,否则操作无法进行。下面层次体系称为寻常算术转换:
long double
double
float
unsigned long int
long int
unsigned int
int
如果某个操作数的类型在上面这个列表中的排名较低,那么它首先将转换为另外一个操作数的类型然后执行操作。
左值意味着一个位置,而右值意味着一个值,所以,在使用右值的地方也可以使用左值,但在需要左值的地方不一定能使用右值。
风格良好的程序会在指针解引用之前对它进行检查,这种初始化策略可以节省大量的调试时间。
数据不等于指针,下标不会比指针更有效率,但指针有时会比下标更有效率。
声明为寄存器变量的指针通常比位于静态内存和堆栈中的指针效率更高。
当一个函数被调用时,编译器如果无法看到它的任何声明,那么它就假定函数返回一个整型值。对于那些返回值不是整型的函数,在调用之前对它们进行声明是非常重要的,这可以避免由于不可预测的类型转换而导致的错误。对于那些没有原型的函数,传递给函数的实参将进行缺省参数提升,char和short类型的实参被转换为int类型,float类型的实参被转换为double类型。
Int matrix[3][10];
func2(matrix);
这里,参数matrix是指向包含10个整型元素的数组的指针,应该一下任何一种:
void func2( int (*mat)[10] );
void func2( int mat[][10] );
不能把fun2的原型写成:void fun2( int **mat);
把mat声明为一个指向整型指针的指针,和指向整型数组的指针是不一样的。
If( strlen( x) – strlen (y) >=0)永远为真。strlen的结果是个无符号数,strlen返回一个类型为size_t的值,size_t为unsigned int型。所以>=左边的表达式也将是无符号数,绝不为负数。
使用strcpy时,必须保证目标字符数组的空间足以容纳需要复制的字符串。如果字符串比数组长,多余的字符仍被复制,它们将覆盖原先存储于数组后面的内存空间的值,strcpy无法解决这个问题,它无法判断目标字符数组的长度。
不要试图自己编写功能相同的函数来取代库函数。
使用字符分类(isupper之类)和转换函数(tolower之类)可以提高函数的移植性。
向函数传递结构体时,传递指针效率更高,函数名被使用时总是由编译器把它转换为函数指针。
fgetc和fputc都是真正的函数,但getc、putc、getchar和putchar都是宏。