1、数据类型的转换:
转换有两种:(1)自动转化:遵循一定的规则,有编译系统自动完成,自动转换规则:由低到高:char,short——>int——>unsigned——>long——>double<——float
(2)强制类型转换:把表达式的运算结果强制转换成所需要的数据类型,例如:(int)(a+b);把a+b的结果转化为整型
3、bool变量与“零值”进行比较
if( !b_test_flag )或者if(b_test_flag);
4、float变量与“零值”进行比较
if((f_test_val >= -0.00000001) && (f_test_val <= 0.00000001)
float和double类型的数据都是有精度限制的,这样直接拿来与0.0比,必须像上面语句那样
5、指针变量和“零值”进行比较
if(NULL == p); if( NULL != p);
6、case语句后面不要忘记加上break;
记住:case后面只能是整型变量、字符型、常量或者常量表达式
const修饰的数据不能用在case后面
7、循环语句的注意点:
(1)在多重循环中,如果有可能,应当将最长的循环放到最里面,最短的放到最外面,以减少CPU跨切循环层的次数。相对来说循环效率高
8、goto语句我主张的应该想内核一样使用:
在实现功能上尽量不要用,
例如:
int fun(void)
{
int i=0;
if(i == 0)
goto error;
else
{
......
}
error :
return -1;
}
9、const关键字也许该被替换为readolny
const是congstant的缩写,是恒定不点的意思,也翻译成常量、常数等。
基于这一点很多人都认为被const修饰的值是常量,这是不精确地,精确地说应该是只读的变量。其值在编译的时不能被使用,因为编译器在编译时不知道其里面存储的什么内容。
const修饰的只读变量必须在定义的同时初始化,同时它存放在静态去,也就是全局变量去,
编译器通常不为普通const只读变量分配存储空间,而是将它们保存在符号表中,这样使得它成为一个编译期间的值,没有了存储与读内存的操作,使得效率也很高。
这里看看和define的区别:例如下面:
#define M 3 //宏常量
const int N=5; //此时并为将N放入内存中
int i=N; //此时为N分配内存,以后不再分配
int i = M; //预编译期间进行宏替换,分配内存
int j = N; //没有内存分配
int j = M; //再进行宏替换,又一次分配内存,
修饰指针:
const int *p; //p可变,p指向的对象不可变
int const *p; //p可变,p指向的对象不可变
int *const p; //p不可变,p指向的对象可变
const int * const p; //指针p和o指向的对象都不可变
这里给出一个记忆方法:
先忽略类型名(编译器解析的时候也是忽略类型吗,我们看到离cost离那个就近,离谁近就修饰谁
)
10、volatite 是一边的、不稳定的意思, 也很少用。
11、union 关键字
union维护足够的空间来置放多个数据成员中的”一种“,而不是为每一个数据成员配置空间,在union中所有的数据成员公用一个空间,同一时间只能存储其中一个数据,所有的数据成员具有相同的起始地址,例如:
union machine
{
char character;
int num;
char *str;
double exp;
};
一个union只配置一个足够大的空间以来容纳最大长度的数据成员,以上栗二样,最大的是double类型,所以machine的空间大小为double 数据类型的大小。
大、小端模式对union的影响:
union
{
int i;
char a[2];
}*p,u;
p=&u;
p->a[0]=0x38;
p->a[1]=0x30;
p.i的值应该为多少呢?
这里需要考虑存储模式:大端模式和小端模式。
union类型数据所占的空间等于其最大成员所占的空间,对union类型的成员的存储都是相对该联合体基地址的偏移量为0处开始,也就是联合体的访问不论对那个变量的存取都是从union的首地址位置开始,
12、enum关键字
很多初学者对枚举感到迷惑,或者认为没有什么用,其实枚举(enum)是个很有用的数据类型。
(1)使用方法:一般定义如下:
enum enmu_type_name
{
ENUM_CONST_1,
ENUM_CONST_2,
.....
}enum_variable_name;
注意: enum_type_name是自定义的一种数据数据类型名,而enum_variable_name为enum_type_name类型的一个变量,也就是我们平时常说的枚举变量,实际上enum_type_name类型是对一个变量取值范围的限定,而花括号内是他的取值范围,即
enum_type_name类型的变量enum_variable_name 只能取值为花括号内的任何一个值,如果赋给该类型变量的值不在列表中,则会报错或者警告。ENUM_CONST_1 、ENUM_CONST_2 、... 、
ENUM_CONST_n ,这些成员都是常量,也就是我们平时所说的枚举常量(常量一般用大写)。enum 变量类型还可以给其中的常量符号赋值,如果不赋值则会从被赋初值的那个常量开始依次加1 ,如果都没有赋值,它们的值从 0 开始依次递增1。
例如分别用一个常数表示不同的颜色:
enum Color
{
GREEN= 1,
RED,
BLUE,
GREEN_RED=10,
GREEN_BLUE
}ColorVal
其中个常量名代表的数值分别为:
GREEN=1
RED=2
BULE=3
GREEN_RED=10
GREEN_BULE=11
枚举与#define宏的区别
下面看看枚举与#define宏区别:
(1)#define 宏常量是在预编译阶段进行简单的低缓,枚举常量是在编译的时候确定的
(2)一般在编译器里,可以调试枚举常量,但是不能吊事宏常量
(3)枚举可以一次定义大量相关的常量,而#define宏一次只能定义一个,
13、typedef
typedef的真正意思是给一个已经存在的数据类型(注意:是类型,不是变量)取一个别名,而非定义一个新的数据类型,在实际项目中,为了方便,可能很多数据类型(尤其是结构体之类的自定义数据类型)需要我们重新取一个适用实际情况的别名。这时候typedef就可以帮忙了:如下例:
typedef struct student
{
//code
}Stu_st,*Stu_pst;
对struct student *stu2; 和 Stu_pst stu2; 和Stu_st *stu2 // 没有区别
在如下面的:
(1)#define INT32 int
unsigned INT32 i=20;
(2)typedef int int32;
unsigned int32 j=20;
其中(2)编译出错,为什么,因为#define编译的时开始宏替换,替换为int 所以(1)正确,那么(2)typedef取别名不支持这种类型扩展,
下面再看看一个与#define宏有关的例子:
(3)#define pch char*
pch p3,p4;
(4)typedef char* pchar;
pchar p1,p2,
两组代码编译都没问题,但是,这里的p4却不是指针仅仅是一个char类型的字符,这种错误很容易被忽略,所以用#define的时候要慎之又慎,
14、关于注释:
编译器在编译的时候会把注释符号剔除掉,用空格代替原来的注释符。
对于全局变量、常量以及函数必须加注释。
在C语言里面 \ 表示断行,\后面不许有空格,同时\也表示转义字符
15、左移和右移 << 、>>
0x01>>2+32;对吗?
显然不对,由于整型数长度为32位,右移32位发生什么了!溢出,所以左移和右移的位数是有讲究的。左移和右移的位数不能大于数据的长度,不能小于0。
16、函数:
(1)如果参数是指针,且仅作为输入参数怎应在类型前加const,以防止指针在函数体内被意外修改
例如:void str_copy(char *str_destination,const char *str_source);
(2)如果没写函数返回类型,那么编译器默认的函数返回类型为int 型。
(3)return语句不可返回指向“栈内存”的“指针”,
例如:
char * fun(void)
{
char str[20];
.......
return str;
}
(4)尽量避免函数带有“记忆”功能,在C语言中,函数的static局部变量是函数的“记忆”存储器,建议尽量少用
static 定义局部变量,除非必需。
(5)函数递归
编写一个测试字符串长度的函数。不使用局部、全局变量也不调用库函数,
int my_strlen(const char *str_dest)
{
assert(NULL != str_dest);
if('\0' == *str_dest)
{
return 0;
}
else
{
return (1 + my_strlen( ++str_dest ));
}
}
2、变量命名:以字符或者下划线开头,由字符、下划线和数字组成;
sizeof:他是求变量的类型所占的内存大小,例如:int int_a=100;sizeof(int_a)结果为:4,因为int类型占内存空间4个字节,而不是100。其中数组int b[10]={0};它所占的空间为40个字节,
对结构体来说:例如:
strcut student
{
int a;
char p;
} type ; 它所占的字节为8,不知道其中的道理,那就自己解决吧! ^_^ 。