结构体

如何使用结构体

首先,创建一个结构体:

struct book
{
    int math;
    int english;
    int history;
};

这个结构体名字叫 book ,有3个 成员 分别是int型的数学英语历史。

注意这里的book是结构体的名字,那么如果我们要使用这个结构体,可以用它声明一个变量

 

比如:

struct book
{
    int math;
    int english;
    int history;
}college

这样我就用结构体book 声明了一个变量名字叫college,就类似于你用 int a = 5;  声明了一个整型常量i 这个值是5。

 

那如果我也想给我刚刚声明的college赋值呢

struct book
{
    int math;
    int english;
    int history;
}college = {102030};

对,就类似于你用int a = 5;一样,只不过结构体用声明了一种结构体类型book,并且给里面的成员分别赋了值

 

当然了你也可以这样:

struct book
{
    int math;
    int english;
    int history;
};
struct book college = {10,20,30};

这两种方法没有任何区别。

 

结构体的成员,也可以是另一个结构体,对,可以套娃:

struct physical
{
     char a;
     int b;
     double c;
};
struct book
{
    int math;
    int english;
    int history;
    struct physical num123;
}college;

我在book这个结构体中加入了一个名为num123的结构体,这个结构体是physical型的。

 

结构体指针

如果我想用*p指向一个数组,那么很简单

    int a[10] = {1,2,3,4,5,6,7,8,9,0};
    int *p = a;

这个指针指向了数组a的首地址,也就是&a[0],对于数组来说,a、&a[0]都可以表示数组的首地址。那么如果我想要指向一个结构体呢?

这样吗:

int *p = book;
int *p = college;

没错,显然是不对的,(因为会报错),结构体的名字并不是结构体的首地址

那么我很聪明的取了地址,这样:

int *p = &book;
int *p = &college;

首先排除&book,因为book是结构体类型,就相当于你int *p = &int ,非常愚蠢。

那么&college呢?显然编译器会告诉你类型不匹配,所以我们可以通过强转的方式让其成为int

    int *p = (int*)&college;

既然没有报错,就说明这种方法是可行的。

事实也确实如此,但是这样做如果你想指向里面的成员变量,就只能使用*p *(p+1) *(p+2) 这种方法访问成员,但是你能保证所有成员都是同样大小吗,

如果不能那么就要计算每个成员的大小才能准确的指向你要的地址,所以不要这么做。

数组可以通过这种方式访问,那是因为数组首先地址是连续的,并且同类型的数组每个单元占空间一定相同,所以*(p+1)一定是p的下一个值。但是结构体中不会这样。

 

正确的做法是

    struct book *p = &college;

声明一个结构体指针p,指向college

那么如何使用该指针:

    p->math = 10;
    p->english = 20;

也可以用这种方式:

    (*p).math = 10;
    (*p).english = 20;

 

 

 

 

 

 

结构体传参

普通的变量可以作为参数使用,传入函数中,那么结构体也同理;

我们先来看一下一般的“正经”函数:

int add(int a,int b)
{
    return a + b;
}

printf("%d/n",add(1,2));

函数的运行结果显然等于3

那我怎么用结构体呈现同样的效果呢?

//首先我声明一个结构体 结构体名字是num 有2个成员 a和b
struct num
{
    int a;
    int b;
};

//然后声明一个函数,使用结构体传参
int add2(struct num tmp)
{
    return tmp.a + tmp.b;    
}

int main()
{
//在使用这个函数之前,要先把结构体的参数赋进去 struct num val; val.a = 1; val.b = 2; //计算并的到结果,编译运行得到3 printf("%d\n", add2(val));

  return 0;
}

当然了,对于a+b这种函数肯定不需要用到结构体,这里只是举个栗子。

 

我们再用指针作为参数重新传一下这个函数

#include <stdio.h>
//首先我声明一个结构体 结构体名字是num 有2个成员 a和b
struct num
{
    int a;
    int b;
};

//然后声明一个函数,使用结构体传参
int add2(struct num *tmp)
{
    return tmp->a+tmp->b;    
}

int main()
{
//在使用这个函数之前,要先把结构体的参数赋进去
    struct num val;
    struct num *p = &val;
    p->a = 1;
    p->b = 2;

//计算并的到结果,编译运行得到3
    printf("%d\n",add2(p));
    return 0;
}

 

 

typedef与结构体

typedef是用来起别名的,通常的用法是

typedef int u16

那么在后续的代码中,你就可以使用u16来替代int了,比如:

u16 a = 5;  效果等同于 int a = 5;

同样的,typedef也可以给结构体起一个新名字:

typedef struct num
{
    int a;
    int b;
}my_num;

相当于给num起了一个新名字叫my_num

实际上这样的声明起到了两个作用

其一:定义了一个结构体num 有两个成员a和b。

其二:给 struct num 起了一个名字叫my_num

不使用typedef的时候,当我们需要声明一个结构体变量时:

struct num tmp;

如果我用typedef给结构体起了一个小名,就可以这样声明了:

my_num tmp;

 

posted @ 2020-03-11 01:05  祁峰_1024  阅读(317)  评论(0编辑  收藏  举报