标准:允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针比较,但是不允许与指向第一个元素之前的那个内存位置的指针进行比较。 🍁指针和数组 数组名和数组首元素的地址是一样的,数组名表示的是数组首元素的地址。(2种情况除外,sizeof(arr)与&arr)  数组名是地址,那就可以把数组名当成地址存放到一个指针中,我们使用指针来访问  可以看到两个地址是相同的,所以 p+i 其实计算的是数组 arr 下标为i的地址 🍁二级指针 指针变量也是变量,是变量就有地址,那指针变量的地址存便存放在二级指针 
- *ppa 通过对ppa中的地址进行解引用,这样找到的是 pa , *ppa 其实访问的就是 pa .
- **ppa 先通过 *ppa 找到 pa ,然后对 pa 进行解引用操作: *pa ,那找到的是 a .
因此,以此类推,实际上,不止只是有二级指针,还有三级指针、四级指针等等…不过用到的地方可能会比较少。 🍁指针数组 存放指针的数组就是指针数组。后面还会有数组指针,不过本篇博客以基础为主,不在这里展开论述。 int* arr[5];
这就是指针数组,下面我们可以简单通过代码来认识一下指针数组: 代码一:  代码二: 这是普通的二维数组打印  下面通过指针数组与一维数组结合打印出二维数组的效果  好了,关于指针的一些知识就先介绍到这。下面,我们来认识一下结构体。 🌳结构体 结构体是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量。 🍁结构体的声明与成员的类型 结构体的声明 struct tag
{
member-list;
}variable-list;
typedef struct Stu
{
char name[20];
int age;
char sex[5];
char id[20];
}Stu;
成员的类型
实际上,结构的成员可以是标量、数组、指针,甚至是其他结构体。
🍁结构体变量的定义和初始化及访问 有了结构体类型,那我们就该研究怎么去定义变量 struct Point
{
int x;
int y;
}p1;
struct Point p2;
一般可以在声明的时候去定义变量。下面我们可以来看看怎么去初始化:
struct Stu
{
char name[15];
int age;
};
struct Stu s = {"zhangsan", 20};
struct Node
{
int data;
struct Point p;
struct Node* next;
}n1 = {10, {4,5}, NULL};
struct Node n2 = {20, {5, 6}, NULL};
定义和初始化完之后,我们自然就要去访问了 结构体变量访问成员
- 结构变量的成员是通过点操作符(.)访问的。点操作符接受两个操作数。

- 如果我们得到的不是一个结构体变量,而是指向一个结构体的指针,这时候通过(->)操作符进行访问

#include <stdio.h>
struct Stu
{
char name[20];
int age;
};
void print(struct Stu* ps)
{
printf("name = %s\t age = %d\n", (*ps).name, (*ps).age);
printf("name = %s\t age = %d\n", ps->name, ps->age);
}
int main()
{
struct Stu s = { "zhangsan", 20 };
print(&s);
return 0;
}
🍁结构体传参 传参既可以传结构体,也可以传结构体地址>,下面进行代码演示:  可以看到两种传参方式不同,打印出来的效果却是一样的,但是有什么区别呢?对于上面的 print1 和 print2 函数哪个更好呢?
print2函数
其实在函数栈帧的时候就大概多多少少有涉及到,可以去看看我之前写的博客。函数传参的时候,参数是需要压栈的。如果传递一个结构体对象的时候,结构体过大,参数压栈的的系统开销比较大,所以会导致性能的下降。 所以,对于结构体传参的时候,传结构体的地址较好。 💺结语 通过上面的学习,我们对指针和结构体有了一定的认识,好了,就先到这里结束。 |
|
评论(0)