首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

【C语言】结构体详解

.结构体类型的声明 1.1 结构体变量的创建和初始化 结构是一些值的集合,这些值称为成员变量,结构的每个成员可以是不同类型的变量,下面是基本结构 struct tag { member - list;...","lingyangjiao",18.8,"A1010" }; 结构体初始化写在{}里面,书名、作者,书号是字符串,就用""初始化,价格是float类型,就直接写,中间用逗号隔开,我上面初始化的内容都是我随便写的...; //匿名 struct { char c; int i; float f; }; 这样的话这个结构体没有名字,定义变量的时候就不可以像下面这样 struct s//正常情况 { char...与 成员变量的大小的较小值 --vs默认对齐数是8 --Linux中gcc没有默认对齐数,所以对齐数就是成员自身大小 i的对齐数是4,从4的倍数的偏移量开始存4个字节,c2的对齐数是1,从1的倍数开始存...,所以结构体大小为12个字节,打红色X的空间都是被浪费掉的,为什么要浪费,我们后面讨论 对前三个规则的练习 1.算结构体大小 struct s2 { char c1; char c2; int

9210

C++ struct与union

struct中的成员变量和成员函数也有访问权限,在class中,默认的访问权限是private,而在struct中默认访问权限是public,这是结构体和类的唯一区别。...struct成员的默认访问权限设为public是C++保持与C语言兼容而采取的一项策略。...(3)如果struct中没有显示定义任何构造函数,那么结构变量可以像在C语言中那样用花括号顺序指明数据成员的值来进行初始化。但是一旦显示定义了任何一个构造函数,就不能用这种方式初始化了。...对其中一个数据成员的修改,一定会同时改变所有其他数据成员的值。不过对体积较小的数据成员的修改,只会影响到该成员应该占用的那些字节,对超出部分(高位字节)没有什么影响。...(4.2)同样,union的对象成员的析构函数也不能被调用,因为其他数据成员的值对于对象成员而言可能毫无意义。

2.3K30
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    关于我、重生到500年前凭借C语言改变世界科技vlog.20——自定义类型:联合&&枚举

    ("%d\n", un1.i); printf("%d\n", un2.i); return 0; } 按照联合体初始化规则,初始化赋值时将值赋给第一个成员 赋值为 0 的情况:这是一种特殊情况...所以整个 un1 结构体都初始化为 0,即 un1.i = 0 赋值为其他值的情况:当用 ‘a’ 初始化联合体的第一个成员(如 char 类型)时,只会将 ‘a’ 的 ASCII 码值 97 存储在第一个成员对应的内存位置...,尽可能节省空间,这样⼀个联合变量的大小,至少是最大成员的大小(因为联合至少得有能力保存最大的那个成员) 代码1 输出:001BC63F、001BC63F、001BC63F 代码2 输出:11223355...不难发现联合体的部分或整体地址都一样,整型 i 的数据被字符 c 覆盖,这是为什么呢?...,也叫 枚举常量,这些可能取值都是有值的,默认从0开始,依次递增1,当然在声明枚举类型的时候也可以赋初值 比如颜色枚举常量,从上到下默认为RED、GREEN、BLUE赋值0、1、2 为什么非要用枚举常量

    6510

    C++11常用的一部分新特性

    新的类功能 默认成员函数 C++11 新增了两个默认成员函数:移动构造函数和移动赋值运算符重载。...针对移动构造函数和移动赋值运算符重载有一些需要注意的点如下: 如果你没有自己实现移动构造函数,且没有实现析构函数 、拷贝构造、拷贝赋值重载中的任意一个。那么编译器会自动生成一个默认移动构造。...默认生成的移动构造函数,对于内置类型成员会执行逐成员按字节拷贝,自定义类型成员,则需要看这个成员是否实现移动构造,如果实现了就调用移动构造,没有实现就调用拷贝构造。...如果你没有自己实现移动赋值重载函数,且没有实现析构函数 、拷贝构造、拷贝赋值重载中的任意一个,那么编译器会自动生成一个默认移动赋值。...默认生成的移动构造函数,对于内置类型成员会执行逐成员按字节拷贝,自定义类型成员,则需要看这个成员是否实现移动赋值,如果实现了就调用移动赋值,没有实现就调用拷贝赋值。

    457110

    干货|手把手教你写单片机的C语言结构体

    其实这不是你的错,也不是单片机的错,而是在C语言和单片机之间需要一个过渡!这个需要过渡的点在很多单片机视频教程中并没有去讲解。...因为教育机构默认你是知道的,所以在讲流水灯时他们并不会讲解GPIO初始化这个结构体,因为默认你是知道如何操作的。 ?...虽然typedef可以给变量取别名,但是没有谁会像上面那样取名字,我这里只是举一个例子。 4、结构体的精髓 注意下: 1、下面的代表了这个结构体数据类型 ?...) { uart_init(115200);//串口初始化 delay_init(); sen.p=&value;//把value的地址赋值 //打印p代表的地址里面的值(其实就是打印value...的值) printf("value=%d\r\n",*(sen.p)); while(1) { } } 既然是指针变量,所以给指针变量赋值时当然是赋值的是一个地址。

    1.6K62

    C语言自定义类型

    ;//名字 int age;//年龄 char sex[5];//性别 char id[20];//学号 }; int main() { //按照结构体成员的顺序初始化 struct Stu...结构体的第一个成员对齐到和结构体变量起始位置偏移量为0的地址处。 2. 其他成员变量要对齐到对齐数的整数倍的地址处。(对齐数 = 编译器默认的⼀个对齐数与该成员变量大小的较小值。) 3. ...否则,我们可能需要执行两次内存访问,因为对象可能被分放在两个8字节内存块中。 3. 总体来说: 1. 结构体的内存对齐是拿空间来换取时间的做法。 修改默认对齐数  1. ...}; struct stu f = { 's',5,5.2 }; //通过指针来初始化 void Printf(struct stu* pf) { printf("%d", pf->n); return...给联合体其中⼀个成员赋值,其他成员的值也跟着变化。

    7610

    C++11

    新的类功能 默认成员函数: 原来C++类中,有6个默认成员函数: 1. 构造函数 2. 析构函数 3. 拷贝构造函数 4. 拷贝赋值重载 5....针对移动构造函数和移动赋值运算符重载有一些需要注意的点如下: 如果你没有自己实现移动构造函数,且没有实现析构函数 、拷贝构造、拷贝赋值重载中的任 意一个。那么编译器会自动生成一个默认移动构造。...默认生成的移动构造函数,对于内置类 型成员会执行逐成员按字节拷贝,自定义类型成员,则需要看这个成员是否实现移动构造, 如果实现了就调用移动构造,没有实现就调用拷贝构造。...如果你没有自己实现移动赋值重载函数,且没有实现析构函数 、拷贝构造、拷贝赋值重载中 的任意一个,那么编译器会自动生成一个默认移动赋值。...默认生成的移动构造函数,对于内 置类型成员会执行逐成员按字节拷贝,自定义类型成员,则需要看这个成员是否实现移动赋 值,如果实现了就调用移动赋值,没有实现就调用拷贝赋值。

    14810

    干货|手把手教你写单片机的结构体

    其实这不是你的错,也不是单片机的错,而是在C语言和单片机之间需要一个过渡!这个需要过渡的点在很多单片机视频教程中并没有去讲解。...因为教育机构默认你是知道的,所以在讲流水灯时他们并不会讲解GPIO初始化这个结构体,因为默认你是知道如何操作的。 ?...虽然typedef可以给变量取别名,但是没有谁会像上面那样取名字,我这里只是举一个例子。 4、结构体的精髓 注意下: 1、下面的代表了这个结构体数据类型 ?...) { uart_init(115200);//串口初始化 delay_init(); sen.p=&value;//把value的地址赋值 //打印p代表的地址里面的值(其实就是打印value...的值) printf("value=%d\r\n",*(sen.p)); while(1) { } } 既然是指针变量,所以给指针变量赋值时当然是赋值的是一个地址。

    81172

    【C++】类和对象核心总结

    只要编译器语义检测过后,类就没有用了,自然就不会出现声明重命名的问题了。 4.5 赋值重载(默认成员函数:两个已经存在的对象之间的赋值) a....之前我们所学的构造函数可以给新创建的对象赋初值,这点我们是知道的,但是它并不是对成员变量的初始化,而是赋值工作。 因为初始化只能初始一次,而构造函数内的赋值是可以赋值多次的。...至于第三个应该也是好理解的,因为如果自定义类型没有合适的默认构造的话,那他就失去了被赋值的权利,所以他必须得在初始化的时候进行 “ 赋值 ”,否则编译器会报错没有合适的默认构造。...如果在初始化列表显示写了,就用显示写的初始化 如果没有在初始化列表显示初始化 1.内置类型,有缺省值用缺省值,没有就用随机值,缺省值其实也是在初始化列表位置使用的。...2.自定义类型,初始化列表会调用他的默认构造函数,如果没有默认构造函数就会报错。 所以尽量用初始化列表来初始化,因为无论你写不写初始化列表,所有的成员变量在进入构造函数之前都要走一遍初始化列表。

    76330

    当类构造与析构的时候...

    文章目录 什么时候会调用默认构造函数 什么时候调用拷贝构造函数? 什么时候调用赋值运算符? 深拷贝与浅拷贝 成员初始化列表的概念,为什么用它会快一些? 有哪些情况必须用到成员列表初始化?...C++中struct和class的区别 什么时候会调用默认构造函数 1、当不使用任何初始值定义一个类的非静态变量时,会调用该类的默认构造函数。...NRV优化,但是由于返回方式是值传递,所以会在返回值的地方调用拷贝构造函数 ---- 什么时候调用赋值运算符?...---- 成员初始化列表的概念,为什么用它会快一些? 在类的构造函数中,不在函数体内对成员变量赋值,而是在构造函数的花括号前面使用冒号和初始化列表赋值。...用初始化列表会快一些的原因是,对于类型,它少了一次调用构造函数的过程,而在函数体中赋值则会多一次调用。而对于内置数据类型则没有差别。

    64520

    C++ struct与union

    struct中的成员变量和成员函数也有访问权限,在class中,默认的访问权限是private,而在struct中默认访问权限是public,这是结构体和类的唯一区别。...struct成员的默认访问权限设为public是C++保持与C语言兼容而采取的一项策略。...(3)如果struct中没有显示定义任何构造函数,那么结构变量可以像在C语言中那样用花括号顺序指明数据成员的值来进行初始化。但是一旦显示定义了任何一个构造函数,就不能用这种方式初始化了。...对其中一个数据成员的修改,一定会同时改变所有其他数据成员的值。不过对体积较小的数据成员的修改,只会影响到该成员应该占用的那些字节,对超出部分(高位字节)没有什么影响。...对于引用变量,引用本质上是一个指着常量,它的值一旦初始化就不允许修改。如果共用体有引用成员,那么共用体对象一创建初始化后就无法修改,只能作为一个普通的引用使用,这就失去了共用体存在的意义。

    63010

    【C++】C++11中的常见语法(上)

    那么为什么右值被右值引用引用以后的属性是左值呢?...默认生成的移动构造函数,对于内置类型成员会执行逐成员按字节拷贝,自定义类型成员,则需要看这个成员是否实现移动构造,如果实现了就调用移动构造,没有实现就调用拷贝构造。...如果你没有自己实现移动赋值重载函数,且没有实现析构函数 、拷贝构造、拷贝赋值重载中的任意一个,也就是都没有实现,那么编译器会自动生成一个默认移动赋值。...默认生成的移动构造函数,对于内置类型成员会执行逐成员按字节拷贝,自定义类型成员,则需要看这个成员是否实现移动赋值,如果实现了就调用移动赋值,没有实现就调用拷贝赋值。...类成员变量初始化 C++11允许在类定义时给成员变量初始缺省值,默认生成构造函数会使用这些缺省值初始化,这个我们在类和对象已经介绍过了,这里就不再细讲了。 3.

    20810

    CC++ 学习笔记五(结构体、字符与字符串)

    例如结构体中拥有int (4个字节),char(1个字节)两个变量,但在使用sizeof进行大小输出时,并不是简单的各个成员数据的大小相加(4+1 = 5字节),而是经过编译器对齐后的8个字节 struct...便是说空结构体在C标准中是一种未定义的行为,而在很多的编译器中(如GCC,VC)则对此做了兼容,是被允许使用。 那作为C的子集C++又为什么空指针的长度为1?...1+7+8 = 16 3.根据规则3,默认的对齐模数为8,结构体最大长度成员8字节的较小值8。...这时候我们可以通过调整成员数据的位置来节省空间。 例如,下方例子默认对齐模数为8时,长度为24。经过将两个char数据提前后,结构体的长度减少为16字节。...即使我们将s1与s2的成员数据设置成相同的值,但在使用memcmp对比时依然返回不为0(两者不相同) typedef struct { char a; int b; }TestStruct

    2.2K00

    终极 C++避坑指南

    所以f2内部调f1的过程会报错。这就是所谓“右值引用传递时会失去右性”。 那么如何保持右性呢?...auto &&的推导原则,有可能会推导出左值引用来,所以auto &&并不是要“定义一个右值引用”,而是“定义一个保持左右性的引用”,也就是说,绑定一个左值时会推导出左值引用,绑定一个右值时会推导出右值引用..., const char *argv[]) {   f(); // 第一次执行时count被定义,并且初始化为0,执行后count值为1,并且不会释放   f(); // 第二次执行时由于count已经存在...,因为在a2.cc中没有找到f1的定义,并不会链接到a1.cc中的f1 } 所以我们发现,在这种场景下,static并不表示“静态”的含义,而是表示“内部”的含义,所以,为什么不再引入个类似于inner...平凡 “平凡(trivial)”指的是: 拥有默认无参构造函数 拥有默认析构函数 拥有默认拷贝构造函数 拥有默认移动构造函数 拥有默认拷贝赋值函数 拥有默认移动赋值函数 换句话说,六大特殊函数都是默认的

    2.3K20

    万字长文【C++】高质量编程指南

    ,成为野指针的原因有: 1,指针变量没有被初始化 指针变量在创建的同时应当被初始化,要么将指针设置为 NULL,要么让它指向合法的内存。...辨识重载:靠参数而不是返回值的不同来区分重载函数,编译器根据参数为每个重载函数产生不同的内部标识符号。 extern "C"的用处 如果C++程序要调用已经被编译后的C函数,我?...0) // 错误,缺省值出现在函数的定义体中 { ⋯ } 为什么?...根据经验,不少难以察觉的程序错误是由于变量没有被正确初始化或清除造成,因此把对象的初始化放在构造函数,把清除工作放在析构函数,当对象被创建时候,构造自动执行,对象消亡时,析构自动执行,不要担心忘记对象的初始化和清除工作了...A 的构造函数 { … } 2,类的const常量只能在初始化列表里被初始化,因为它不能在函数体内赋值的方式来初始化 3,非内部数据类型的成员对象应当采用初始化列表方式来初始化,以获取更高的效率。

    1.6K20

    C++11

    针对移动构造函数和移动赋值运算符重载有一些需要注意的点如下: 如果你没有自己实现移动构造函数,且没有实现析构函数 、拷贝构造、拷贝赋值重载中的任 意一个。那么编译器会自动生成一个默认移动构造。...默认生成的移动构造函数,对于内置类 型成员会执行逐成员按字节拷贝,自定义类型成员,则需要看这个成员是否实现移动构造, 如果实现了就调用移动构造,没有实现就调用拷贝构造。...如果你没有自己实现移动赋值重载函数,且没有实现析构函数 、拷贝构造、拷贝赋值重载中的任意一个,那么编译器会自动生成一个默认移动赋值。...默认生成的移动构造函数,对于内置类型成员会执行逐成员按字节拷贝,自定义类型成员,则需要看这个成员是否实现移动赋值,如果实现了就调用移动赋值,没有实现就调用拷贝赋值。...C++11允许在类定义时给成员变量初始缺省值,默认生成构造函数会使用这些缺省值初始化。

    14110

    【笔记】《C++Primer》—— 第7章:类

    const,当创建const对象时,对象是在构造初始化完成后(执行构造函数体前的瞬间)获得const属性的 当没有任何构造函数时编译器会默认生成一个构造函数,初始化(值初始化,默认构造或用初始值赋值)类内的各种成员...拷贝构造在赋值或初始化与值传递等操作中产生,但当类需要分配对象以外的资源时,默认的拷贝构造常常失效,此时用vector类来代劳内存分配等能避免这种复杂情况 7.2 访问控制与封装 在类的成员前加访问控制符...因此一方面是最好保持参数顺序与声明顺序相同以方便查找,另一方面尽量避免用某些成员来初始化其他的成员以防止初始化顺序导致的问题 ?...const属性的初始值或用constexpr来初始化 要注意由于静态变量不是由构造函数初始化的,一般来说我们不能在类内初始化它,而是在类内声明它然后在类外定义并初始化它 由于类内的它的初始化只是声明而已...,若外部的函数没有获得类的完整声明则无法使用类内的静态初始化,所以我们应该保持一个良好习惯即即便我们已经类内初始化它,也在外部进行一次定义(但不用初始化)来保证其作用域的正常 ?

    61420
    领券