以下内容为大学期间学习C++语言总结的知识:
《C++》基础入门_01——数据存储,表示形式,基本运算
《C++》基础入门_02——面向对象的总体概括
《C++》基础入门_03——程序的开发过程
《C++》基础入门_04——四大语句
《C++》基础入门_05——函数详解篇
《C++》基础入门_06——面向对象的详述
《C++》基础入门_07——数据的共享保护:const
《C++》基础入门_08——利用数组实现对批量数据的处理
《C++》基础入门_09——指针和引用的讲解
《C++》基础入门_10——用户自定义数据类型详细篇
《C++》基础入门_11——友元的讲解
《C++》基础入门_12——类模板
《C++》基础入门_13——运算符的重载
《C++》基础入门_14——继承与派生
《C++》基础入门_15——多态性
《C++》基础入门_16——输入输出流详讲
《C++》基础入门_17——对象串行化
《C++》基础入门_18——异常处理
《C++》基础入门_19——命名空间
《C++》基础入门_20——文件操作
《C++》基础入门_21——在函数中返回数组的常用方法
文章目录
一、结构体类型
在一个组合中包含若干个类型不同的数据项。相当于其他高级语言中的记录。
1.1 声明
-
一般形式:
struct 结构名{ 数据类型 成员名 1; 数据类型 成员名 2; : 数据类型 成员名 n; };
- 结构体类型名作为结构体类型的标志。
- 声明一个结构体类型时必须对各个成员进行类型声明:类型名 成员名;
- 每一个成员也成为结构体中一个域,所以成员表又称为域表。
- 结构体的成员可以是数据,又可以是函数。
-
声明结构体并不实际分配内存单元。
struct Student //声明一个结构体类型 { int num; char name[20]; char sex; int age; };
-
注意:
- 结构变量的存储类型概念、它的寿命、可见性及使用范围与普通变量完全一致。
- 结构变量说明在结构类型声明之后,二者也可同时进行。
- 结构变量占内存大小可用 sizeof 运算求出: sizeof(运算量)
1.2 结构体类型变量的定义方法与初始化
- 定义结构体类型变量的2中方法:
-
先声明结构体类型再定义变量
Student student1,student2;//student1,student2是两个结构体类型Student的变量
-
声明结构体类型的同时定义变量
一般形式:struct 结构体类型名{ 成员名; } 变量名表;
例如:
struct Student { int num; char name[20]; char sex; int age; }student1,student2;//student1,student2是两个结构体类型Student的变量
定义了结构体变量之后,系统会给它分配内存空间。 -
- 初始化
-
可以在声明结构体并定义变量时初始化
struct Student { int num; char name[20]; char sex; int age; }student1={201313232,“yejing”,‘f’,18};
-
结构体声明与定义分开的情况,在定义变量时初始化。
Student student1={201313232,“yejing”,‘f’,18};
-
1.3 引用结构体变量
-
可以将一个结构体变量的值赋给另一个具有相同结构的结构体变量。
student1=student2;
-
可以引用一个结构体变量中的一个成员的值。
引用形式:
结构体变量名.成员名
;
" . " : 成员运算符student1.name;
#include <iostream>
using namespace std;
struct Student
{
int num;
char name[20];
char sex;
int age;
}student1,student2;
int main() {
student1 = { 123,"yejing",'f',18 };
student2 = student1;
cout << student1.num << " " << student2.num; // 123 123
cout << student1.name << " " << student2.name; // yejing yejing
}
1.4 结构体数组
每个数组元素都是一个结构体类型的数据,它们分别都包含各自的成员项。
#include <iostream>
using namespace std;
struct Student
{
char name[20];
int count;
};
int main() {
Student s[3] = {"Tom",0,"Rain",0,"Sun",0};
char na[20];
for (int i = 0; i < 10; i++) {
cin >> na;
//以下对分支if可以使用for+if改写
if (strcmp(na, s[0].name)==0)//对字符数组的比较需要使用特殊函数
s[0].count++;
else if (strcmp(na, s[1].name)==0)
s[1].count++;
else if (strcmp(na, s[2].name)==0)
s[2].count++;
}
for (int i = 0; i < 3; i++)
cout << s[i].name << ":" << s[i].count<<endl;
}
结果:
1.5 指向结构体变量的指针
一个结构体变量的指针就是该变量所占据的内存段的起始地址。
指针变量也可以指向结构体数组中的元素。
-
通过指向结构体变量的指针引用结构体变量的成员
以下3种方式等价:- 结构体变量 . 成员名
- (* 指针名 ). 成员名
- 指针名->成员名
#include <iostream> #include <string> using namespace std; struct Student { string name; char sex; int age; }; int main() { Student s; Student *p = &s; s.name = "yj"; s.age = 19; s.sex = 'm'; p->sex = 'f';//通过指针操作结构体类型变量的成员值 cout << s.name << " " << s.age<<" "<<s.sex<<endl; //yj 19 f cout << (*p).name << " " << (*p).age << " " << (*p).sex; //yj 19 f 注意*p两边的()不可以省去,因为成员运算符‘.’优先级高于‘*’优先级。此外p->name等价于(*p).name。 return 0; }
-
用结构体变量和指向结构体变量的指针构成链表
链表:- 链表是一种重要的数据结构。
- 链表有一个头指针,它存放一个地址。该地址指向一个元素。
- 链表中的每一个元素称为节点。每个节点都应该包括两部分:用户需要用的实际数据和下一个节点的地址。最后一个元素不在指向其他元素,它的地址部分放一个“NULL”表示空地址。链表到此结束。
- 链表中各元素的地址可以是不连续的,要找某个元素,可以通过上一个元素提供的地址找到它。
- 链表数据结构必须使用指针和结构体变量才能实现。可以声明一个结构体类型,包含两种数据成员:一种是用户需要用的实际数据,另一种是用来存放下一个节点地址的指针变量。
#include <iostream>
#include <string>
using namespace std;
struct Student {
int sno;
string name;
Student *next;
};
int main() {
Student a, b, c;
a.sno = 11; a.name = "Tom";
b.sno = 22; b.name = "Sun";
c.sno = 33; c.name = "Cloud";
Student *head;
Student *p;
head = &a;
a.next = &b;
b.next = &c;
c.next = NULL;
p = head;
do {
cout << p->sno << " " << p->name << " " <<endl; //输出p指向的节点的数据
p=p->next; //使p指向下一个节点;相当于p=(*p).next;(*)p.next相当于a.next;
} while (p!=NULL); //输出节点c数据后,p指针为null;
return 0;
}
输出: 11 Tom
22 Sun
33 Cloud
1.6 结构体类型数据作为函数参数
- 结构体变量名作为作参数
- 用指向结构体变量的指针作形参,结构体变量的地址作为实参
- 用结构体变量的引用作为函数形参,它成为实参的别名。
#include <iostream>
#include <string>
using namespace std;
struct Student {
int sno;
string name;
};
int main() {
Student a, b, c;
a.sno = 11; a.name = "Tom";
b.sno = 22; b.name = "Sun";
c.sno = 33; c.name = "Cloud";
void print(Student s);
void print(Student *p);
void print1(Student &ss);
print(a); //Tom 11
print(&b); //Sun 22
print1(c); //Cloud 33
return 0;
}
//1. 结构体变量名作为作参数
void print(Student s) {
cout << s.name << " " << s.sno << endl;
}
//2. 用指向结构体变量的指针作形参,结构体变量的地址作为实参
void print(Student *p) {
cout << p->name << " " << p->sno;
}
//3. 用结构体变量的引用作为函数形参,它成为实参的别名。
void print1(Student &s) {
cout << s.name << " " << s.sno << endl;
}
二、动态空间分配与释放
c语言中,使用库函数malloc和free来分配和撤销内存空间。
c++提供运算符new和delete来取代malloc和free函数。
- new 和delete是运算符,而不是函数,执行效率高。
2.1 动态空间分配
一般形式:
new 类型[初值]
;
- 用new分配数组空间时不可以指定初值。
- 若因为内存原因而导致不能正常分配空间,new会返回一个空指针。
new int; //开辟一个存放整数的存储空间,返回一个指向该存储空间的地址(即指针);
new int(100);//开辟一个存放整数的存储空间,并且初值为100,返回一个指向该存储空间的地址(即指针);
new char[10];//开辟一个存放字符数组的空间,返回一个指向字符数组首元素的地址(即指针);
new int[4][3];//开辟一个存放二维整型数组的空间,返回一个指向该数组首元素的地址(即指针);
float *p = new float(3.14);//开辟一个存放单精度数的空间,并指定初值为3.14,将返回的该空间的地址赋给指针变量p
2.2 动态空间释放
delete 指针变量------- --对变量
delete [] 指针变量 -------对数组
char *p1=new char[10];//开辟一个存放字符数组的空间,返回一个指向字符数组首元素的地址(即指针);
delete[] p1; //释放开辟的空间
int **p2 =new int[4][3]; //错误(活动) E0144 "int (*)[3]" 类型的值不能用于初始化 "int **" 类型的实体, C2440 “初始化” : 无法从“int(*)[3]”转换为“int **”
delete[] p2;
float *p = new float(float(3.14));//开辟一个存放单精度数的空间,并指定初值为3.14,将返回的该空间的地址赋给指针变量p
delete p;//释放开辟的空间
三、枚举类型——enum
-
只要将需要的变量值一一列举出来,便构成了一个枚举类型。
-
枚举类型的声明形式如下:
enum 枚举类型名 {变量值列表}
;例如:
enum Weekday
{SUN, MON, TUE, WED, THU, FRI, SAT}; -
枚举类型应用说明:
-
对枚举元素按常量处理,不能对它们赋值。例如,不能写: SUN = 0;
-
枚举元素具有默认值,它们依次为:0,1,2,…。
-
也可以在声明时另行指定枚举元素的值
如:
enum Weekday {SUN=7,MON=1,TUE,WED,THU,FRI,SAT};
-
枚举值可以进行关系运算。
-
整数值不能直接赋给枚举变量,如需要将整数赋值给枚举变量,应进行强制类型转换
-
设某次体育比赛的结果有四种可能:胜(WIN)、负(LOSE)、平局(TIE)、比赛取(CANCEL),编写程序顺序输出这四种情况。
四、typedef语句
-
为一个已有的数据类型另外命名
-
语法形式
typedef 已有类型名 新类型名表;
例如:
typedef double Area;
Area a; -
不推荐使用,降低可读性
五、联合体
-
声明形式:
union 联合名{ 数据类型 成员名 1; 数据类型 成员名 2; : 数据类型 成员名 n; };
例如: union uarea{ char c_data; short s_data; long l_data; };
-
联合体类型变量说明的语法形式
联合名 联合变量名;
-
引用形式:
联合名.成员名
-
无名联合
无名联合没有标记名,只是声明一个成员项的集合,这些成员项具有相同的内存地址,可以由成员项的名字直接访问。例: union{ int i; float f; } 在程序中可以这样使用: i=10; f=2.2;