结构体、结构体变量、结构体指针、字符串

2023-05-16

结构体

数组是用于保存一组相同类型数据的, 而结构体是用于保存一组不同类型数组的
在使用结构体之前必须先定义结构体类型, 因为C语言不知道你的结构体中需要存储哪些类型数据, 我们必须通过定义结构体类型来告诉C语言, 我们的结构体中需要存储哪些类型的数据

struct 结构体名{
     类型名1 成员名1;
     类型名2 成员名2;
     ……
     类型名n 成员名n;
 };

结构体变量占用存储空间大小

结构体的总大小为结构体最宽基本类型元素大小的整数倍

  struct Person{
        int age; // 4  第一次开辟8byte 剩4
        char ch; // 1  不开辟使用第一次开辟剩余的4byte,剩3 
        double score; // 8 3byte不够分配,第二次开辟8byte
    };
   struct Person p;
   printf("sizeof = %i\n", sizeof(p)); // 16
占用内存最大属性是score, 占8个字节, 所以第一次会分配8个字节
将第一次分配的8个字节分配给age4个,分配给ch1个, 还剩下3个字节
当需要分配给score时, 发现只剩下3个字节, 所以会再次开辟8个字节存储空间
一共开辟了两次8个字节空间, 所以最终p占用16个字节
    struct Person{
        int age; // 4  第一次开辟88byte  剩4
        double score; // 8  不够,第二次开辟8byte 
        char ch; // 1   无剩,第三次开辟8 byte
    };
    struct Person p;
    printf("sizeof = %i\n", sizeof(p)); // 24
占用内存最大属性是score, 占8个字节, 所以第一次会分配8个字节
将第一次分配的8个字节分配给age4个,还剩下4个字节
当需要分配给score时, 发现只剩下4个字节, 所以会再次开辟8个字节存储空间
将新分配的8个字节分配给score, 还剩下0个字节
当需要分配给ch时, 发现上一次分配的已经没有了, 所以会再次开辟8个字节存储空间
一共开辟了3次8个字节空间, 所以最终p占用24个字节

结构体变量的定义

定义结构体变量:struct 结构体名 结构体变量名;

先定义结构体类型,再定义变量:

struct Student {
     char *name;
     int age;
 };
struct Student stu;

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

struct Student {
    char *name;
    int age;
} stu;

匿名结构体定义结构体变量

struct {
    char *name;
    int age;
} stu;

第三种方法与第二种方法的区别在于,第三种方法中省去了结构体类型名称,而直接给出结构变量,
这种结构体最大的问题是结构体类型不能复用。

结构体变量的初始化

定义的同时按顺序初始化

struct Student {
     char *name;
     int age;
 };
struct Student stu = {“cxx", 22};

定义的同时不按顺序初始化

struct Student{
	char *name;
	int age;
};
struct Student stu = {.age = 22, .name = "cxx" };

先定义后逐个初始化

struct Student{
	char *name;
	int age;
};
struct Student stu;
stu.age = 22;
stu.name = "cxx" ;

先定义后一次性初始化

struct Student {
     char *name;
     int age;
 };
struct Student stu;
stu2 = (struct Student){"cxx", 22};

结构体指针

一个指针变量当用来指向一个结构体变量时,称之为结构体指针变量
格式:== struct 结构名 *结构指针变量名==

int main(void)
{
    // 定义一个结构体类型
      struct Student {
          char *name;
          int age;
      };

     // 定义一个结构体变量
     struct Student stu = {“lnj", 18};
     // 定义一个指向结构体的指针变量
     struct Student *p;

    // 指向结构体变量stu
    p = &stu;
    
     //这时候可以用3种方式访问结构体的成员
     // 方式1:结构体变量名.成员名
     printf("name=%s, age = %d \n", stu.name, stu.age);

     // 方式2:(*指针变量名).成员名
     printf("name=%s, age = %d \n", (*p).name, (*p).age);

     // 方式3:指针变量名->成员名
     printf("name=%s, age = %d \n", p->name, p->age);

     return 0;
 }

结构体指针成员访问

通过结构体指针访问结构体成员, 可以通过以下两种方式:
(*结构指针变量).成员名
== 结构指针变量->成员名==

字符串定义、初始化:

	char string[]="cxx";
	printf("%s\n",string); //输出结果:cxx
	//数组名保存的是数组第0个元素的地址, 指针也可以保存第0个元素的地址
	char *str = "abc"
	for(int i = 0; i < strlen(str);i++){
  		printf("%c-", *(str+i)); //输出结果:a-b-c
	}
    char name[9] = "cxx"; //在内存中以“\0”结束, \0ASCII码值是0
    char name1[9] = {'c,'x','x','\0'};
    char name2[9] = {'c','x','x',0};
    // 当数组元素个数大于存储字符内容时, 未被初始化的部分默认值是0, 所以下面也可以看做是一个字符串
    char name3[9] = {'c','x','x'};

字符串输出:

如果字符数组中存储的是一个字符串, 那么字符数组的输入输出将变得简单方便。
不必使用循环语句逐个地输入输出每个字符
可以使用printf函数和scanf函数一次性输出输入一个字符数组中的字符串
使用的格式字符串为“%s”,表示输入、输出的是一个字符串

输出%s的本质就是根据传入的name的地址逐个去取数组中的元素然后输出,直到遇到 ‘\0’ 位置结束

	char name[]="chenc\0hen";
	printf("%s\n",name); //输出结果:chenc
 	//对一个字符串数组, 如果不做初始化赋值, 必须指定数组长度
	char name[10];
	scanf("%s",name); //输入一串字符
	
//name最多存放由9个字符构成的字符串,其中最后一个字符的位置要留给字符串的结尾标示‘\0’
//当用scanf函数输入字符串时,字符串中不能含有空格,否则将以空格作为串的结束符;

字符串长度计算:

sizeof关键字:

因为字符串在内存中是逐个字符存储的,一个字符占用一个字节,所以字符串的结束符长度也是占用的内存单元的字节数。

    char name[] = "it666";
    int size = sizeof(name);// 包含\0结束符
    printf("size = %d\n", size); //输出结果:6

strlen函数:

测字符串的实际长度(不含字符串结束标志‘\0’)并作为函数返回值。

  char name[] = "it666";
  size_t len = strlen(name2);
  printf("len = %lu\n", len); //输出结果:5

以“\0”为字符串结束条件进行统计

/**
 *  自定义方法计算字符串的长度
 *  @param name 需要计算的字符串
 *  @return 不包含\0的长度
 */
int myStrlen2(char str[])
{
    //    1.定义变量保存字符串的长度
    int length = 0;
    while (str[length] != '\0')
    {
        length++;//1 2 3 4
    }
    return length;
}
/**
 *  自定义方法计算字符串的长度
 *  @param name  需要计算的字符串
 *  @param count 字符串的总长度
 *  @return 不包含\0的长度
 */
int myStrlen(char str[], int count)
{
//    1.定义变量保存字符串的长度
    int length = 0;
//    2.通过遍历取出字符串中的所有字符逐个比较
    for (int i = 0; i < count; i++) {
//        3.判断是否是字符串结尾
        if (str[i] == '\0') {
            return length;
        }
        length++;
    }
    return length;
}

字符串连接函数:strcat

格式: strcat(字符数组名1,字符数组名2)
功能:把字符数组2中的字符串连接到字符数组1 中字符串的后面,并删去字符串1后的串标志 “\0”。本函数返回值是字符数组1的首地址。

char oldStr[100] = "welcome to";
char newStr[20] = " cxx";
strcat(oldStr, newStr);
puts(oldStr); //输出: welcome to lnj"

本程序把初始化赋值的字符数组与动态赋值的字符串连接起来。
要注意的是,字符数组1应定义足 够的长度,否则不能全部装入被连接的字符串。

字符串拷贝函数:strcpy

格式: strcpy(字符数组名1,字符数组名2)
功能:把字符数组2中的字符串拷贝到字符数组1中。串结束标志“\0”也一同拷贝。字符数名2, 也可以是一个字符串常量。这时相当于把一个字符串赋予一个字符数组。

char oldStr[100] = "welcome to";
char newStr[50] = " cxx";
strcpy(oldStr, newStr);
puts(oldStr); // 输出结果:  lnj // 原有数据会被覆盖

本函数要求字符数组1应有足够的长度,否则不能全部装入所拷贝的字符串。

字符串比较函数:strcmp

格式: strcmp(字符数组名1,字符数组名2)
功能:按照ASCII码顺序比较两个数组中的字符串,并由函数返回值返回比较结果。
字符串1=字符串2,返回值=0;
字符串1>字符串2,返回值>0;
字符串1<字符串2,返回值<0。

char oldStr[100] = "0";
char newStr[50] = "1";
printf("%d", strcmp(oldStr, newStr)); //输出结果:-1
char oldStr[100] = "1";
char newStr[50] = "1";
printf("%d", strcmp(oldStr, newStr));  //输出结果:0
char oldStr[100] = "1";
char newStr[50] = "0";
printf("%d", strcmp(oldStr, newStr)); //输出结果:1
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

结构体、结构体变量、结构体指针、字符串 的相关文章

  • 第一届ACC全国高校联赛

    y 竞赛 AcWing 面向全国高校同学的高校联赛 https www acwing com activity content 1173 一 1 暴力 include lt bits stdc 43 43 h gt using namesp
  • JDBC连接数据库

    个人简介 x1f496 作者简介 xff1a 大家好 xff01 我是yukki 个人主页 xff1a yukki x1f4c2 喜欢 xff1a x1f308 点赞 x1f308 收藏 xff01 更新Java x1f308 python
  • idea 文件夹右键新建没有Class

    个人简介 作者简介 xff1a 大家好 xff01 我是yukki 个人主页 xff1a yukki 喜欢 xff1a x1f308 点赞 x1f308 收藏 x1f308 一键三连 xff01 共勉 一 问题发现 xff1a 没法创建ja
  • 《关于我找了好久的bug,却没找出来的,又不小心解决了的事》

    个人简介 作者简介 xff1a 大家好 xff01 我是yukki 个人主页 xff1a yukki 喜欢 xff1a x1f308 点赞 x1f308 收藏 x1f308 一键三连 xff01 共勉 问题 xff1a 这是一个Spring
  • 某某科技实习日志

    个人简介 作者简介 xff1a 大家好 xff01 我是yukki 个人主页 xff1a yukki 喜欢 xff1a x1f308 点赞 x1f308 收藏 x1f308 一键三连 xff01 共勉 时间 2023年 4月 11日 今日任
  • XXXX实习日志

    个人简介 作者简介 xff1a 大家好 xff01 我是yukki 个人主页 xff1a yukki 喜欢 xff1a x1f308 点赞 x1f308 收藏 x1f308 一键三连 xff01 共勉 时间 2023年 4月 12日 今日任
  • STM32——中断优先级分组

    一 SCB AIRCR寄存器 首先 xff0c 对STM32中断进行分组 xff0c 0 4 同时 xff0c 每个中断设置一个抢占优先级和一个响应优先级 1 高抢占可以打断正在执行的低抢占 2 抢占相等 xff0c 高响应不能打断低响应
  • Keil报错总结(1)

    一 newline expected extra characters found c323 头文件定义有问题 ifndef define endif 他们后面的文件名与文件名不一致 xff0c 或者大小写不一致 xff0c 文件名尽量避免
  • GPIO实验

    一 GPIO简介 GPIO xff08 General purpose input output xff09 即通用型输入输出 xff0c GPIO可以控制连接在其之上的引脚实现信号的输入和输出 芯片的引脚与外部设备相连 xff0c 从而实
  • Exynos_4412——中断处理(中断学习结尾篇)

    目录 一 ARM的异常处理机制 1 1异常概念 1 2异常处理机制 1 3ARM异常源 1 4异常模式 1 5ARM异常响应 1 6异常向量表 1 7异常返回 1 8IRQ异常举例 二 工程模板代码结构 三 中断处理框架搭建 四 中断处理程
  • ROS中控制小乌龟移动(2种方法)

    操作系统 xff1a Ubuntu16 04 ROS版本 xff1a Kinetic 目录 方法一 xff1a 用键盘控制小乌龟移动1 启动ROS Master2 打开小乌龟3 键盘控制小乌龟 方法二 xff1a 通过命令发布话题控制小乌龟
  • QT/C++——对话框

    一 标准对话框 include 34 widget h 34 include lt QVBoxLayout gt include lt QHBoxLayout gt Widget Widget QWidget parent QWidget
  • QT/C++——主窗口和事件处理

    一 主窗口 上面就是一个主窗口 xff0c 主窗口中的每一个都是Action 这次新建工程要选择mainwindow ifndef MAINWINDOW H define MAINWINDOW H include lt QMainWindo
  • QT/C++——网络编程

    目录 一 基础知识复习 二 UDP 客户端 xff1a 服务器 xff1a 三 TCP 服务器 xff1a 客户端 xff1a 四 小项目 客户端 xff1a 服务器 xff1a 一 基础知识复习 这部分内容前面讲的比较详细 xff0c 现
  • Linux驱动开发——高级I/O操作(一)

    一个设备除了能通过读写操作来收发数据或返回 保存数据 xff0c 还应该有很多其他的操作 比如一个串口设备还应该具备波特率获取和设置 帧格式获取和设置的操作 一个LED设备甚至不应该有读写操作 xff0c 而应该具备点灯和灭灯的操作 硬件设
  • ubuntu22.04安装与配置

    目录 一 环境及下载 iso下载 VM配置 二 虚拟机与环境配置 虚拟机开始后的配置 一些工具配置 参考 xff1a VMware Workstation Pro 文档 一 环境及下载 iso下载 Download Ubuntu Deskt
  • Linux——互斥与同步

    目录 一种典型的竞态 内核中的并发 中断屏蔽 原子变量 自旋锁 读写锁 顺序锁 一种典型的竞态 假设整型变量i是驱动代码中的一个个全局变量 xff0c 在驱动的某个例程中执行了i 43 43 操作 xff0c 而在中断服务程序中也执行了i
  • 基于max30102的物联网病房监测系统(传感驱动和数据处理)

    目录 一 实物展示 二 主体介绍 三 MAX30102的驱动 四 MAX30102的数据处理 奋斗一个星期 xff0c 每个引脚都是扒皮焊接然后再把皮包回去的 这几天吸的垃圾气体感觉要少活两年 一 实物展示 这次吸取上次教训 xff0c 把
  • 基于max30102的物联网病房监测系统(中断处理和主题逻辑)

    目录 五 中断处理 六 主体框架 对采集数据的初始化 核心功能的实现 烟雾 通信帧格式 wifi接收数据的处理 OLED显示 五 中断处理 void SysTick Handler void TimingDelay Decrement vo
  • 无人机4G数传方案(合宙cat1模块)

    一 合宙Cat1简介 YED C724 核心板是由银尔达 xff08 yinerda xff09 基于合宙 Air724 模组推出的低功耗 xff0c 超小体积 xff0c 高性能嵌入式 4G Cat1 核心版 xff0c 标准的 2 54

随机推荐

  • C++学习ros2话题机制(发布与订阅)

    C 43 43 学习ros2 一 创建文件和文件夹1 结构2 创建工作空间和工作包3 直接创建node cpp文件 二 编写节点文件 xff08 发布订阅 xff09 1 node1 cpp xff08 发布 xff09 2 CMakeLi
  • AttributeError: module ‘keras.backend’ has no attribute ‘set_image_dim_ordering’

    问题 原始代码如下 xff1a keras span class token punctuation span backend span class token punctuation span set image dim ordering
  • openmv识别红色物体并返回坐标给stm32单片机,通过pid控制舵机云台

    本人搜索了有关于舵机云台pid控制的代码 xff0c 但是都没有搜到想要的结果 xff0c 现在自己写出来了代码 xff0c 所以就将自己写的代码分享出来 xff0c 和大家一起学习进步 1 openmv识别红色物体 43 返回中心坐标的的
  • vs解决报错:C++ qualified name is not allowed(E0283)

    我们看 把在GCC下编译过关的c 43 43 程序放在vs下却不能过 仅给出部分代码 其他以此类推 先不要慌着改 看下详细信息 看上去都是语法错误 但这真的没任何语法错误啊 百度上查找下 报错信息都不一样 别人是类里面多加限定符 我这是正常
  • Linux下的man命令

    目录 一 man是什么 xff1f 二 man命令的使用1 通过man man查看man手册2 通过man来进行查询 四 总结 一 man是什么 xff1f man所代表的的是英文单词manual xff0c 也就是帮助手册的意思 xff0
  • IO多路复用之select

    目录 一 IO多路复用二 select函数三 select实现socket服务器 xff08 1 xff09 流程图 xff1a xff08 2 xff09 代码讲解 xff1a 四 总结代码示例 xff1a 一 IO多路复用 IO多路复用
  • curl 和 wget 命令下载

    curl 和 wget 命令下载 一 wget下载1 wget介绍2 wget下载方法 二 curl下载1 curl介绍2 curl下载方法 三 wget下载sqlite实例总结 一 wget下载 1 wget介绍 wget 是一个从网络上
  • Linux下载安装和使用SQLite

    Linux安装SQLite 一 SQLite下载二 SQLite安装三 SQLite的使用1 解决无法直接用sqlit3命令2 解决无法编译的问题 总结 一 SQLite下载 首先 xff0c 前往SQLite官网下载页面找到包含confi
  • 解决:‘config.status: error: Something went wrong bootstrapping makefile fragments......’问题

    解决 xff1a config status error Something went wrong bootstrapping makefile fragments 问题 一 问题二 解决方法 一 问题 首先我们来看安装sqlite时报的这
  • TFTP服务器搭建与使用

    文章目录 一 TFTP协议二 TFTP服务器搭建1 安装TFTP服务器2 创建TFTP服务文件夹3 配置tftp文件4 配置tftpd hpa文件 三 TFTP服务器使用 一 TFTP协议 TFTP xff08 Trivial File T
  • 深入探讨Linux驱动开发:Linux设备树

    文章目录 一 设备树介绍二 设备树框架1 设备树框架2 节点基本格式3 节点部分属性简介 总结 一 设备树介绍 设备树 xff08 Device Tree xff0c 简称 DT xff09 是一种在嵌入式系统中描述硬件设备的一种数据结构和
  • 深入探讨Linux驱动开发:驱动介绍与hello驱动实例

    文章目录 前言一 Linux驱动介绍1 用户态和内核态2 内核功能介绍3 驱动程序介绍 二 驱动程序分类与注意事项1 驱动程序分类2 内核驱动开发注意事项 三 hello驱动开发1 驱动模块2 模块加载和卸载函数3 编写hello模块4 M
  • ROS中使用乐视 奥比中光(Astra Pro)深度相机显示彩色和深度图像

    环境 UbuntuROS Kinect or Melodic 奥比中光ROS驱动包安装地址 xff1a https github com orbbec ros astra camera 1 安装ROS 2 安装依赖 span class t
  • 深入探讨Linux驱动开发:字符设备驱动开发与测试

    文章目录 一 字符设备驱动介绍1 设备驱动介绍 二 设备号1 设备号介绍2 分配与释放设备编号 dev t类型 静态分配设备号 动态分配设备号 释放主次设备号 手动创建设备节点 自动创建设备节点 删除设备节点 三 字符设备注册1 cdev结
  • ZED-深度感知使用

    文章目录 1 深度感知配置2 得到深度数据2 1 得到深度值 3 展示深度图4 获取点云数据4 1 从点云数据中计算距离 5 得到法线图像6 调整深度分辨率 1 深度感知配置 可以在初始化时使用InitParameters xff0c 在运
  • Linux系统之 开机自启动程序脚本 编写

    Linux系统启动加载程序 最近完成了项目 xff0c 来个开机自启运行 找到已编译好的程序 xff08 以下是我编译的house xff09 span class token function ls span l span class t
  • 算法时间复杂度、空间复杂度分析

    算法时间复杂度 在计算机程序编写前 xff0c 依据统计方法对算法进行估算 xff0c 经过总结 xff0c 我们发现一个高级语言编写的程序程序在计算机上运行所消耗的时间取决于下列因素 1 算法采用的策略和方案 编译产生的代码质量 3 问题
  • Linux 选择题一百道

    cron 后台常驻程序 daemon 用于 xff1a A 负责文件在网络中的共享 B 管理打印子系统 C 跟踪管理系统信息和错误 D 管理系统日常任务的调度 在大多数Linux发行版本中 xff0c 以下哪个属于块设备 block dev
  • 程序返回return与系统退出exit

    程序返回return与系统退出exit return是语言级别的 xff0c 它表示了调用堆栈的返回 xff1b exit则是系统调用级别的 xff0c 它表示了一个进程的结束 return是返回函数调用 xff0c 如果返回的是main函
  • 结构体、结构体变量、结构体指针、字符串

    结构体 数组是用于保存一组相同类型数据的 而结构体是用于保存一组不同类型数组的 在使用结构体之前必须先定义结构体类型 因为C语言不知道你的结构体中需要存储哪些类型数据 我们必须通过定义结构体类型来告诉C语言 我们的结构体中需要存储哪些类型的