这里写目录标题
1. 基础
1.1数组
array:放在连续内存空间内,每个元素是相同类型
一维定义方式
- 数据类型 数组名[数组长度];
- 数据类型 数组名[数组长度]={值1,值2…};
- 数据类型 数组名[]={值1,值2…};
通过下标访问数组中的元素,数组元素下标是从0开始
//1
int arr[3];
arr[0] = 12;
arr[1] = 22;
arr[2] = 32;
cout<<arr[2]<<endl;
//2
int arr2[3] = {12,22,32};
for(i=0;i<3;i++)
{
cout<<arr[i]<<endl;
}
//3
一维数组数组名
可以统计整个数组在内存中的长度;sizeof(arr)
可以获取数组在内存中的首地址;cout<<arr<<endl
数组名是常量,不能幅值:arr=100 ❌
#include<iostream>
using namespace std;
int main(){
int arr[10]={1,2,3,4,5,6,7,8,9,0};//int类型 4个字节
cout<<"整个数组在内存中的长度"<sizeof(arr)<<endl;
cout<<"1个数组在内存中的长度"<sizeof(arr[0])<<endl;
cout<<"整个数组的元素个数"<sizeof(arr)/sizeof(arr[0])<<endl;
cout<<"数组首地址为:"<<(int)arr<<endl;
cout<<"数组第一个元素的地址为:"<<(int)&arr[0]<<endl;
cout<<"数组第二个元素的地址为:"<<(int)&arr[1]<<endl;
system("pause");
return 0;
}
案例
- 五只小猪称体重
在一个数组中找到最大值
#include<iostream>
using namespace std;
int main(){
int arr[5]={300,350,200,400,250};
int max=0;
for(i=0;i<5;i++)
{
if(arr[i]>max)
{
max=arr[i];
}
}
cout<<"the most heavy"<<max<<endl;
system("pause");
return 0;
}
- 数组元素逆置
#include<iostream>
using namespace std;
int main(){
int arr[5]={1,3,2,5,4}
cout<<"before tranpose"<<endl;
for(i=0;i<5;i++)
{
cout<<arr[i]<<endl;
}
while(start<end)
{
int start=0;//起始元素下标
int end =sizeof(arr)/sizeof(arr[0]-1);//末尾元素下标
int temp=arr[start];
arr[start]=arr[end];
arr[end]=temp;//exchange items
start++;
end--;//update items
}
cout<<"after transpose"<<endl;
for(i=0;i<5;i++)
{
cout<<arr[i]<<endl;
}
system("pasuse");
return 0;
}
- 冒泡排序
最常用的数组排序方法——比较相邻元素
#include<iostream>
using namespace std;
int main(){
int arr[9]={2,4,1,3,7,5,9,6,8};
cout<<"排序前"<<endl;
for(i=0;i<9;i++)
{
cout<<arr[i]<<"";
}
cout<<endl;
//排序总轮数为元素个数减一;每轮比较次数为`元素个数-排序轮数-1`
for(int i=0;i<9;i++)
{
//内层循环比较
for(int j=0;j<9-i-1;j++)
{
//依次比较相邻元素
if(arr[j]>arr[j+1])
{
int temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
cout<<"排序后"<<endl;
for(i=0;i<9;i++)
{
cout<<arr[i]<<"";
}
cout<<endl;
system("pasuse");
return 0;
}
二维数组定义方式
- 数据类型 数组名[ 行数 ] [列数];
- 数据类型 数组名[ 行数 ] [列数]={ {值1,值2…},{值1,值2}…};//更直观
- 数据类型 数组名[ 行数 ] [列数]={值1,值2,值3,值4};
- 数据类型 数组名[ ] [列数]={值1,值2,值3,值4};
二维数组数组名
- 查看二维数组所占内存空间
- 获取二维数组首地址
#include<iostream>
using namespace std;
int main(){
int arr[2][3]={
{1,3,5},{2,4,6}}
cout<<"二维数组占用的内存空间"<<sizeof(arr)<<endl;
cout<<"二维数组第一行占用的内存空间"<<sizeof(arr[0])<<endl;
cout<<"二维数组第一个元素占用的内存空间"<<sizeof(arr[0][0])<<endl;
cout<<"二维数组的行数"<<sizeof(arr)/sizeof(arr[0])<<endl;
cout<<"二维数组的列数"<<sizeof(arr[0])/sizeof(arr[0][0])<<endl;
cout<<"二维数组的首地址"<<(int)arr<<endl;//强转为十进制
cout<<"二维数组第一行首地址"<<(int)arr[0]<<endl;
cout<<"二维数组第二行首地址"<<(int)arr[1]<<endl;
cout<<"二维数组第二行首地址"<<(int)&arr[0][0]<<endl;//取址符
system("pasuse");
return 0;
}
案例
考试成绩统计,输出总成绩
#include<iostream>
using namespace std;
#include string;
int main(){
int sores[3][3]={
{100,100,100},{90,50,100},{60,70,80}}
string names[3]={张三,李四,王五};//include string
for(int i=0;i<3;i++)
{
int sum=0;
for(int j=0;j<3;j++)
{
sum+=sores[i][j]
cout<<sores[i][j]<<" ";
}
cout<<names[i]<<"的分数"<<sum<<endl;
}
system("pasuse");
return 0;
}
1.2 函数
作用:将一段经常使用的代码封装起来减少重复代码
一个较大的程序分为若干模块以实现不同功能
函数的定义
- 返回值类型
- 函数名
- 参数列表
- 函数体语句
- return表达式
返回值类型 函数名 (参数列表)//main 函数参数列表不用传入数据
{
函数体语句
return表达式
}
函数的调用
语法:函数名(参数)
int add (int num1,int num2)//定义加法函数
{
int sum = num1 + num2;
return sum;
}
int main()
{
int a = 10;
int b = 20;
int c = add(a, b);//a,b叫做实参,传递给形参num1,num2
cout << "c=" << c << endl;
system("pause");
return 0;
}
值传递
- 函数调用时实参将数值传入形参
- 值传递时,形参发生变化不会影响实参
//如果函数不需要返回值,声明的时候可以用void
void swap(int num1, int num2)
{
cout << "交换前:" << endl;
cout << "number1=" << num1 << endl;
cout << "number2=" << num2 << endl;
int temp = num1;
num1 = num2;
num2 = temp;
cout << "交换后:" << endl;
cout << "number1=" << num1 << endl;
cout << "number2=" << num2 << endl;
}
int main()
{
int a = 10;
int b = 20;
swap(a, b);
cout << "a=" << a << endl;
cout << "b=" << b << endl;
system("pause");
return 0;
}
函数的常见样式
-
无参无返
-
有参无返
-
无参有返
-
有参有返
void test01()
{
cout << "test01" << endl;
}
void test02(int a)
{
cout << "test02 a=" <<a<< endl;
}
int test03()
{
cout << "test03 " << endl;
return 1000;
}
int test04(int a)
{
cout << "test04 " << endl;
return a;
}
int main()
{
test01();
test02(100);
int number1 = test03();
cout << "number1= " << number1<<endl;
int number2 = test04(1222);
cout << "number2= " << number2 << endl;
system("pause");
return 0;
}
函数的声明
作用:告诉编译器函数的名称和如何调用,函数的实际主体可以单独定义
- 函数的声明可以多次,但是函数的定义只能有一次
//比较函数,返回较大值
int max(int a, int b)
{
return a > b ? a : b;
}
int main()
{
int a = 10;
int b = 30;
cout << max(a, b) << endl;
system("pause");
return 0;
}
int max(int a, int b);//函数的声明
int main()
{
int a = 10;
int b = 30;
cout << max(a, b) << endl;
system("pause");
return 0;
}
//比较函数,返回较大值
int max(int a, int b)
{
return a > b ? a : b;
}
函数的分文件编写
作用:让代码结构更加清晰
步骤:
- 创建后缀名为.h的头文件
- 创建后缀名为.cpp的文件
- 在头文件中写函数的声明
- 在源文件中写函数的定义
==swap.h==
#include <iostream>;
using namespace std;
void swap(int num1, int num2);//函数的声明
==swap.cpp==
#include"swap.h"
void swap(int num1, int num2)
{
int temp = num1;
num1 = num2;
num2 = temp;
}
==function.cpp==
#include<iostream>
using namespace std;
#include "swap.h";
int main() {
int a = 10;int b = 20;
swap(a, b);
system("pause");
return 0;
}
一些快捷键
ctrl+s储存
windows+space=切换输入法
shift+字母=大写
对齐代码Ctrl a+k+f
注释:ctrl+k,ctrl+c
取消注释:ctrl+k,ctrl+u
1.3指针
指针的基本概念
指针就是一个地址
作用:通过指针访问内存——利用指针变量保存内存地址
指针变量的定义和使用
1.定义指针数据变量 * 变量名
2.使用指针:通过**解引用*
**的方式找到指针指向的内存
//1.定义指针
int a=10;
int *p;
p = &a;//将a的地址给指针
cout << "adress of a" << &a <<endl;
cout << "指针p为"<< p <<endl;
//2.使用指针
*p = 1000;
cout << "adress of a" << &a <<endl;
cout << "指针p为"<< p <<endl;
指针所占的内存空间
在32位系统下占4个字节;在64位下占8个字节
int main()
{
int a =10;
int *p = &a;
cout<<"sizeof(int *)="<<sizeof(int *)<<endl;
cout<<"sizeof(float *)="<<sizeof(float *)<<endl;
cout<<"sizeof(double *)="<<sizeof(double *)<<endl;
cout<<"sizeof(char *)="<<sizeof(char *)<<endl;
}
空指针
定义:指针变量指向内存中编号为0的空间
用途:初始化指针变量
注意:空指针指向的内存不能访问:0~255之间的内存编号是系统占用的
int main()
{ //1.初始化指针变量
int * p = NULL;
//2.空指针指向的内存不能访问
cout << *p<<endl;
system("pause");
return;
}
野指针
int main()
{ //1.初始化指针变量
int * p =(int *) 0x1100;
//2.空指针指向的内存不能访问
cout << *p<<endl;
system("pause");
return;
}//在程序中尽量避免出现野指针
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
特点:指针的指针的指向不可以修改,但是指针指向的值不可以改
int a = 10;
int b = 20;
//const修饰指针——常量指针
const int * p1 = &a;
p1 = &b;
//const修饰常量——指针常量
int * const p2 = &a;
*p2 = 100;
//const既修饰指针,又修饰常量
const int * const p3 = &a;
指针和数组
利用指针访问数组元素
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
cout << "第一个元素为" << arr[0]<<endl;
for(int i=0;i<10;i++)
{
cout<<arr[i]<<endl;
}//普通方式
int * p = arr;//arr就是数组的首地址
cout<<"利用指针访问数组第一个元素"<<*p<<endl;
p++;//指针向后偏移四个字节
cout<<"利用指针访问数组第2个元素"<<*p<<endl;
for(int i=0;i<10;i++)
{
cout<<*p[i]<<endl;
p2++;
}
system("pause");
return 0;
}
指针和函数
利用指针作为函数参数,可以修改实参的值
//1.值传递
void swap01(int a, int b)
{
int temp = a;
a = b;
b = temp;
}
void swap02(int *p1, int *p2)
{
int temp = *p1;
*p1 = *p2;
*p2 = temp;
}
int main()
{
//1.值传递
int a=10;
int b=20;
swap01(a,b);//实参不发生改变,形参改变
cout << "a="<<a<<endl;
cout << "b="<<a<<endl;
//2.地址传递
swap02(&a,&b);//传入a,b变量的地址
cout << "a="<<a<<endl;
cout << "b="<<a<<endl;//地址传递可以修饰实参
system("pause");
return 0;
}
案例
封装一个函数,利用冒泡排序实现对整形数组的升序排列
void buubleSort(int * arr,int len)//int arr[]
{
//排序总轮数为元素个数减一;每轮比较次数为`元素个数-排序轮数-1`
for(int i=0;i<len;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 printArry(int * arr, int len)
{
for (int i = 0;i < len; i++)
{
cout << arr[i] << " ";
}
cout << endl;
}
int main() {
int arr[10] = { 2,4,1,8,5,6,3,10,9,7 };
int len = sizeof(arr) / sizeof(arr[0]);//求数组长度
buubleSort(arr, len);//传数组的首地址,数组长度
printArry(arr, len);
system("pause");
return 0;
}
1.4结构体
基本概念
结构体属于用户自定义的数据类型,允许用户储存不同的数据类型
定义:struct 结构体名{结构体成员列表}
struct Student//学生数据类型:包括姓名、年龄、分数
{
//成员列表
string name;
int age;
int score;
};
通过结构体创建变量的方式:
- struct 结构体名 变量名
- struct 结构体名 变量名 = {成员1值,成员2值}
- 定义结构体时顺便创建变量
struct Student s1; //struct关键字在创建变量时可以省略
s1.name = "Mary";
s1.age = 22;
s1.score = 99;//给s1赋值,通过.访问结构体变量中的属性
cout << "name: " << s1.name << " age: " << s1.age << "score: " << s1.score << endl;
struct Student s2 { "Lily", 19, 98 };
cout << "name: " << s2.name << " age: " << s2.age << "score: " << s2.score << endl;
struct Student
{
string name;
int age;
int score;
}s3;//顺便创建结构体变量,第三种用的少
s3.name = "Bob";
s3.age = 23;
s3.score = 97;
cout << "name: " << s3.name << " age: " << s3.age << "score: " << s3.score << endl;
结构体数组
作用:将自定义的结构体放到数组中方便维护
语法:struct 结构体名 数组名[元素个数]={
{},{},...{}}
#include <string>
//定义一个结构体
struct Student
{
string name;
int age;
int score;
}
int main() {
//创建结构体数组
struct Student stuArray[3] =
{
{"Marrt",18,100},
{"Lily",19,98},
{"Bob",20,99}
};
//给结构体数组中的元素赋值
stuArray[2].name = "Liming";
stuArray[2].age = 22;
stuArray[2].score = 99;
//遍历结构体数组
for (int i = 0; i < 3; i++)
{
cout << "姓名:" << stuArray[i].name
<< " age:" << stuArray[i].a