结构体常见操作

结构体类型

  • 数组只能将相同类型的数据放在一起,结构体是可以将不同类型的数据放在一起

声明

//结构体模板
struct  student
    {
        long studentID;//定义学号
        char studentName;//姓名
        char studentSex;//性别
        int yearBirth;//出生年
        int scoreMath;//数学成绩
        int scoreEnglish;//英语成绩
        int scoreComputer;//计算机
        int scoreP;
  	    //int score[4];//等价上面成绩
    };

定义结构体变量

1、先定义结构体类型,在定义变量名

struct  student//student为标签名
    {
        long studentID;//定义学号
        char studentName;//姓名
        char studentSex;//性别
    };
    struct student stu1;//定义变量

2、在定义结构体类型的同时定义变量

struct  student
    {
        long studentID;//定义学号
        char studentName;//姓名
        char studentSex;//性别
        int yearBirth;//出生
    }stu1;

3、直接定义结构体变量(不指定结构体标签)

struct 
    {
        long studentID;//定义学号
        char studentName;//姓名
        char studentSex;//性别
        int yearBirth;//出生年
    }stu1;

typedef

  • 用typedef给数据类型定义一个别名
  • 别名用全部大写
  • struct student等价STUDENT
struct student
    {
        long studentID;//定义学号
        char studentName;//姓名
        char studentSex;//性别
    }stu1;
    typedef struct student STUDENT;
//或者
typedef struct student
    {
        long studentID;//定义学号
        char studentName;//姓名
        char studentSex;//性别
    }STUDENT;
//或者
typedef struct
    {
        long studentID;//定义学号
        char studentName;//姓名
        char studentSex;//性别
    }STUDENT;//结构体声明

初始化

  • 初始化列表成员必须与结构体类型定义的顺序一致
  • 没给初始值就默认为0
typedef struct student
    {
        long studentID;//定义学号
        char studentName;//姓名
        char studentSex;//性别
        int yearBirth;//出生年分
        int score[4];//成绩
    }STUDENT;
    STUDENT stu1={1203,"小王""Man",1991,{72,90,29,28}};//初始化

结构体与数组嵌套

嵌套的结构体

typedef struct data
    {
        int year;
        int month;
        int day;
    }DATE;
    typedef struct student
    {
        long studentID;//定义学号
        char studentName[10];//姓名
        char studentSex[10];//性别
        DATE yearBirth;//出生年
        int score[4];//成绩
    }STUDENT;

初始化

  • 嵌套的结构体要用花括号表示内容–里面花括号
  • 外面花括号—原结构体数组类型
 STUDENT stu1={1203,"小王","Man",{1991,5,19},{72,90,29,28}};//初始化

结构体数组

  • 前面结构体声明一样
  • 数据就用花括号嵌套表示
STUDENT stu1[3]={{1203,"小王","Man",{1991,5,19},{72,90,29,28}},
                    {13503,"小红","Man",{1991,5,19},{72,90,29,28}},
                    {1253,"小西南","WOMan",{1983,5,19},{72,90,29,28}}
                };

计算结构体内存数

  • sizeof(变量或表达式)
  • 为满足内存地址要求,在较小的成员加入补位

访问结构体成员

  • 通过名字访问结构体成员
  • 成员选择运算符(原点运算符)
  • 结构体变量名.成员名
  • 对于嵌套体成员,必须以级联方式访问
#include <stdio.h>
#include<string.h>
int main()
{
    typedef struct data
    {
        int year;
        int month;
        int day;
    }DATE;
    typedef struct student
    {
        long studentID;//定义学号
        char studentName[10];//姓名
        char studentSex;//性别
        DATE Birth;
        int score[4];//成绩
    }STUDENT;
    STUDENT stu1={12033,"小王",'M',{1991,5,19},{72,90,29,28}};
    
    //访问操作
    stu1.studentID=101001;//访问id
    strcpy(stu1.studentName,"小");//访问,字符数组要用strcpy函数
    stu1.studentSex='M';//若是定义单个字符,直接赋值
    stu1.Birth.year=19;//级联方式访问
    printf("姓名为%s\n性别是%c\n学号是%d\n",stu1.studentName,stu1.studentSex,stu1.studentID);  
}

赋值

  • 只能在相同类型的结构体变量之间进行赋值
#include <stdio.h>
int main()
{
    int i;
    typedef struct data
    {
        int year;
        int month;
        int day;
    }DATE;
    typedef struct student
    {
        long studentID;//定义学号
        char studentName[10];//姓名
        char studentSex[10];//性别
        DATE yearBirth;//出生年
        int score[4];//成绩
    }STUDENT;
    STUDENT stu1={1203,"小王","Man",{1991,5,19},{72,90,29,28}};
    STUDENT stu2;
    
    //赋值
    stu2.studentID=stu1.studentID;//赋值
    for(i=0;i<4;i++)
    {
        stu2.score[i]=stu1.score[i];
        printf("%d\n",stu2.score[i]);
    }
}

取地址操作

STUDENT stu2;
stu1=stu2;
printf("&stu1=%p\n",&stu1 );
printf("&stu2=%p",&stu2);

结构体指针

访问

  • 通过成员选择运算符访问
(*pt).studentID=1;
  • 通过指向运算符访问:->
pt -> studentID=1;

总体

#include <stdio.h>
int main()
{
    typedef struct student
    {
        long studentID;//定义学号
        char studentName[10];//姓名
        char studentSex[10];//性别
        int score[4];//成绩
    }STUDENT;
    //定义结构体指针
    STUDENT stu1;
    STUDENT *pt;


    pt = &stu1;//初始化
    //STUDENT *pt = &stu1;//与上式等价

    //访问
    (*pt).studentID=1;
    pt -> studentID=1;
    stu1.studentID=1;
}

结构体数组

STUDENT stu[30];
STUDENT *pt;
pt=stu;//数组首地址指向指针
//等价
STUDENT *pt=stu;
//等价
STUDENT *pt = &stu[0];
//访问
pt -> studentID;//等价于stu[0].studentID

向函数传递结构体

传递单个成员

向函数传递结构体的完整结构

  • 赋值结构体的所有成员

向函数传递结构体的首地址

  • 仅复制一个地址值

应用

  • 封装函数参数:精简参数个数、函数接口简洁
#include <stdio.h>

typedef struct point//结构体声明
    {
        int x;
        int y;
        int z;
    }POINT;

void Func(POINT *p);//函数结构体指针定义

int main()
{
    POINT position={0,0,0};
    printf("%d,%d,%d\n",position.x,position.y,position.z);
    Func(&position);//传参
    printf("%d,%d,%d\n",position.x,position.y,position.z);
}

void Func(POINT *pt)
{
    pt -> x=1;
    pt -> y=2;
    pt -> z=3;
}
向函数传递结构体完整结构向函数传递结构体的首地址
用结构体变量做函数参数用结构体数组/结构指针做函数参数
复制整个结构体成员内容,一组数据仅复制结构体的首地址,一个数据
参数传递直观,开销大,效率低参数传递效率高
函数内对结构体内容的修改不影响原来结构体可修改结构体指针所指向的结构体内容

枚举类型

  • 应用:当某些量仅由有限个整型数据值组成时
  • 枚举常量是整型常量
  • 增强程序看可读性:定义标志变量
  • MON后面常量依次加1
enum weeks ={SUN=7,MON=1,TUE,WED,THU,FRI,SAT}//枚举类型声明
typedef enum weeks ={SUN=7,MON=1,TUE,WED,THU,FRI,SAT} WEEKS;//定义别名

//定义变量
enum weeks today;
WEEKS today;

共用体

声明

  • 字节数取决于占空间最多的成员变量
    • 同一内存在每一瞬间只能保存一个成员;起作用的成员是最后一次赋值的成员
  • 与结构体类似
  • 成员最好互斥
union sample
    {
        short i;
        char ch;
        float f;
    };
    //访问
    struct sample s;//定义变量
    s.i=1;

    union sample u={1};//只能对共用体第一个成员进行初始化

应用

  • 构造混合的数据类型
typedef union
    {
        int i;
        float f;
    }NUMBER;

    NUMBER array[100];//既可以存储int型,也可以存储float型

    //访问
    array[0].i=10;
    array[1].f=3.2;

对比

结构体共用体
关系紧密且逻辑相关的多种不同类型的数据的结集合情形互斥但逻辑相关的多种不同类型的数据的集合
可以保存所有成员的值,用sizeof来计算占用内存的总字节数内存重叠存储,每一瞬间只能保存一个成员,最后一次赋值的成员起作用
对所有成员初始化只能对第一个成员初始化

C程序的内存映像

变量的内存分配方式

  • 从静态存储区分配
    • 全局变量和静态变量
  • 从栈上分配
  • 从堆上分配

动态内存分配函数

  • void*型指针不指定其指向哪一种类型,可指向任意类型的变量
  • 使用时,需强转(Type*)为其他类型
#include<stdlib.h>
void* malloc(unsigned int size);
//向系统申请大小为size的内存块;

void* calloc(unsigned int num,unsigned int size);
//向系统申请num个size大小的内存块

void *realloc(void *p,unsigned int size);
//改变原来分配存储空间的大小
//指针p所指向存储空间的大小改为size个字节

void free(void *p);//释放内存

p=(int*)malloc(n*sizeof(int));//强制转换

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值