复习树的时候发现结构体实现并不流畅熟练,先搞定一下结构体。之后搞定树,二叉树,图等

目录

  • 一、 几种结构体定义:
    • 1.先是定义不带初始化的两个
    • 2.然后是两个定义时就进行初始化的两个结构体
  • 二、机构体初始化(在一、的基础上)
    • 1.对机构体其中几个成员做初始化或修改
    • 2.定义结构体,分配了内存空间,之后对每个成员进行赋值(注意数组成员赋值方法)
  • 三、结构体定以后的内容修改(包括输入)
    • 1.进行整体修改
    • 2.进行某些或某个成员进行修改
    • 3.进行输入
  • 三、结构体的调用及输出
    • 1. 整体,部分成员输出
    • 2.结构体嵌套输出
  • 四、结构体在内存中的存储方式
      • 原则1:
      • 原则2:
      • 原则3:
    • 1.理论存储练习:
    • 2.测试代码:
  • 代码

一、 几种结构体定义:

1.先是定义不带初始化的两个

(1)struct crunode 在定义的时候就定义了其类型的crunode1变量 ,之后仍可以在其他函数中定义其他变量如二、1.
(2)struct b 则没有,调用时需要再定义struct b b1; //b1为变量

struct crunode
{struct crunode *parent;int data;char name[20];struct crunode *leftchild;struct crunode *rightchild;
}crunode1;
//in this define you can't determine the parameter.if you want to determine those you can determin at the position "a" like the next one .
// crunode is a type ,crunode1 is a parameterstruct b   //determine 2
{char* p;int data;
};

2.然后是两个定义时就进行初始化的两个结构体

struct a是简单的成员分别为一个char指针和一个int数的结构体,在结构体后面进行初始化
struct c是直接初始化了一个结构体数组分别为c[0],c[1],然后其中成员包括char型数组,char型指针,int型数还有一个结构体(这里注意不能再次定义自己例如这里将struct c中的struct b b2; 换为struct c c2,;会造成死循环)。在结构体后面进行初始化要注意其中嵌套的结构体初始化内容需要用{ }进行表明,即每个机构体的内容都需要用{ }来进行标注,表明其是一个机构体。

struct a //determine 1
{char* p;int data;
}a1 = {"test",99}; //init 1

二、机构体初始化(在一、的基础上)

1.对机构体其中几个成员做初始化或修改

crunode1 的内存空间已经分配所以可以随意一些。
crunode2 未定义过也就没有进行过内存空间分配,也可以先定义变量然后再像crunode1一样进行初始化。

 crunode1 =(struct crunode){.data = 13};  //init 4//init one of the parameter of the structure.//equal to        crunode1.data  =  13;struct crunode crunode2 = {.data = 14,.name = "crunode2"};//init 4.1   //init some members of the structure

2.定义结构体,分配了内存空间,之后对每个成员进行赋值(注意数组成员赋值方法)

 struct d d1;    //determine 2.1//d1.name = {'D'}; //array can't do this. int just can be modified in turn with circulation,char can  be modfied inturn with circulation and use string.h()strcmp(name,string);strcmp(d1.name,"dudezheng");    //modify 3d1.grade = 100;      d1.str = "aliyun";

三、结构体定以后的内容修改(包括输入)

1.进行整体修改

(struct c)可以理解强制类型转换,即向编译器表明{ }内内容为struct c类型的

c[1]=(struct c){"Dudezheng","c3",3,{"b3",33}};    //modify 2

2.进行某些或某个成员进行修改

 crunode1 =(struct crunode){.data = 13};  //init 4//init one of the parameter of the structure.//equal to        crunode1.data  =  13;struct crunode crunode2 = {.data = 14,.name = "crunode2"};//init 4.1   //init some members of the structure

3.进行输入

第二个问题比较好懂,基本上是研究结构体的存储结构体就行了$$$$$

 //scanf("%s%s%d",&c[1].name,&c[1].q,&c[1].num); //false//scanf("%s,%s,%d,%s,%d",&c[1]);   //false the address of the structure main for the parameter of the function and transmit the address of the member of the structure like: &c[1].name

对于第一个语句,不知道哪里有问题,先分别对三个成员分别进行赋值,发现第二个成员赋值出现问题(过程中发现c[1].name前面的&可以省略,因为name本来就是一个指针)
测试代码:

#include<stdio.h>
#include<string.h>
struct b    //determine 2
{char* p;int data;
};struct c  //determine 3
{char name[20];char* q;int num;struct b b2;
}c[2] ={{"DU","c1",1,{"b1",11}},{"CH","c2",2,{"b2",22}}};//init 2,3int main()
{printf("before changing:%s\n",c[1].q);scanf("%s",c[1].q) ;printf("after changing:%s\n",c[1].q);return 0;
}

出现的问题:

解决办法:c[1].q是一个指针不可以直接用scanf()进行输入,而可以用一个字符数组来接受输入,然后再将c[1].q指向这个字符数组。而printf()的时候,因为c[1].q是一个字符串的初始地址,所以对它进行输出的时候就将字符串输出出来了。实现代码如下:

char array[20];
scanf("%s",array);
c[1].q = array;

三、结构体的调用及输出

1. 整体,部分成员输出

void print(struct c test)//output1
{printf("%s,%s,%d,%s,%d\n",test.name,test.q,test.num,test.b2.p,test.b2.data);//printf("%s,%s,%d,%s,%d\n",test);   //false-------c[1].q不能这么输入,其他的可以//printf("%s,%s,%d,%s,%d\n",c[1]);   //false
}

2.结构体嵌套输出

     printf("%d\n",crunode1.data);     //output 2printf("%d\n",c[1].b2.data);    //output 3

四、结构体在内存中的存储方式

取自:结构体在内存中的存储方式
结构体对齐原因有很大部分是因为计算机扫描的内存单元个数,也就是数据总线的大小。

原则1:

数据成员对齐规则:结构(struct或联合union)的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小的整数倍开始(比如int在32位机为4字节,则要从4的整数倍地址开始存储)。

原则2:

结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储。(struct a里存有struct b,b里有char,int,double等元素,那b应该从8的整数倍开始存储。)

原则3:

收尾工作:结构体的总大小,也就是sizeof的结果,必须是其内部最大成员的整数倍,不足的要补齐。
这三个原则具体怎样理解呢?我们看下面几个例子,通过实例来加深理解。

例1:struct{short a1;short a2;short a3;}A;struct{long a1;short a2;}B;sizeof(A) = 6; 这个很好理解,三个short都为2。sizeof(B) = 8; 这个比是不是比预想的大2个字节?long为4,short为2,整个为8,因为原则3。例2:struct A{int a;char b;short c;};struct B{char b;int a;short c;};sizeof(A) = 8; int为4,char为1,short为2,这里用到了原则1和原则3。sizeof(B) = 12; 是否超出预想范围?char为1,int为4,short为2,怎么会是12?还是原则1和原则3。深究一下,为什么是这样,我们可以看看内存里的布局情况。a         b       cA的内存布局:1111,     1*,      11b         a       cB的内存布局:1***,     1111,   11**其中星号*表示填充的字节。A中,b后面为何要补充一个字节?因为c为short,其起始位置要为2的倍数,就是原则1。c的后面没有补充,因为b和c正好占用4个字节,整个A占用空间为4的倍数,也就是最大成员int类型的倍数,所以不用补充。B中,b是char为1,b后面补充了3个字节,因为a是int为4,根据原则1,起始位置要为4的倍数,所以b后面要补充3个字节。c后面补充两个字节,根据原则3,整个B占用空间要为4的倍数,c后面不补充,整个B的空间为10,不符,所以要补充2个字节。再看一个结构中含有结构成员的例子:例3:struct A{int a;double b;float c;};struct B{char e[2];int f;double g;short h;struct A i;};sizeof(A) = 24; 这个比较好理解,int为4,double为8,float为4,总长为8的倍数,补齐,所以整个A为24。sizeof(B) = 48; 看看B的内存布局。e      f       g           h                         i B的内存布局:11* *, 1111, 11111111, 11 * * * * * *,1111* * * *, 11111111, 1111 * * * *省略宏与结构体中含位域字段两种情况说明,祥见原文。考虑一个问题,为什么要设计内存对齐的处理方式呢?如果体系结构是不对齐的,成员将会一个挨一个存储,显然对齐更浪费了空间。那么为什么要使用对齐呢?体 系结构的对齐和不对齐,是在时间和空间上的一个权衡。对齐节省了时间。假设一个体系结构的字长为w,那么它同时就假设了在这种体系结构上对宽度为w的数据 的处理最频繁也是最重要的。它的设计也是从优先提高对w位数据操作的效率来考虑的。有兴趣的可以google一下,人家就可以跟你解释的,一大堆的道理。最后顺便提一点,在设计结构体的时候,一般会尊照一个习惯,就是把占用空间小的类型排在前面,占用空间大的类型排在后面,这样可以相对节约一些对齐空间。

1.理论存储练习:

struct b //determine 2
{char* p;int data;
}stu;struct c   //determine 3
{char name[20];char* q;int num;struct b b2;
}c[2] ={{"DU","c1",1,{"b1",11}},{"CH","c2",2,{"b2",22}}};//init 2,3sizeof(stu)=  8 +4**** = 16;
sizeof(c[1])= 20**** + 8+4**** +8 +4  + ******** = 60  //char name [20]大小为20,则先填进去20字节;char*在64位系统中跟CPU字长一样所以是8字节,由原则一,需要从8的倍数开始,则补充4字节,然后填入8;int 在64位系统中为4字节,符合原则一则直接填入4字节;来到第二个结构体 其组成为char* 和int,由原则二,起开始需要为其最大成员的倍数,则为8字节的倍数,补充4字节(****),写入char* 8字节;int data符合原则一,直接填入4字节;然后整个结构体中最大成员为20字节,由原则三,其所占用内存空间为20字节的倍数,所以补足********,最后结果为60字节

在C语言中指针是一个unsigned 类型的无符号数,其所占内存字节一般是和计算机的CPU字长是一致的,拿32位计算机来说,指针所占的内存空间一般为4个字节,不管char *还是int *抑或是float *,都是4个字节。
程序员可以使用sizeof运算符获取数据类型或者某个变量的内存所占字节数。比如
printf("%d\t%d\t%d\n", sizeof(char *), sizeof(int *), sizeof(float *));

2.测试代码:

#include <stdio.h>#ifdef _DEBUG
#pragma pack(4)
struct test
{    char x[13]; // 13int d;        // 4    double f;     // 8
}ss;
#else
#pragma pack(8)
struct test
{    char x[13]; // 13int d;        // 4    double f;     // 8
}ss;
#endifint main(void){  printf("%d\n", sizeof(ss));  return 0;
}

代码

//some methods to determine the structure and some methods to init the structures and some to modify the structure#include<stdio.h>
#include<string.h>struct crunode
{struct crunode *parent;int data;char name[20];struct crunode *leftchild;struct crunode *rightchild;
}crunode1;
//in this define you can't determine the parameter.if you want to determine those you can determin at the position "a" like the next one .
// crunode is a type ,crunode1 is a parameter
struct a    //determine 1
{char* p;int data;
}a1 = {"test",99}; //init 1struct b  //determine 2
{char* p;int data;
};struct c  //determine 3
{char name[20];char* q;int num;struct b b2;
}c[2] ={{"DU","c1",1,{"b1",11}},{"CH","c2",2,{"b2",22}}};//init 2,3struct d    //determine 2.1------deal with array problem
{char name[20];int grade;char *str;
};void print(struct c test)//output1
{printf("%s,%s,%d,%s,%d\n",test.name,test.q,test.num,test.b2.p,test.b2.data);//printf("%s,%s,%d,%s,%d\n",test);   //false
}int main()
{//struct  crunode  crunode;crunode1.data = 99;    //modify 1printf("%d\n",crunode1.data);   //output 2crunode1 =(struct crunode){.data = 13};  //init 4//init one of the parameter of the structure.struct crunode crunode2 = {.data = 14,.name = "crunode2"};//init 4.1   //init some members of the structureprintf("%d\n",c[1].b2.data);    //output 3c[1]=(struct c){"Dudezheng","c3",3,{"b3",33}};     //modify 2printf("After change:");printf("%d\n",c[1].b2.data);    //output 3//scanf("%s%s%d",&c[1].name,&c[1].q,&c[1].num);//scanf("%s,%s,%d,%s,%d",&c[1]);   //false the address of the structure main for the parameter of the function and transmit the address of the member of the structure like: &c[1].namestruct d d1;  //determine 2.1//d1.name = {'D'}; //array can't do this. int just can be modified in turn with circulation,char can  be modfied inturn with circulation and use string.h()strcmp(name,string);strcmp(d1.name,"dudezheng");    //modify 3d1.grade = 100;      d1.str = "aliyun";print(c[1]);   //output 1//printf("%s,%s,%d,%s,%d\n",c[1]);   //falsereturn 0;
}

C语言结构体复习(一)相关推荐

  1. c语言结构体复习笔记

    1.定义结构提的语法格式 struct [结构名称] { 成员变量定义 }[变量名列表]: 2.结构体数据类型名 struct [结构名称],[结构名称]如果缺省则无法使用结构类型名来定义变量. 3. ...

  2. 计算机科学类专升本复习之“C语言结构体”详解(初稿)

    C语言结构体详解,C语言struct用法详解 前面所学到的"数组":它是一组具有"相同类型"的数据的集合. 但是在实际的编程中,我们往往还需要 一组" ...

  3. c语言结构体教案,结构体——教学设计

    <结构体--教学设计>由会员分享,可在线阅读,更多相关<结构体--教学设计(7页珍藏版)>请在人人文库网上搜索. 1.课堂教学设计表章节名称结构体学科C语言程序设计授课班级大一 ...

  4. ARM汇编语言实现peek()_ARM汇编之访问C语言结构体数据

    前言 本文的写作目的在于装逼,没有要产生实际价值的意思. 前几天在做编译器的项目,有一个项目团队成员一直在问我ARM汇编能不能读C语言的结构体.我心想,我这生成ARM汇编的代码是用C++写的呀,又不是 ...

  5. C语言结构体和结构体数组示例 - Win32窗口程序演示

    C语言结构体和结构体数组的使用: /* C结构体和结构体数组示例,by bobo */#include <windows.h>LRESULT CALLBACK WndProc (HWND, ...

  6. C语言结构体-大小,对齐,填充,使用及其他

    C语言结构体-大小,对齐 C语言中的结构体(struct)的定义 在C语言中,最常用的数据结构就是结构体了,结构体也是其它数据结构(比如链表等)的基础,结构体的使用非常简单. 比如,定义一个结构体: ...

  7. 关于c语言结构体偏移的一点思考

    注:此处只是利用了编译器的特性来计算结构体偏移 这句话就一笔带过,说得有点牵强附会.以后有时间自己再详细了解一下编译器的特性... more exceptional c++ 中文版 26页 https ...

  8. C语言结构体指针的使用方法

    1.首先定义一个结构体,给它取别名: typedef struct node{ struct node * next://指向下一节点 int data://数据域 }pnode,*linklist; ...

  9. C语言结构体与联合体

    c语言结构体与联合体 结构类型定义和结构变量说明 一.结构的定义 二.结构类型变量的说明 结构变量的赋值 结构变量的初始化 结构数组 结构指针变量 其访问的一般形式为: (*结构指针变量).成员名 结 ...

最新文章

  1. Select2 的简单使用
  2. 独家 | Kaggle 大神Dan Becker与你分享他的数据科学之旅!
  3. frdora10_a8_linux,在Fedora 10中安装IRAF
  4. 【C++ 语言】容器 ( queue 队列 | stack 栈 | priority_queue 优先级队列 | set 集合 | 容器遍历 | map )
  5. Uboot分析(三)
  6. 树莓派Raspberry命令行配置无线网络连接
  7. 操作方法:Maven的Spring Boot和Thymeleaf
  8. input长度随输入内容动态变化 input光标定位在最右侧
  9. Mysql学习总结(12)——21分钟Mysql入门教程
  10. 这个连“炒菜的油”都不放过的“吝啬”男人,却用“吝啬”创造了世界奇迹!...
  11. 魔都高清特写曝光,外国人眼中的魔幻
  12. 彩虹浏览器使用技巧:页签自动切换
  13. Filecoin Gas基础费率降至0.23 nanoFIL
  14. 录入商品信息的c语言,超市商品信息系统设计报告及程序C语言.doc
  15. NP、NP-完全、NP-难问题
  16. Matlab 谢尔宾斯基三角形
  17. hcia hdcp实验
  18. c语言中char与static
  19. SAP-MM-PA精解分析系列之基本介绍(01)-采购基本流程
  20. 【搬运】1 简谱和基本知识

热门文章

  1. (01)ORB-SLAM2源码无死角解析-(64) BA优化(g2o)→闭环线程:Optimizer::OptimizeSim3→Sim3变换优化
  2. Ubuntu安装后MTK系列网卡无法开启wifi和蓝牙的部分解决方式
  3. 2019北航961考研初试经验之谈
  4. python接口压测1000并发_测试工具:黑羽压测
  5. 青春励志感悟人生语录
  6. idea的pom.xml文件图标是黄色而不是蓝色
  7. .jar和sources.jar及javadoc.jar三者的关系
  8. python无法安装tensorflow_Windows上安装Tensorflow踩的坑
  9. ios中导入第三方类库
  10. 自然语言处理——词性标注、词干提取、词形还原