C语言查漏补缺
一、基本知识点
1、sizeof
1)sizeof()返回长度,以字节为单位
2)sizeof(n) 判断表达式的长度并不需要对表达式进行求值,所以sizeof(a=b+1)并没有向a赋任何值.
int b = 3;
int a = 0;
printf("sizeof a: %d \n", sizeof(a=b+3)); /*sizeof 并不会计算*/
printf("a=%d\n", a);/* 输出a=0*/
3)sizeof计算数组
- a.int a[10]; sizeof(a) 返回数组长度*sizeof(int)
- b.数组作为函数参数会退化为指向数组首元素的指针
int caculateArraySize(int arr[])
{
return sizeof(arr); /*输出为4*/
}
2、逗号操作符
将两个或多个操作符分隔开来,表达式自左向右逐个求值,整个逗号表达式的值就是最后那个表达式的值,如if(b+1, c/2, d>0),只要d>0,整个表达式的值为真
3、运算符的优先级
- 1)任何一个逻辑运算符的优先级低于任何一个关系运算符
- 2)移位运算符的优先级比算数运算符要低,但比关系运算符要高
- 3)赋值运算符优先级低于条件运算符的优先级
4、指针
- 1)指针的指针
int a = 12;
int *b = &a;
int **c = &b; /*指向指针的指针*/
-
2)指向数组的指针
int (*p)[10];
-
3)指针数组
int *p[10];
5、结构体
- 1)结构的自引用
struct SELF_REF {
int a;
struct SELF_REF *b;
int c;
};
- 2)结构体对齐
a. 基本概念
1)数据类型自身的对齐值:对于char型数据,其自身对齐值为1,对于short型为2,对于int,float,double类型,其自身对齐值为4,单位字节
2)结构体或者类的自身对齐值:其成员中自身对齐值最大的那个值
3)指定对齐值:#pragma pack (value)时的指定对齐值value
4)数据成员、结构体的有效对齐值:自身对齐值和指定对齐值中小的那个值
b. 规则
1)在结构体中,所有的成员的偏移量(结构体成员的地址-结构体的首地址 = 偏移量)必须是该成员大小的整数倍。 也就是说成员的起始地址取余它大小为0
2)结构体的总大小必须可以整除最宽基本成员
3)如果结构体中,内嵌了构造类型(枚举,数组,结构体,共同体),那么这个结构体是按照其成员来对齐的(结构体拆除一个个对齐)
4)每个特定平台上编译器都有自己的默认的对齐系数(对齐模数),#pragma pack(n);//n=1,2,4,8,16,其中n就是你想要指定的系数
struct A{
char a; //起始地址0x0000,1个字节
int b; //起始地址0x0004, 4个字节,a补齐3个字节
short c; //起始地址0x0008,2个字节,必须为最宽成员的整数倍,补齐2个字节
};
//sizeof(A):12 总大小必须为最宽成员的整数倍
struct B{
int a; //起始地址0x0000,4个字节
char b; //起始地址0x0004, 1个字节,补齐1个字节
short c; //起始地址0x0006, 2个字节
};
//sizeof(B):8 总大小必须为最宽成员的整数倍
6、联合体
- 1)联合体确认CPU大小端
int CheckCPU(void)
{
union w
{
int a;
char b;
}c;
c.a = 1;
return (c.b==1);
} //返回值: 0 为大端模式, 1 为小端模式
- 2)大小端转换
uint32_t swap_endian(uinte32_t &val){
val = ((val << 8)&0xFF00FF00) | ((val >> 8)&0x00FF00FF);
return (val << 16) | (val >> 16);
}
7、堆内存
只要是连续的内存空间,都能使用下标的方式访问内存
int *p = malloc(sizeof(int) * 5);
for (int i = 0; i < 5; ++i)
{
p[i] = i;
}
二、陷阱与缺陷
-
1、词法分析的贪心法
规则:每一个符号应该包含尽可能多的字符
-
2、语法分析
(void ) ( )( ) )0 — 指向返回值为void的函数的指针 ((void()( ))0)( ) 可以替换为
(* fp)( )*,fp为函数指针,*fp就是该指针所指向的函数,所以(*fp)( )就是调用该函数的方式 -
3、语义陷阱
C语言中只有一维数组,而且数组大小必须在编译期就作为一个常数确定下来,数组中的元素可以是任何类型的对象,当然也可以是另外一个数组
三、Function
- 1、定时器实现
//等待60秒
time_t start, current, end;
time(&start);
printf("start time:%s \n",ctime(&start));
do{
time(¤t);//设置当前时间
}while((current-start) != 60);
time(&end);
printf("end time:%s \n",ctime(&end));
- 2、strlen
size_t strlen(char *string){
int length = 0;
while(*string++ != '\0')
length++;
return length;
}