首页 > 其他分享 >C语言----结构体

C语言----结构体

时间:2024-08-10 16:23:01浏览次数:16  
标签:name int age struct C语言 ---- str printf 结构

结构体

结构体的含义

  1. 自定义的数据类型

  2. 它是由很多的数据组合成的一个整体,结构型数据

  3. 其中的每一个数据,都是结构体的成员

书写的位置:

函数的里面:局部位置,只能再本函数中使用

函数的外面:全局位置,在所有的函数中都可以使用

#include<stdio.h>
#include<string.h>
struct myFriend
{
    char name[100];
    int age;
    char gender;
    double height;
};
int main()
{
    struct myFriend f1;
    //因为这步是要把现定义的字符串传入字符数组,所以使用strcopy函数
    strcpy(f1.name,"刘慧玲");
    f1.age = 19;
    f1.gender = 'F';
    f1.height = 1.63;
    printf("我朋友的名字是%s\n",f1.name);
    printf("我朋友的年龄是%d岁\n",f1.age);
    printf("我朋友的性别是%c\n",f1.gender);
    printf("我朋友的身高是%.2f米\n",f1.height);
    return 0;
}

结构化数组代码案例(3种方式)

直接定义结构体数组
#include<stdio.h>
#include<string.h>
struct student
    {
        char name[100];
        int age;
    };
int main()
    {
    //定义student型变量并传入实参
    struct student st1 = {"张三",18};
    struct student st2 = {"李四",19}; 
    struct student st3 = {"王五",20};
    //定义数组来接收3个student变量
    struct student strArr[3] = {st1,st2,st3};
    int i;
    for(i=0;i<3;i++)
    {
        printf("学生的名字为:%s;学生的年龄为:%d\n",strArr[i].name,strArr[i].age);
    
    }
    return 0;
}

直接将三个 struct student 对象初始化到一个数组中,这在某些编译器中可能会引发类型不匹配的错误

定义结构体指针数组存放数据
#include<stdio.h>
#include<string.h>
 
struct student
{
    char name[100];
    int age;
};
 
int main()
{
    struct student st1 = {"张三", 18};
    struct student st2 = {"李四", 19};
    struct student st3 = {"王五", 20};
    //定义指针数组来接收3个student变量的内存地址
    struct student *strArr[3] = {&st1, &st2, &st3};
    int i;
    for(i = 0; i < 3; i++)
    {
        //指向结构体或类对象的指针数组访问数据需使用->
        //strArr[i]->name 表示访问 strArr 数组中第 i 个元素所指向的对象的 name 成员。
        printf("学生的名字为:%s;学生的年龄为:%d\n", strArr[i]->name, strArr[i]->age);
    }
    return 0;
}
先定义结构体数组,再依次写入数据
#include<stdio.h>
#include<string.h>
 
struct student
{
    char name[100];
    int age;
};
int main()
{
    //struct student strArr[3] = {{"张三", 18}, {"李四", 19}, {"王五", 20}};
    //上面的定义效果与下面的一致,是依次初始化结构体数组中的元素
    struct student strArr[3];
    int i;
    strcpy(strArr[0].name, "张三");
    strArr[0].age = 18;
    strcpy(strArr[1].name, "李四");
    strArr[1].age = 19;
    strcpy(strArr[2].name, "王五");
    strArr[2].age = 20;
    
    for(i = 0;i < 3;i++)
    {
        printf("学生的名字为:%s;学生的年龄为:%d\n", strArr[i].name, strArr[i].age);
    }
 
    return 0;
}

起别名

代码案例
#include<stdio.h>
//其中的gameRole可以省略不写
typedef struct gameRole
{
    char name[100];
    int attact;
    int defend;
    int blood;
//GR就是起的别名
}GR;
int main()
{
    //定义时直接使用GR
    GR gr1 = {"火男",100,50,50};
    GR gr2 = {"狐狸",100,40,60};
    GR gr3 = {"岳山",40,80,80};
    GR *grArr[3] = {&gr1,&gr2,&gr3};
    int len = sizeof(grArr) / sizeof(grArr[0]);
    int i;
    for(i=0;i<len;i++)
    {
        printf("角色名字:%s;角色攻击:%d;角色防御:%d;角色血量:%d;\n",grArr[i]->name,grArr[i]->attact,grArr[i]->defend,grArr[i]->blood);
    }
    return 0;
}

结构体作为函数参数

函数中可以传递结构体

代码案例(通过函数修改结构体变量内的数据)
#include<stdio.h>
//定义一个结构体
typedef struct student
{
    char name[100];
    int age;
}S;
//因为函数中需要结构体传参,所以要声明在结构体下方,(代码自上往下依次执行)
void method1(S *str);
void method2(S str);
int main()
{
    //定义结构体变量
    S st = {"name",0};
    //调用method2函数修改结构体变量中的数据
    method2(st);    
    printf("main中调用method2修改后的的姓名:%s,年龄%d\n",st.name,st.age);//name,0;结构体数据未被修改
    printf("--------------------------------------------\n");
    method1(&st);   
    printf("main中调用method1修改后的的姓名:%s,年龄%d\n",st.name,st.age);//张三,18;结构体数据已被修改
    return 0;
}
//method1函数中是传递结构体变量的内存地址,直接指向了结构体变量,所以可以修改函数外部的数据
void method1(S *str)
{
    printf("接收到的姓名:%s,年龄%d\n",str->name,(*str).age);
    printf("请输入你要更新的姓名:");
    scanf("%s",(*str).name);
    printf("请输入你要更新的年龄:");
    scanf("%d",&(str->age));
    printf("method1中修改后的的姓名:%s,年龄%d\n",str->name,(*str).age);
}
//method2函数中是传递结构体变量的数据赋给str,str是函数内的数据,所以函数外部的数据未被修改,修改的是函数内的str
void method2(S str)
{
    printf("接收到的姓名:%s,年龄%d\n",str.name,str.age);
    printf("请输入你要更新的姓名:");
    scanf("%s",str.name);
    printf("请输入你要更新的年龄:");
    scanf("%d",&(str.age));
    printf("method2中修改后的的姓名:%s,年龄%d\n",str.name,str.age);
}

结构体嵌套

结构体中的成员是其他的结构体

代码案例
#include<stdio.h>
#include<string.h>
typedef struct contactWay
{
    char phone[12];
    char mail[12];
}CW;
typedef struct student
{
    char name[100];
    char sex;
    int age;
    double height;
    CW cw;
}ST;
int main()
{
    ST st1 = {"小柒",'M',19,1.78,{"15976633334","[email protected]"}};
    ST st2;
    strcpy(st2.name,"小扒");
    st2.sex = 'F';
    st2.age = 19;
    st2.height = 1.62;
    strcpy(st2.cw.phone,"15979673555");
    strcpy(st2.cw.mail,"[email protected]");
    printf("姓名:%s,性别:%c,年龄:%d,身高:%.2lf,电话:%s,邮箱:%s\n",st1.name,st1.sex,st1.age,st1.height,st1.cw.phone,st1.cw.mail);
    printf("姓名:%s,性别:%c,年龄:%d,身高:%.2lf,电话:%s,邮箱:%s\n",st2.name,st2.sex,st2.age,st2.height,st2.cw.phone,st2.cw.mail);
    return 0;
}

内存对齐:

不管是结构体,还是普通的变量都存在内存对齐

规则:

只能放在自己类型整数倍的内存地址上

简单理解: 内存地址 /占用字节 = 结果可以整除

举例:

int存放的位置:内存地址一定能被4整除

1ong 1ong存放的位置:内存地址一定能被8整除

double存放的位置:内存地址一定能被8整除

结构体的内存对齐:

结构体在上面的基础上又多了一条,结构体的总大小,是最大类型的整数倍(用来确定最后一个数据补位的情况)

切记!:对齐的时候会补空白字节,但是不会改变原本字节的大小,例:char补位之后,本身还是1个字节

定义结构体时,小的数据类型定义在上面,大的数据类型定义在下面,可以有效节约空间

代码案例
#include<stdio.h>
struct ram
{
    //内存地址从0开始
    char a;     //此时内存地址为0  char必须放在1的整数倍的内存地址内     0可以放    放入后就占用了0
    int c;      //此时内存地址为1  int必须放在4的整数倍的内存地址内      4可以放    放入后就占用了4-8
    char b;     //此时内存地址为9  char必须放在1的整数倍的内存地址内     9可以放    放入后就占用了9
    double d;   //此时内存地址为10 double必须放在8的整数倍的内存地址内   16可以放   放入后就占用了16-24
};
int main()
{
    struct ram a;
    printf("%d",sizeof(a));//一共占用了24个字节
    return 0;
}

标签:name,int,age,struct,C语言,----,str,printf,结构
From: https://blog.csdn.net/2301_80464770/article/details/141092661

相关文章

  • 2.g++分步编译演示从源码到执行程序的四步
    2.g++分步编译演示从源码到执行程序的四步2.1gcc的工作流程gcc编译器将c源文件到生成一个可执行程序,中间一共经历了四个步骤:四个步骤并不是gcc独立完成的,而是在内部调用了其他工具,从而完成了整个工作流程,其中编译最耗时,因为要逐行检查语法。gcc的工作流程:1.预处理:cpp预......
  • css子元素、兄弟元素、直接子元素如何表示
    在CSS中,选择器用于指定你想要样式化的HTML元素。关于子元素、兄弟元素和直接子元素的表示,我们可以使用不同类型的选择器。以下是一些基本的概念和示例:子元素(DescendantSelector)子元素选择器,或者更准确地说是后代选择器,使用空格来指定一个元素内部的另一个元素,无论它们之间隔了......
  • 3.makefile运行流程分析并使用变量改写项目
    3.makefile运行流程分析并使用变量改写项目GNUmake用来构建和管理自己的工程Makefile文件描述了整个工程的编译、连接等规则3.1makefile变量的使用命令格式含义CXXC++编译器的名称,默认值为g++CXXFLAGSC++编译器的选项,无默认值$*不包含扩展名的目标文件......
  • LeetCode | 225 Implement Stack Using Queues
    分析阻塞(Blocking)阻塞操作指的是在调用一个函数或方法时,如果该操作不能立即完成(例如,因为需要等待某个事件的发生,如数据达到或资源可用),那么当前线程或进程会被挂起(暂停执行),直到操作完成为止。在这个等待期间,线程或进程无法执行其他任务。等待:调用方必须等待操作完成独......
  • 数据资产入表
    1、白话说什么是“数据资产入表”数据资产入表:是一个将组织的各类数据资产进行登记、分类、评估和管理的流程。数据资产包括:客户信息、交易记录、产品数据、财务数据等。做个比喻吧:数据资产入表就像是给公司的数据资产做“人口普查”——①找出公司有哪些数据=找出数据的......
  • AI 与 新生产要素
    AI大模型通过提升生产要素的产出效率,显著提高了数据要素在生产要素组合中的地位。数据已成为数字经济时代的新型生产要素,AI大模型通过改变数据生成方式和企业经营决策驱动方式,进一步增强了数据要素的流通性和价值创造能力。在生产函数中,AI大模型的应用对经济增长的影响呈发散态势,......
  • [HDCTF2019]MFC
    第一次遇到mfc类的题目,写个blog记录一下首先了解一下什么是mfc,百度百科上是这么写的:MFC(MicrosoftFoundationClasses),是微软公司提供的一个类库(classlibraries),以C++类的形式封装了Windows的API,并且包含一个应用程序框架,以减少应用程序开发人员的工作量。其中包含的类包含大......
  • 如何避免同一时间接口多次重复请求
    问题当在项目中遇到一个场景,有一个tab页面,tab的切换调用的都是一个接口,只是传入的参数不同,这个时候接口返回很慢,短时间内多次切换tab栏,可能会造成数据渲染错误,页面多次刷新等问题解决思路在请求接口时,如果上个接口没有请求介绍,就取消掉上次接口的调用。实现接口请求是通过axi......
  • Python 潮流周刊#64:Python 的函数调用还很慢么?(摘要)
    本周刊由Python猫出品,精心筛选国内外的250+信息源,为你挑选最值得分享的文章、教程、开源项目、软件工具、播客和视频、热门话题等内容。愿景:帮助所有读者精进Python技术,并增长职业和副业的收入。分享了11篇文章,13个开源项目,1则音视频,全文2000字。以下是本期摘要:......
  • costmap代价地图
    1什么是costmap代价地图在机器人进行路径规划时,我们需要明白规划算法是依靠什么在地图上来计算出来一条路径的。依靠的是gmapping扫描构建的一张环境全局地图,但是仅仅依靠一张原始的全局地图是不行的。因为这张地图是静态的,无法随时来更新地图上的障碍物信息。在现实环境中,......