刚刚入门C语言不久,想来之前学习的有些忘记了,开始重新温习C语言基础:
在我C语言学习的过程中,除去数据结构的部分,基本上都围绕着32个关键字展开。
我个人将C语言关键字分为n类,我把32个关键字使用方法和注意点回忆一下。
1、数据类型:
void 空类型
1、void perror( const char * ); void声明函数的返回值类型,表示这个函数没有返回值。
2、FILE *namefile( void ); void出现在了函数的参数中,表示这个函数没有参数。
3、( void )printf(""); void出现在了调用函数的前并且加了小括号,表示把这个函数的返回值丢弃。
4、void malloc( size_t size ); void声明函数的返回值类型,表示这是一个万能返回值,可以根据调用者需要的类型,return不同的类型。
5、void free( void ptr ); void在函数的参数内,它是一个“任意”指针,可以接受不同类型的指针参数。
free函数的释放为 ptr == realloc(ptr,0); ptr = NULL;
char 字符型
1、char* name(char* str); char*声明函数的返回值,返回值为char类型的指针。
char* 在函数参数中,只能接收char类型的指针。
2、(char*)malloc(size_t size); 把malloc的返回值void* 转换成 char*。
3、char** name; char** 二级指针,char*(* char),(* char)中存放着地址p1,char中存放*p1(p1地址指向的值)。
short,int,long,float,double 用法和char一样。
struct 结构体类型
结构体是一种把多个不同类型的成员封装成一个结构体。方便读程序。
stu.name / stu->name 来访问不同的成员。
enum 枚举
union 联合
修饰变量
auto:动态变量,修饰在函数或块函数的变量中,在函数结束时会自动释放变量。
原理:把变量压入栈中,遵守后进先出的原则,当所在的函数结束时,会从栈里弹出。
const:保护被修饰的变量不被修改,但还是可以修改的。
const int *p; 修饰指针,可以通过获取地址,在解引用地址来修改数据
int *const p; 修饰地址,可以直接修改数据
被const修饰的全局变量,可以在别的文件中使用exter声明,来实现调用。
a.c
const int ARR[] = {0,1,2,3,4,5,6,7,8,9};//定义int数组
b.c
extern const int ARR[];//注意,这里不能再对ARR进行赋值
static:静态变量,把修饰的变量从堆内存存放到静态内存中,可以让变量在函数结束是不会被释放,在下次调用时依旧保留上次调用时的值。
static声明的函数与普通函数的区别是:用static修饰的函数,限定在本源码文件中,不能被本源码文件以外的代码文件调用。而普通的函数,默认是extern的,也就是说它可以被其它代码文件调用。
register:将变量从堆内存申请到寄存器内,可能会失败。常用于变量调用频率极高的情况。
volatile:可见性,有序性
可见性:由于cpu是多线程工作的,每一个cpu会对应各自的一块高速缓存区,在执行共享变量时,如果在cpu1中被修改,并且返回到内存中,在cpu2的高速缓存区中并没有修改,那么会导致cpu1的执行为空操作。被volatile修饰后,当cpu2再读取到该变量时,会强制对该内存无效,返回内存中去寻找。这时便可以避免这个问题。
有序性:众所周知,我们写的代码并非是计算机执行文件,需要通过编译器后才能生成执行文件,在不影响结果的条件下,编译器会根据每条语句的执行快慢来优化执行语句运行顺序。加volatile的变量后,必须保证此变量的前后变量顺序不改变。但是他之前的变量顺序可以改变。
extern:它是一个外部的函数声明变量,修饰在变量前表示它在别的文件中存在,可以调用其他文件中的数据。
注意:它是可以在被调用的文件中修改。
unsigned 无符号,用于修饰整型和浮点型,内存中补码存储,无标志位
signed 有符号,用于修饰整型和浮点型,在内存中存储时以补码形式存储,最高位为标志位。
补码标志位:1/0 负/正。
补码换算:1000 1101 0110 0110 这是一个有符号int
反码=补码-1:1000 1101 0110 0101
原码=反码取反:0111 0010 1001 1010
结果=标志位+原码
如:unsigned n = 1;
(-1 < n)?put("yes"):put("no");
这句语句中在K&R标准下输出为no。
ANSI C 标准中采用的是值保留原则。而K&R C 标准中,采用的是无符号保留(unsigned preserving)原则,即:不区分操作数大小,统一转换为无符号类型。如果采用K&R C 标准的话,那么例一、例二就都会输出Error了。
流程控制
if else for do while switch case default break continue return goto
用法比较简单
其他:
typedef
取一个名字,可以用这个名字找到这个定义类型或变量。
sizeof 判断一个变量或结构体,堆内存空间的大小
注意点在于计算结构体的字节数:
遵守补齐和对齐的原则,并且在Linux操作系统下,成员的字节数超过4字节时按4字节计算。
一个优秀的结构体,需要通过成员的排列,做到结构体字节数最短。
struct Student
{
char name[10]; //char类型为1个字节,name[10] 占10个字节;
int age; //int类型占4字节
char sex; //占1字节,因为补齐原则,它需要和int类型对齐,变为4个字节
int height; //占4字节
}Student;
总共为10+4+4+4 = 22个字节,但是因为补齐原则,结构体的字节数等于最长成员的整数倍,所以变为24个字节
struct Student
{
char name[10]; //char类型为1个字节,name[10] 占10个字节;
char sex; //占1字节
int age; //int类型占4字节
int height; //占4字节
}Student;
总共为10+1+4+4 = 19个字节,补齐原则变为20个字节。