- 指针和内存
- C程序在编译后,会以三种形式使用内存:
- 静态、全局内存:静态变量和全局变量使用这部分内存,生存周期为整个程序运行时,全局变量所有函数都可以访问,但静态变量虽然生存周期为整个程序运行时,但作用域和局部变量是一样的,只限于定义它的函数内部,全局变量和静态变量会执行默认初始化。
- 自动内存,也就是所说的栈上,局部变量,在函数内部声明,并且只有函数被调用时才创建,生命周期和作用域都随函数开始而开始,函数结束而结束,由系统自行回收
- 动态内存,也就是所说的堆,手动申请内存,手动释放
- 声明指针:
- 通过在数据类型后面跟星号(*),再加上指针变量名就可以声明指针,如:int *pi; pi是一个指向int型变量的指针
- 如何阅读声明:
- 介绍一种可以更容易理解指针变量的方法,就是倒过来念声明,也就是从右向左念,比如:const int *pci;
1 pci是一个变量 const int *pci;
2 pci是一个指针变量 const int *pci;
3 pci是一个指向int类型的指针变量 const int *pci;
4 pci是一个指向int常量的指针变量 const int *pci;
- 指针的初始化:
- 地址操作符&会返回操作数的地址,我们可以使用地址操作符来初始化指针:
1 int num; //num是一个int类型变量
2 int *pi = # //通过&获取num地址然后赋值给指针变量pi完成初始化
- 接引指针:
- 间接引用操作符(*)返回指针所指向的值,一般称之为解引指针,比如:
1 int num = 5; //创建int型变量num并初始化为5
2 int *pi = # //创建指针pi指向num
3 printf(“%d
”,*pi); //通过解引指针,输出指针所指向的值,值为5
- null的概念
- NULL被赋值给指针就意味着指针不指向任何数据,null的概念是指指针包含了一个特殊的值,和其它指针不同的是,没有指向任何内存区域(注意:两个null指针总是相等的)
- NULL宏是强制类型转换为void指针的整数常量0,在很多库中定义:#define NULL ((void*)0)
- null指针和未初始化的指针是不同的,未初始化的指针可能包含任何值,但null指针则是不指向任何内存区域的
- 我们可以给指针赋值常量0表示空指针,但不能赋予任何别的数值
- 注意:任何时候都不要对null指针进行解引操作,否则会造成程序终止
- 由于null值会被解释成为0值,所以可以使用指针作为逻辑表达式的唯一操作数:
1 if (pi)
2 {
3 //pi不为null
4 }else{
5 //pi为null
6 }
- void指针:
- void指针是通用指针,任何类型的指针都可以转换为void指针,也可以转换回原来的指针的类型
- 指针长度和类型:
- 在大部分现代平台上,数据指针的长度通常是一样的,与指针类型无关,取决于使用的机器和编译器
- sizeof操作符可以用来判断指针长度,如: printf(“Size of *char: %d
”,sizeof(char*));
- size_t: size_t类型表示C中任何对象所能达到的最大长度,定义在stddef头文件中,是一个与机器相关的unsigned类型,用作sizeof操作符的返回值类型,典型的定义如下:
1 #ifndef _SIZE_T
2 #define _SIZE_T
3 typedef unsigned int size_t;
4 #endif
- 指针操作符:
- 解引操作符:* ,用来解引指针
- 指向操作符:-> ,用来访问指针引用的结构的字段
- +、—操作符:用来对指针执行加减法
- ==、!=操作符:用来比较两个指针
- 指针的常见用法:
- 指向常量的指针:不能通过指针修改所引用的值,但可以改变指针,可以解引pci读取所指值,但不能解引来修改它
1 int num = 5; //定义一个整型变量num,赋值为5
2 const int limit = 500; //定义一个整型常量limit,赋值为500
3 int *pi; //定义一个指向整数的指针pi
4 const int *pci; //定义一个指向整型常量的指针pci
5
6 pi = # //指针pi指向num
7 pci = &limit; //指针pci指向limit
//pci可以被修改为指向不同的整数常量
//pci可以被修改为指向不同的非整数常量
//可以解引pci读取数据
//不可以解引pci从而修改它指向的数据
- 指向非常量的常量指针:指针不可变,所指数据可变
-
1 int num;
2 int *const chi = #
3 //cpi必须被初始化为指向非常量变量
4 //cpi不能被修改
5 //cpi所指数据可以被修改,也就是解引cpi赋新值
- 指向常量的常量指针:指针与所指数据都不能被修改
-
1 const int *const clci = &limit;
2 //声明常量指针时一定要初始化