C++ 结构体

本文最后更新于:2022年4月22日 上午

C++ 结构体

结构体的基本使用

通过 struct 关键字来声明定义结构体,结构体就类似于 js 的对象

#include <iostream>;
using namespace std;

// 定义结构体
// 学生
struct Student {
  string name;
  int age;
};


int main() {

  // struct 可以省略
  // 赋值的时候需要按顺序赋值
  struct Student s1 = { "小明", 18 };

  cout << "姓名:" << s1.name << " 年龄:" << s1.age << endl;


  system("pause");
  return 0;
}

输出

姓名:小明 年龄:18

结构体数组

如果结构体是数组的元素,则通过数组操作的话

// 定义时在后面加上 [] 即表示结构体数组
struct Student s2[2] = { { "小明", 18 }, { "小红", 19 } };

// 遍历
for (int i = 0; i < sizeof(s2) / sizeof(s2[0]); i++) {
  cout << "姓名:" << s2[i].name << " 年龄:" << s2[i].age << endl;
}

输出

姓名:小明 年龄:18
姓名:小红 年龄:19

结构体指针

通过结构体指针访问成员 xx->yyy 通过 -> 访问成员

struct Student s1 = { "小明", 18 };

struct Student* p1 = &s1;

p1->name = "小明123";

cout << "姓名:" << s1.name << " 年龄:" << s1.age << endl;

输出

姓名:小明123 年龄:18

嵌套结构体

// 学校
struct School {
  string name;
  int number;
};

struct Student {
  string name;
  int age;
  struct School school;
};

// --------------------------------------------------------

struct Student s3 = { "小张", 18, { "实验小学", 300 } };
cout << "姓名:" << s3.name << " 年龄:" << s3.age << " 学校:" << s3.school.name <<  endl;

输出

姓名:小张 年龄:18 学校:实验小学

结构体作为函数参数 (值传递和引用传递)

 // 结构体参数    接收地址(如果进行操作会改变原来的结构体)
 void sayStuName(struct Student *s) {
   s->name = "小明 1";
   cout << "hello " << s->name << endl;
 }
 
 // 结构体参数    接收值(如果进行操作不会影响原来的结构体)
 void sayStuName2(struct Student s) {
   s.name = "小明 2";
   cout << "hello " << s.name << endl;
 }

// ---------------------------------------------------------

 struct Student s1 = { "小明", 18 };

 sayStuName(&s1);
 sayStuName2(s1);
 cout << "姓名:" << s1.name << " 年龄:" << s1.age << endl;

输出

hello 小明 1
hello 小明 2
姓名:小明 1 年龄:18

结构体案例(按照人物年龄升序排列)

struct Hero {
  string name;
  int age;
};

// 根据年龄从小到大排序
// 这里需要注意 如果传入的是数组,则相当于是地址传递
void sortHero(struct Hero h[], int len) {
  for (int i = 0; i < len; i++) {
    for (int j = i+1; j < len ; j++) {
      if (h[i].age > h[j].age) {
        struct Hero temp = h[i];
        h[i] = h[j];
        h[j] = temp;
      }
    }
  }
}

// 通过 const 来修饰结构体,可防止该函数内部对实参进行修改
void printHero(const struct Hero h[], int len) {
  for (int i = 0; i < len; i++) {
    cout << "英雄姓名:" << h[i].name << " 英雄年龄:" << h[i].age << endl;
  }
}

// ---------------------------------------------------------

 
// 根据年龄从小到大排序
struct Hero h1[5] = { 
  { "刘备", 23 }, 
  { "关羽", 22 },
  { "张飞", 21 },
  { "赵云", 20 },
  { "貂蝉", 19 }
};

int heroLen = sizeof(h1) / sizeof(h1[0]);

cout << "排序前\n";
printHero(h1, heroLen);

// 当传入的是数组时,相当于隐式传递的地址,内部可操作修改数据
sortHero(h1, heroLen);

cout << "\n排序后\n";
printHero(h1, heroLen);

输出

排序前
英雄姓名:刘备 英雄年龄:23
英雄姓名:关羽 英雄年龄:22
英雄姓名:张飞 英雄年龄:21
英雄姓名:赵云 英雄年龄:20
英雄姓名:貂蝉 英雄年龄:19

排序后
英雄姓名:貂蝉 英雄年龄:19
英雄姓名:赵云 英雄年龄:20
英雄姓名:张飞 英雄年龄:21
英雄姓名:关羽 英雄年龄:22
英雄姓名:刘备 英雄年龄:23

结构体案例

需求

实现一个通讯录,输入不同的数字调用不同的功能

1、添加联系人
2、显示联系人
3、删除联系人
4、查找联系人
5、修改联系人
6、清空联系人
0、退出通讯录

实现

#include <iostream>;
using namespace std;

void showMenu() {
  cout << endl;
  cout << "1、添加联系人" << endl;
  cout << "2、显示联系人" << endl;
  cout << "3、删除联系人" << endl;
  cout << "4、查找联系人" << endl;
  cout << "5、修改联系人" << endl;
  cout << "6、清空联系人" << endl;
  cout << "0、退出通讯录" << endl;

  cout << "请输入:" << endl;

}

const int MAX_SIZE = 1000;

// 联系人结构体
struct Contact {
  string name;
  int age;
  string sex;
  string mobile;
  string address;
};

// 通讯录结构体
struct AddressBook {
  struct Contact contact[MAX_SIZE];
  int len;
};

// 判断是否存在该联系人,存在则返回索引,不存在则返回 -1
int isExistContact(const AddressBook* addressBook, string name) {
  for (int i = 0; i < addressBook->len; i++) {
    if (addressBook->contact[i].name == name) {
      return i;
    }
  }
  return -1;
}

// 添加联系人
void addContact(struct AddressBook* addressBook) {
  cout << "\n **************** 添加联系人 **************** \n ";

  if (addressBook->len == MAX_SIZE) {
    cout << "通讯录已满,无法添加新联系人" << endl;
    return;
  }

  string name;
  int age;
  int sex;
  string mobile;
  string address;

  cout << "请输入姓名:" << endl;
  cin >> name;

  cout << "请输入年龄:" << endl;
  cin >> age;

  cout << "请输入性别:" << endl;
  cout << "1: 男:" << endl;
  cout << "0: 女:" << endl;
  cin >> sex;

  while (sex != 1 && sex != 0) {
    cout << "请输入性别:" << endl;
    cout << "1: 男:" << endl;
    cout << "0: 女:" << endl;
    cin >> sex;
  }

  cout << "请输入手机号:" << endl;
  cin >> mobile;

  cout << "请输入住址:" << endl;
  cin >> address;


  addressBook->contact[addressBook->len].name = name;
  addressBook->contact[addressBook->len].age = age;
  addressBook->contact[addressBook->len].sex = sex == 1 ? "男" : "女";
  addressBook->contact[addressBook->len].mobile = mobile;
  addressBook->contact[addressBook->len].address = address;
  addressBook->len++;

  system("cls");
  cout << "添加成功" << endl;

}

// 显示联系人
void printContact(const struct AddressBook* addressBook) {
  cout << "\n **************** 显示联系人 **************** \n";

  if (addressBook->len < 1) {
    cout << "通讯录暂时没有联系人,请先进行添加" << endl;
    return;
  }

  cout << "姓名\t 年龄\t 性别\t 手机号\t\t 住址\t " << endl;

  for (int i = 0; i < addressBook->len; i++) {
    cout << addressBook->contact[i].name << "\t ";
    cout << addressBook->contact[i].age << "\t ";
    cout << addressBook->contact[i].sex << "\t ";
    cout << addressBook->contact[i].mobile << "\t ";
    cout << addressBook->contact[i].address << "\t " << endl;
  }

}

// 查找联系人
void findContact(const struct AddressBook* addressBook) {
  cout << "\n **************** 查找联系人 **************** \n ";

  if (addressBook->len < 1) {
    cout << "通讯录暂时没有联系人,请先进行添加" << endl;
    return;
  }

  string name;

  cout << "请输入需要查找的联系人姓名:" << endl;
  cin >> name;

  int index = isExistContact(addressBook, name);
  
  if (index == -1) {
    cout << "查无此人" << endl;
    return;
  }

  cout << "姓名\t 年龄\t 性别\t 手机号\t\t 住址\t " << endl;
  cout << addressBook->contact[index].name << "\t ";
  cout << addressBook->contact[index].age << "\t ";
  cout << addressBook->contact[index].sex << "\t ";
  cout << addressBook->contact[index].mobile << "\t ";
  cout << addressBook->contact[index].address << "\t " << endl;

  system("pause");
  system("cls");

}

// 删除联系人
void removeContact(struct AddressBook* addressBook) {
  cout << "\n **************** 删除联系人 **************** \n ";

  if (addressBook->len < 1) {
    cout << "通讯录暂时没有联系人,请先进行添加" << endl;
    return;
  }

  string name;
  cout << "请输入需要删除的联系人姓名" << endl;
  cin >> name;

  int index = isExistContact(addressBook, name);
  if (index == -1) {
    cout << "查无此人" << endl;
    return;
  }

  // 将制定索引的后的元素全部向前移动
  // 减一是为了防止下标越界
  for (int i = index; i < addressBook->len - 1; i++) {
    addressBook->contact[i] = addressBook->contact[i + 1];
  }

  addressBook->len--;

}

// 编辑联系人
void editContact(struct AddressBook* addressBook) {
  cout << "\n **************** 编辑联系人 **************** \n ";

  if (addressBook->len < 1) {
    cout << "通讯录暂时没有联系人,请先进行添加" << endl;
    return;
  }
  string editName;

  cout << "请输入需要编辑的联系人姓名" << endl;
  cin >> editName;

  int index = isExistContact(addressBook, editName);
  if (index == -1) {
    cout << "查无此人" << endl;
    return;
  }


  string name;
  int age;
  int sex;
  string mobile;
  string address;

  cout << "请输入姓名:" << endl;
  cin >> name;

  cout << "请输入年龄:" << endl;
  cin >> age;

  cout << "请输入性别:" << endl;
  cout << "1: 男:" << endl;
  cout << "0: 女:" << endl;
  cin >> sex;

  while (sex != 1 && sex != 0) {
    cout << "请输入性别:" << endl;
    cout << "1: 男:" << endl;
    cout << "0: 女:" << endl;
    cin >> sex;
  }

  cout << "请输入手机号:" << endl;
  cin >> mobile;

  cout << "请输入住址:" << endl;
  cin >> address;

  addressBook->contact[index].name = name;
  addressBook->contact[index].age = age;
  addressBook->contact[index].sex = sex == 1 ? '男' : '女';
  addressBook->contact[index].mobile = mobile;
  addressBook->contact[index].address = address;

  system("cls");
  cout << "修改成功" << endl;
}

// 清空联系人
void clearAddressBook(struct AddressBook* addressBook) {
  // 采用逻辑清空的方式清空
  addressBook->len = 0;
  cout << "清空成功" << endl;

}

int main() {

  // 初始化通讯录
  struct AddressBook addressBook = {};
  addressBook.len = 0;

  addressBook.contact[0].name = "张三";
  addressBook.contact[0].age = 18;
  addressBook.contact[0].sex = "男";
  addressBook.contact[0].mobile = "13366660000";
  addressBook.contact[0].address = "成都市武侯区";
  addressBook.len++;

  while (1) {
    showMenu();

    int select;

    cin >> select;

    switch (select) {
      case 1: 
        addContact(&addressBook);
        break;
      case 2:
        printContact(&addressBook);
        break;
      case 3:
        removeContact(&addressBook);
        break;
      case 4:
        findContact(&addressBook);
        break;
      case 5:
        editContact(&addressBook);
        break;
      case 6:
        clearAddressBook(&addressBook);
        break;
      case 0:
        return 0;
    }
  }

  system("pause");
  return 0;
}

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议,转载请注明出处。