(C语言入门)六、结构体

  • 结构体类型的声明

  • 结构体初始化

  • 结构体成员访问

  • 结构体传参

  1. 结构体的声明

1.1结构体基础知识

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

1.2结构的声明

struct tag { member-list; }variable-list;

例如:

struct book
{
    int price;
    char name[20];
};

这里的prince和name都是book的成员变量。

struct book
{
    int price;
    char name[20];
}b3,b4,b5;

int main()
{
    struct book b1;
    struct book b2;
    return 0;
}

这里b3,b4,b5都是全局变量,而b1,b2是局部变量。如果定义时,写成typedef struct book,那么定义新变量可以用book当作结构体类型。

typedef struct book
{
    int price;
    char name[20];
}book;

int main()
{
    struct book b1;
    struct book b2;
    book b3;
    return 0;
}

1.3结构成员的类型

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

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

struct S
{
    char c;
    char arr[10];
    int* p;
}s1, s2;//声明类型的同时定义变量s1,s2

struct S s3;//定义结构体变量p2

struct B
{
    int a;
    struct S s;
    double d;
}sb1, sb2;//声明类型的同时定义变量s1,s2

struct B sb3;//定义结构体变量p2

int main()
{
    int a = 10;
    struct S s4 = {'c', "zhangsan", &a};
    int b = 10;
    struct B sb4 = { 100, {'q', "lisi", &b}, 3.14};//结构体嵌套初始化

    return 0;
}

也可以这样定义和访问成员:

struct Book
{
    char name[20];
    int price;
};
void print(struct Book* p)
{
    printf("%s %d\n", p->name, p->price);//#2 结构体指针->结构体成员
}
int main()
{
    struct Book b1 = { "hehe", 66 };
    struct Book b2 = { .price = 80, .name = "xixi" };//#1 结构体变量.结构体成员
    printf("%s %d\n", b1.name, b1.price);
    printf("%s %d\n", b2.name, b2.price);
    
    print(&b1);//struct Book* p1 = &b1;//只给了地址,要访问成员
    return 0;
}

2. 结构体成员的访问

结构体访问成员

结构体变量的成员是可以通过点操作符(.)访问。点操作符需要两个操作数。

例如:

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

我们可以看到结构体S里面有成员name 和age.如果我们需要访问成员,那么需要结构体指针指向变量的成员。

struct Stu
{
    char name[20];
    int age;
};
void print(struct Stu* ps)
{
    printf("name = %s   age = %d\n", (*ps).name, (*ps).age);
    //使用结构体指针访问指向对象的成员
    printf("name = %s   age = %d\n", ps->name, ps->age);
}
int main()
{
    struct Stu s = { "zhangsan", 20 };
    print(&s);//结构体地址传参
    return 0;
}

3.结构体传参

例:

struct S 
{
    int data[100];
    int num;
};
void print1(struct S ss)
{
    int i = 0;
    for (i = 0; i < 10; i++)
    {
        printf("%d ", ss.data[i]);
    }
    printf("%d \n", ss.num);
}
void print2(struct S* ps)
{
    int i = 0;
    for (i = 0; i < 10; i++)
    {
        printf("%d ", ps->data[i]);
    }
    printf("%d \n", ps->num);
}

int main()
{
    struct S s = { {1,2,3,4,5},100 };
    print1(s);
    print2(&s);
    return 0;
}

上面有两种传参print1(结构体传参)和print2(结构体地址传参)的方式。两种传参还是有区别的,如果对比上面的print1和print2哪个更好?应该是print2函数比较好。

是因为:

函数传参的时候,参数是需要压栈的。 如果传递一个结构体对象的时候,结构体过大,参数压栈的的系统开销比较大,所以会导致性能的 下降。

因此:print2只需要一个指针4/8个字节大小,但是print1是有两个int整形数组和整形的大小,效率远不如print2.

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

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值