C++基础学习笔记(上)
文章目录
一、常量
1.宏常量:通常在文件上方,使用#define 常量名 常量值 定义;
2.const修饰的变量:const 数据类型 常量名 = 常量值,不可修改。
二、数据类型:
1.整型:
short:短整型,2B,-32768~32767
int:整型,4B,-231~231-1
long:长整型,win 4B,Unix 4B(32b),8B(64b)
long long:8B
2.sizeof()关键字可以统计数据类型占的内存大小。
3.实型(浮点型):
float:4B
double:8B
科学计数法:f = 3e-2
4.字符型:char 1B,字符型变量将字符对应的ASCII码放到存储单元。
5.字符串型:
char 变量名[] = ”xx“ ——C风格
string 变量名 = ”xx“ ——C++风格
6.bool型:1B
7.数据输入:cin >> 变量
8.前置递增: 先让变量递增,再进行表达式运算。后置递增: 先进行表达式运算,再让变量递增。
三、程序流程结构
1.三目运算符返回的是变量,可以继续赋值。
2.do-while循环:do{循环语句} while{循环条件},与while的区别在于先执性一次循环语句,再判断循环条件。
do {
cout << num << endl;
num ++;
}
while(num < 10);
水仙花数:
do {
int i = num % 10;
int j = num / 10 % 10;
int k = num / 100;
if (i*i*i + j*j*j + k*k*k == num){
cout << num << endl;
}
num ++;
}
while(num < 1000);
3.for(起始表达式;条件表达式;末尾循环体){循环语句;} 等价于下:
int i = 0;
for (;;) {
if(i > 10){
break;}
cout << i <<endl;
i ++;
}
continue本次循环剩下的代码不执行。
4.goto标记:如果标记的名称存在,执行到goto语句时会跳转到标记的位置。
goto FLAG;
FLAG:
cout << "goto!!" << endl;
四、数组
1.数组放在一块连续的内存空间中,每个元素都是相同的数据类型。创建方式:
int arr[5];
int arr[] = {1, 2, 3, 4, 5};
int arr[];
2.冒泡排序:
for (int i = 0; i < size - 1; ++i) {
//总轮数为元素个数-1
for (int j = 0; j < size - i - 1 ; ++j) {
//对比次数 = 元素个数 - 当前轮数 - 1
if (arr[j] > arr[j+1]){
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
五、函数
1.函数的声明:函数写在main函数之后会找不到函数,需要事先声明。声明函数只有函数类型、函数名和参数列表。声明可以写多次,但函数定义只能有一次。
2.函数的分文件编写:
(1)创建.h头文件;(2)创建.cpp源文件;(3)在头文件中写函数的声明;(4)在源文件中写函数的定义,包含头文件。
六、指针(int *类型)
1.指针变量保存一个地址。通过解引用的方式使用指针:*p
2.指针在32b系统下占4B,在64b系统占8B;
3.空指针:指针变量指向内存中编号为0的空间,一般用于初始化指针变量:int *p = NULL;空指针指向的内存不允许访问,0-255的内存编号是系统使用。
4.野指针:指针变量指向非法内存空间。空指针和野指针都市自己申请的空间,不允许访问。
5.const修饰指针(3种情况):
const修饰指针:常量指针:const int * p = &a;指针的指向可以修改,但指针指向的值不能修改。
const修饰常量:指针常量:int * const p = &a;指针的指向不可以修改,但指针指向的值可以修改。
const既修饰指针又修饰常量:const int * const p = &a;指针的指向和指向的值都不能修改。
6.利用指针访问数组中的元素:
int arr[] = {
1,2,3,4,5,6,7,8,9};
int * p = arr;//指向数组首地址
for (int i = 0; i < 9; ++i) {
cout << *p << endl;
p++;//指针向后偏移4B
}
7.指针和函数:在函数中需要修改传入的实参,则需要传入地址。
8.指针、数组、函数实现冒泡排序:
void bubbleSort(int * arr, int len){
cout << "arr:" << arr <<endl;//arr地址
cout << "* arr:" << * arr <<endl;//数组首元素
for (int i = 0; i < len - 1; ++i) {
for (int j = 0; j < len - i - 1; ++j) {
if (arr[j] > arr[j+1]){
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
}
void printArr(int * arr, int len){
for (int i = 0; i < len; ++i) {
cout << arr[i] << endl;
}
}
int main(){
int arr[] = {
12,2,5,4,1,6,17,28,9,3};
int len = sizeof(arr) / sizeof(arr[0]);
bubbleSort(arr, len);
printArr(arr, len);
}
七、结构体
1.结构体是用户自定义的数据类型,允许存储不同的数据类型。语法:struct 结构体名 { 结构体成员列表 };通过结构体创建变量的方式有三种(常用一二种),创建时struct关键字可胜省略,定义时不可省略:
struct 结构体名 变量名
struct 结构体名 变量名 = {成员1值, 成员2值…}
定义结构体时顺便创建变量
struct Student{
string name;
int age;
int score;
} s3;//第三种
int main(){
//第一种
struct Student s1;
s1.name = "a";
s1.age = 13;
s1.score = 100;
//第二种
struct Student s2 = {
"b", 18, 99};
//第三种
s3.name = "c";
s3.age = 22;
s3.score = 66;
}
2.结构体数组:将自定义的结构体放入数组中方便维护。语法:struct 结构体名 数组名[元素个数] = { {}, {}, {}, …}
struct Student{
string name;
int age;
int score;
};
int main(){
Student stuArr[3] = {
{
"a", 16, 100},
{
"b", 18,99},
{
"c",22,66}
};
stuArr[0].name = "d";//修改结构体变量
for (int i = 0; i < 3; ++i) {
//遍历输出结构体变量
cout << stuArr[i].name << stuArr[i].age << stuArr[i].score << endl;
}
}
3.结构体指针:作用:通过指针访问结构体中的成员。利用操作符 -> 可以通过结构体指针访问结构体属性。
struct Student{
string name;
int age;
int score;
};
int main(){
Student s = {
"a", 16, 100};
Student * p = &s;//通过指针指向结构体变量
cout << "姓名:" << p->name << endl;
}
4.结构体嵌套结构体:例:一个老师带多个学生。
struct Student{
string name;
int age;
int score;
};
struct Teacher{
int id;
string name;
int age;
struct Student stu;
};
int main(){
Teacher t;
t.id = 1;
t.name = "王老师";
t.age = 45;
t.stu.name = "小明";
t.stu.age = 20;
t.stu.score = 100;
cout << t.name << t.id << t.age << t.stu.name << t.stu.age << endl;
}
5.结构体做函数参数:作用:将结构体作为参数向函数中传递,传递方式有值传递和地址传递。
struct Student{
string name;
int age;
int score;
};
void printStu(Student * s){
cout << s->name << s->age << s->score << endl;
}
int main(){
Student s;
s.name = "小明";
s.age = 18;
s.score = 100;
printStu(&s);
}
6.结构体重const使用:用来防止误操作。
//将函数的形参改为指针可以减少占用内存空间,而且不会复制新的副本出来。
//但会有误修改结构体数据的风险。使用const可以避免,有修改的操作会报错
void printStu(const Student * s){
cout << s->name << s->age << s->score <<endl;
}
int main(){
Student s = {
"小明", 18, 100};
printStu(&s);
}
7.例:每个老师带五个学生
struct Student{
string sName;
int score;
};
struct Teacher{
string tName;
Student sArr[5];
};
void allocateSpace(Teacher tArr[], int len){
string nameSeed = "ABCDE";
for (int i = 0; i < len; ++i) {
tArr[i].tName = "teacher_";
tArr[i].tName += nameSeed[i];
for (int j = 0; j < 5; ++j) {
tArr[i].sArr[j].sName = "student_";
tArr[i].sArr[j].sName += nameSeed[j];
tArr[i].sArr[j].score = 66;
}
}
}
void printInfo(Teacher tArr[], int len){
for (int i = 0; i < len; ++i) {
cout << "老师姓名:\t" << tArr[i].tName << endl;
for (int j = 0; j < 5; ++j) {
cout << "学生姓名:\t" << tArr[i].sArr[j].sName << "学生分数:\t" << tArr[i].sArr[j].score << endl;
}
}
}
int main(){
//创建三个老师的数组
Teacher tArr[3];
//给三老师和其学生赋值
int len = sizeof(tArr) / sizeof(tArr[0]);
allocateSpace(tArr, len);
//输出老师和学生信息
printInfo(tArr, len);
}
8.例:冒泡排序输出按结构体的某个值排序结果:
struct Hero{
string name;
int age;
string sex;
};
void bubbleSort(Hero heroArr[], int len){
for (int i = 0; i < len - 1; ++i) {
for (int j = 0; j < len - i - 1; ++j) {
if (heroArr[j].age > heroArr[j+1].age){
Hero temp = heroArr[j];
heroArr[j] = heroArr[j+1];
heroArr[j+1] = temp;
}
}
}
}
void printArr(Hero heroArr[],int len){
for (int i = 0; i < len; ++i) {
cout << "名字:" << heroArr[i].name