结构体 结构体c++

结构体是用户自定义的类型,可以将多种数据的表示合并到一起,描述一个完整的对象。

结构体的存在也就是相当于将多个变量结合在一起进行管理

使用结构体有两个步骤:1)定义结构体描述(类型);2)创建结构体变量。

cpp 复制代码
定义结构体语法:
struct 结构体名
{
成员一的数据类型  成员名一;
成员二的数据类型  成员名二;
成员三的数据类型  成员名三;
......
成员n的数据类型  成员名n;
};
cpp 复制代码
创建结构体变量
struct 结构体名 结构体变量名;
struct 结构体名 结构体变量名={成员一的值, 成员二的值,......, 成员n的值};
struct 结构体名 结构体变量名={};
struct 结构体名 结构体变量名={0};❌️,会导致类型不匹配,不要用

清空结构体

1.解释让其={}

2.用memset()函数可以把结构体中全部的成员清零。(只适用于C++基本数据类型)

复制结构体

1.直接用等于号(只适用于C++基本数据类型)。

2.用memcpy()函数把结构体中全部的元素复制到另一个相同类型的结构体(只适用于C++基本数据类型)。

那么为了方便,肯定是使用指针去调用结构体的数据

cpp 复制代码
 (*指针名).成员变量名     
指针名->成员变量名    ✅️这个最直观
cpp 复制代码
#include"iostream"
using namespace std;

struct Student 
{
    string name;
    int age;
    int score;
};

int main()
{
    Student zs={"jk",18,90};
    cout<<"zs name="<<zs.name<<endl;
    Student *ptr=&zs;
    cout<<"ptr name="<<ptr->name<<endl;
    cout<<"(*ptr).name="<<(*ptr).name<<endl;
}

还是那句话,结构体的创建相当于自己创建的一个数据类型,在使用函数进行传参的时候和普通的没有区别。结构体传递给函数,实参取结构体变量的地址,函数的形参用结构体指针。若不想更改结构体的数据增加const约束。

cpp 复制代码
#include"iostream"
using namespace std;

struct Student 
{
    string name;
    int age;
    int score;
};
void changname(Student *p,string newname)
{
    p->name=newname;
    cout<<"new name="<<p->name<<endl;
}
int main()
{
    Student zs={"jk",18,90};
    cout<<"zs name="<<zs.name<<endl;
    Student *ptr=&zs;
    cout<<"ptr name="<<ptr->name<<endl;
    cout<<"(*ptr).name="<<(*ptr).name<<endl;
    changname(&zs,"lisi");
    changname(ptr,"wangwu");
    cout<<"zs name="<<zs.name<<endl;
}

用结构体指针指向动态分配的内存的地址。先new再delete

cpp 复制代码
 Student* p = new Student{"lisi", 20, 0};  // 动态创建
 cout << p->name << endl;              // 访问成员
 delete p;                             // ⚠️ 必须手动释放!

假设数组的数据类型是不是c++基础类型,而是自定义类型,这时候就需要结合数组了,但是也是类似的。

cpp 复制代码
    Student array[3] = {{"lisi", 20, 0}, {"wangwu", 18, 100}, {"zhaoliu", 16, 90}};
    for (int i = 0; i < 3; i++) {
        cout << array[i].name << ", " << array[i].age << ", " << array[i].score << endl;
    }

同样的,结构体里面是可以嵌套的

cpp 复制代码
struct Point {
    double x, y;
};

struct Triangle {
    Point vertices[3];  // 三角形由3个点组成
};

int main() {
    Triangle tri = {
        {{0.0, 0.0},     // vertices[0]
         {1.0, 0.0},     // vertices[1]
         {0.5, 0.866}}   // vertices[2]
    };

    cout << "三角形三个顶点:\n";
    for (int i = 0; i < 3; ++i) {
        cout << "(" << tri.vertices[i].x 
             << ", " << tri.vertices[i].y << ")\n";
    }
}

接下来有个问题,结构体是可以包含指针的,那么这个指针怎么使用、初始化的时候指针是什么状态?

其实结构体中的指针的作用是指向的是动态分配的内存地址。那么你会反应到这就是new,对没错,所以我们初始化的时候就得小心了,因为不控制的话就是随机值 or 0值。这在设计代码的时候会涉及到的。

两种推荐

1.直接初始为0

cpp 复制代码
struct teacher 
{
    string name;
    int age;
    int score;
    string* ID;

};


  cout<<"--------------------------"<<endl;
    teacher t1={};
    cout<<"ID="<<t1.ID<<endl;

2.显式初始化,我比较推荐这个

cpp 复制代码
 teacher t2={"t2",18,100,new string("123456")};
    cout<<"t2 ID="<<*(t2.ID)<<endl;
    delete t2.ID; // 释放动态分配的内存

其实也可以初始化为0,指针为空指针,再单独new。

假如说指针类型指向的数据类型就是自己定义的结构体类型,就构成了链表了。

cpp 复制代码
 struct lbiao
{
    int no;
    string name;
    struct lbiao*next;
};

cout<<"--------------------------"<<endl;
    lbiao*head=nullptr,*tail=nullptr,*tmp=nullptr;
    tmp=new lbiao{1,"node1",nullptr};
    head=tail=tmp;

    tmp=new lbiao{6,"node2",nullptr};
    tail->next=tmp;
    tail=tmp;

    tmp = new lbiao({ 3, "node2", nullptr });      // 分配第三个节点。
	tail->next = tmp;     // 把上一个节点的next指针指向新节点。
	tail = tmp;                 // 移动尾指针,让尾指针指向刚分配出来的新节点。


    // 遍历链表。
	tmp = head;             // 从头节点开始。
	while (tmp != nullptr)
	{
		cout << "no=" << tmp->no << "name=" << tmp->name << "tmp->next=" << tmp->next << endl;
		tmp = tmp->next;   // 顺着next指向往后面找。
	}
	
	// 释放链表。
	while (head != nullptr)
	{
		tmp = head;               // 让临时节点指向头节点。
		head = head->next;  // 头节点后移。
		delete tmp;                 // 删除临时节点。
	}

枚举

使用枚举可以表达我们数据的状态。

cpp 复制代码
枚举的语法:
enum 枚举名 { 枚举量1 , 枚举量2 , 枚举量3, ......, 枚举量n };
例如:
enum colors { red , yellow , blue };
enum colors {red=1,yellow=2,blue=3};
enum colors {red=10,yellow,blue};

值得注意的是用枚举创建的变量取值只能在枚举量范围之内,并且枚举的作用域与变量的作用域相同。

相关推荐
kyle~42 分钟前
虚拟仪器LabView(VI)
c++·python·ros·labview
小股虫43 分钟前
消息中间件关键技术、设计原理与实现架构总纲
java·开发语言·架构
洲星河ZXH1 小时前
Java,日期时间API
java·开发语言·python
前端老曹1 小时前
Jspreadsheet CE V5 使用手册(保姆版) 二
开发语言·前端·vue.js·学习
秋邱1 小时前
AR 定位技术深度解析:从 GPS 到视觉 SLAM 的轻量化实现
开发语言·前端·网络·人工智能·python·html·ar
Boop_wu1 小时前
[Java EE] 多线程进阶(3) [线程安全集合类]
开发语言·windows·python
雨疏风骤12401 小时前
【FreeRTOS】任务、任务状态
开发语言·stm32·c#·rtos
SongYuLong的博客1 小时前
开源 C 标准库(C Library)
c语言·开发语言·开源
GHL2842710901 小时前
win32给进程设置图标、修改图标
c++·windows