C语言进阶-自定义类型:结构体、枚举、联合(上)

简介: C语言进阶-自定义类型:结构体、枚举、联合(上)

一、结构体的声明



1.1 结构的基础知识


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


1.2 结构的定义


struct tag
{
    member - list;//成员列表
}variable - list;//变量列表


示例:表述学生的信息


struct stu
{
    char  id[12];
    char name[20];
    char sex[10];
    short age[4];
}


1.3 特殊定义


struct
{
        int a ;
        char b ;
        float c ;
} x ;
struct
{
        int a ;
        char b ;
        float c ;
}   * p ;

若p=&x,编译器会将上面的两个定义当成不同的两个类型


1.4 结构自引用


结构中包含一个结构体本身的成员。


struct Node
{
    int date;//数据域
    struct Node* next;//指针域
};
typedef struct  Node
{
        int date;//数据域
        struct Node* next;//指针域
}Node;


29bf9055ccba46478c0f5572f14f6709.png


1.5 结构体变量和初始化


struct stu
{
    char id[12];
    char name[20];
    char sex[10];
    short age[4];
} stu1;///定义类型同时定义变量stu1
struct stu stu2;//定义结构体变量stu2
struct stu stu3={“1234567890”,“张三”,“男”,21};//定义结构体变量时初始化
struct Point
{
    int a;
    int b;
};
struct Node
{
    int data;
    struct Point p;
    struct Node* next;
}n1 = { 10,{4,5},NULL}; //结构体嵌套初始化
struct Node n2 = { 20, {5, 6},NULL};//结构体嵌套初始化


1.6 结构体内存对齐


#include<stdio.h>
struct s1
{                  
    char a1;  
    int a2;
    char a3; 
};
struct s2
{
    char a1;
    char a3;
    int a2;
};
int main()
{
    printf("%d", sizeof(struct s1));
    printf("%d", sizeof(struct s2));
}


输出


85bca6b50ee64131bec97e95b7c8c231.png


struct s1:


afceee594f3749b8821fe49c6e0a5528.png

struct s2:

0a05b644a26c48efba4ed055d7323207.png

struct s3//结构体嵌套
{
    char c1;
    struct s2 s2;
    double d;
}


输出


c562127d4fdf45e9a13c1740d0f71f97.png


0d31b91566914de9a781266f61ff8b16.png


结构体对齐规则:


               1. 第一个成员在与结构体变量偏移量为0的地址处。


               2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。


                    对齐数=成员的大小与编译器默认对齐数中的较小值


                      vs默认值为8,Linux没有默认对齐数,对齐数为成员大小


               3. 结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。                                     4. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处结构                          体的整 体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。


存在内存对齐的原因:


               1.平台原因:不是所有的硬件平台都能访问任意地址上的任意数据;某些硬件平台只                        能在某些地址处取某些特定类型的数据,否则抛出硬件异常。


               2.性能原因:数据结构(尤其是栈)应该尽可能地在自然边界上对齐。为了访问未对齐的                       内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。


注意:结构体的内存对齐是用空间来换时间。


1.7 修改默认对齐数


#include <stdio.h>
#pragma pack(1)//设置默认对齐数为1
struct s1
{
    char c1;
    int i;
    char c2;
};
int main()
{
    //printf("%d\n", sizeof(struct s1));
    //printf("%d\n", sizeof(struct s2));
    printf("%d", sizeof(struct s1));
    return 0;
}


输出


dddf8a217fc946f4bd19681e11515ae5.png


#pragma pack() //取消设置的默认对齐数,还原为默认


1.8 结构体传参


struct S
{
        int data [ 1000 ];
        int num ;
};
//结构体传参
void print1(struct S s)
{
        printf("%d\n", s.num);
}
//结构体地址传参
void print2(struct S* ps)
{
        printf("%d\n", ps->num);
}
int main()
{
    struct S s = { {1,2,3,4},100 };
    print1(s);
    print2(&s)
    return 0;
}

输出


a368fe655f4b4d3aa0fea176f25a3117.png


目录
相关文章
|
1天前
|
存储 Serverless C语言
每天一道C语言编程(结构体的运用):这是一年的第几天?
每天一道C语言编程(结构体的运用):这是一年的第几天?
6 0
|
1天前
|
算法 C语言
C语言易混淆、简单算法、结构体题目练习、常见关键字总结-2
C语言易混淆、简单算法、结构体题目练习、常见关键字总结
|
1天前
|
算法 编译器 API
C语言易混淆、简单算法、结构体题目练习、常见关键字总结-1
C语言易混淆、简单算法、结构体题目练习、常见关键字总结
|
1天前
|
存储 编译器 程序员
C语言:自定义类型 - 结构体 & 联合体 & 枚举
C语言:自定义类型 - 结构体 & 联合体 & 枚举
12 2
|
1天前
|
C语言
C语言:内存函数(memcpy memmove memset memcmp使用)
C语言:内存函数(memcpy memmove memset memcmp使用)
|
1天前
|
存储 编译器 C语言
C语言:字符函数 & 字符串函数 & 内存函数
C语言:字符函数 & 字符串函数 & 内存函数
15 2
|
1天前
|
缓存 安全 编译器
【C 言专栏】C 语言函数的高效编程技巧
【5月更文挑战第1天】本文探讨了C语言中函数的高效编程技巧,包括函数的定义与作用(如代码复用和提高可读性)、设计原则(单一职责和接口简洁)、参数传递方式(值传递、指针传递和引用传递)、返回值管理、调用约定、嵌套与递归调用,以及函数优化技巧和常见错误避免。掌握这些技巧能提升C语言代码的质量和效率。
【C 言专栏】C 语言函数的高效编程技巧
|
1天前
|
C语言
pta浙大版《C语言程序设计(第3版)》 习题6-4 使用函数输出指定范围内的Fibonacci数 (20分)
pta浙大版《C语言程序设计(第3版)》 习题6-4 使用函数输出指定范围内的Fibonacci数 (20分)
|
1天前
|
C语言
pta 浙大版《C语言程序设计(第3版)》题目集 习题6-6 使用函数输出一个整数的逆序数 (20分)
pta 浙大版《C语言程序设计(第3版)》题目集 习题6-6 使用函数输出一个整数的逆序数 (20分)