bilibili 黑马程序员课程
Day 1
1.1 变量
作用:方便管理内存空间;
int a=10;
1.2 常量
作用:不可更改的数据;
定义: # define 宏常量 或 const 修饰的变量
#define day 7
const int month=12;
1.3 关键字
作用:C++预先保留的单词(标识词)
1.4 标识符
开头只能是字母或数字,见名知意
- 数据类型
2.1 作用:给变量分配合适的内存空间
整形 (区别在于所占内存空间不同) |
short (短整型) int(整型) long (长整型) long long (长长整型) |
2字节 4字节 window为4字节,linux为 4字节、8字节 8字节 |
|
---|---|---|---|
实型(浮点型) | float 单精度 double双精度 |
7位有效数字 15-16位有效数字 |
float f1=3.14f,加f是为了避免默认的double. 默认情况下,输出一个小数会显示6位小数。 科学计数法:f2=3e2, 其实是 3*10^2 |
字符型 | char | 1个字节 | 显示单个字符,单引号,char ch = ‘a’; 是将字符对应的ASCII编码放到存储单元;a-97,A-65. |
转移字符 | \n \t \\ |
换行符 水平制表符 反斜杠 |
短斜杠 水平制表符默认8个位置,4个空格,但可以整齐输出数据 |
字符串 | char string |
char str1[]=”hello” 注意[ ]和双引号, C风格 string str2=”hello” 要包含头文件 |
|
布尔类型 | bool | 1个字节 | true , false . 其实就是1和0 |
2.2 sizeof
运算符,统计数据类型所占内存大小
sizeof(short/num1); //sizeof(变量或数据类型)
2.3 数据
int a=0;
cin>>a; //输入
cout<<a; //输出
运算符 | 算术运算符 | 处理四则运算,+ - / %(取余) ++(递增) —(递减) | 两个小数不可取余数,必须有一个整数.
前置 ++a, —a, 后置 a++, a— .
前置,先变量+1,在进行表达式运算,后置,先进行表达式运算,在变量+1. | | —- | —- | —- | | 赋值运算符 | = += -+ = /= %= | | | 比较运算符 | == != < > <= >= | 输出1或0 | | 逻辑运算符 | ! && || | |程序流程结果
- 顺序结构
- 选择结构
- 循环结构
4.1 顺序结构——if 、 if else 、 switch
//单行格式if语句
if (score>600){
cout<<"Success!"<<endl;
}
//多行格式if语句
if(score>600){
cout<<"Success!"<<endl;
}else{
cout<<"Fail!"<<endl;
}
//多行条件if语句
if(score>600){
cout<<"Success!"<<endl;
}else if(score>400){
cout<<"Fail-1!"<<endl;
}else if(score>200){
cout<<"Fail-2!"<<endl;
}else{
cout<<"Fail-3!"<<endl;
}
//还有一种嵌套if
if(score>600){
if(score>700){
cout<<"Success-1!"<<endl;
}else{
cout<<"Success-2!"<<endl;
}
}else if(score>400){
cout<<"Fail-1!"<<endl;
}else if(score>200){
cout<<"Fail-2!"<<endl;
}else{
cout<<"Fail-3!"<<endl;
}
Day 2
案例一:三只小猪称体重, 找最重的。
#include<iostream>
using namespace std;
int main(void){
int num1,num2,num3;
char flag;
cout<<"请输入三只小猪的体重:"<<endl;
cin>>num1>>num2>>num3;
if(num1>=num2){
flag=num1>=num3?'A':'C';
cout<<"小猪"<<flag<<"最重"<<endl;
}else{
flag=num2>=num3?'B':'C';
cout<<"小猪"<<flag<<"最重"<<endl;
}
system("pause");
return 0;
}
三目运算符,可以返回值,也可以返回变量(继续赋值)。
switch(表达式){
case 结果1: 语句1; break;
case 结果2: 语句2; break;
case 结果3: 语句3; break;
default : 语句4;break;
}
相比于if:
switch只能判断整型和字符型,不可以是一个区间,但是结构清晰,执行效率高。
4.2 循环结构——while 、 do…while 、for 、嵌套循环
while(循环条件){
循环语句;
}
do{
循环语句;
}while(循环条件);
//先执行一次
for(int i=0;i<100;i++){
循环语句;
}
//嵌套循环
案例:猜数字,随机1-100 ,while
#include<iostream>
#include <time.h>
using namespace std;
int main(void){
//添加随机数种子,根据系统时间生成,防止每次生成的随机数都一样
srand((unsigned int)time(NULL));
//生成随机数1-100,rand()%区间
int num=rand()%100+1;
int val=0;
while(1){
cout<<"请输入您的猜测:"<<endl;
cin>>val;
if(val>num){
cout<<"过大"<<endl;
}else if(val<num){
cout<<"过小"<<endl;
}else{
cout<<"猜对了"<<endl;
break;
}
}
system("pause");
return 0;
}
案例:输出所有三位数中的水仙花数,每个位子上的数字的三次幂之和等于其本身 do…while
#include<iostream>
#include <time.h>
using namespace std;
int main(void){
int num=100;
int ge=0,shi=0,bai=0;
do{
ge=num%10;
shi=num/10%10;
bai=num/100;
if(ge*ge*ge+shi*shi*shi+bai*bai*bai==num){
cout<<num<<endl;
}
num++;
}while(num<1000);
system("pause");
return 0;
}
案例:敲桌子,从1报到100,含7或7的倍数,输出敲桌子 for
#include<iostream>
#include <time.h>
using namespace std;
int main(void){
for(int i=1;i<100;i++){
if(i/10==7||i%10==7||i/7==0){
cout<<"敲桌子"<<endl;
}else{
cout<<i<<endl;
}
}
system("pause");
return 0;
}
案例:星图 嵌套循环
#include<iostream>
#include <time.h>
using namespace std;
int main(void){
for(int i=0;i<10;i++){
for(int j=0;j<10;j++){
cout<<"* ";
}
cout<<endl;
}
system("pause");
return 0;
}
案例:乘法口诀 嵌套循环
#include<iostream>
#include <time.h>
using namespace std;
int main(void){
for(int i=1;i<10;i++){
for(int j=1;j<=i;j++){
cout<<j<<"*"<<i<<"="<<i*j<<" ";
}
cout<<endl;
}
system("pause");
return 0;
}
4.3 跳转语句 break 、 contiinue 、goto
break:用在switch、 循环 、嵌套中,跳出循环
continue :跳出本次循环,执行下一次循环。
goto:无条件跳转。goto FLAG;FLAG:xxxxx;
5 数组
放在一块连续的内存空间。通过下标访问。存放相同数据类型。
5.1 一维数组
//创建,第一种
int arr[5];
arr[0]=1;
//创建,第二种
int arr[3]={1,2,3};
//创建,第三种
int arr[]={1,2,3};
数组名用途:
- 统计长度、元素个数 sizeof(arr); sizeof(arr[0]);
- 获取在内存的首地址 cout<<arr<endl; cout<<&arr[0]<<endl; 首地址其实就是第一个元素地址
案例:五只小猪称体重,找最大。
#include<iostream>
#include <time.h>
using namespace std;
int main(void){
int weight[5],w_max=0;
cout<<"请依次输出小猪的重量:"<<endl;
for(int i=1;i<5;i++){
cin>>weight[i];
if(w_max<weight[i]){
w_max=weight[i];
}
}
cout<<"最重的小猪重量为:"<<w_max<<"kg"<<endl;
system("pause");
return 0;
}
案例:元素逆置,首尾交换
#include<iostream>
#include <time.h>
using namespace std;
int main(void){
int num_arr[5];
cout<<"请依次输入元素:"<<endl;
for(int i=0;i<5;i++){
cin>>num_arr[5-1-i];
}
for(int i=0;i<5;i++){
cout<<num_arr[i]<<" ";
}
system("pause");
return 0;
}
//或者 交换
#include<iostream>
#include <time.h>
using namespace std;
int main(void){
int num_arr[5];
cout<<"请依次输入元素:"<<endl;
for(int i=0;i<5;i++){
cin>>num_arr[i];
}
int start=0,end=sizeof(num_arr)/sizeof(num_arr[0])-1;
int temp=num_arr[start];
while(start<end){
temp=num_arr[start];
num_arr[start]=num_arr[end];
num_arr[end]=temp;
start++;end--;
}
for(int i=0;i<5;i++){
cout<<num_arr[i]<<" ";
}
system("pause");
return 0;
}
案例:冒泡排序 升序
#include<iostream>
#include <time.h>
using namespace std;
int main(void){
int length=8;
int num_arr[length];
int temp;
cout<<"请依次输入8个元素:"<<endl;
for(int i=0;i<8;i++){
cin>>num_arr[i];
}
for(int i=0;i<length-1;i++){ //总共排序轮数为length-1
for(int j=0;j<length-1-i;j++){ //内层对比次数 length-当前轮数-1
if(num_arr[j]>num_arr[j+1]){
temp=num_arr[j];
num_arr[j]=num_arr[j+1];
num_arr[j+1]=temp;
}
}
}
for(int i=0;i<8;i++){
cout<<num_arr[i]<<" ";
}
cout<<endl;
system("pause");
return 0;
}
5.2 二维数组
//创建 第1种
int arr[2][3];
arr[0][0]=1; arr[0][1]=2; arr[1][0]=1;
//创建 第2种
int arr[2][3]={ {1,2,3}, {4,5,6} };
//创建 第3种
int arr[2][3]={ 1,2,3,4,5,6 };
//创建 第4种 行数可省略
int arr[][3]={ 1,2,3,4,5,6 };
数组名: 查看数组所占内存空间sizeof, 获取数组首地址
案例: 统计考试成绩
#include<iostream>
#include <string.h>
using namespace std;
int main(void){
int score[3][3]={100,100,100,90,50,100,60,70,80};
int result[3]={0};
string names[3]={"张三","李四","王五"};
for(int i=0;i<3;i++){
for(int j=0;j<3;j++)
result[i]+=score[i][j];
cout<<names[i]<<"的总分是:"<<result[i]<<endl;
}
system("pause");
return 0;
}
6 函数
实参 形参
值传递:函数调用时将实参传入形参。但形参的改变不会影响实参。 因为他们占据不同的内存空间。
函数声明:函数定义前,告诉编译器有这样的一个函数。
分文件编写: 头文件 (.h文件中写函数声明) 源文件(.cpp文件中写函数定义)
7 指针
7.1 作用:通过指针间接访问内存,通过一个指针来保存地址,指针就是地址。
定义: (&取地址符)
使用:解引用,即在指针前加*,就能找到指针指向的内存的中的数据
int a=10;
int * p;
p=&a; (地址)
a=*p; (值)
所占的内存空间:4个字节(32位操作系统下)8个字节(64位操作系统下) sizeof(int *)或 sizeof(p)
空指针:指针表里指向内存中编号为0的空间,用来初始化指针变量,指向的内存不可访问(0-255编号的内存是系统占用的)。
野指针:非法的内存空间。
7.2 用const修饰指针
const 修饰指针——常量指针; 指针前加const 如,const int p =&a; 是一个指针,指向一个常量。
指针的指向可以修改,但是指针指向的值不可以改。p=20;不可以,但p=&b可以。
const修饰常量——指针常量; int const p =&a; 指针的指向不可以变,但是指针指向的值可以改 p=20;可以,但p=&b不可以。 是一个常量。
const既修饰指针,又修饰常量。 const int * const p =&a; 指针的指向和指针指向的值都不可以变。
7.3 指针和数组
利用指针访问数组元素
cout<<arr[0]; //传统方式
int * p=arr; //arr就是数组首地址
cout<<"第一个元素"<<*p;
p++; //指针偏移
cout<<"第2个元素"<<*p;
7.4 指针和函数
利用指针做函数参数,可以修改实参的值。
区别于值传递,形参的改变不影响实参,指针上的是地址传递,形参的改变影响实参。
void swap1(int a,int b){
int temp=a;
a=b;
b=temp;
}
void swap2(int *a, int *b){
int temp=*a;
*a=*b;
*b=temp;
}
int main(void){
int a=1,b=2;
cout<<a<<" "<<b<<endl;
swap1(a,b);
cout<<a<<" "<<b<<endl;
swap2(&a,&b);
cout<<a<<" "<<b<<endl;
system("pause");
return 0;
}
结果:
1 2
1 2
2 1
案例:封装一个函数,冒泡排序,整型数组升序
void BubbleSort(int * arr,int len){
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 PrintArray(int *arr,int len){
for(int i=0;i<len;i++){
cout<<arr[i]<<endl;
}
}
int main(void){
int arr[10]={4,3,6,9,1,2,10,8,7,5};
int len=sizeof(arr)/sizeof(arr[0]);
BubbleSort(arr,len);
PrintArray(arr,len);
system("pause");
return 0;
}
指针只是一个针,他需要指向一个类型
#include<iostream>
#include <string.h>
using namespace std;
class person{
public:
int m_age;
string m_name;
person(){}
person(int age,string name):m_age(age),m_name(name){}
};
int main(void){
person * ptr=new person();
//person * ptr; 就不行 没有指向任何东西
ptr->m_age=18;
cout<<ptr->m_age<<endl;
//再如 ,直接 int *p; *p=10;就会报错
int a=10;
int * p=&a;
cout<<*p<<endl;
system("pause");
return 0;
}
8 结构体
8.1 用户自定义的数据类型
struct 结构体名{
结构体成员列表
};
//其实就是类型集合
struct Student{
string name;
int age;
int score;
};
//创建,第1种方式 struct 在创建变量时可以省略
struct Student s1;
s1.name="Zhou"; s1.age=18; s1.score=100;
//创建,第2种方式
struct Student s1={"Zhou",18,100};
//创建,第3种方式
//定义结构体时顺便定义变量
struct Student{
string name;
int age;
int score;
}s3;
s3.name="Zhou"; s3.age=18; s3.score=100;
8.2 结构体数组
Student StuArr[3]={
{"Zhou",18,100},{"Wang",18,90},{"Tang",18,120}
};
8.3 结构体指针
利用操作符 —>来访问。
struct Student s= {"Zhou",18,100};
struct Student * p = &s;
cout<<s.name<<endl;
cout<<p->name<<endl;
Day 3
8.4 结构体嵌套结构体——子结构体
struct Student{
string name;
int age;
int score;
}
struct Teacher{
int id;
string name;
int age;
struct Student stu;
}
8.5 结构体做函数参数
传递方式:值传递、地址传递
8.6 结构体中使用const
避免误操作
void PrintStudent1(const struct Student * s)
案例:
#include<iostream>
#include <string.h>
#include<time.h>
using namespace std;
struct Student{
string name;
int score;
};
struct Teacher{
string name;
struct Student sArray[5];
};
void AllocateSpace(struct Teacher tArray[], int length){
srand((unsigned int)time(NULL));
string nameSeed="ABCDE";
for(int i=0;i<length;i++){
tArray[i].name="Teacher_";
tArray[i].name+=nameSeed[i];
for(int j=0;j<5;j++){
tArray[i].sArray[j].name="Student_";
tArray[i].sArray[j].name+=nameSeed[j];
tArray[i].sArray[j].score=rand()%41+60;;
}
}
}
void PrintInfo(struct Teacher tArray[], int length){
for(int i=0;i<length;i++){
cout<<"Teacher Name:"<<tArray[i].name<<endl;
for(int j=0;j<5;j++){
cout<<" Student Name:"<<tArray[i].sArray[j].name<<",Score:"
<<tArray[i].sArray[j].score<<endl;
}
}
}
int main(void){
Teacher tArray[3];
int len=sizeof(tArray)/sizeof(tArray[0]);
AllocateSpace(tArray,len);
PrintInfo(tArray,len);
system("pause");
return 0;
}
案例:
#include<iostream>
#include <string.h>
#include<time.h>
using namespace std;
struct Hero{
string name;
int age;
string sex;
};
void BubbleSort(struct Hero hArray[], int length){
for(int i=0;i<length-1;i++){
for(int j=0;j<length-i-1;j++){
if(hArray[j].age>hArray[j+1].age){
Hero temp;
temp=hArray[j];
hArray[j]=hArray[j+1];
hArray[j+1]=temp;
}
}
}
}
void PrintInfo(struct Hero hArray[], int length){
for(int i=0;i<length;i++){
cout<<hArray[i].name<<" "<<hArray[i].age<<" "<<hArray[i].sex<<endl;
}
}
int main(void){
Hero hArray[5]={
{"刘备",23,"男"},{"关羽",22,"男"},{"张飞",20,"男"},{"赵云",21,"男"},{"貂蝉",19,"女"}
};
int len=sizeof(hArray)/sizeof(hArray[0]);
BubbleSort(hArray,len);
PrintInfo(hArray,len);
system("pause");
return 0;
}
综合案例:通讯录管理系统