C++ 结构体的声明

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++ 结构体的声明相关的知识,希望对你有一定的参考价值。

在"a.cpp"中我定义了一个结构体
struct A
...
A(...)


...

在"b.cpp"与"c.cpp"中我都需要用到该类型的数据,于是我将"a.h"分别在"b.cpp"与"c.cpp"中包含
但是,在"a.h"中,我用
struct A;
语句来声明A类型,却在定义A类型的数据时被报错“A类型没有初始化函数"
正确的做法应该是怎么样的?

参考技术A 你显式定义了带参数的构造函数A,所以你定义变量的时候,必须以参数初始化变量。

定义了A::A(T);
A aV1(t1),av2(t2);//正确
A aV3,av4;//不正确
A *av5,*av6;正确
A av8(t8),*av7;正确
参考技术B 直接把定义写在a.h追问

那样不是会因为重复包含头文件导致重复定义吗

追答

使用 #ifdef 来控制

追问

但是不是说一般不在头文件里做定义吗。。。
我想知道正确的声明方法

追答

如果你是想全局变量,假如有如下结构体
typedef struct A

char a[10];
A;
那在main函数所在的cpp中,这样定一个该结构体的变量:
A a;
在其他需要使用该变量的cpp文件中,加如下语句:
extern A a;
这样其他cpp文件也就可以用了。

如果是想通用这个a,那么一般情况下。文件都是这么写,无论你怎么弄都不会重复了
#ifndef __A_H__//这个宏一般就是你的文件名.变成下划线,前后各加两个下划线
#define __A_H__
你要写的代码的内容
#endif

你这样写 无论你怎么包含这个文件。都不会出现重定义的情况。

本回答被提问者采纳

第九章 结构体的使用

1. 结构体的声明和定义

介绍

  • 我们知道数组是同种类型值的集合,而结构就是可以将不同类型的值放在一起。
  • 结构是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量。
  • 结构的成员可以是标量、数组、指针,甚至是其他结构体。

如我们可以将一个学生的一些属性放在一起

struct stu//定义一个结构体类型,就如int、char,struct stu是我们定义的结构体类型
{
    //成员变量
    char name[20];//名字
    int age;//岁数
    char id[20];//学号
};
int main()
{
    struct stu a;//定义一个struct stu类型的变量a,而对象a中就包含了名字,岁数,学号的属性
}

定义的几种类型

类型1:

struct stu
{
    char name[20];
    int age;
};
int main()
{
    struct stu a;//定义局部变量a
}

类型2:

struct stu
{
    char name[20];
    int age;
}s1,s2;//定义全局变量s1,s2

2. 结构体初始化

看这段代码

struct book
{
   float height;
   char name[20];
}b;
struct stu
{
    char name[20];
    int age;
    char id[20];
    struct book b;
};
int main()
{
    //初始化时,其实是和数组初始化一样,用大括号,里面放上初始化的值。若结构体里面包含结构体,则大括号里面	//在放一个大括号,里面放内部结构体初始化的值
    
    struct stu a={"bobo",18,"2021520",{15.8,"free"}};
}

3. 结构体成员访问

介绍

  1. 结构变量的成员是通过点操作符(.)访问的。点操作符接受两个操作数,如:m.n(m为结构体变量,n为结构体中你想要访问的成员变量)
  2. 指向一个结构体的指针访问指向变量的成员是通过操作符(->)访问的。 如:m->n(m为指向一个结构体的指针,n为结构体中你想要访问的成员变量),也可以(*m).n
struct book
{
   float height;
   char name[20];
}b;
struct stu
{
    char name[20];
    int age;
    char id[20];
    struct book b;
};
int main()
{
    struct stu a={"bobo",18,"2021520",{15.8,"free"}};
    //法一
    printf("%s\\n",a.name);
    printf("%d\\n",a.age);
    printf("%.1f\\n",a.b.height);//若访问结构体中的结构体中的一个成员,先访问到内部的结构体,再访问内部结构体中的成员
    
    //法二
    struct stu* pa=&a;
    printf("%s\\n",pa->name);
    printf("%d\\n",pa->age);
    printf("%.1f\\n",pa->b.height);
    
    //法三
    printf("%s\\n",(*pa).name);
    printf("%d\\n",(*pa).age);
    printf("%.1f\\n",(*pa).b.height);
}

4. 结构体传参

注意

结构体传参的时候,要传结构体的地址更好

看一段代码

struct book
{
   float height;
   char name[20];
}b;
struct stu
{
    char name[20];
    int age;
    char id[20];
    struct book b;
};
void print1(struct stu p)
{
    printf("%s %d %s %.1f %s",p.name,p.age,p.id,p.b.height,p.b.name);
}
void print2(struct stu* pa)
{
    printf("%s %d %s %.1f %s",pa->name,pa->age,pa->id,pa->b.height,pa->b.name);
}
int main()
{
    struct stu a={"bobo",18,"2021520",{15.8,"free"}};
    
    //写一个函数打印a的内容
    
    print1(a);//结果为:bobo 18 2021520 15.8 free(正常打印)
    
    //再写一个函数,通过传a的地址打印a的内容
    
    print2(&a);//结果为:bobo 18 2021520 15.8 free(正常打印)
    
    return 0;
}

那么传值和传址有什么不同,哪个更好呢?(首选传址)

  1. 传参时,其实是对实参的一份拷贝,是会开辟一块空间来存储实参。传值,是将整个实参拷贝过去,而传地址,传过去的只是地址,传参的效率更高一些。

  2. 函数传参的时候,参数是需要压栈的。 如果传递一个结构体对象的时候,结构体过大,参数压栈的的系统开销比较大,所以会导致性能的下降。

那么什么是函数调用的参数压栈呢?

  • :一种数据结构,是一种只能在一端进行插入和删除操作的特殊线性表

  • 特点:先进的后出,后进的先出。(先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据(最后一个数据被第一个读出来))

  • 压栈:给栈里存数据

在这里插入图片描述

  • 每一个函数的调用都会在内存的栈区上开辟一块空间,并且数据都会如压栈一样一个一个的存放进栈区,如果数据比较多、大时,参数压栈就比较吃力,所以导致性能就会下降。

总结

以上介绍了个人对结构体简单的一些总结,而还有一些跟结构体有关的,后面会专门有一章再继续讲解结构体的更多知识点。希望大家喜欢我的内容,并且欢迎大家指正我的错误和不足。

以上是关于C++ 结构体的声明的主要内容,如果未能解决你的问题,请参考以下文章

C++——class类和struct结构体的唯一区别

C++中结构体的大小

C++中类和结构体的区别

结构体的声明是在文件中的那个位置,函数的声明是在引用函数的声明部分还是在整个文件开始

用c或c++实现结构体的序列化和反序列化

07结构体.