玩转C语言---初始结构体

       在学习c语言时,系统会为我们提供大量的数据类型,比如int、float、char等等,我们可以借助这些数据类型定义变量,处理一般的问题,但是当我们需要处理的问题过于复杂时,只有系统提供的类型还不能满足应用的要求,c语言允许人们根据自己的要求创建一些数据类型,并用它创建变量。

一、结构体的定义与使用

        在前面所见的程序中,所有的变量都是相互独立的,无内在联系,但实际生活中有些数据是有内在联系、成组出现的,例如,一个人的性命、年龄、体重、身高是相互独立的,同属于一个人,但是不同的人都具有这些属性,因此人们想到,定义一个变量,能够将这些属性都会包括在内,这样使用起来就方便的多了。

        在学习数组的时候,我们说,数组是 一组相同元素的集合,但是我们发现上述问题中,这些属性是不同的变量,仅靠数组是无法解决的,因此,我们引入结构体变量的概念。

        结构体:是C语言中允许用户自己建立不同类型数据组成的组合型的数据结构。简单来说,结构体是一些值的集合,这些值是成员变量,结构体的每个成员可以是不同的类型。

struct  peo//结构体类型
{
    char name[20];
    char tele[12];
    char sex[5];
    int high;
}  p1,p2;

         如上所示,为一个结构体的定义,struct为关键字(不能省略),说明其为结构体的类型变量,peo为标签,也为结构体名,{}内部为结构体的成员列表包括不同的成员变量,p1,p2为结构体变量名。

         因此,结构体类型的一般形式为:

        struct 结构体名

          {成员列表};

        结构体花括号中所包含的子项,称为结构体的成员,上述name,sex等都为它的成员,对成员都应该进行相应的类型声明。

        类型名 成员名;

        当然结构体中也可以包含另外一种结构体,我在此的理解是如同函数,函数中可以调用其他函数,但是不能在函数内部进行另外函数的定义,结构体也是一样的;比如:

struct peo
{
    char name[20];
    char tele[12];
    char sex[5];
    int high;
};

struct st
{
    struct peo p;//结构体成员变量可以是,标量、数组、指针,甚至是其他结构体;
     int num;
     float f;
};

此处结构体st内部就包含peo结构体;

1、先声明,在定义

先声明一个结构体类型,在定义该类型的变量;

#include <stdio.h>
struct peo//定义结构体类型
{
    char name[20];
    char tele[12];
    char sex[5];
    int high;
}

int main()
{
struct peo s1;//定义结构体变量s1
struct peo s2;//定义结构体变量s2
return 0;
}

 其结果为:

2、在声明时同时定义变量

#include <stdio.h>
struct peo//定义结构体类型
{
    char name[20];
    char tele[12];
    char sex[5];
    int high;
}s1,s2;//定义结构体变量s1、s2

int main()
{
return 0;
}

        在声明结构体时顺便定义变量,其结过是相同的。

        结构体变量的初始化与引用

        在结构体进行定义时,顺便赋予初值,称为结构体的初始化,再将其输出引用;

例如:

#include <stdio.h>
struct peo
{
    char name[20];
    char tele[12];
    char sex[5];
    int high;
};

struct st
{
    struct peo p;//结构体成员变量可以是,标量、数组、指针,甚至是其他结构体;
     int num;
     float f;
};


int main()
{
    struct peo p1={"张三","1559668862","男", 187};
    struct st s={{"lisi","1559668862","女",166},100,3.14};//浮点数在内存中,不能精确保存
    printf("%s %s %s %d\n",p1.tele,p1.sex,p1.name,p1.high);//结构体变量  成员变量
    printf("%s %s %s %d %d %f\n",s.p.tele,s.p.name,s.p.sex,s.p.high,s.num,s.f);//结构体指针 成员变量

    return 0;
}

        程序中声明结构体类型后,在主函数进行赋初值,进行初始化,在变量 p1与变量s花括号的后面进行初值赋予,按照顺序依次进行赋予。

注意:

1、在初始化时,是对结构体变量(p1)进行初始化,不是对结构体类型初始化(peo);

2、引用结构体变量的成员时,采用结构体变量.成员名(p1.name)其作用与普通变量相同,可以直接进行赋值等操作。

3、结构体的“.”是成员运算符,它在所有的运算符中优先级最高,因此可以将p1.name看作一个整体,相当于一个整型变量。

二、结构体传参      

#include <stdio.h>

struct peo
{
    char name[20];
    char tele[12];
    char sex[5];
    int high;
};

struct st
{
    struct peo p;//结构体成员变量可以是,标量、数组、指针,甚至是其他结构体;
     int num;
     float f;
};


void print2(struct peo*r)
{
    printf("%s %s %s %d\n",r->name,r->sex,r->tele,r->high);
}
void print1(struct peo r)
{
    printf("%s %s %s %d\n",r.name,r.sex,r.tele,r.high);
}

int main()
{
    struct peo p1={"张三","1559668862","男", 187};
    struct st s={{"lisi","1559668862","女",166},100,3.14};//浮点数在内存中,不能精确保存
    printf("%s %s %s %d\n",p1.tele,p1.sex,p1.name,p1.high);//结构体变量  成员变量
    printf("%s %s %s %d %d %f\n",s.p.tele,s.p.name,s.p.sex,s.p.high,s.num,s.f);//结构体指针 成员变量
    print2(&p1);
    print1(p1);
    return 0;
}

运行结果为:

        在结构体传参中,分为结构体变量(p1)传参与结构体变量地址传参(&p1)如上述代码,作用是相同的,不同的是在使用结构体成员变量时,一个采用“.”一个采用“->”; 在结构体传参的时候,参数是需要压栈的,如果传递一个结构体对象时,结构体过大,参数压栈的系统开销比较大,所以导致性能的下降;结构体传参的时候尽量传结构体的地址。

三、结构体数组

        一个结构体变量中可以存放一组相关的数据(如:一个学生的学号、姓名、成绩等),如果有十个学生的数据,显然此处应该用作数组,这就是结构体数组。

        定义结构体数组的一般形式为:

                struct  结构体名

        {成员列表}数组名 [数组长度];

或先声明一个结构体,在进行定义;

               struct  结构体名

                    {成员列表};

  struct  结构体名 数组名[数组长度];

        对结构体数组初始化的形式是在定义数组的后面加

                ={初值表列};

举例:有n个学生信息(学号、姓名、成绩)要求按照成绩的由高到低排序输出;

#include <stdio.h>
struct stu//声明结构体类型
{
    int num;
    char name[20];
    float score;
};

int main()
{
    struct stu s[5]={{1001,"lihua",95.6},{1003,"wangqiang",85},{1004,"zhanglan",98.5},{1002,"liuliu",75},{1005,"lili",97}};//定义结构体数组,并赋初值;

printf("按照成绩排序为:\n");

int i=0;
int j=0;

struct stu temp;
for(i=0;i<4;i++)//采用冒泡排序进行成绩排序
{
   for(j=0;j<4-i;j++)
   {
       if(s[j].score<s[j+1].score)

        {
             temp=s[j];
            s[j]=s[j+1];
            s[j+1]=  temp;
            }
   }
}
for(i=0;i<4;i++)//输出结构体数组
 {
      printf("%d  %8s  %6.2f\n",s[i].num,s[i].name,s[i].score);
    printf("\n");
 }
    return 0;
}

运行结果:

 四、结构体指针

        所谓的结构体指针,就是指向结构体变量的指针,一个结构体变量的起始地址就是这个结构体变量的指针。如果把一个结构体变量的起始地址存放在一个指针变量中,那么,这个指针变量就是结构体变量。

1、指向结构体变量的指针

#include <stdio.h>
int main()
{
    struct stu
    {
        int num;
        char name[20];
        char sex;
    };
    struct stu a1={100,"linhua",'m'};
    struct stu *p;
    p=&a1;
    printf("No.:%d\n name:%s\n  sex:%c\n",a1.num,a1.name,a1.sex);
    printf("No.:%d\n name:%s\n  sex:%c\n",(*p).num,(*p).name,(*p).sex);
    printf("No.:%d\n name:%s\n  sex:%c\n",p->num,p->name,p->sex);
    return 0;
}

 指针p指向结构体的起始地址,在后面输出时,以下3种用法等价:

1、a1.成员名,如(a1.num);

2、(*p).成员名,如(*p).num;

3、p->成员名,如p->num;

运行结果: 

2、指向结构体数组的指针

        我们知道结构体数组的本质还是数组,对于数组指针,我们之前已经分析的很透彻了,而结构体数组我们可以认为是数组的每个元素都是一个结构体变量,然后指针指向数组元素也就是指针指向每个结构体的地址。

举例:有3个学生的信息,放在结构体数组中,要求输出全部学生的信息;

#include <stdio.h>
struct student
{
    int num;
    char name[20];
    char sex;
    int age;
};
struct student s[3]={{1001,"lili",'M',20},{1002,"liuliu",'F',25},{1003,"zhangzhang",'M',31}};

int main()
{
    struct student *p;
    p=s;
    for(p=s;p<s+3;p++)
        printf("%d %s %c %d\n",p->num,p->name,p->sex,p->age);
    return 0;
}

        此处,运用到了指向结构体数组的指针来完成结构体内容的输出。p指向第一个结构的内容,p+1指向第二个结构体的内容,依次进行结构体数组中数组元素的输出;

        综上所述,本节我们学习的结构体的相关内容,其中包括结构体的结构体的定义与使用,结构的传参,结构体数组以及结构体指针,在后面的使用中将大量使用本节内容,还希望读者多多理解多多练习。

        创作不易,还请大家多多点赞支持。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值