C语言中,通过指针可以简化一些C编程任务的执行,比如,动态内存分配,没有指针是无法执行的。
每一个变量都有一个内存位置,每个内存位置定义了可使用&运算符访问的地址,它表示内存中的一个地址。
一、什么是指针?
指针是一个变量,其值为另一个变量的地址,即内存位置的直接地址,就像其他变量或常量一样,您必须在使用指针存储其他变量之前,对其进行声明。
指针变量声明的一般形式为:type *var-name
type是指针的基类型,必须是有效的C数据类型
var-name是指针变量的名字
*是用来指定一个变量是指针
注意:
- 不管是整型,浮点型,字符型,还是其他数据类型,对应指针的值的类型都是一样的,都是一个代表内存地址的长的十六进制数。
- 不同数据类型的指针之间唯一的不同是,指针指向的变量或常量的数据类型不同。
二、如何使用指针?
使用指针的操作:
@定义一个指针变量,把变量地址赋给指针
@访问指针变量中可用地址的值,这些是通过一元运算符*来返回操作数所指定地址的变量的值。
注意:
- 在变量声明的时候,如果没有确切的地址可以赋值,可以将指针变量赋值为“NULL”,称为空指针。
- NULL指针是一个定义在标准库中的值为0的常量。
- 在大多数的操作系统上,程序不允许访问地址为 0 的内存,因为该内存是操作系统保留的。然而,内存地址 0 有特别重要的意义,它表明该指针不指向一个可访问的内存位置。但按照惯例,如果指针包含空值(零值),则假定它不指向任何东西。
如需检查一个空指针,您可以使用 if 语句,如下所示:
if(ptr) /* 如果 p 非空,则完成 */
if(!ptr) /* 如果 p 为空,则完成 */
三、C指针详解
3.1、指针的算术运算
可以对指针进行:++,--,+,-
3.2、指针数组
用来存储指针的数组
3.3、指针指向的指针
C允许指向指针的指针
3.4、传递指针给函数
通过引用或地址传递参数,使传递的参数在调用函数中被改变
3.5、从函数返回指针
C允许函数返回指针到局部变量,静态变量和动态内存分配
四、函数指针
函数指针是指向函数的指针变量。
通常我们说的指针变量是指向一个整型、字符型或数组等变量,而函数指针是指向函数。
函数指针可以像一般函数一样,用于调用函数、传递参数。
函数指针变量的声明:
typedef int (*fun_ptr)(int,int); // 声明一个指向同样参数、返回值的函数指针类型
五、回调函数
函数指针作为某个函数的参数
函数指针变量可以作为某个函数的参数来使用的,回调函数就是一个通过函数指针调用的函数。
简单讲:回调函数是由别人的函数执行时调用你实现的函数。
举个简单的例子:
你到一个商店买东西,刚好你要的东西没有货,于是你在店员那里留下了你的电话,过了几天店里有货了,店员就打了你的电话,然后你接到电话后就到店里去取了货。在这个例子里,你的电话号码就叫回调函数,你把电话留给店员就叫登记回调函数,店里后来有货了叫做触发了回调关联的事件,店员给你打电话叫做调用回调函数,你到店里去取货叫做响应回调事件。
六、补充enum(枚举)
枚举是 C 语言中的一种基本数据类型,它可以让数据更简洁,更易读。
语法格式:
enum 枚举名 {枚举元素1,枚举元素2,……};
enum DAY
{
MON=1, TUE, WED, THU, FRI, SAT, SUN
};
注意:第一个枚举成员的默认值为整型的 0,后续枚举成员的值在前一个成员上加 1。我们在这个实例中把第一个枚举成员的值定义为 1,第二个就为 2,以此类推。
可以在定义枚举类型时改变枚举元素的值:
enum season {spring, summer=3, autumn, winter};没有指定值的枚举元素,其值为前一元素加 1。也就说 spring 的值为 0,summer 的值为 3,autumn 的值为 4,winter 的值为 5
枚举变量的定义:
1、先定义枚举类型,再定义枚举变量
enum DAY { MON=1, TUE, WED, THU, FRI, SAT, SUN }; enum DAY day;2、定义枚举类型的同时定义枚举变量
enum DAY { MON=1, TUE, WED, THU, FRI, SAT, SUN } day;3、省略枚举名称,直接定义枚举变量
enum { MON=1, TUE, WED, THU, FRI, SAT, SUN } day;
在C 语言中,枚举类型是被当做 int 或者 unsigned int 类型来处理的,所以按照 C 语言规范是没有办法遍历枚举类型的。
不过在一些特殊的情况下,枚举类型必须连续是可以实现有条件的遍历。例子如下:
#include <stdio.h>
enum DAY
{
MON=1, TUE, WED, THU, FRI, SAT, SUN
} day;
int main()
{
// 遍历枚举元素
for (day = MON; day <= SUN; day++) {
printf("枚举元素:%d \n", day);
}
}
/*输出结果*/
枚举元素:1
枚举元素:2
枚举元素:3
枚举元素:4
枚举元素:5
枚举元素:6
枚举元素:7