结构体指针地址的问题,指针的地址疑惑的问题

纯属自己的片面总结,如有不对的地方请指出

首先推荐Visual studio2010,对于一些C的操作和变量、指针地址的疑惑问题都可以在这里进行调试,很直观。

  1. 首先要记住,不管定义任何变量,他的地址都是编译的时候按情况(随机)分配的。

  2. 明白指针变量也是一个变量,所以当你定义一个指针的时候他会开辟一块四个字节的内存空间,来存放这个指针变量,任何类型的指针他开辟的内存大小都是四个字节的,不管是你自己定义的结构体指针还是int* p都是四个字节的。

  3. 定义一个指针变量之后,该变量有自己的地址并且此时指针并不指向任何地方,你可以理解为没有绑定任何地址,就是一个普普通通的变量,像int a;也可以理解为指针变量有例如CPU的寻址能力,也就是他可以寻任何地址

  4. 字符型变量都是一个地址,所以他可以在内存当中的可以分配的空间内任何地址分配,对比int 型变量(四个字节),那么他地址都是以 0 4 8 C结尾的,如下图所示:
    在这里插入图片描述

  5. 要明白在进行指针操作的时候的,例如 p=&test;,这里有两方面的意思:
    0x00:指针变量的p地址 &p 还是你一开始就定义的int* p;的地址,这个指针类型的变量地址永远不会变的。
    0x01:指针指向的地址变了,他指向了test的地址。
    如图:

struct TEST
{
	char one;
	char two;
	char three;
	int four;
	
};
struct TEST* find()
{
	struct TEST* tmp;     //定义一个struct TEST类型的指针
	struct TEST test;     //这里要说一下当定义test之后,就会分配sizeof(test)大小的内存空间
	printf("结构体类型test地址%p\n",&test); //定义了一个结构体变量test,他的地址
	test.one=1;           //给成员变量赋个值
	printf("指针tmp的地址%p\n",&tmp); //看看这个tmp的指针在内存当中的地址;
	tmp=&test;            //tmp已经指向了结构体类型变量 test;(类似CPU寻址)
	printf("指针tmp的地址%p\n",&tmp); //此时再看看指针tmp的地址,tmp的地址不变,指向的地址变
	return tmp;           //返回同类型 同指针的tmp,因为函数是TEST类型的指针函数,所以返回
						  //的值也得是这个类型且是指针才行。
}
int main(void)
{
	struct TEST* p;       //定义一个TEST类型的指针
	p=find();             //指针p指向find()的返回值(注:同类型、都是指针才可以赋值,所以P必须是  
						  //struct TEST类型)
	printf("%d\n",p->one);//p指向结构体test的地址,然后访问该结构体内存块当中成员变量。
	printf("成员变量 One的地址%p\n",&p->one);//该成员变量的地址是多少呢?one是第一个结构体当中的变量,所以他的地址
						  //就是test的地址 注:(所有的变量名都是个代号,他没有内存空间)
	                      //所以 &test = &p->one

	printf("结构体的大小为:%d\n",sizeof(TEST));
	system("pause");
	return 1;
}

在这里插入图片描述
到了这里我觉得很多疑惑都解开了,这里想说一下的就是这个结构体TEST为什么是8个字节。按说应该是7个字节的对吧,结构体类似数组会分配连续的内存空间,而int 型必须是0 4 8 C结尾,如果char类型内存分配完成之后,下一个地址不是以0 4 8 C结尾的那么编译器会往下寻址寻到第一个以 0 4 8 C结尾的地址并开辟4字节的int 型。这里就是所说的,当要整合一个结构体的时候要排排序,尽可能都不出现内存泄漏的情况。

  1. 平常不需要指针基本上也是没有问题的,为什么采用结构体类型 指针函数,并且返回结构体类型 指针变量呢。
    我是这么理解的,如果初搞stm32的话不搞协议,也就是配置一下寄存器,while()循环 IO口输出几个电平 PWM波什么的,基本上上是接触不了多少数据操作的。一旦接触协议大量数据操作那么,假如你把每个变量的含义都给放到 a[ ] 数组当中,或者一个变量一个变量的定义那也是可以的,举个例子,当你想知道某个变量的含义是干什么的或者有什么用,你去数组当中取这个变量,你也直到这个变量可能是a[21],但是很不直观,你能直到一个你能知道100个都是什么意思嘛,这个时候结构体就有了这样的作用,我把所有我需要的变量有名字有值的打包成为一个内存块,当我想去访问的时候,欸,我知道这个是张三的内存块,这个是王五的,那个又是李四的,这样直接拿来用,“ 结构体当中也可以开辟数组啊,那干嘛还弄结构体不麻烦嘛?” ,这就是为什么大家都把数组叫做缓冲区,我们知道数组是连续的同类型数据块,我们把一些较长的同种类型数据放到数组当中即可啊,缓冲区。比如说“ 李四今天早上喝饭、跑步,中午大鱼大肉等等 ” 很长的一个包就给他放到缓冲区当中,其他王五也可以,这样假如要操作,结构体的操作方便功能又体现了我可以弄一个指针 p - > 直接访问啊,还带有提示,不要你从其他文件里面再去找,哎呀,李四当初的数组名字起的什么来着,多方便。
    以上是我的简单理解,具体还有什么作用,今后多看大佬的代码,从leetcode里多看看算法,算法虽然看不懂但C语言的水平肯定能体现出来


先到这里······

  • 4
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,这里是一个使用结构体指针数组对学生成绩进行排序的示例代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> // 定义学生结构体 typedef struct student { char name[20]; // 学生姓名 double score; // 学生成绩 } Student; // 冒泡排序函数 void bubbleSort(Student **students, int n) { int i, j; Student *temp; for (i = 0; i < n - 1; i++) { for (j = 0; j < n - i - 1; j++) { if (students[j]->score < students[j + 1]->score) { temp = students[j]; students[j] = students[j + 1]; students[j + 1] = temp; } } } } int main() { int n, i; // 输入学生人数 printf("Enter the number of students: "); scanf("%d", &n); // 动态分配学生结构体指针数组内存 Student **students = (Student **)malloc(n * sizeof(Student *)); if (students == NULL) { printf("Error: Failed to allocate memory for students!\n"); exit(EXIT_FAILURE); } // 输入学生信息 for (i = 0; i < n; i++) { students[i] = (Student *)malloc(sizeof(Student)); if (students[i] == NULL) { printf("Error: Failed to allocate memory for student %d!\n", i + 1); exit(EXIT_FAILURE); } printf("Enter the name and score of student %d: ", i + 1); scanf("%s %lf", students[i]->name, &students[i]->score); } // 对学生成绩进行排序 bubbleSort(students, n); // 输出排序结果 printf("\nSorted list of students:\n"); for (i = 0; i < n; i++) { printf("%s\t%.2lf\n", students[i]->name, students[i]->score); } // 释放动态分配的内存 for (i = 0; i < n; i++) { free(students[i]); } free(students); return 0; } ``` 在这个代码中,我们首先输入学生人数,然后动态分配一个学生结构体指针数组,用来存储每个学生的信息和成绩。接下来,我们输入每个学生的信息,并将学生结构体指针存储在指针数组中。然后,我们使用 `bubbleSort` 函数对学生成绩进行排序,并输出排序后的结果。最后,我们释放动态分配的内存。 希望这个示例代码能够帮到您。如果您还有其他问题疑惑,请随时问我。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值