有关指针,结构体,数组的总结

本文深入探讨了指针、结构体和数组的概念及其相互关系,详细解析了一级指针的定义与使用,指针与数组之间的联系,以及如何通过指针引用数组元素。同时,文章还介绍了数组名作为函数参数的实质,以及指针在多维数组中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

有关指针,结构体,数组的总结

一级指针

*p和p的区别以及如何定义指针

首先理解一个语句

i_pointer=&i;

*i_pointer表达的是指针所指的对象就是你输入i变量的数值。
i_pointer有一个具体的值,这个值就是地址也就是&i…

那么如何定义指针呢?
再看一个语句 int *pointer_1,*pointer_2;

就是定义了两个指针
可见,虽然这里也用到了*的符号,但他表示的并不是上面所说的表示变量的数值。

所以:int *pointer_1中的pointer_1为指针变量
i_pointer为指针
区分好指针变量和指针的区别

大概的理解就是,指针变量他是一个变化的指针,你可以把指针理解为门牌号,指针内容理解为门里面的内容。
而上面所说的指针变量就是一个变化的门牌号

同样的char *pointer_1也可以表示一个指针,但是这个叫做指针变量的基类型

基类型表示的是可以指向变量的类型,比如说,你想找一个指针指向数字和字符是不一样的。

指针和数组之间的关系

我们先理解一下下面三句话

int *p;
p=&a[0];
p=a;

上面的效果是完全一样的。
为什么呢?
首先,第二行的意思是a[0]表达的是一个数字,那么对他取地址然后赋值给p
第三行的意思是,a这个数组的第一个元素的地址赋值给a
所以我们可以总结得

已知一个数组a[n],a代表的就是这个数组第一个元素所对应的地址

那么我们如何通过指针来引用数组的元素呢?

上面我们说到

int *p;
p=&a[0];
p=a;

我们如果对p+1其实就是a[1]这个元素的地址
引用的话就直接用*解运算符来得到指针对应的内容

*(p+i);

这个就是引用数组的内容。

数组名和函数参数

首先看一下这个语句

void(int arr[],int n);
fun(arrar,10)

还记得上面是怎么用指针做函数参数的么?

void swap(int *p1,int &p2);
swap(p1,p2);

是不是觉得两个其实非常像?
没错!

我们可以看到。
在定义函数的时候,括号里面都是指针变量
在用函数的时候,都是把指针放进去

但其实程序在编译的时候,是将arr指针当作变量来处理其实就是

void(int arr[],int n);
等价于
void fun(int *arr,int n);

由int arr[]==int *arr,我们可以得出一个结论

数组的本质就是一个指针(在计算机处理数组的时候)

指针和多维数组的关系

我们先看一个二维数组

int a[3][4]={
{1,3,5,7}
{9,11,13,15}
{17,19,21,23}
};

1 3 5 7
9 11 13 15
17 19 21 23
从二维数组来看a代表的是二维数组首元素的地址
但是现在的首元素不是一个简单的整型元素
而是一个由4个整形元素所组成的一维数组。

所以a代表的是首行(即序号为0的行的)首地址。

表达形式含义地址
a二维数组的组名,第0行的首地址2000
a+1,&a[1]第一行的首地址2000
a[0],*(a+0),*a0行0列的元素的地址2016
a[1],*a+1第1行第0列的地址2016
a[1]+2,* (a+1)+2,&a[1][2]第1行第2列的地址2021
* (a[1]+2),* (*(a+1)+2),a[1][2]第1行第2列的数值元素值为13

还有一个东西你要注意的是,一个int型的指针变量,相差一个位置,就是加4,但是现在这个地方,一行有四个元素,所以相差了16

–end of the article–
明天早上再把结构体还有多重指针总结一下

<think>好的,我需要帮助用户理解指针结构体数组的初始化。首先,我得回忆一下C语言中结构体指针数组的相关知识。结构体数组就是数组里的每个元素都是结构体,而指针结构体数组应该是指数组元素是指向结构体指针。初始化这样的数组可能需要动态分配内存或者直接指向已有的结构体实例。 用户可能对如何正确初始化分配内存不太清楚,容易混淆指针数组结构体数组的概念。我需要分步骤解释,先定义结构体,然后创建指针数组,接着逐个初始化每个指针,可能还要提到动态分配内存的方法,比如使用malloc。同时,要注意内存管理的部分,提醒用户释放内存避免泄漏。 可能还需要举例说明,比如定义一个Student结构体,然后创建指针数组,每个指针指向一个Student实例。示例代码要正确展示如何声明、分配内存、赋值以及释放内存。需要检查语法是否正确,比如结构体指针访问成员时用->而不是.,还有malloc的类型转换是否需要。 另外,用户可能想知道静态初始化动态初始化的区别,如果有的话。比如,如果结构体实例已经存在,指针数组可以直接指向它们,而动态初始化则是运行时分配内存。要确保例子覆盖这两种情况,或者至少说明常见做法。 还要注意术语的准确性,比如“指针结构体数组”可能应该更准确地说成“结构体指针数组”,避免歧义。在解释过程中,语言要简洁明了,步骤清晰,避免技术术语过于复杂,同时确保覆盖关键点:定义结构体、声明指针数组、内存分配、成员赋值、释放内存。 最后,检查是否有常见的错误点需要提醒,比如未分配内存就访问指针,或者忘记释放内存导致泄漏。确保用户不仅知道如何初始化,还要了解背后的原理注意事项。</think>指针结构体数组初始化在C语言中是一个关键操作,需要结合结构体指针数组的特性。以下是详细步骤示例: ### 一、核心概念梳理 1. **结构体**:自定义数据类型,可包含多个不同基础类型的成员 2. **指针数组**数组元素全为指针类型 3. **结构体指针数组**数组元素为指向结构体指针 ### 二、初始化步骤 1. **定义结构体类型**: ```c typedef struct { int id; char name[20]; float score; } Student; ``` 2. **声明指针数组**: ```c Student* stuArr[3]; // 包含3个Student指针数组 ``` 3. **内存分配与初始化**: ```c // 动态内存分配 for(int i = 0; i < 3; i++) { stuArr[i] = (Student*)malloc(sizeof(Student)); // 成员初始化 stuArr[i]->id = i+1; strcpy(stuArr[i]->name, "Student_0"); stuArr[i]->name[8] = '1' + i; // 设置不同名称 stuArr[i]->score = 80.0 + i; } ``` ### 三、两种初始化方式对比 | 方式 | 特点 | 适用场景 | |-----------|-------------------------|-------------------| | 静态初始化 | 直接指向已存在的结构体变量 | 数据量小且生命周期明确的情况 | | 动态初始化 | 使用malloc动态分配内存 | 数据量大或需要灵活管理的情况 | **静态初始化示例**: ```c Student s1 = {1, "Alice", 95.5}; Student s2 = {2, "Bob", 88.0}; Student* staticArr[] = {&s1, &s2}; ``` ### 四、注意事项 1. **内存管理**: ```c // 使用后必须释放内存 for(int i = 0; i < 3; i++) { free(stuArr[i]); } ``` 2. 访问成员时使用`->`运算符: $$ \text{指针} \rightarrow \text{成员名} $$ 3. 检查malloc返回值: ```c if(stuArr[i] == NULL) { fprintf(stderr, "内存分配失败"); exit(EXIT_FAILURE); } ``` ### 五、完整示例代码 ```c #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct { int id; char name[20]; float score; } Student; int main() { Student* arr[3]; // 初始化 for(int i=0; i<3; i++){ arr[i] = malloc(sizeof(Student)); arr[i]->id = 1001 + i; sprintf(arr[i]->name, "Stu_%c", 'A'+i); arr[i]->score = 75.5 + i*5; } // 打印验证 for(int i=0; i<3; i++){ printf("ID: %d\nName: %s\nScore: %.1f\n\n", arr[i]->id, arr[i]->name, arr[i]->score); } // 释放内存 for(int i=0; i<3; i++){ free(arr[i]); } return 0; } ``` ### 六、常见错误 1. 未分配内存直接访问指针 2. 内存泄漏(分配后未释放) 3. 越界访问数组元素 4. 使用野指针(已释放的内存再次访问) 理解这些内容后,您就能正确进行指针结构体数组的初始化操作了。实际开发中建议结合具体需求选择初始化方式,并严格管理内存生命周期。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值