1. 内存和地址
1.1 内存
在讲内存和地址之前,我们想有个⽣活中的案例: 假设有⼀栋宿舍楼,把你放在楼⾥,楼上有100个房间,但是房间没有编号,你的⼀个朋友来找你玩, 如果想找到你,就得挨个房⼦去找,这样效率很低,但是我们如果根据楼层和楼层的房间的情况,给 每个房间编上号,如:
1.⼀楼:101,102,103...
2.⼆楼:201,202,203....
3....
有了房间号,如果你的朋友得到房间号,就可以快速的找房间,找到你。⽣活中,每个房间有了房间号,就能提⾼效率,能快速的找到房间。 如果把上⾯的例⼦对照到计算中,⼜是怎么样呢? 我们知道计算上CPU(中央处理器)在处理数据的时候,需要的数据是在内存中读取的,处理后的数 据也会放回内存中,那我们买电脑的时候,电脑上内存是8GB/16GB/32GB等,那这些内存空间如何⾼ 效的管理呢? 其实也是把内存划分为⼀个个的内存单元,每个内存单元的⼤⼩取1个字节。 计算机中常⻅的单位(补充): ⼀个⽐特位可以存储⼀个2进制的位1或者0
通过上面的数据可以发现除了第一个:byte和bit的换算是8倍其他全都是2^10
回归正题
当我们在编写C语言程序时,指针是一个非常重要的概念。指针可以让我们直接访问内存中的数据,实现高效的数据操作。本文将详细介绍指针的概念、用法和示例,包括数组指针、指针数组、函数指针、野指针、void指针等,让读者能够更容易地理解和掌握指针的知识。
1.指针的概念
指针是一个变量,其值为另一个变量的地址。通过指针,我们可以直接操作内存中的数据,而不需要将数据复制到新的变量中。这样可以节省内存空间并提高程序的效率。
在C语言中,我们可以通过以下方式定义一个指针变量:
int *ptr; // 定义一个指向整数的指针变量
在上面的例子中,int *ptr
表示定义了一个指向整数的指针变量ptr。*
表示这是一个指针变量,int
表示指针指向的数据类型。
2.指针的用法
指针的用法非常灵活,我们可以通过指针来访问和修改变量的值,也可以通过指针来访问数组中的元素。下面是一些指针的常见用法示例:
2.1 访问变量的地址和值
int num = 10;
int *ptr = # // 将num的地址赋给指针ptr
printf("变量num的地址:%p\n", &num); // 打印变量num的地址
printf("指针ptr的值:%d\n", *ptr); // 通过指针ptr访问变量num的值
2.2 通过指针修改变量的值
int num = 10;
int *ptr = #
*ptr = 20; // 通过指针ptr修改变量num的值
printf("变量num的值:%d\n", num); // 打印变量num的新值
2.3 使用指针访问数组元素
int arr[] = {1, 2, 3, 4, 5};
int *ptr = arr; // 将数组arr的首地址赋给指针ptr
for (int i = 0; i < 5; i++) {
printf("数组arr的第%d个元素:%d\n", i, *(ptr + i)); // 通过指针ptr访问数组arr的元素
}
3.数组指针
数组指针是一个指向数组的指针变量。我们可以通过数组指针来访问数组中的元素,也可以通过数组指针来修改数组中的元素。下面是一个数组指针的示例:
int arr[] = {1, 2, 3, 4, 5};
int (*ptr)[5] = &arr; // 定义一个指向数组arr的指针变量ptr
for (int i = 0; i < 5; i++) {
printf("数组arr的第%d个元素:%d\n", i, (*ptr)[i]); // 通过数组指针ptr访问数组arr的元素
}
在上面的例子中,int (*ptr)[5]
表示定义了一个指向整数数组的指针变量ptr。*
表示这是一个指针变量,[5]
表示指针指向的是一个包含5个整数的数组。
4.指针数组
指针数组是一个包含指针的数组。我们可以通过指针数组来存储多个指针,也可以通过指针数组来访问和修改指针指向的数据。下面是一个指针数组的示例:
int num1 = 10, num2 = 20, num3 = 30;
int *arr[] = {&num1, &num2, &num3}; // 定义一个包含指针的数组arr
for (int i = 0; i < 3; i++) {
printf("指针arr[%d]指向的值:%d\n", i, *arr[i]); // 通过指针数组arr访问指针指向的值
}
在上面的例子中,int *arr[]
表示定义了一个包含指针的数组arr。数组中的每个元素都是一个指向整数的指针变量。
5.函数指针
函数指针是一个指向函数的指针变量。我们可以通过函数指针来调用函数,也可以将函数指针作为参数传递给其他函数。下面是一个函数指针的示例:
int add(int a, int b) {
return a + b;
}
int (*ptr)(int, int) = &add; // 定义一个指向函数add的指针变量ptr
int result = (*ptr)(10, 20); // 通过函数指针ptr调用函数add
printf("函数add的结果:%d\n", result);
在上面的例子中,int (*ptr)(int, int)
表示定义了一个指向函数的指针变量ptr。*
表示这是一个指针变量,(int, int)
表示函数的参数类型。
6.野指针
野指针是指一个没有被初始化或被赋值为NULL的指针变量。野指针可能会指向一个随机的内存地址,这样就会导致程序崩溃或产生不可预测的结果。因此,在使用指针时,我们应该始终将指针初始化或赋值为NULL,以避免野指针的出现。
7.void指针
void指针是一个通用的指针类型,可以指向任何类型的数据。我们可以通过void指针来实现数据的通用访问和传递。下面是一个void指针的示例:
int num = 10;
float fnum = 3.14;
void *ptr;
ptr = # // 将整数num的地址赋给void指针ptr
printf("变量num的值:%d\n", *(int *)ptr); // 通过void指针ptr访问整数num的值
ptr = &fnum; // 将浮点数fnum的地址赋给void指针ptr
printf("变量fnum的值:%f\n", *(float *)ptr); // 通过void指针ptr访问浮点数fnum的值
在上面的例子中,void *ptr
表示定义了一个void指针变量ptr。我们可以将任何类型的数据的地址赋给void指针ptr,并通过强制类型转换将void指针转换为特定类型的指针来访问数据。
总之,指针是C语言中非常重要的概念,掌握好指针的用法可以让我们的程序更加高效和灵活。本文介绍了指针的概念、用法和示例,包括数组指针、指针数组、函数指针、野指针、void指针等。希望本文的介绍和示例能够帮助读者更容易地理解和掌握指针的知