结构体

  1. 结构体类型的声明
  2. 结构体初始化
  3. 结构体成员访问
  4. 结构体传参

结构体类型的声明

1. 结构的基础知识

结构是一些值的集合,这些值成为成员变量。结构的每个成员可以是不同类型的变量。

2.结构的声明

//struct 结构体关键字
//Stu 结构体标签
//struct Stu 结构体类型
struct tag
{
    member-list;
}variable-list;

//例如:
//描述一个学生
//名字
//年龄
//电话
//性别

struct Stu
{
    //成员变量
    char name[20];
    short age;
    char tel[12];
    char sex[5];
}s1,s2,s3;//s1,s2,s3是三个全局的结构体变量(尽量少用)

typedef struct Stu
{
    //成员变量
    char name[20];
    short age;
    char tel[12];
    char sex[5];
}Stu;//将结构体重命名为Stu

int main()
{
    //创建结构体变量
    //s是局部变量
    struct Stu s1;
    
    //重命名为Stu后可以直接用于定义成员变量
    Stu s2;
    
    return 0 ;
}

3.结构成员的类型

结构的成员可以是标量、数组、指针,甚至是其他结构体。

结构体初始化

结构体变量的定义和初始化

struct Point
{
    int x;
    int y;
}p1;
struct Point p2;

//******************示例******************
//初始化:定义变量的同时赋初值。
struct Point p3 = {x,y};
struct Stu //类型声明
{
    char name[15];
    int age;
};
struct Stu s = {"zhangsan",20};//初始化

//******************示例******************
typedef struct Stu
{
    //成员变量
    char name[20];
    short age;
    char tel[12];
    char sex[5];
}Stu;//将结构体重命名为Stu

int main()
{
    Stu s1={"张三",20,"12345678910","男"};
    struct Stu s2 = {"旺财",30,"12345678912","女"};
    
    return 0 ;
}
//结构成员为其它结构体
struct Node
{
    int data;
    struct Point p;
}

//******************示例******************
struct S
{
    int a;
    char c;
    char arr[20];
    double d;
};

struct T
{
    char ch[10];
    struct S s;
    char *pc;
};

int main()
{
    char arr[]="hello bit\n";
    struct T t={"haha",{100,'w',"hello world",3.14},arr};
    printf("%s\n",t.ch);
    printf("%s\n",t.s.arr);
    printf("%lf",t.s.d);
    pritnf("%s\n",t.pc);
    
    return 0 ;
}

结构体成员访问

结构体变量访问成员,结构变量的成员是通过点操作符(.)访问的。点操作符接受两个操作数。例如:

struct Stu
{
	char name[20];
    int age;
};

//定义结构体变量
struct Stu s;
//访问结构体变量
struct S s;
strcpy(s.name,"zhangsan");//使用.访问name成员
s.age = 20;//使用.访问age成员

结构体传参

typedef struct Stu
{
    //成员变量
    char name[20];
    short age;
    char tel[12];
    char sex[5];
}Stu;

//.点操作符访问
void Print1(Stu tmp)
{
    printf("name:%s\n",tmp.name);
    printf("age:%d\n",tmp.age);
    printf("tel:%s\n",tmp.tel);
    printf("sex:%s\n",tmp.sex);
}

//->箭号操作符访问
void Print2(Stu* ps)
{
    printf("name:%s\n",ps->name);
    printf("age:%d\n",ps->age);
    printf("tel:%s\n",ps->tel);
    printf("sex:%s\n",ps->sex);
}

int main()
{
    Stu s = {"李四",40,"15588888888","男"};
    //打印结构体数据
    //Print1()和Print2()那个更好一点?
    //Ptint2()√
    //时间和空间上都是2比较优
    //函数传参的时候,参数是需要压栈的。如果传递一个结构体对象的时候,结构体过大,参数压栈的系统开销比较大,所以会导致性能的下降。
    Print1(s);
    Print2(&s);
    
    return 0 ;
}

结论:结构体传参的时候,要传结构体的地址。

压栈解释

函数传参的时候,参数是需要压栈的。

(搜索:函数栈帧的创建和销毁)

int Add(int x,int y)
{
    int z=0;
    z=x+y;
    return z;
}

int main()
{
    int a=10;
    int b=20;
    int ret=0;
    ret=Add(a,b);
    
    return 0 ;
}

栈:先进后出,后进先出。

插入一个元素:压栈

删除一个元素:出栈