精华内容
下载资源
问答
  • 关于结构体变量等于0的问题

    千次阅读 2016-07-06 10:22:34
    1 综述 ...其中A是结构体变量,犹豫了一下,这么简单的东西不应该啊,因此做个学习。 2 结构体变量的值 有如下结构体: typedef struct LsAfccDataWriteReqTag { TaskId TaskId; Int32 DataID;

    1 综述

    今天看到几行代码:

    if(!A)
    {
    }
    else
    {
    }

    其中A是结构体变量,犹豫了一下,这么简单的东西不应该啊,因此做个学习。

    2 结构体变量的值

    有如下结构体:

    typedef struct  LsAfccDataWriteReqTag 
    {
      TaskId              TaskId; 
      Int32               DataID;      
      Bool                OnOff;      
      Int8                Oprt;        
      union LSAFCC_Data   Data;        
    }LsAfccDataWriteReq;

    我们可以直接用下面的代码将结构体变量设置为0:

    LsAfccDataWriteReq req = {0};

    上面这行代码相当于下面这行代码:

    memset(&req, 0, sizeof(LsAfccDataWriteReq));
    实际上,如果req是全局的或者静态的编译器就默认初始化为0, 如果局部的(栈上分配)则为随机值。

    如果在栈上分配这个结构并且只初始化第一个字段,如:

    LsAfccDataWriteReq   req   =   {1};
    那么req剩下的字段默认初始化为0(不是随机值!)

    3 结语

    实际上,数组同样是这样,如果栈上的数组没有初始化,则为随机值,如果初始化了第一个变量或者前几个变量,则后面的变量默认初始化为0。

    参考文献

    本文是根据本帖整理而来。

    【2016-07-06】

    展开全文
  • c语言结构体学习整理(结构体初始化,结构体指针)

    万次阅读 多人点赞 2018-11-01 20:22:12
    c语言中交换两个结构体的值(结构体指针) 1关于语言的结构体: 首先我们为什么要用到结构体,我们都已经学了很多int char …等类型还学到了同类型元素构成的数组,以及取上述类型的指针,在一些小应用可以灵活...

    渣渣c的c语言学习之路

    1.关于c语言的结构体:

    首先我们为什么要用到结构体,我们都已经学了很多int char …等类型还学到了同类型元素构成的数组,以及取上述类型的指针,在一些小应用可以灵活使用,然而,在我们实际应用中,每一种变量进行一次声明,再结合起来显然是不太实际的,类如一位学生的信息管理,他可能有,姓名(char),学号(int)成绩(float)等多种数据。如果把这些数据分别单独定义,就会特别松散、复杂,难以规划,因此我们需要把一些相关的变量组合起来,以一个整体形式对对象进行描述,这就是结构体的好处。

    2首先我们要了解一些小知识

    2.1**只有结构体变量才分配地址,而结构体的定义是不分配空间的。**
    2.2结构体中各成员的定义和之前的变量定义一样,但在定义时也不分配空间。
    2.3结构体变量的声明需要在主函数之上或者主函数中声明,如果在主函数之下则会报错
    2.4c语言中的结构体不能直接进行强制转换,只有结构体指针才能进行强制转换
    2.5相同类型的成员是可以定义在同一类型下的
    列如

    
    struct Student
    { 
    	int number,age;//int型学号和年龄
    	char name[20],sex;//char类型姓名和性别
    	float score;
    }

    最后的分号不要忘了 有的编译器会自动加上,因此有的同学就会不注意。

    3关于结构体变量的定义和引用

    在编译时,结构体的定义并不分配存储空间,对结构体变量才按其数据结构分配相应的存储空间

    
     struct Book
     { 
     	char title[20];//一个字符串表
    
    示的titile 题目
    	char author[20];//一个字符串表示的author作者
     	float value;//价格表示 
     };//这里只是声明 结构体的定义 
    struct Book book1,book2;//结构体变量的定义 分配空间
    
    book1.value;//引用结构体变量
    

    定义结构体变量以后,系统就会为其分配内存单元,比如book1和book2在内存中占44个字节(20+20+4)具体的长度你可以在你的编译器中使用sizeof关键字分别求出来。
    列如

    当然,要注意一点:用sizeof关键字求结构体长度时,返回的最大基本类型所占字节的整数倍 比方说我们上面求得的为44 为 float(4个字节)的整数倍,
    但是我们把title修改为title[22]; 这时正常长度为46 ,但是你会发现实际求得的为48,(4的整数倍)

    这就涉及到结构体的存储

    1结构体整体空间是占用空间最大的成员(的类型)所占字节数的整数倍。

    2.结构体的每个成员相对结构体首地址的偏移量(offset)都是最大基本类型成员字节大小的整数倍,如果不是编译器会自动补齐,

    关于这个我们简单介绍下:

    1.偏移量----偏移量指的是结构体变量中成员的地址和结构体变量首地址的差。即偏移字节数,结构体大小等于最后一个成员的偏移量加上他的大小,第一个成员的偏移量为0,

    struct S1
    {
        char a;
    
        int b;
    
        double c;
    };
    

    这里char a 偏移量为1 之后为int b 因为偏移量1不为int(4)的整数倍,所以会自动补齐,而在 double c 时,偏移量为8 是double(8)的整数倍,所以不用自动补齐 最后求得结构体得大小为 16

    具体看下图:
    在这里插入图片描述
    通过上面的代码同学们应该会有一个简单的认知

    4结构体变量的初始化

    结构体的初始化有很多需要注意的地方,这里我们说明下
    首先是几种初始化的方法
    ps在对结构体变量初始化时,要对结构体成员一一赋值,不能跳过前面成员变量,而直接给后面成员赋初值,但是可以只赋值前面几个,对与后面未赋值的变量,如果是数值型,则会自动赋值为0,对于字符型,会自动赋初值为NULL,即‘\0’

    4.1定义时直接赋值

    struct Student
    { 
    	char name[20];
    	char sex;
    	int number;
    }stu1={"zhaozixuan",'M',12345};
    //或者
    struct Student
    { 
    	char name[20];
    	char sex;
    	int number;
    }struct Student stu1={"zhaozixuan",'M',12345};
    
    

    注意字符为‘ ’ 字符串为""
    4.2定义结构体之后逐个赋值

    stu1.name="王伟";
    stu1.sex='M';
    stu1.number=12305;
    //也可用strcpy函数进行赋值
    strcpy(stu1.name,"王伟");
    
    

    4.3定义之后任意赋值

     struct Student stu1={
      .name="Wang",
      .number=12345,
      .sex='W', 
     };//可以对任意变量赋值
    

    这样写的好处时不用按照顺序来进行初始化,而且可以对你想要赋值的变量直接进行赋值,而不想赋值的变量可以不用赋值

    需要注意的是如果在定义结构体变量的时候没有初始化,那么后面就不能全部一起初始化了;

    等下结构体数组初始化时我们还会有一个讲解

    这里我们顺带提一下typedef说明结构体类型


    这里的BOOK就相当于struct book的一个别名一样,用它来定义结构体变量非常简便
    主要也是考二级要用到,所以我们简单介绍下

    5结构体变量的引用(输出和输入)

    5.1结构体变量的赋值用scanf赋值和printf输出时跟其他变量操作一样
    但是有几点需要注意
    (1) .是运算符,在所有运算符优先级中最高
    (2)如果结构体的成员本身是一个结构体,则需要继续用.运算符,直到最低一级的成员。

    struct Student
    {	char name[20];
    	char sex;
    	int number;
    	struct Date
    	{
    		int year;
     		int month;
     		int day;
    	}birthday;
    
    }stu1;
    printf("%d",stu1.birthday);//这样子是错误的,因为birthday也是一个结构体变量
    scanf("%d",&stu1.birthday.month);//正确
    

    (3)可以引用接头体变量成员的地址,也可以引用结构体变量的地址:

    printf("%o", student);(输出student的首地址)(%o 按八进制输出)

    6结构体数组及其初始化(重点)

    这里我们简单说下,具有相同类型的结构体变量组成数组就是结构体数组

    结构体数组与结构体变量区别只是将结构体变量替换为数组

    struct Student
    { 
    	char name[20];
    	char sex;
    	int number;
    }stu1[5]={
    	 {"zhaozixuan",'M',12345},
    	 {"houxiaohong",'M',12306},
    	 {"qxiaoxin",'W',12546},
    	 {"wangwei",'M',14679},
    	 {"yulongjiao",'W',17857}
    };
    stu1[3].name[3]//表示stu1的第三个结构变量中姓名的第五个字符
    //若初始化时已经是结构体数组全部元素[]中的数可以不写如stu1[]=
    

    注意结构体数组要在定义时就直接初始化,如果先定义再赋初值是错误的
    比如:

    struct Student stu1;
    stu1[3]={
      {"zhaozixuan",'M',12345},
      {"houxiaohong",'M',12306},
      {"qxiaoxin",'W',12546}
      };
      
    

    这样子是错误的,

    这里我在写的时候遇到一些问题,还是结构体数组初始化的问题,折腾了下解决了,给大家分享下
    对于数组初始化时
    比如

    char str[20];
    str="I love you";/* 这样会修改数组的地址,但是数组的地址分配之后是不允许改变的 */
    
    

    在第一条语句中 str就已经被定义成数组而在C99标准中不允许将字符串(实际上是一个指针变量) 赋值给数组,所以如果我们直接赋值是错误的

    那么怎么弄呢
    这里提供3种方法

    1.定义数组时直接定义
    char str[20]=“I love you”;

    2.用strcpy或者memset函数进行复制
    char str[20];
    strcpy(str,“I love you”);
    再用到memset函数时,出现了一些问题
    对于memcset函数简单介绍下

    memset
    void *memset(void *s,int c,size_t n)
    作用:将已开辟内存空间s的首n个字节的值设为值c。

    char str[20];
    memset(str,'a',20);
    

    如果是字符类型数组的话,memset可以随便用,但是对于其他类型的数组,一般只用来清0或者填-1,如果是填充其他数据就会出错

    int str[10];
    memset(str,1,sizeof(str));//这样是错误的
    
    

    这里我们说下这个错误,

    首先我们要知道memset在进行赋值时,是按字节为单位来进行赋值的,每次填充的数据长度为一个字节,而对于其他类型的变量,比如int,占4个字节 所以sizeof(str)=40; 而用memset赋值时,将会对指向str地址的前40个字节进行赋值0x01(00000001) 的操作,把0x00000000赋值4次0x01操作变为0x01010101(00000001000000010000000100000001)

    相当于给“前10个int”进行了赋值0x01010101的操作 对应十进制的16843009
    所以会出很大的错误

    这里请务必要注意,但是如果是清零一个数组用memset还是很方便的
    简单使用的话同学们用strcmp函数就行

    3用指针(注意内存分配)
    char *str;
    str=“I love you”;

    这两句话的本质是,在内存中开辟一段内存空间,把"I love you"放进这段内存空间,然后把这段内存空间的地址交给str,由于str是变量,所以给它赋值是合法的。

    请注意,在我们进行数组初始化的时候如果定义的数组过长,而我们只初始化了一部分数据,对于未初始化的数据如果是数值型,则会自动赋值为0,对于字符型,会自动赋初值为NULL,即‘\0’ 即不足的元素补以默认值
    这里我们在4小节中也提到了
    比如

    int str[10]={1};//这里只是把str的第一个元素赋值为1,其他元素默认为0
    
    



    7结构体与指针

    我们知道,指针指向的是变量所占内存的首地址,在结构体中,指针指向的是结构体变量的起始地址,当然也可指向结构体变量的元素
    这里我们分为三部分
    7.1指向结构体变量的指针

    定义形式一般为
    struct 结构体名* 指针名;
    比如: struct Student* p;

    struct Student
    {	
    	char cName[20];
     	int number;
     	char csex;  
    }student1;
    struct Student*p;
    p=&student1;
    //若为结构体数组则
    struct Student stu1[5];
    struct Student*p;
    p=stu1;//因为stu1为结构体数组而p=stu1直接是指向stu1的首地址,就不用再加&符
    
    

    用结构体指针变量访问结构体变量成员有以下两种方式:
    (*p).cName //这里的括号不能少,在5.1中有提到
    p->cName

    简单来说以下三种形式是等价的

    p->cName
    (*p).cName 
    student1.cName
    p->cName //可以进行正常的运算
    

    p->number++; 是将结构体变量中number的值进行运算,然后再加一,
    这里要注意下,等下在7.2中会有比较

    7.2指向结构体数组的指针

    7.1中我们已经提到结构体数组指针的命名,这里我们仅对一些知识点做下介绍
    这里我们接着来说结构体数组指针
    在我们想要用指针访问结构体数组的第n个数据时可以用

    struct Student stu1[5];
    struct Student*p;
    p=stu[n];
    (++p).number//是指向了结构体数组下一个元素的地址
    
    

    7.3结构体成员是指针类型变量
    比如

    struct Student
    {
     	char* Name;//这样防止名字长短不一造成空间的浪费
     	int number;
     	char csex;  
    }student1;
    
    

    在使用时可以很好地防止内存被浪费,但是注意在引用时一定要给指针变量分配地址,如果你不分配地址,结果可能是对的,但是Name会被分配到任意的一的地址,结构体不为字符串分配任何内存存储空间具有不确定性,这样就存在潜在的危险,

    struct Student
    {
     	char* Name;
     	int number;
     	char csex;  
    }stu,*stu;
    
    stu.name=(char*)malloc(sizeof(char));//内存初始化
    

    这里我们说一下,同学们看书的时候一般不会看到,
    如果我们定义了结构体指针变量,他没有指向一个结构体,那么这个结构体指针也是要分配内存初始化的,他所对应的指针类型结构体成员也要相应初始化分配内存

    struct Student
    {
     	char* Name;
     	int number;
    	char csex;  
    }stu,*stu;
    stu = (struct student*)malloc(sizeof(struct student));./*结构体指针初始化*/
      stu->name = (char*)malloc(sizeof(char));/*结构体指针的成员指针同样需要初始化*/  
    
    

    7.4二叉树遍历算法
    二叉树的二叉链表类型定义如下:
    typedef struct btnode {
    datatype data;
    struct btnode *lchild,*rchild;
    };
    这里我们仅仅提出以下,因为涉及到链表,感兴趣的同学可以去学习下(二级要用),
    7.5结构体作为函数参数

    首先我们要注意的一点,使用结构体变量作为函数参数的时候,采取的是值传递的方式,将结构体所占内存单元的内容全部传递给形参,并且形参必须也要是同类型的结构体变量,在使用时,会自动创建一个结构体变量作为原变量的副本,并且也需要占内存,并且在调用期间如果修改(形参)结构体中成员的值,修改值是无效的

    而如果用指针作为实参,传递给函数的形参,这时候传递的是结构体的地址,形参所指向的地址就是结构体变量的地址,这时候进行修改的话是可以修改的,这正是指针的精华所在

    在这里我们再提供几种互换两个结构体的方法

    struct Student
    {
     char cName[20];
     int number;
     char csex;  
    }student1,student2;
    struct Student student1={"Wang",12345,'W'};
    struct Student student2={"Zhao",54321,'M'}; 
    struct Student*stu1=&student1;
    struct Student*stu2=&student2;
    
    struct Student *student3;
    student3=stu1;
    stu1=stu2;
    stu2=student3;//互换地址
    
    2对于同类型结构体直接互换值就行
    struct stu student3;
    student3=student1;
    student1=student2;
    student2=student3;
    //这里也可以写成应strcmp函数互换
    
    3memcpy()函数进行互换
    
    
    4比较笨的方法: 用for循环互换
    

    最后提下memset清空结构体

    struct Student
    {
     char cName[20];
     int number;
     char csex;  
    }stu1;
    
    一般情况下,清空str的方法:
      str.cName[0]='\0';
      str.csex='0';
      str.number=0;
      但是我们用memset就非常方便:
      memset(&str,0,sizeof(struct Student));
      如果是数组:
      struct Student stu[10];
      就是
      memset(stu,0,sizeof(struct Student)*10);
    

    整理不易,点个赞再走呗!

    展开全文
  • 结构体

    2011-07-14 20:45:37
    结构体
  • 结构体&结构体数组

    万次阅读 多人点赞 2018-08-16 18:17:39
    1、结构体的定义 struct 结构体类型名 { 类型名 成员名; 类型名 成员名; …… }; 先声明结构体类型,再定义结构体变量名 声明结构体类型,不分配空间 定义结构体类型变量,就要分配内存空间 1)结构体被...

    1、结构体的定义

    struct 结构体类型名

    类型名 成员名;
    类型名 成员名;
    ……
    };

    先声明结构体类型,再定义结构体变量名

    声明结构体类型,不分配空间

    定义结构体类型变量,就要分配内存空间

    1)结构体被分配的内存空间

    struct student
    {
        int num;//4字节
        char name[20];//20字节
        char sex;//1字节,但因为内存对齐占4字节
        int age;//4字节
        double score;//8字节
        char addr[30];//30字节,内存对齐占32字节
    };
    int main()
    {
        struct student stu1,stu2;
        printf("%d\n",sizeof(stu1));
        return 0;
    }

    2)结构体的嵌套

    /*
    *copyright(c) 2018,HH
    *All rights reserved.
    *作 者:HH
    *完成日期:2018年8月15日
    *版本号:v1.0
    *
    *问题描述:结构体嵌套、赋值、输出
    *输入描述:;
    *程序输出:
    */
    
    #include<stdio.h>
    #include<string.h>
    struct date
    {
        int month;
        int day;
        int year;
    };
    struct student
    {
        int num;
        char name[20];
        char sex;
        struct date birthday;
        float score;
    };
    struct student1;
    struct student2={10002,"MaYun",'f',8,28,2000,99.9999};
    int main()
    {
        student1=student2;
        printf("%d\n",student1.num);
        printf("%s\n",student1.name);
        printf("%c\n",student1.sex);
        printf("%d\n",student1.date birthday.month);
        printf("%d\n",student1.date birthday.day);
        printf("%d\n",student1.date birthday.year);
        printf("%f\n",student1.score);
        return 0;
    }
    

    3)结构体的成员是数组

    /*
    *copyright(c) 2018,HH
    *All rights reserved.
    *作 者:HH
    *完成日期:2018年8月14日
    *版本号:v1.0
    *
    *问题描述:结构体输出
    *输入描述:;
    *程序输出:
    */
    
    #include<stdio.h>
    #include<string.h>
    struct student//自定义结构体
    {
        int num;//学号
        char name[10];//名字
        double score[3];//三科成绩
    };
    void print(struct student s)//自定义输出函数
    {
        printf("%ld %s\n",s.num,s.name);
        printf("%1f %1f %1f\n",s.score[0],s.score[1],s.score[2]);
    }
    
    int main()
    {
        struct student stu;
        stu.num=42001;
        strcpy(stu.name,"MaHuTeng");//字符串赋值函数,将字符串复制到数据项name中
        stu.score[0]=98,stu.score[1]=99,stu.score[2]=100;
        print(stu);
        return 0;
    }
    

    2、结构体数组

    定义:该数组的每个元素都是一个结构体。

    结构体数组的初始化及直接输出方法:

    /*
    *copyright(c) 2018,HH
    *All rights reserved.
    *作 者:HH
    *完成日期:2018年8月16日
    *版本号:v1.0
    *
    *问题描述:结构体数组的正确初始化及输出
    *输入描述:;
    *程序输出:
    */
    
    #include<stdio.h>
    #include<string.h>
    struct student
    {
        int num;
        char name[20];
        char sex;
        int age;
        float score;
        char addr[30];
    };
    int main()
    {
        int i;
        struct student stu[3]={{10101,"LiuHu",'F',18,99.7,"beijing road"},{10102,"NaoDan",'M',17,99.8,"shanghai road"},{10103,"MaHuangTeng",'F',48,99.9,"shenzhen road"}};
        for(i=0;i<3;i++)
        {
           printf("%d %s %c %d %1f %s\n",stu[i].num,stu[i].name,stu[i].sex,stu[i].age,stu[i].score,stu[i].addr);
        }
        return 0;
    }
    

    以下为自定义函数调用的方式实现结构体数组的输出:

    /*
    *copyright(c) 2018,HH
    *All rights reserved.
    *作 者:HH
    *完成日期:2018年8月16日
    *版本号:v1.0
    *
    *问题描述:结构体数组的正确初始化及输出(函数调用的方法)
    *输入描述:;
    *程序输出:
    *注意,数组地址传递容易出错
    */
    
    #include<stdio.h>
    #include<string.h>
    struct student
    {
        int num;
        char name[20];
        char sex;
        int age;
        float score;
        char addr[30];
    };
    struct student s[3];
    void print(struct student s[3])//自定义输出函数以供调用
    {
        int i;
        for(i=0;i<3;i++)
        {
            printf("%d %s %c\n",s[i].num,s[i].name,s[i].sex);
            printf("%d %1f %s\n",s[i].age,s[i].score,s[i].addr);
        }
    }
    int main()
    {
        struct student stu[3]={{10101,"LiuHu",'F',18,99.7,"beijing road"},{10102,"NaoDan",'M',17,99.8,"shanghai road"},{10103,"MaHuangTeng",'F',48,99.9,"shenzhen road"}};
        print(stu);//若此处写成print(stu[])则会报错expected expression before'print'
        return 0;
    }
    

    在此方法中,由于print()函数的定义

    print(stu)不会报错

    而print (stu[ ])会报错,

    数组名等价于等同于指向数组首元素的指针,stu[ ]代表的是数组,而stu代表指向的数组首地址的指针

    报错原因是,因为被调用函数的形参对象是数组名,而不是数组!

    展开全文
  • 结构体的定义与使用 结构体是一种构造数据类型 把不同类型的数据组合成一个整体 结构体的定义形式: struct 结构体名{ 结构体所包含的变量或数组 }; 结构体是一种集合,它里面包含了多个变量或数组,它们的...

    1.结构体的定义与使用

    • 结构体是一种构造数据类型
    • 把不同类型的数据组合成一个整体

    结构体的定义形式:

    struct 结构体名{
        结构体所包含的变量或数组
    };

    结构体是一种集合,它里面包含了多个变量或数组,它们的类型可以相同,也可以不同,每个这样的变量或数组都称为结构体的成员(Member)。请看下面的一个例子:

    struct stu{
        char name[];  //姓名
        int num;  //学号
        int age;  //年龄
        char group;  //所在学习小组
        float score;  //成绩
    };

    注意:大括号后面的分号;不能少,这是一条完整的语句。

    stu 为结构体名,它包含了 5 个成员,分别是 name、num、age、group、score。结构体成员的定义方式与变量和数组的定义方式相同,只是不能初始化

    结构体也是一种数据类型,它由程序员自己定义,可以包含多个其他类型的数据。
    像 int、float、char 等是由C语言本身提供的数据类型,不能再进行分拆,我们称之为基本数据类型;而结构体可以包含多个基本类型的数据,也可以包含其他的结构体,我们将它称为复杂数据类型或构造数据类型。

    • 先定义结构体类型,再定义结构体变量
     struct   student 
    {       
     int num;
     char  name[20];
     char sex;
     int age; 
     float score;
     char addr[30];
     };
     struct student stu1,stu2;         
    • 定义结构体类型的同时定义结构体变量
     struct   data
     {      
      int day int month;
      int year
     }time1,time2; 
    • 直接定义结构体变量
     struct 
    {
     char name[20];
     char sex; 
     int num; 
     float score[3]
     }person1,person2; 

    2.结构体变量的初始化

    和其它类型变量一样,对结构体变量可以在定义时指定初始值。

    #include <stdio.h>
     
    struct Books
    {
       char  title[50];
       char  author[50];
       char  subject[100];
       int   book_id;
    } book = {"C 语言", "RUNOOB", "编程语言", 123456};
     
    int main()
    {
        printf("title : %s\nauthor: %s\nsubject: %s\nbook_id: %d\n", book.title, book.author, book.subject, book.book_id);
    }

    输出结果:

    title : C 语言
    author: RUNOOB
    subject: 编程语言
    book_id: 123456

    3.访问结构成员

    为了访问结构的成员,我们使用成员访问运算符(.)

    引用形式:<结构体类型变量名>.<成员名>

    注意:结构体变量不能整体引用,只能引用变量成员

    成员访问运算符是结构变量名称和我们要访问的结构成员之间的一个句号。可以使用 struct 关键字来定义结构类型的变量。下面的实例演示了结构的用法:

    #include <stdio.h>
    int main(){
        struct{
            char *name;  //姓名
            int num;  //学号
            int age;  //年龄
            char group;  //所在小组
            float score;  //成绩
        } stu1;
    
        //给结构体成员赋值
        stu1.name = "Tom";
        stu1.num = 12;
        stu1.age = 18;
        stu1.group = 'A';
        stu1.score = 136.5;
    
        //读取结构体成员的值
        printf("%s的学号是%d,年龄是%d,在%c组,今年的成绩是%.1f!\n", stu1.name, stu1.num, stu1.age, stu1.group, stu1.score);
    
        return 0;
    }

    运行结果:
    Tom的学号是12,年龄是18,在A组,今年的成绩是136.5!

    除了可以对成员进行逐一赋值,也可以在定义时整体赋值,例如: 

    struct{
        char *name;  //姓名
        int num;  //学号
        int age;  //年龄
        char group;  //所在小组
        float score;  //成绩
    } stu1, stu2 = { "Tom", 12, 18, 'A', 136.5 };

    不过整体赋值仅限于定义结构体变量的时候,在使用过程中只能对成员逐一赋值,这和数组的赋值非常类似。

    需要注意的是,结构体是一种自定义的数据类型,是创建变量的模板,不占用内存空间;结构体变量才包含了实实在在的数据,需要内存空间来存储。

    4.结构作为函数参数

    可以把结构作为函数参数,传参方式与其他类型的变量或指针类似。例如:

    #include <stdio.h>
    #include<string.h>
    
    struct Books
    {
    	char title[50];
    	char author[50];
    	char subject[100];
    	int book_id;
    };
    
    void printBook(struct Books book);//函数声明
    
    int main()
    {
    	struct Books Book1;//声明Book1,类型为Books
    	struct Books Book2;
    
    	/* Book1 详述 */
    	strcpy(Book1.title, "C Programming");
    	strcpy(Book1.author, "Nuha Ali");
    	strcpy(Book1.subject, "C Programming Tutorial");
    	Book1.book_id = 6495407;
    	printBook(Book1);
    	return 0;
    }
    void printBook(struct Books book)
    {
    	printf("Book title:%s\n", book.title);
    	printf("Book author:%s\n", book.author);
    	printf("Book subject:%s\n", book.subject);
    	printf("Book book_id:%d\n", book.book_id);
    }

    运行结果:

    Book title:C Programming
    Book author:Nuha Ali
    Book subject:C Programming Tutorial
    Book book_id:6495407

    5.结构体数组

    所谓结构体数组,是指数组中的每个元素都是一个结构体。在实际应用中,结构体数组常被用来表示一个拥有相同数据结构的群体,比如一个班的学生、一个车间的职工等。

    定义结构体数组和定义结构体变量的方式类似,请看下面的例子:

    struct stu{
        char *name;  //姓名
        int num;  //学号
        int age;  //年龄
        char group;  //所在小组 
        float score;  //成绩
    }class[5];
    //表示一个班有5个人

    结构体数组在定义的同时也可以初始化,例如:

    struct stu{
        char *name;  //姓名
        int num;  //学号
        int age;  //年龄
        char group;  //所在小组 
        float score;  //成绩
    }class[5] = {
        {"Li ping", 5, 18, 'C', 145.0},
        {"Zhang ping", 4, 19, 'A', 130.5},
        {"He fang", 1, 18, 'A', 148.5},
        {"Cheng ling", 2, 17, 'F', 139.0},
        {"Wang ming", 3, 17, 'B', 144.5}
    };

    当对数组中全部元素赋值时,也可以不给出数组长度,如:

    struct stu{
        char *name;  //姓名
        int num;  //学号
        int age;  //年龄
        char group;  //所在小组 
        float score;  //成绩
    }class[] = {
        {"Li ping", 5, 18, 'C', 145.0},
        {"Zhang ping", 4, 19, 'A', 130.5},
        {"He fang", 1, 18, 'A', 148.5},
        {"Cheng ling", 2, 17, 'F', 139.0},
        {"Wang ming", 3, 17, 'B', 144.5}
    };

    结构体数组的使用也很简单。例如,计算全班学生的总成绩、平均成绩和140分一下的人数:

    #include <stdio.h>
    
    struct{
        char *name;  //姓名
        int num;  //学号
        int age;  //年龄
        char group;  //所在小组
        float score;  //成绩
    }class[] = {
        {"Li ping", 5, 18, 'C', 145.0},
        {"Zhang ping", 4, 19, 'A', 130.5},
        {"He fang", 1, 18, 'A', 148.5},
        {"Cheng ling", 2, 17, 'F', 139.0},
        {"Wang ming", 3, 17, 'B', 144.5}
    };
    
    int main(){
        int i, num_140 = 0;
        float sum = 0;
        for(i=0; i<5; i++){
            sum += class[i].score;
            if(class[i].score < 140) num_140++;
        }
        printf("sum=%.2f\naverage=%.2f\nnum_140=%d\n", sum, sum/5, num_140);
        return 0;
    }

    运行结果:

    sum=707.50
    average=141.50
    num_140=2

    6.指向结构的指针

    可以定义指向结构的指针,方式与定义指向奇特类型变量的指针类似,

    定义形式:struct 结构体名 *结构体指针名;

    struct Books *struct_pointer;

    定义之后可以在上述定义的指针变量中存储结构变量的地址。例:

    struct_pointer = &Book1;

    为了使用指向该结构的指针访问结构的成员,必须使用->运算符,如下所示:

    struct_pointer->title;

    定义结构体指针的实例:

    struct stu{
        char *name;  //姓名
        int num;  //学号
        int age;  //年龄
        char group;  //所在小组
        float score;  //成绩
    } stu1 = { "Tom", 12, 18, 'A', 136.5 };
    //结构体指针
    struct stu *pstu = &stu1;

    也可以在定义结构体的同时定义结构体指针:

    struct stu{
        char *name;  //姓名
        int num;  //学号
        int age;  //年龄
        char group;  //所在小组
        float score;  //成绩
    } stu1 = { "Tom", 12, 18, 'A', 136.5 }, *pstu = &stu1;

    注意:结构体变量名和数组名不同,数组名在表达式中会被转换为数组指针,而结构体变量名不会,无论在任何表达式中它表示的都是整个集合本身,要想取得结构体变量的地址,必须在前面加&符号,所以给p赋值只能写成

    struct stu *p=&stu1;

    而不能写成:

    struct stu *p=stu1;

    注意:结构体和结构体变量是两个不同的概念:结构体是一种数据类型,是一种创建变量的模板,编译器不会为它分配内存空间,就像 int、float、char 这些关键字本身不占用内存一样;结构体变量才包含实实在在的数据,才需要内存来存储。下面的写法是错误的,不可能去取一个结构体名的地址,也不能将它赋值给其他变量:

    struct stu *pstu = &stu;
    struct stu *p=stu;

    7.获取结构体成员

    通过结构体指针可以获取结构体成员,一般形式为:

    (*pointer).memberName

    或者:

    pointer->memberName

    第一种写法中,.的优先级高于*,(*pointer)两边的括号不能少,如果去掉括号写成*pointer.memberName,那么就等效于*(pointer.memberName),这样意义就不对了。

    第二种写法中,->是一个新的运算符,习惯称它为“箭头”,有了它,可以通过结构体指针直接取得结构体成员,这也是->在C语言中的唯一用途。

    上面两种写法是等效的,我们通常采用第二种写法,这样更加直观。

    实例:结构体指针的使用

    #include <stdio.h>
    int main(){
        struct{
            char *name;  //姓名
            int num;  //学号
            int age;  //年龄
            char group;  //所在小组
            float score;  //成绩
        } stu1 = { "Tom", 12, 18, 'A', 136.5 }, *pstu = &stu1;
    
        //读取结构体成员的值
        printf("%s的学号是%d,年龄是%d,在%c组,今年的成绩是%.1f!\n", (*pstu).name, (*pstu).num, (*pstu).age, (*pstu).group, (*pstu).score);
        printf("%s的学号是%d,年龄是%d,在%c组,今年的成绩是%.1f!\n", pstu->name, pstu->num, pstu->age, pstu->group, pstu->score);
    
        return 0;
    }

    运行结果:

    Tom的学号是12,年龄是18,在A组,今年的成绩是136.5!
    Tom的学号是12,年龄是18,在A组,今年的成绩是136.5!

    示例:结构体数组指针的使用

    #include <stdio.h>
    
    struct stu{
        char *name;  //姓名
        int num;  //学号
        int age;  //年龄
        char group;  //所在小组
        float score;  //成绩
    }stus[] = {
        {"Zhou ping", 5, 18, 'C', 145.0},
        {"Zhang ping", 4, 19, 'A', 130.5},
        {"Liu fang", 1, 18, 'A', 148.5},
        {"Cheng ling", 2, 17, 'F', 139.0},
        {"Wang ming", 3, 17, 'B', 144.5}
    }, *ps;
    
    int main(){
        //求数组长度
        int len = sizeof(stus) / sizeof(struct stu);
        printf("Name\t\tNum\tAge\tGroup\tScore\t\n");
        for(ps=stus; ps<stus+len; ps++){
            printf("%s\t%d\t%d\t%c\t%.1f\n", ps->name, ps->num, ps->age, ps->group, ps->score);
        }
    
        return 0;
    }

    运行结果:

    Name            Num     Age     Group   Score
    Zhou ping       5       18      C       145.0
    Zhang ping      4       19      A       130.5
    Liu fang        1       18      A       148.5
    Cheng ling      2       17      F       139.0
    Wang ming       3       17      B       144.5

    参考资料:

    C语言结构体和指针

    C语言结构体数组

    C结构体

    展开全文
  • C语言结构体(struct)常见使用方法

    万次阅读 多人点赞 2014-04-14 01:51:57
    基本定义:结构体,通俗讲就像是打包封装,把一些有共同特征(比如同属于某一类事物的属性,往往是某种业务相关属性的聚合)的变量封装在内部,通过一定方法访问修改内部变量。 (因为C++和C有共通之处,但是在...
  • 结构体嵌套结构体

    千次阅读 2020-08-05 18:06:11
    作用:结构体成员可以是另一个结构体 例如:每个老师辅导一个学员,一个老师的结构体中,记录一个学生的结构体 #include<iostream> #include<cstring> using namespace std; //1.要先创建学生数据类型:...
  • 结构体结构体链表

    万次阅读 多人点赞 2018-08-24 16:12:07
    在c语言表针中有多种数据类型,他们的应用使变量的应用... 结构体是一种类型,他的应用和int,float等变量类型的应用方法一致,切记,结构体是一种类型,不可当作变量进行使用。 在结构体类型使用时要先进行结构体...
  • 结构体结构体指针

    2019-11-09 21:11:58
    一个结构体变量的指针就是该变量所占据的内存段的起始地址(如结构体Student变量name的指针就是name这个变量所占据的内存段的起始地址,在定义结构体的时候已经为name分配好了内存空间)。可以设一个指针变量,用来...
  • C++ 结构体初始化与赋值

    万次阅读 多人点赞 2016-05-30 13:28:57
    1.CC++结构体的初始化今天看到项目中对自定义结构体初始化方式有点陌生,特在此罗列一下可用的结构体初始化的方式。对结构体struct A { int b; int c; }有几种初始化方式:第一种:struct A a = { .b = 1, ...
  • Swift 结构体

    2021-01-06 02:58:17
    Swift 结构体 Swift 结构体是构建代码所用的一种通用且灵活的构造体。 我们可以为结构体定义属性(常量、变量)和添加方法,从而扩展结构体的功能。 与 C 和 Objective C 不同的是: 结构体不需要包含实现文件和...
  • C++ 结构体嵌套结构体

    千次阅读 2019-08-01 17:48:42
    1、结构体嵌套结构体 #include<iostream> using namespace std; //创建结构体 struct student { string name; int age; int score; }; struct teacher { int id; string name; int age; struct ...
  • C++结构体结构体创建,结构体数组) 目录 C++结构体结构体创建,结构体数组) 1、结构体创建 2、结构体创建代码演示 3、结构体数组 4、结构体数组代码演示 1、结构体创建 struct结构体名 变量名 struct...
  • 1.结构体转map 2.map转结构体 3.结构体数据转移到结构体 4.json字符串转结构体 package main import ( encoding/json fmt reflect ) type User struct { Name string `json:name` Age int `json:age` } func ...
  • 结构体结构体数组

    千次阅读 2020-03-14 11:14:21
    什么是结构体: 一组数组异质的数组,但自成整体的数据 结构体变量的定义方法: 先声明结构体类型,再定义变量类型。 声明结构体变量时不分配空间,在定义结构体变量时才分配内存空间。 例1 学校体育考试,...
  • 结构体变量作为函数参数,是将实参值传递给形参,属于值传递。将结构体所有参数传递给形参使用,但本身的值不会改变。将指向结构体变量的指针作为实参进行传递时,是将结构体变量的地址传递给形参,属于地址传递,...
  • 文章目录1.前言2.内存空间上面的差别3.访问上的差别 ...结构体指针p是指向一个结构体的,这个结构体没有名字,它指向的是一个结构体空间的首地址;如果需要使用这个结构体就必须malloc一个空间出来或者将一个
  • 结构体 结构体: 一系列不同类型的数据的结合 强调:类型!= 变量。 结构体名代表的只是结构体类型,没有内存空间。 结构体中的成员可以单独使用 1 定义结构体 struct Studet { char name[20]; int age; char ...
  • 结构体内存对其计算结构体大小,大神总结,很有用,结构体内存对其计算结构体大小,结构体内存对其计算结构体大小结构体内存对其计算结构体大小
  • 结构体中嵌套结构体

    万次阅读 多人点赞 2016-08-12 22:09:41
    结构体的嵌套问题 结构体的自引用(self reference),就是在结构体内部,包含指向自身类型结构体的指针。 结构体的相互引用(mutual reference),就是说在多个结构体中,都包含指向其他结构体的指针。 1. ...
  • C语言结构体结构体排序

    千次阅读 多人点赞 2019-01-26 22:06:48
    结构体 结构体是一种构造数据类型 (构造数据类型包括:数组类型、结构体类型、共用体类型) 定义:把不同的数据组合成一个整体。 结构体的一般形式 struct [结构体名称]//struct是关键字 { 类型标识符 成员名;//...
  • 结构体-初学结构体

    千次阅读 2016-12-20 16:01:20
    1436 初学结构体 Time Limit : 1000 MS | Memory Limit : 32768 KB Submits : 220 | Solved : 119 Description请用标准数据类型创建结构体,用于描述一个人的信息,结构体包括三个成员,分别为姓名、性别、3门课的...
  • C语言中的结构体结构体中数组初始化与赋值

    万次阅读 多人点赞 2018-01-03 10:18:33
    结构体是连续存储的,但由于结构体中成员类型各异,所以会存在内存对齐问题,也就是内存里面会有空档,具体的对齐方式这里 暂不讨论; 1.结构体的定义和赋值 结构体是可以直接初始化的,在定义的时候,就可
  • c语言结构体

    2014-06-03 18:26:23
    大一c语言课程之c语言结构体。详细讲解了结构体数据类型,结构体变量的应用结构体数据类型的定义及其变量的申明和引用。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 616,972
精华内容 246,788
关键字:

结构体等于0