c++结构体

本文详细介绍了C++中结构体的概念,包括其成员定义、变量声明、排序方法(如自定义cmp函数和std::sort),以及结构体与模板、函数的交互,包括值传递与引用传递的区别。
摘要由CSDN通过智能技术生成

结构体

关于结构体

在 C++ 语言中,结构体 (struct) 是复合数据类型的一种。同时也是一些元素的集合,这些元素称为结构体的成员,且这些成员可以为不同的类型,成员一般用名字访问。结构体可以被声明为变量、指针或数组等,用以实现较复杂的数据结构。

注:在 C 语言中,结构体不能包含函数, C++ 中可以使用函数。

struct 结构体名{

   结构体所包含的变量或数组

 };

结构体是一种集合,它里面包含了多个变量或数组,它们的类型可以相同,也可以不同,每个这样的变量或数组都称为结构体的成员( Member )

请看下面的一个例子

struct stu{
   string name;     //姓名  
   int num;         //学号
   int age;         //年龄
   char group;      //所在学习小组
   float score;     //成绩
};

stu 为结构体名,它包含了 5 个成员,分别是 name 、 num 、 age 、 group 、 score

结构体成员的定义方式与变量和数组的定义方式相同,只是不能初始化。

注意大括号后面的分号;不能少,这是一条完整的语句。

结构体也是一种数据类型,它由程序员自己定义,可以包含多个其他类型的数据。

像 int 、 float 、 char 等是由 C++ 语言本身提供的数据类型,不能再进行分拆,我们称之为基本数据类型;而结构体可以包含多个基本类型的数据,也可以包含其他的结构体,我们将它称为复杂数据类型或构造数据类型。

结构体变量

既然结构体是一种数据类型,那么就可以用它来定义变量。例如:

struct stu{
   string name;     //姓名  
   int num;         //学号
   int age;         //年龄
   char group;      //所在学习小组
   float score;     //成绩
};
struct stu stu1, stu2;

定义了两个变量 stu1 和 stu2 ,它们都是 stu 类型,都由 5 个成员组成。

注意在 C 语言中关键字 struct 不能少, C++ 可以省略。

这段程序里 stu 就像一个“模板”,定义出来的变量都具有相同的性质。也可以将结构体比作“图纸”,将结构体变量比作“零件”,根据同一张图纸生产出来的零件的特性都是一样的。你也可以在定义结构体的同时定义结构体变量:

将变量放在结构体定义的最后即可。

除了可以对成员进行逐一赋值,也可以在定义时整体赋值,例如:

struct{

    string name;      //姓名

    int num;          //学号

    int age;          //年龄

    char group;       //所在小组

    float score;      //成绩

}stu1, stu2 = { "Tom", 12, 18, 'A', 136.5 };

结构体排序

C++ 标准库提供的 sort ,不仅可以对 int,double... 等系统类型进行排序,同样可以对结构体排序。

只要按照标准书写 cmp 函数即可,

有一个 node 类型的数组 node arr[100] ,想对它进行排序:先按 a 值升序排列,如果 a 值相同,再按 b 值降序排列,如果 b 还相同,就按 c 降序排列。就可以写这样一个比较函数:

bool cmp(node x,node y){

    if(x.a != y.a) return x.a < y.a;

    if(x.b != y.b) return x.b > y.b;

    return x.c > y.c;

}

使用 C++ 标准库的 sort ​,我们可以轻松定义两个相同类型元素的大小。在之前排序的课程中,曾经讲到过稳定排序这个概念,当一个数列中有相同的元素时,排序后这些相同元素之间的顺序可能会同初始序列不一样。使用非稳定的排序方法对一个整型数组排序,对于普通的一个数字 5 ,如果数组中同时存在多个 5 ,我们无法区分每个 5 究竟是来自于最初数组中的那个位置。标准库中的 sort  是使用快速排序实现的,快速排序是一种非稳定排序,如果我们的比较函数只比较结构体的某一个值,则原有的顺序可能会被打乱,这点在我们写代码的时候要特别注意,有可能因为顺序问题造成计算结果的错误。那么如何能够使用 sort的同时,又保证排序后的数组顺序仍然是稳定的呢?需要做特殊的处理,可以在结构体中增加一个属性,专门用来记录在原始数组中的位置,在其它值相等的情况下,再比较这个位置数据,这相当于没有两个值是完全相等的,这种情况下稳定排序的结果与非稳定排序是相同的。

结构体与模板

结构体嵌套

在结构体中我们可以定义自己需要的成员及成员类型。成员类型可以是 C++ 的标准类型,也可以是另一个结构体。例如:

struct Book{

    int book_id;

    string name;

    string ISBN;

};

struct Home{

    int size;

    Book One;

};

需要注意的是,这个类型不可以是自己。例如:

struct Book{

    int book_id;

    string name;

    string ISBN;

    Book book;

};

这个程序无法通过编译。

结构体与函数

结构体与其他类型相同,可以作为函数的参数进行传递。

将结构体作为函数参数时,遵循值传递的规则。函数体内对结构体进行修改并不会影响原来变量的值。

 struct Book{
    int book_id;
    string name;
};
void setBook(Book bk){
    bk.book_id = 3;
    bk.name = "World";
}
int main(){
    Book s;
    s.book_id = 1;
    s.name = "Hello";
    setBook(s);
    cout << s.book_id << endl;
    cout << s.name << endl;
}
运行结果如下:	1	Hello

 可以看到把结构体变量 s 作为函数的参数传入,并在函数内部对传入的 s 的内容做修改,是不会影响到原来 s变量的取值的。如果希望能够在调用函数的内部,修改传入参数的值,则需要增加引用传递符号 & 。或者把函数的返回值类型设为结构体。

struct Book{
    int book_id;
    string name;
};
void setBook(Book &bk){
    bk.book_id = 3;
    bk.name = "World";
}
int main(){
    Book s;
    s.book_id = 1;
    s.name = "Hello";
    setBook(s);
    cout << s.book_id << endl;
    cout << s.name << endl;
}
运行结果如下:	3	World

结构体除了可以作为函数的参数,也可以作为函数的返回值。

struct Books {
   int Id;
   string Title;
} book;
void F1(Books n){
    n.Id += 8;
    n.Title += " Ok";
}
void F2(Books &n){
    n.Id += 8;
    n.Title += " Ok";
}
Books F3(Books n){
    n.Id += 8;
    n.Title += " Ok";
    return n;
}
int main() { 
    Books a, b;
    a.Id = 3;
    a.Title = "CL1";
    b = a;
    F1(a);
    cout << a.Id << " " << a.Title << endl;
    F2(a);
    cout << a.Id << " " << a.Title << endl;
    a = F3(b);
    cout << a.Id << " " << a.Title << endl;
    return 0;
}

这段程序输出的结果如下:3 CL111 CL1 Ok11 CL1 Ok

第一个函数 F1(n) 中虽然对传入参数进行了修改,但并不影响原来 a 的值。

第二个函数 F2(n) 使用了 & 符号传递参数,在函数中修改传入参数,影响了原来 a ​ 的取值。

第三个函数 F3(n) ,我们将返回值重新赋值给 a , 影响了 a 的取值。如果把 a 作为函数的参数,传入函数并执行时,在函数内部对传入的 a 的内容做修改,是不会影响到原来 a 变量的取值的。如果希望能够在调用函数的内部,修改传入参数的值,则需要增加引用传递符号 & 。或者把函数的返回值类型设为结构体。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值