第四十九天学习记录:C语言进阶:结构体

这篇具有很好参考价值的文章主要介绍了第四十九天学习记录:C语言进阶:结构体。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

结构体

结构体的声明

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

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

问:C++的new和C语言的结构体有什么异同?
ChatAI答:
C++中的new是一个运算符,用于在堆上分配动态内存,并返回指向该内存的地址。它会自动调用要分配的对象的构造函数,以便初始化新分配的内存。与之相反,C语言中的结构体只是一种用户自定义的数据类型。我们可以在栈上或者堆上申请结构体变量内存,但在C语言中不会自动调用结构体的构造函数。

C++中的new还有一个重载版本,可以显式地调用类的构造函数来初始化新分配的内存。而在C语言中,如果结构体中有指向其他类型的指针,需要手动分配空间并进行初始化,否则可能导致内存泄漏或者越界错误。

此外,C++中的new还可以抛出异常,而C语言中的结构体是不支持异常处理的。

综上所述,C++中的new提供了更高级别的内存分配方式,同时还能够自动调用构造函数来初始化,更加方便和安全。

问:匿名结构体可以声明了一个集合后再声明另外一个不一样集合的匿名结构体吗?

ChatAI答:
可以,匿名结构体的定义与使用方式与普通结构体一样,可以在同一作用域内用多个匿名结构体类型的变量或声明。

下面是一个示例代码:

#include <stdio.h>

int main()
{
    struct {
        int x;
        int y;
    } s1 = {1, 2}, s2 = {3, 4};

    struct {
        double x;
        double y;
    } s3 = {1.23, 4.56}, s4 = {7.89, 9.87};

    printf("s1: x=%d, y=%d\n", s1.x, s1.y);
    printf("s2: x=%d, y=%d\n", s2.x, s2.y);
    printf("s3: x=%f, y=%f\n", s3.x, s3.y);
    printf("s4: x=%f, y=%f\n", s4.x, s4.y);

    return 0;
}

在这个例子中,我们在同一作用域内定义了两个不同的匿名结构体,其中s1s2类型相同,而s3s4类型相同。可以看到,它们被视为两个不同的结构体类型,内部成员的类型和名称可以不同。在使用时,也没有区别,可以直接使用.操作符访问内部成员。

问:C++的链表和C的链表有何异同
ChatAI答:
C语言和C++语言中的链表在实现和使用上有一些异同点:

  1. 数据结构实现

    • C语言中通常使用结构体来实现链表的节点,结构体内部包含指向前驱和后继节点的指针。
    • C++语言中可以使用类(class)或结构体(struct)来实现链表节点,通过类或结构体实现的链表节点可以使用类的成员函数来实现插入、删除、遍历等操作。
  2. 头文件和命名空间

    • 在C语言中,链表通常以结构体和相关的函数以及宏定义形式定义在单独的头文件中,并且可能需要包含其他系统头文件以使用标准库函数、类型和宏定义等。
    • 在C++语言中,链表的实现通常放在类或命名空间中。例如,可以使用std::list来定义一个标准库中的链表实现。
  3. 模板支持

    • C语言不支持模板,因此需要在代码中每次为需要操作的数据类型编写专门的函数。
    • C++支持模板,可以使用通用的泛型编程方式来实现链表,从而支持对任何类型数据进行操作。
  4. 对象和构造函数/析构函数支持

    • 在C语言中,链表通常由一组函数和结构体成员变量构成,没有构造函数和析构函数的概念,因此需要手动初始化和清理链表的节点和指针。
    • 在C++语言中,链表可以作为一个对象来看待,支持使用构造函数和析构函数进行自动初始化和清理。必要的资源申请和释放由构造函数和析构函数负责处理,使用起来更加方便。

除了上述区别,C++语言中的链表还可以利用STL标准库提供的迭代器、算法和其他容器等功能,提供更丰富的数据结构和算法支持。总的来说,C++语言的链表实现更加现代化、方便、可靠和安全。

结构体内存对齐

#define _CRT_SECURE_NO_WARNINGS 1

#include <stdio.h>

struct S1
{
	char c1;
	int a;
	char c2;
};

struct S2
{
	char c1;
	char c2;
	int a;
};

struct S3   //16
{
	double d;
	char c;
	int i;
};

struct S4   //32
{
	char c1;
	struct S3 s3;
	double d;
};

int main()
{
	struct S1 s1 = { 0 };
	printf("%d\n", sizeof(s1));//12
	struct S2 s2 = { 0 };
	printf("%d\n", sizeof(s2));//8
	return 0;
}

输出:12 8

结构体的对齐规则:
1、第一个成员在结构体变量偏移量为0的地址处。
2、其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
对齐数=编译器默认的一个对齐数与该成员大小的较小值。
VS中默认的值为8 gcc没有默认对齐数
3、结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。
4、如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
第四十九天学习记录:C语言进阶:结构体
第四十九天学习记录:C语言进阶:结构体

修改默认对齐数

#pragma pack(4)
#pragma pack()

C语言结构体偏移量

在C语言中,结构体是一种用户自定义的数据类型,它允许将不同的变量类型组合在一起,并按照用户定义的方式对它们进行存储。结构体中的每个成员在内存中是按照定义的顺序依次存放的,每个成员的偏移量从结构体变量的起始地址开始依次增加。可以使用C语言中的“offsetof”宏来计算结构体中各个成员的偏移量,语法如下:

#include <stddef.h>
#define offsetof(type, member) ((size_t) &((type *)0)->member)

其中,type表示结构体类型,member表示结构体成员名。使用这个宏,可以计算处任意结构体类型中指定成员的偏移量。

#define _CRT_SECURE_NO_WARNINGS 1

#include <stdio.h>
#include <stddef.h>

struct S
{
	char c;
	int i;
	double d;
};

int main()
{
	//offsetof();
	printf("%d\n", offsetof(struct  S, c));
	printf("%d\n", offsetof(struct  S, i));
	printf("%d\n", offsetof(struct  S, d));
	return 0;
}

第四十九天学习记录:C语言进阶:结构体文章来源地址https://www.toymoban.com/news/detail-457239.html

结构体传参

#define _CRT_SECURE_NO_WARNINGS 1

#include <stdio.h>

struct S
{
	char c;
	int a;
	double d;
};

void Init(struct  S* ps)
{
	ps->a = 100;
	ps->c = 'w';
	ps->d = 3.14;
}

int main()
{
	struct S s;
	Init(&s);
	return 0;
}

到了这里,关于第四十九天学习记录:C语言进阶:结构体的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 从零开始的力扣刷题记录-第四十八天

    给你一个下标从 0 开始的数组 nums ,数组大小为 n ,且由 非负 整数组成。 你需要对数组执行 n - 1 步操作,其中第 i 步操作(从 0 开始计数)要求对 nums 中第 i 个元素执行下述指令: 如果 nums[i] == nums[i + 1] ,则 nums[i] 的值变成原来的 2 倍,nums[i + 1] 的值变成 0 。否则,跳过

    2024年02月09日
    浏览(38)
  • 从零开始的力扣刷题记录-第四十二天

    题目描述: 给你长度相等的两个字符串 s1 和 s2 。一次 字符串交换 操作的步骤如下:选出某个字符串中的两个下标(不必不同),并交换这两个下标所对应的字符。 如果对 其中一个字符串 执行 最多一次字符串交换 就可以使两个字符串相等,返回 true ;否则,返回 false 。

    2024年02月06日
    浏览(42)
  • MySQL学习记录:第四章 TCL语言

    /* TCL语言 :transaction control language 事务控制语言 事务 : 一个或一组语句组成的一个执行单元,该执行单元要么全执行,要么全不执行 事务由单独单元的一个或多个SQL语句组成,在这个单元中,每个MySQL语句是相互依赖的。而整个单独单元作为一个不可分割的整体,如果单元

    2024年02月14日
    浏览(35)
  • C语言第四十弹---预处理(下)

    ✨ 个人主页:  熬夜学编程的小林 💗 系列专栏:   【C语言详解】   【数据结构详解】 预处理 1、#和## 1.1 #运算符 1.2、##运算符 2、命名约定 3、#undef 4、命令行定义 5、条件编译 6、头文件的包含 6.1、头文件被包含的方式 6.1.1、本地文件包含 6.1.2、库文件包含 6.2、嵌套文件

    2024年04月09日
    浏览(26)
  • C语言第四十一弹---猜数字游戏

     ✨ 个人主页:  熬夜学编程的小林 💗 系列专栏:   【C语言详解】   【数据结构详解】 猜数字游戏 1、随机数生成 1.1、rand 1.2、srand 1.3、time 1.4、设置随机数的范围 2、猜数字游戏的分析和设计 2.1、猜数字游戏功能说明 2.2、猜数字游戏的结构分析 2.2.1、用户选择 2.2.2、生

    2024年04月11日
    浏览(26)
  • 学习java第四十三天

    Spring AOP 相关术语 (1)切面(Aspect):切面是通知和切点的结合。通知和切点共同定义了切面的全部内容。 (2)连接点(Join point):指方法,在Spring AOP中,一个连接点总是代表一个方法的执行。连接点是在应用执行过程中能够插入切面的一个点。这个点可以是调用方法时

    2024年04月15日
    浏览(33)
  • 学习java第四十一天

    Spring MVC 运行流程: 第一步:发起请求到前端控制器(DispatcherServlet) 第二步:前端控制器请求HandlerMapping查找 Handler( 可以根据xml配置、注解进行查找) 第三步:处理器映射器HandlerMapping向前端控制器返回Handler 第四步:前端控制器调用处理器适配器去执行Handler 第五步:处理

    2024年04月13日
    浏览(31)
  • 学习JAVA打卡第四十一天

    字符串与字符数组、字节数组 ⑴字符串与字符数组 String类的构造方法String(char a[])和String(char a[]),int offset,int length,分别用数组a中的全部字符和部分字符创建string对象。 String类也提供将string对象的字符序列存放到数组中的方法: Public void getChars(int start,int.end,char c [],i

    2024年02月11日
    浏览(37)
  • 学习JAVA打卡第四十二天

    正则表达式及字符串的替换与分解 ⑴正则表达式 正则表达式是string对象的字符序列,该字符序列中含有具有特殊意义的字符,这些特殊字符称作正则表达式的元字符。  注:由于“   ”代表任何一个字符,所以在正则表达式中如果想使用普通意义的点字符必须使用[.]或5

    2024年02月11日
    浏览(27)
  • 学习JAVA打卡第四十五天

    StringBuffer类 StringBuffer对象 String对象的字符序列是不可修改的,也就是说,String对象的字符序列的字符不能被修改、删除,即String对象的实体是不可以再发生变化,例如:对于  StringBuffer有三个构造方法: ⑴StringBuffer(); ⑵StringBuffer(int Size); ⑶StringBuffer(String s);

    2024年02月11日
    浏览(31)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包