纯属自己的片面总结,如有不对的地方请指出
首先推荐Visual studio2010,对于一些C的操作和变量、指针地址的疑惑问题都可以在这里进行调试,很直观。
-
首先要记住,不管定义任何变量,他的地址都是编译的时候按情况(随机)分配的。
-
明白指针变量也是一个变量,所以当你定义一个指针的时候他会开辟一块四个字节的内存空间,来存放这个指针变量,任何类型的指针他开辟的内存大小都是四个字节的,不管是你自己定义的结构体指针还是int* p都是四个字节的。
-
定义一个指针变量之后,该变量有自己的地址并且此时指针并不指向任何地方,你可以理解为没有绑定任何地址,就是一个普普通通的变量,像int a;也可以理解为指针变量有例如CPU的寻址能力,也就是他可以寻任何地址
-
字符型变量都是一个地址,所以他可以在内存当中的可以分配的空间内任何地址分配,对比int 型变量(四个字节),那么他地址都是以 0 4 8 C结尾的,如下图所示:
-
要明白在进行指针操作的时候的,例如 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 型。这里就是所说的,当要整合一个结构体的时候要排排序,尽可能都不出现内存泄漏的情况。
- 平常不需要指针基本上也是没有问题的,为什么采用结构体类型 指针函数,并且返回结构体类型 指针变量呢。
我是这么理解的,如果初搞stm32的话不搞协议,也就是配置一下寄存器,while()循环 IO口输出几个电平 PWM波什么的,基本上上是接触不了多少数据操作的。一旦接触协议大量数据操作那么,假如你把每个变量的含义都给放到 a[ ] 数组当中,或者一个变量一个变量的定义那也是可以的,举个例子,当你想知道某个变量的含义是干什么的或者有什么用,你去数组当中取这个变量,你也直到这个变量可能是a[21],但是很不直观,你能直到一个你能知道100个都是什么意思嘛,这个时候结构体就有了这样的作用,我把所有我需要的变量有名字有值的打包成为一个内存块,当我想去访问的时候,欸,我知道这个是张三的内存块,这个是王五的,那个又是李四的,这样直接拿来用,“ 结构体当中也可以开辟数组啊,那干嘛还弄结构体不麻烦嘛?” ,这就是为什么大家都把数组叫做缓冲区,我们知道数组是连续的同类型数据块,我们把一些较长的同种类型数据放到数组当中即可啊,缓冲区。比如说“ 李四今天早上喝饭、跑步,中午大鱼大肉等等 ” 很长的一个包就给他放到缓冲区当中,其他王五也可以,这样假如要操作,结构体的操作方便功能又体现了我可以弄一个指针 p - > 直接访问啊,还带有提示,不要你从其他文件里面再去找,哎呀,李四当初的数组名字起的什么来着,多方便。
以上是我的简单理解,具体还有什么作用,今后多看大佬的代码,从leetcode里多看看算法,算法虽然看不懂但C语言的水平肯定能体现出来
先到这里······