2009年2月18日星期三

C语言备忘知识点

一个整常量后面加上u或U,就表示此常量为无符号数。如12345u或12345U,则计算机就会在内存里按unsigned int规定的方式来存放。

如果是-12345u,那么计算机会先将-12345转换为其补码形式53191,然后再按无符号数形式存放。
如果一个整常量后面加字母l或L,则表示为long int型常量。

当计算机遇到一个小数,则会先将它转换成一个双精度数据存储(64位),虽然提高了精度,但这样运算速度就会降低。所以如果我们更注重运算速度,可以在小数后面加上f或F,来告诉计算机按单精度处理,不要转换为双精度数。

在不同类型数据的混合运算中,有一些隐蔽的规则:

1 char和short是必须先转换为int才可以进行运算的。
2 float一律转换为双精度型再进行运算,即使是两个float型数据相加,亦是如此。
3 如果int和double进行运算,那么int先转换成double,然后两个double进行运算
4 如果int和unsigned int进行运算,那么int要先转换为unsigned int,然后两个unsigned int进行运算
5 这些类型转换是由系统自动完成的。

在强制类型转换时,得到的是一个所需类型的中间变量,原来变量的类型不会发生变化,如(double)(x),x的类型本身不会变化。

单目运算符包括:!,~,++,–,-,(type),*,&,sizeof
单目运算符的优先级仅次于(),[],->,.这四个(并非真正意义上的)运算符。
单目运算符的结合性是自右向左。如-i++,即-(i++);如*i++,即*(i++)。

C编译系统会使用贪心法来识别运算符,如 i+++j,会被理解为(i++)+j

逗号表达式形如:表达式1,表达式2
逗号表达式的值是表达式2的值。

由于赋值运算符的优先级高于逗号运算符,所以a=3*5,a*4被理解为(a=3*5),a*4

逗号运算符基本上是优先级最最低的一个运算符,而赋值运算符基本上是排在倒数第二。(逗号全班倒数第一。赋值全班倒数第二,呵呵),你一定想知道倒数第三是谁,告诉你,条件运算符,也就是C中唯一的三目运算符"?:"。

C语言提供的关系运算符有6种:
<, <=, >, >=, ==, !=,其中前四种的优先级要高于后两种。

C语言提供3种逻辑运算符:
&&,||,!,这三种优先级各不相同,!优先级最高,&&次之,||优先级最低。而且更复杂的是,&&和||的优先级低于关系运算符,而!高于算术算符

总结起来就是:
逗号运算符<赋值运算符<||<&&<关系运算符<算术运算符<!

具有自右向左结合性的运算符都包括:赋值运算符,单目运算符和条件运算符。如a>b?a:c>d?c:d,即a>b?a:(c>d?c:d)

scanf函数会以空格来作为结束符。所以scanf("%s",str)的话,

如果输入是how are you? 那么最后str中存入的只有how。这点要特别注意。

共用体的定义为:
union 共用体名称
{
成员列表;
}变量列表;

例如:
union data
{
int i;
char ch;
float f;
}a,b,c;

共用体变量所占的内存长度是最长的成员的长度。

在引用共用体变量时应十分注意当前存放在共用体变量中的究竟是哪一个成员。
&a、&a.i、&a.ch、&a.f都是同一个地址值。
不能对共用体变量名赋值,也不能企图引用变量名得到一个值,更不能在定义共用体时对它初始化。


位段的概念非常重要,在编写网络程序常会用到。

struct packet_data
{
unsigned a:2;
unsigned b:6;
unsigned c:4;
unsigned d:4;
int i;
}data;

当然也可以不恰好占满一个字节,如

struct packet_data

unsigned a:2;
unsigned b:3;
unsigned c:4;
int i;
}data;

这样的话a,b,c会占去2字节中的前9位,而后7位会空闲下来,而i会从另一个新字节开头开始。

在引用位域时,要特别注意其最大值范围,如占2位,那么最大值为3.

位段成员的类型只能指定为unsigned int或int型。

若要强制一个域从新字节开始,那么可以这样:
unsigned a:1;
unsigned b:2;
unsigned :0;
unsigned c:3;

此时c会从一个新字节开始存储。

位段可以用%d来输出。

可以定义无名位段,表示这些位我不用:

unsigned a:1;
unsigned :2; //这两位空间不使用
unsigned c:3;

没有评论: