c语言笔记
1.在C语言中,不同数据类型在进行运算时首先要转换成同一类型,一种是自动转换,二是强制转换。short、int、long、char、float、double这六个关键字代表C 语言里的六种基本数据类型。转换方向:char,short->int->unsigned->long,float->double。强制转换如下:
- 枚举常量:转换成int,如超出int范围,则转成long int等
- 浮点类型:
- 如果转成整类型,只保留整数部分,如果超出整类型表示范围,则转换错误;
- 如果向上转成double/long double,值不变;
- 如果向下转成float/double等,如果能用float/double表示,则正常,如果超出表示范围,则转换错误,而如果在表示范围内,但精度降低,则要依赖于编译器的处理了;
- 整类型:short int/char/枚举类型/位域类型都可转换成int,如果超出int表示范围,则提升到unsigned int。
2.指针有两个属性:指向变量/对象的地址和长度,但是指针只存储地址,长度则取决于指针的类型;编译器根据指针的类型从指针指向的地址向后寻址,指针类型不同则寻址范围也不同。
3.& 运算符的地址可以应用于变量而不是具体的数字。不能把一个具体的数字赋给指针(类型不匹配)。
4.在进行某些算法的C语言编程的时候,需要使几种不同类型的变量存放到同一段内存单元中。也就是使用覆盖技术,几个变量互相覆盖。这种几个不同的变量共同占用一段内存的结构,在C语言中,被称作“共用体”类型结构,简称共用体。
5.volatile是一个特征修饰符(type specifier).volatile的作用是作为指令关键字,确保本条指令不会因编译器的优化而省略,且要求每次直接读值。volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。
6.long/short和unsigned/signed类型修饰符:long类型不能比变通类型短,short类型不能比普通类型长。而unsigned与signed的区别在实现上是有无符号的区别,而是使用上是取值范围的区别,两者表示范围相同,但前者全是正数,后者关于0对称。
- long/short可以修饰int,long还可以修饰double。
- unsigned/signed可以修饰int, char,不可以修饰浮点型。
- int长度是机器的字长,short int是半个字长,long int是一个或两个字长。
- unsigned/signed长度与普通类型一样,只是表示区间不同。
7.C语言里typedef的解释是用来声明新的类型名来代替已有的类姓名。typedef为C语言的关键字,作用是为一种数据类型定义一个新名字。这里的数据类型包括内部数据类型(int,char等)和自定义的数据类型(struct等)。
8.系统编程使用回调函数的时候,经常需要把一个值存在 void * 中传给回调函数,然后在回调函数内部把 int 值从 void * 中取出。void即“无类型”,void *则为“无类型指针”,可以指向任何数据类型。
把一个 int 存到 void * 变量需要先把它转换成 long, 这样能避免 warning: cast to pointer from integer of different size int num; void *arg; arg = (void *)(long)num;
同样,从 void * 取出 int, 需要这样: int fd = (int) (long)arg;
9.extern表示是外部函数或外部变量,比如:
- extern void add(int x,inty);表示该函数主体不在当前模块中,在另一个模块中(文件)
- extern int total;表示该变量在另一个模块中定义过。
一般都把一些经常用到的枚举和变量之类的写在.h头文件中。这样要引用时直接include "头文件名"就可以了调用里面所有的枚举和变量了。在大型项目中,引用别的.c文件中的函数则只能用extern,因为.c文件是不能 include的。所以想引用别的.c文件中的函数和全局变量、枚举等等的就只能用extern。
10.strlen()和sizeof()比较:
- strlen(char*)函数求的是字符串的实际长度,它求得方法是从开始到遇到第一个'\0'。sizeof(...)是运算符,在头文件中typedef为unsigned int,其值在编译时即计算好了,参数可以是数组、指针、类型、对象、函数等。
- sizeof()函数返的是变量声明后所占的内存数,不是实际长度,我若通过赋值方法给字符串中某一字符赋值为\0,它的strlen()值变化很大,而sizeof()不变。strlen(...)是函数,要在运行时才能计算。参数必须是字符型指针(char*)。当数组名作为参数传入时,实际上数组就退化成指针了。
11.在用%.*s时,后面跟着两个参数,如下 a表示输出数据占得位置的大小,sval 表示要输出的内容
printf("%.*s" ,a , sval); /*意思是输出字符串sval,但至少占a个位置,如果用%*s在字符串sval左边补空格
12.字符数组是一个数组,每个元素的值都可以改变。而字符串指针指向的是一个常量字符串,它被存放在程序的静态数据区,一旦定义就不能改变。数组能隐式转换成指针。