指针
当数据存储在内存中时,我们需要把数据中的空间进行编号,以便之后可以很方便的找到它。就像你买快递,送到驿站之后,凭借着取货码可以很方便的找到快递的位置。指针便是用来找到取货码的工具。
在谈论指针之前我们先看下chatgpt的介绍:指针是一种非常强大的特性,它本质上是一个变量,用于存储另一个变量的内存地址。指针允许你直接访问和操作内存,这可以带来程序效率的提升,但也需要小心处理以避免错误。
指针的声明
int* ptr;
这里int*表示“指向整数的指针”,而ptr是这个指针变量的名称。
当我们需要将这个指针指向某个地址的时候,地址操作符&将被使用。
int x = 10;
int* ptr = &x;
这里,ptr
是一个指向整数的指针,&x
获取 x
的内存地址并将其赋值给 ptr
。现在,ptr
指向 x
,所以通过 ptr
可以访问 x
的值。
这样说可能有些抽象,让我们来举两个例子
#include<stdio.h>
int main()
{
int a = 10; //初始化a
int* p = &a; //*p 就是指向地址的工具,指向哪里呢,指向&a(取地址操作符),取a的地址
* p= 20;//我们通过指向a的地址的工具来直接修改地址里储存的值
printf("%d\n", *p);
return 0;
}
试着打印这串代码,结果会输出20,证明我们成功通过*p, 直接修改地址里储存的值。
int main()
{
int x = 10;//初始化x
int* ptr = &x;
printf("%d\n", *ptr);
return 0;
}
这个就是可以通过*ptr,直接查看地址内储存的值。
指针先告一段落,接下来是结构体。
结构体
结构体的关键字
struct//把一些单一类型组合在一起
举个例子,当我们需要介绍一件产品,例如车。这不是一个单一的类型可以描述出来的,我们需要描述它的型号,重量,燃油种类。
struct car {
char type[10];
int weight;
char fuel[5];
};
int main() {
struct car car1 = { "轿车", 5000, "汽油" };
printf("Type: %s\nWeight: %d\nFuel: %s\n", car1.type, car1.weight, car1.fuel);
return 0;
}
最后,我们将指针和结构体结合起来。
#include <stdio.h> // 包含标准输入输出库,用于调用 printf 函数
// 定义 car 结构体,用来存储车辆的相关信息
struct car {
char type[10]; // 车型,字符数组,最大存储 9 个字符加上一个字符串结束符 '\0'
int weight; // 车辆重量,整数类型
char fuel[10]; // 燃料类型,字符数组
};
// 定义 print 函数,用于打印 car 结构体的内容,接受一个指向 car 结构体的指针
void print(struct car* ptr){
// 使用解引用操作符 (*) 和点操作符 (.) 来访问结构体成员,并打印
printf("Type: %s\nWeight: %d\nFuel: %s\n", (*ptr).type, (*ptr).weight, (*ptr).fuel);
// 使用箭头操作符 (->) 直接访问结构体指针的成员,并打印
printf("Type: %s\nWeight: %d\nFuel: %s\n", ptr->type, ptr->weight, ptr->fuel);
}
// 主函数
int main() {
// 创建并初始化 car 类型的变量 car1
struct car car1 = { "轿车", 5000, "汽油" };
// 调用 print 函数,传递 car1 的地址
print(&car1);
return 0;
}
这段代码中还使用了箭头操作符
-
结构体定义 (
struct car
):此结构体设计用于描述一个车辆的属性,包括车型、重量和燃料类型。这些属性用于定义车辆的基本特征。 -
函数定义 (
print
):此函数接受一个指向car
结构体的指针,说明函数旨在操作car
类型的数据。函数内部有两次打印操作,一次使用了解引用和点操作符来访问结构体成员,另一次使用了箭头操作符。两种方式都能有效地访问和打印结构体中的数据。 -
主函数 (
main
):在主函数中,首先声明并初始化一个car
类型的变量car1
,然后调用print
函数,并将car1
的地址传递给该函数。这演示了如何在程序中创建和使用自定义的数据类型以及如何通过函数对这些数据进行操作