C语言教程-详解C语言中的指针

C语言中的指针是一种存储另一个变量的地址的变量。这个变量可以是int、char、数组、函数或任何其他指针类型。指针的大小取决于计算机体系结构。然而,在32位计算机体系结构中,指针的大小为2个字节。
考虑以下示例来定义一个指针,该指针存储一个整数的地址。
int n = 10;
int* p = &n; // 指针变量p指向整数变量n的地址
声明指针
在C语言中,可以使用*(星号)符号来声明指针。它也被称为间接指针,用于解引用指针。
int* a; // 指向int的指针
char* c; // 指向char的指针
指针示例
下面是一个使用指针打印地址和值的示例。
指针变量存储了变量number的地址,即fff4。number变量的值为50。但是指针变量p的地址是aaa3。
通过使用*(间接操作符),我们可以打印指针变量p的值。
让我们看一下上面解释的指针示例。
#include<stdio.h>
int main() {
int number = 50;
int* p;
p = &number; // 存储number变量的地址
printf("p变量的地址为:%x\n", p); // p包含number的地址,因此打印p会得到number的地址
printf("p变量的值为:%d\n", *p); // 如我们所知,*用于解引用指针,因此如果打印*p,我们将得到p所包含地址处存储的值
return 0;
}
输出
p变量的地址为:fff4
p变量的值为:50
指向数组的指针
int arr[10];
int* p[10] = &arr; // 指针变量p指向整型数组arr的地址
指向函数的指针
void show(int);
void (*p)(int) = &display; // 指针p指向函数的地址
指向结构体的指针
struct st {
int i;
float f;
} ref;
struct st* p = &ref;
指针的优点
- 指针减少了代码量并提高了性能,它用于检索字符串、树等,并与数组、结构体和函数一起使用。
- 我们可以使用指针从函数中返回多个值。
- 它使您能够访问计算机内存中的任何内存位置。
指针的用途
在C语言中,指针有许多应用。
1)动态内存分配
在C语言中,我们可以使用malloc()和calloc()函数来动态分配内存,这就涉及到指针的使用。
2)数组、函数和结构体
指针在C语言中广泛用于数组、函数和结构体。它减少了代码量并提高了性能。
取址运算符(&)
取址运算符&
返回变量的地址。但是,在显示变量的地址时,我们需要使用%u。
#include<stdio.h>
int main() {
int number = 50;
printf("number的值为:%d,number的地址为:%u", number, &number);
return 0;
}
输出
number的值为:50,number的地址为:fff4
空指针
一个未分配任何值但为NULL的指针被称为空指针。如果在声明指针时没有指定任何地址,可以赋予其NULL值,这将提供更好的方法。
int* p = NULL;
在大多数库中,指针的值为0(零)。
指针程序:不使用第三个变量交换两个数
#include<stdio.h>
int main() {
int a = 10, b = 20, *p1 = &a, *p2 = &b;
printf("交换前:*p1=%d *p2=%d\n", *p1, *p2);
*p1 = *p1 + *p2;
*p2 = *p1 - *p2;
*p1 = *p1 - *p2;
printf("交换后:*p1=%d *p2=%d\n", *p1, *p2);
return 0;
}
输出
交换前:*p1=10 *p2=20
交换后:*p1=20 *p2=10
阅读复杂指针
在C语言中阅读复杂指针时,需要考虑几个因素。让我们看一下与指针相关的运算符的优先级和结合性。
运算符 | 优先级 | 结合性 |
---|---|---|
(), [] | 1 | 从左到右 |
*, 标识符 | 2 | 从右到左 |
数据类型 | 3 | - |
这里要注意的是:
- ():括号运算符用于声明和定义函数。
- []:数组下标运算符
- *:指针运算符。
- 标识符:指针的名称。优先级总是分配给标识符。
- 数据类型:指针所指向的变量的类型。它还包括修饰符,如signed int、long等)。
如何阅读指针:int (*p)[10]。
为了阅读指针,我们必须注意到()和[]具有相等的优先级。因此,必须考虑它们的结合性。结合性是从左到右,因此优先级属于()。
在括号()内部,指针运算符和指针名(标识符)p具有相同的优先级。因此,必须考虑它们的结合性,即从右到左,因此优先级属于p,其次是。
给[]分配第三优先级,因为数据类型具有最后的优先级。因此,指针将如下所示:
- char -> 4
- * -> 2
- p -> 1
- [10] -> 3
指针将被解读为p是指向大小为10的整型数组的指针。
示例
如何阅读以下指针?
int (*p)(int (*)[2], int (*)(void))
解释
这个指针将被解读为p是指向这样的函数的指针,该函数的第一个参数是指向大小为2的一维整型数组的指针,第二个参数是指向参数为void且返回类型为整型的函数的指针。