C语言基础回顾-定义声明+关键字

来源:互联网 发布:活动致辞知乎 编辑:程序博客网 时间:2024/05/21 16:54

一、关于定义和声明

声明: 例: extern int i; extern int arr[ ];
告诉编译器,已经定义了一个变量名,但是不分配空间,声明可以出现多次。
定义: 例: int i const int i = 0(定义的同时初始化)
创建一个对象或者变量并且给其分配内存,名字和内存匹配,并且内存的位置也不能改变,定义只能出现一次
定义是一种特殊的声明。

二、重要关键字:

1.auto:
任何变量默认auto
2.register
请求编译器尽可能的将变量放在CPU的寄存器里而不是内存中寻址访问,注意是尽可能
注意注意: register修饰的变量的类型必须是CPU接收的类型,register变量必须是一个单一的值,长度应该小于或者等于整形的长度;
register的变量可能不放在内存里面,所以不能取地址&
3.static关键字
(1)修饰变量:
全局变量:改变链接属性
局部变量:改变存储特性、程序运行时候创建,结束才销毁
(2)修饰函数
改变链接属性,使得函数只能在本文件中使用
4.sizeof
32个关键字之一,后面跟类型或者变量,得到所占空间的大小
记得加括号
5.signed和unsigned关键字
记得再看看正数负数的加减运算操作,整形提升
6.void
void: 空类型 void* 空指针类型 空指针可以指向任意类型的数据
void的作用发挥在: (1) 限定函数的返回值 (2) 限定函数的参数
注意点:
1)、任何类型的指针都可以直接赋值给void* 的指针,不需要强转,但是void* 的指针不可以赋值给任何指针。
2)、一个函数如果没有返回值,那么就必须要使用void类型声明這个函数!!,因为不加返回值说明的函数返回值默认为int
加了void返回类型增强函数的自描述性。
3)、函数参数使用void 表示函数不接受任何参数,C语言中,可以向无参函数传递参数,不会出错但是再C++中不可以向无参函数传递参数;
所以有的时候C编译器能跑C++编译器报错,所以就统一在函数内部使用void表示不接受任何参数(C和C++)保证了都不接受传参;
4)、void* p =&a *p 错!,不能对外能指针解引用,p++/p+n 错!不能对万能指针进行运算操作。
5)、void a 错,之前写的void* p 定义可能不错因为所有的指针都是4字节大小,但是定义一个void变量是不对的,void不能代表一个真实的变量
7.return
return不可以返回栈空间的指针
8.const关键字:
const修饰只读变量、不可以修改,实际上const的出现就是为了取代#define #define不是关键字是之指令
const修饰的变量本质是变量,不能放在数组的下标引用中作为数组元素,数组的元素必须是常量,但是在C++中却可以
const修饰的只读变量必须在定义的同时初始化!!(为啥)
case后面可以跟const修饰的变量吗? 不可以 ,依然是一个变量
注意:
A.const的底层实现
编译器不为const只读变量分配内存,把他保存在符号表里面,const只读变量在编译的时候确定了值,没有对内存的读和操作,所以使用const可以提高效率,const修饰的变量在程序的运行期间只有一份拷贝,拷贝了的值存放在静态区。
B.const和#define的区别
(1)从汇编的角度: const给的是静态区那个只读变量的地址,但是#define是替换,直接给的是立即数。
(2)const修饰的变量在编译过后开始运行的时候分配内存,分配在静态区,因为是全局的,所以就只有这一份。但是宏常量在内存里面有若干拷贝,替换一次就拷贝一次。
(3)#define宏是在预编译阶段替换,但是const修饰变量是在编译的时候确定值。
(4)#define宏是没有类型的,但是const修饰的变量有类型。
C.const修饰的指针:
const int* p;
int const* p;
int *const p;
const int *const p
近水楼台先得月
9.volatile
保证内存可见性
告诉编译器修饰的這个变量不稳定,防止编译器优化,可以提供对特殊地址的稳定的访问。
10.extern

可以放在变量或者函数前,表示函数或者变量被定义在别的文件中, 声明

11、enum
枚举和#define的区别:
(1) #define宏常量是在预编译阶段进行简单的替换,枚举常量是在编译的时候确定其值
(2)#define宏常量是无法调试的,但是编译器中可以调试枚举常量
(3)枚举可以一次性定义大量相关的常量,但是宏定义一次一个
sizeof(枚举类型对象)=4 注意是枚举类型的对象,不是枚举类型,不论怎么变都是4个字节,是一个整形;
12.typedef
给类型定义新的名字;
typedef和#define的区别:define无法正确的处理指针:
define PCHAR char* PCHAR p3, p4;  //p3是char*类型,但是p4不是
typedef char* pchar;pchar p3, p4;   //p3是指针类型但是p4不是,可以把pchar看作int 看作double
如上看出来,#define不能像typedef那样正确的处理指针。