结构类型
结构也称为结构体,结构体的成员可以自定义,用来保存相关的复杂数据。
可以使用指定成员初始化或顺序初始化两种方式初始化结构变量。
结构变量可以通过 . 点 操作符访问成员变量。结构变量指针可以通过 -> 箭头 操作符直接访问结构成员。
// 定义结构类型
struct Student
{
int no; // 学号
char gender; // 性别
int age; // 年龄
float chieseScore; // 语文成绩
float mathScore; // 数学成绩
} s3, s4; // 定义结构类型的同时定义结构变量
void show(Student s);
int main()
{
// 定义结构变量
Student s1, s2;
// 指定成员初始化
s1.no = 10000;
s1.age = 16;
s1.gender = 'm';
s1.chieseScore = 99;
s1.mathScore = 100;
// 顺序初始化
s2 = { 10001, 'f', 17, 100, 99};
show(s1);
show(s2);
s3 = { 10003, 'f', 16, 80, 80 };
show(s3);
// 结构变量通过.操作符访问成员
s3.mathScore = 100;
Student* p = &s3;
// 结构指针可以使用->操作符,直接访问结构的成员。
p->chieseScore = 100; // 相当于(*p).chinseScore = 100,常用->操作符。
show(s3);
// Student占用20字节,结构体中各个成员的存储空间是独立的。
cout << "sizeof(s3): " << sizeof(s3) << endl;
return 0;
}
void show(Student s)
{
cout << "学号:" << s.no << " 性别:" << s.gender << " 年龄:" << s.age
<< " 语文成绩:" << s.chieseScore << " 数学成绩:" << s.mathScore << endl;
}
结构类型允许嵌套,即结构类型中可以使用其他结构类型变量作为成员。嵌套不允许使用结构类型本身的变量作为成员,但可以使用结构类型本身的指针作为成员。
// 定义结构类型
struct Date
{
int year;
int month;
int day;
};
struct Student
{
int no; // 学号
char gender; // 性别
int age; // 年龄
float chieseScore; // 语文成绩
float mathScore; // 数学成绩
// 结构类型嵌套。结构体中可以使用其他结构类型作为成员
Date birthday;
/*
嵌套不允许使用结构类型本身的变量作为成员,但可以使用结构类型本身的指针作为成员。
Student s; 不允许
Student *p; 允许
*/
};
void show(Student s);
int main()
{
Student s1, s2;
// 指定成员初始化
s1.no = 10000;
s1.age = 16;
s1.gender = 'm';
s1.chieseScore = 99;
s1.mathScore = 100;
s1.birthday.year = 2000;
s1.birthday.month = 1;
s1.birthday.day = 1;
show(s1);
// 顺序初始化
s2 = { 10001, 'f', 17, 100, 99, {1999, 1, 2} };
show(s2);
return 0;
}
void show(Student s)
{
cout << "学号:" << s.no << " 性别:" << s.gender << " 年龄:" << s.age
<< " 语文成绩:" << s.chieseScore << " 数学成绩:" << s.mathScore
<< " 出生日期:" << s.birthday.year << "-" << s.birthday.month << "-" << s.birthday.day
<< endl;
}
结构体的简洁名称(起别名)
// 声明结构体时起别名
typedef struct Student S;
// 定义结构类型简洁名称
typedef struct Student
{
int no; // 学号
char gender; // 性别
int age; // 年龄
float chieseScore; // 语文成绩
float mathScore; // 数学成绩
} s3, s4; // s3,s4是Student的别名
// typedef定义结构的简洁名称。
typedef struct Student S2;
void show(Student s);
int main()
{
s3 ss1 = { 10001, 'f', 17, 100, 99 };
s4 ss2 = { 10002, 'm', 16, 98, 99 };
S ss3 = { 10003, 'f', 17, 99, 99 };
S2 ss4 = { 10004, 'f', 17, 99, 99 };
show(ss1);
show(ss2);
show(ss3);
show(ss4);
return 0;
}
void show(Student s)
{
cout << "学号:" << s.no << " 性别:" << s.gender << " 年龄:" << s.age
<< " 语文成绩:" << s.chieseScore << " 数学成绩:" << s.mathScore << endl;
}
结构数组与结构指针
// 定义结构类型
struct Student
{
int no; // 学号
char gender; // 性别
int age; // 年龄
float chieseScore; // 语文成绩
float mathScore; // 数学成绩
};
int getBestChineseScoreStudentID(Student* p, int n);
int getBestChineseScoreStudentID1(Student* p, int n);
int main()
{
Student s[5] = {
{10000, 'f', 16, 85, 99},
{10001, 'm', 17, 86, 98},
{10002, 'f', 18, 87, 97},
{10003, 'm', 19, 88, 96},
{10004, 'f', 15, 89, 95},
};
cout << getBestChineseScoreStudentID1(s, 5) << endl;
}
int getBestChineseScoreStudentID(Student* p, int n)
{
// 定义指针p1指向数组p的首地址
Student* p1 = p;
for (int i = 0; i < n; i++)
{
// 如果p1指向元素的chieseScore成员小于数组p的第i个元素的chieseScore成员
if (p1->chieseScore < p[i].chieseScore)
{
p1 = p + i; // p1指向数组p的第i个元素
}
}
return p1->no;
}
int getBestChineseScoreStudentID1(Student* p, int n)
{
int no = p[0].no, score = p[0].chieseScore;
for (int i = 0; i < n; i++)
{
if (score < p[i].chieseScore)
{
no = p[i].no;
score = p[i].chieseScore;
}
}
return no;
}
联合类型、
联合可以使几个不同变量,占用同一内存空间。
// 定义联合类型
union MyData
{
int i;
char c;
double d;
};
int main()
{
cout << "sizeof(MyData): " << sizeof(MyData) << endl;
// 定义联合类型变量
MyData d;
// 联合类型变量的成员共用一块内存区域
d.i = 97;
cout << "d.i: " << d.i << " d.c: " << d.c << " d.d: " << d.d << endl;
d.c = 'b';
cout << "d.i: " << d.i << " d.c: " << d.c << " d.d: " << d.d << endl;
cout << "&d.i: " << &d.i << " &d.c: " << (void*) & d.c << " &d.d" << &d.d << endl;
return 0;
}
枚举类型
枚举是用标识符表示的整型常量的集合。
/*
定义枚举类型
枚举类型定义中各个枚举类型不能同名。
如果不指定枚举元素的起始值,将自动从0开始为各个枚举类型设置初值,后面的元素自动增加1。
enum weekday {Sun, Mon, Tue, Wed, Thu, Fri, Sat}; // 0, 1, 2, 3, 4, 5, 6, 7
如果指定某个枚元素的值,则下一枚举元素没有指定值,就是上一个枚举元素的值增加1。
enum weekday {Sun = 100, Mon, Tue, Wed, Thu, Fri, Sat}; // 100, 101, 102, 103, 104, 105, 106
enum weekday {Sun = 100, Mon, Tue = 200, Wed, Thu, Fri, Sat}; // 100, 101, 200, 201, 202, 203, 204
*/
enum weekday {Sun, Mon, Tue , Wed, Thu, Fri, Sat};
int main()
{
cout << "Sun: " << Sun << endl;
cout << "Mon: " << Mon << endl;
cout << "Tue: " << Tue << endl;
cout << "Wed: " << Wed << endl;
cout << "Thu: " << Thu << endl;
cout << "Fri: " << Fri << endl;
cout << "Sat: " << Sat << endl;
int n;
cin >> n;
switch(n)
{
case Sun:
cout << "星期日" << endl;
break;
case Mon:
cout << "星期一" << endl;
break;
case Tue:
cout << "星期二" << endl;
break;
default:
cout << "请输入0到2的整数" << endl;
break;
}
return 0;
}
命名空间
随着程序规模的不断扩大,处理名称冲突问题就越来越麻烦,为此C++引入了一个新机制,即命名空间(也叫名称空间)。
定义
命名空间只能在全局范围内定义,命名空间允许嵌套。
一个命名空间可以是另一个命名空间的别名。
使用
using namespace 命名空间; 使用命名空间中所有的标识符。
using 命名空间::成员;使用命名空间中指定的成员。
命名空间::成员,通过命名空间和::(域运算符)访问指定的成员。
// 使用命名空间中所有的标识符
using namespace std;
// 指定使用命名空间中的某个成员。
using std::cout;
using std::endl;
// 定义命名空间
namespace NS1
{
int a = 10;
void f1()
{
cout << "NS1 f1()" << endl;
}
// 命名空间允许嵌套
namespace NS2
{
int a2 = 20;
void f2()
{
cout << "NS2 f2()" << endl;
}
}
}
using namespace NS1;
//using namespace NS1::NS2;
// ns2命名空间,是NS1::NS2的别名
namespace ns2 = NS1::NS2;
using NS1::NS2::f2;
int main()
{
// 通过域运算符访问命名空间中的成员。
cout << NS1::a << endl;
NS1::f1();
cout << NS1::NS2::a2 << endl;
// 访问NS1中的NS2命名空间中的f2()成员函数。
NS1::NS2::f2();
// using namespace NS1; 使用NS1中全的成员,此时可以直接通过NS2::访问NS2中的成员。
NS2::f2();
// using namespace NS1::NS2;使用NS2命名空间中所有的成员,此时可以直接访问f2()。
f2();
// 通过ns2命名空间访问NS1::NS2命名空间
ns2::f2();
return 0;
}
多文件组织
一个项目由多个(.c)文件,(.h)文件和主函数文件组成。
// Point.h 文件
/*
编译预处理指令
#include <文件名> 或 #include "文件名" 导入库或头文件
#define 标识符 字符串 宏定义。
条件编译:
#ifndef 标识符
程序段1
#else
程序段2
#endif
*/
#ifndef POINT_H
#define POINT_H
struct Point
{
int x;
int y;
};
#endif
// Rectangle.h 文件
#ifndef RECTANGLE_H
#define RECTANGLE_H
#include "Point.h"
struct Rectangle
{
Point center;
int length;
int width;
};
// 计算矩形面积
int area(Rectangle& r);
// 计算矩形周长
int perimeter(Rectangle& r);
#endif
// Rectangle.c 文件
#include "Rectangle.h"
int area(Rectangle& r)
{
return r.width * r.length;
}
int perimeter(Rectangle& r)
{
return 2*(r.width + r.length);
}
// Circle.h 文件
#ifndef CIRCLE_H
#define CIRCLE_H
#include "Point.h"
struct Circle
{
Point center;
int radius;
};
int area(Circle& c);
int perimeter(Circle& c);
#endif
// Circle.c 文件
#include "Circle.h"
const float PI = 3.1415926;
int area(Circle& c)
{
return PI * c.radius * c.radius;
}
int perimeter(Circle& c)
{
return 2* PI * c.radius;
}
// Main.c 文件
#include <iostream>
#include "Point.h"
#include "Rectangle.h"
#include "Circle.h"
using namespace std;
int main()
{
Point point1 = { 1, 1 };
cout << point1.x << ", " << point1.y << endl;
Rectangle r = { {2, 2}, 1, 1 };
cout << "area(r): " << area(r) << endl;
cout << "perimeter(r):" << perimeter(r) << endl;
Circle c = { {0, 0} , 3 };
cout << "area(c): " << area(c) << endl;
cout << "perimeter(c):" << perimeter(c) << endl;
return 0;
}