C++入门第一阶段——基础篇

如何创建C++程序

①:创建项目
第一步创建项目
之后选择Visual C+±>空项目->编写项目名称->点击浏览选择路劲
②:创建文件
创建文件
之后选择C++文件,并编写自己想要的名称
③:编写代码
固定模板:

#include<iostream>
using namespace std;//使用一个名为std的namespace
int main()
{
   system("pause");
   return 0;
}

主体程序

#include<iostream>
using namespace std;//使用一个名为std的namespace
int main()
{
   cout<<"HelloWorld";
   //没有换行
   cout<<"HelloWorld"<<endl;
   //书写并换行
   system("pause");
   return 0;
}

④:运行程序

C++相关基础

变量

变量的意义

变量的意义就是管理内存空间的
当我们需要在内存上存储一块数据的时候怎么办?
第一种就是知道他的内存块编号,然后将相关数据存在该内存块上,但这个方法有明显缺陷,就是我们存储的数据过多的,编号的复杂性会让我们头疼,于是我们便引入了变量这个概念。

变量创建的语法

数据类型 变量名 = 变量初始值;

代码示例

#include<iostream>
using namespace std;
int main()
{

int a;
a = 10;
cout<<"a的值为:"<<a<<endl;
system("pause");
return 0;
}

常量

常量的意义

常量的作用:用于记录程序段不可以修改的数据。
如:一个星期七天

常量的定义方式

①:#define 宏常量 ;一般定义在文件的上方
②:const修饰的变量

#include<iostream>
using  namespace  std;
#define day 7  //无分号的结尾
int main()
{
//day = 10;//day是一个常量,修改会报错,如左边必须为可修改的左值
const int year = 12;//const修饰的变量也可以修改
cout<<"一周有多少天"<<day<<endl;
cout<<"一年有多少个月"<<year<<endl;
system("pause");
return 0;
}

关键字

关键字的含义

C++中预先保留的单词

sizeof

用法 :sizeof(数据类型/变量)
代码示例可见下面数据类型的整型的代码示例

标志符的命名

什么是标志符

标志符是指我们上面所说的变量和常量

命名规则

①:有数字,字母和_(下划线)组成
②:不可以数字在最前面
③:为了方便自己回顾和他人看你的程序,命名时要有一定的意义
④:命名时要区分大小写
⑤:命名时,如上面所说,不能为关键字

数据类型

整型

①整形的作用:
表示整数类型的数据
②:不同的整型所占的字节数不一样
short 2个字节
int 4个字节
long 根据不同的编译器,所占字节数不一样,Windows为4个字节
long long 占8个字节
③:代码示意:

#include<iostream>
using namespace std;
int main()
{
short a =10;
cout<<"short类型数据所占内存"<<sizeof(short)<<endl;
int b =10;
cout<<"int类型数据所占内存"<<sizeof(b)<<endl;
cout<<"int类型数据所占内存"<<sizeof(int)<<endl;
long c =10;
cout<<"long类型数据所占内存"<<sizeof(long)<<endl;
long c =10;
cout<<"long类型数据所占内存"<<sizeof(long)<<endl;
system("pause");
return 0;
}

实型

作用:
用来表示小数;
浮点型变量分为两种:
单精度: float;占用字节数:4个字节;7位有效数字(包括小数点前后);
双精度:doule;占用字节数:8个字节;

#include<iostream>
using namespace std;
int main()
{
float a =3.14f;
cout<<"a ="<<a<<endl;
double b =3.14f;
cout<<"b="<<b<<endl;
system("pause");
return 0;
}

注意点:
默认情况下无论是double还是float,输出的都是6位有效数字;
下面将入一些代码,看其结果,大家会加深印象的:

#include<iostream>
using namespace std;
int main()
{

float a = 2.13123445f;
double b =2.13123445;
cout<<"a =" << a<<endl;
cout<<"b="<<b  <<endl;
system("pause");
return 0;

}

上面程序编译后的结果如下图所示:在这里插入图片描述
科学计数法:
float a =2e2;

字符型

语法:char a =‘a’;
注意点:
①:单引号,不是双引号
②:只能是一个字符;
③:字符型变量不是将字符本身放到内存中存储,而是将其对应的ASCII码放到存储单元
④:char所占的内存大小为1个字节
⑤:区分大小写

#include<iostream>
using namespace std;
int main()
{
char a= 'a';
cout<<"a =" << a<<endl;
cout<<"char所占的内存大小为:"<<(sizeof(char))<<endl;
cout<<"a对应的ASCII码为:"<<(int)a<<endl;
system("pause");
return 0;
}

补充点:
ASCII码有两部分组成:
①:0 ~ 31为非打印字符控制字符,用于控制像打印机等一些外围设备。
②:32-126是分配可以在键盘上找到的字符

转义字符

作用:用于表示一些不能显示出来的ASCII字符
\n:换行;
\t:水平制表(HT),(跳转到下一个TAB位置)
\:输出一个;

字符串

char 变量名[ ] =“字符串值”;
注意点:
①:右边的字符串必须有双引号
②:别忘了[ ];
string 变量名;
注意点
①://右边的字符串必须有双引号
②:必须包含有文件#include

#include <iostream>
#include<string>//头文件别忘了
using namespace std;
int main()
{  
char a[] = "jianchizhu";
string b = "jsdfhuj";
cout<<a<<endl;
cout<<b<<endl;
system("pause");
}  

布尔

①:只占一个字节的大小
②:除了0和flase表述假,别的都是表示真
③:相关代码示例:

#include <iostream>
#include<string>
using namespace std;
int main()
{  
bool a = 1; 
bool b = false;
cout<<a<<endl;
cout<<b<<endl;
cout<<sizeof(a)<<endl;
system("pause");
} 

字符的输入

cin>>变量:用于从键盘上获取数据;

#include <iostream>
#include<string>
using namespace std;
int main()
{  
int a = 0; 
cout<<"请输入一个整型数:"<<endl;
cin>>a;
cout<<"你输入的值为"<<a<<endl;
bool b = false;
cout<<b<<endl;
cout<<sizeof(a)<<endl;
system("pause");
} 

运算符

算数运算符

①:分类:
+既可以表示整数,又可以表示加号
%取余符号(除数不能为0;只有当两个整型的时候才能做取余运算);
*:乘
/:除(当两个整数型除的时候,为取整符号)
++:分为前置递增和后置递增;
前置递增;先让变量+1.然后进行表达式运算
后置递增:先进行表达式运算,再进行+1操作
–:也分为前置递减和后置递减;
赋值运算符;
比较运算符;
逻辑运算符;
①:代码试讲:

#include<iostream>
using namespace std;
int main()
{
int a = 10;
int b =3;
cout<<a/b<<endl;
int  c = 5;
int d =10;
cout<<c/d<<endl;
//"/"有几特别的地方:
//①:被除数不能为0;
//②:两个整型相除的时候,得的结果为整数,且注意不是四舍五入,单纯的取出其整数部分;
//除数不能为0;
double d1 =0.5;
double  d2 =2;
cout<<d1/d2<<endl;(可以得到小数)
system("pause");
return 0;
}
#include<iostream>
using namespace std;
int main()
{
int a = 10;
int b =3;
cout<<a/b<<endl;
int  c = 5;
int  d=++c*10;
cout<<c<<endl;
cout<<d<<endl;
//"/"有几特别的地方:
//①:被除数不能为0;
//②:两个整型相除的时候,得的结果为整数,且注意不是四舍五入,单纯的取出其整数部分;
//除数不能为0;
int  e = 5;
int  f=e++*10;
cout<<e<<endl;
cout<<f<<endl;
system("pause");
return 0;
}

赋值运算符

=;*=;/=;+=;-=;%;

比较运算符

==;!=;>;<;<=;>=;

#include<iostream>
using namespace std;
int main()
{
int a = 10;
int b =3;
cout<<(a<b)<<endl;
cout<<(a==b)<<endl;
cout<<(a!=b)<<endl;
cout<<(a>b)<<endl;
system("pause");
return 0;
}

逻辑运算符

逻辑非:!;
c++中除了0之外,别的都是逻辑真,为1;
逻辑与:&&;真真为真,剩余的都为假;
逻辑或:||;假假为假,剩余的都为真;

#include<iostream>
using namespace std;
int main()
{
int a = 10;
int b = 0;
cout<<!a<<endl;
cout<<!!a<<endl;
cout<<(a&&b)<<endl;
cout<<(a||b)<<endl;
system("pause");
return 0;
}

程序的流程结构

顺序结构

选择结构

①:多行格式If语句

#include<iostream>
using namespace std;
int main()
{
int a =0;
cout<<"请输入你高考考得分数"<<endl;
cin>>a;
if(a>600)//注意选择语句中没有if;
 {
	cout<<"恭喜你考上了家里蹲大学"<<endl;
 }
else
{
	cout<<"家里蹲吧"<<endl;
}
system("pause");
return 0;
}

②:多条件if语句

#include<iostream>
using namespace std;
int main()
{
int a =0;
cout<<"请输入你高考考得分数"<<endl;
cin>>a;
if(a>600)
 {
	cout<<"恭喜你考上了家里蹲大学"<<endl;
 }
else if(a>300)
{
	cout<<"再来一年吧"<<endl;
}
else
{
	cout<<"家里蹲吧"<<endl;
}
system("pause");
return 0;
}

③:嵌套if语句:

#include<iostream>
using namespace std;
int main()
{
int a =0;
cout<<"请输入你高考考得分数"<<endl;
cin>>a;
if(a>600)
 {
	if(a>1000)
	{
    cout<<"恭喜你国外蹲"<<endl;
	}
	else  if(a>800)
	{
     cout<<"恭喜你北京蹲"<<endl;
	}
	else 
	{
     cout<<"恭喜南京蹲"<<endl;
	}
 }
else if(a>300)
{
	cout<<"再来一年吧"<<endl;
}
else
{
	cout<<"家里蹲吧"<<endl;
}
system("pause");
return 0;
}

示例操练:
自己输入三头小猪的重量,让软件自己给这三头猪排序:

#include<iostream>
using namespace std;
int main()
{
int a,b,c,max,mid,min=0;
cout<<"请输入A猪的重量"<<endl;
cin>>a;
cout<<"请输入B猪的重量"<<endl;
cin>>b;
cout<<"请输入c猪的重量"<<endl;
cin>>c;

if((a>b)&&(a>c)&&(b>c))
 {
	 max=a;
	 mid=b;
	 min=c;
 }
else if((a>b)&&(a>c)&&(c>b))
{
	 max=a;
	 mid=c;
	 min=b;
}
else  if((a>b)&&(c>a)&&(c>b))
{
	 max=c;
	 mid=a;
	 min=b;
}
else  if((a<b)&&(c>a)&&(c>b))
{
	 max=c;
	 mid=b;
	 min=a;
}
else  if((b>a)&&(a>c)&&(b>c))
{
	 max=b;
	 mid=a;
	 min=c;
}
else 
{
	 max=b;
	 mid=c;
	 min=a;
}
cout<<"你输入最大猪的重量为:"<<max<<endl;
cout<<"你的猪排序为:"<<"\t"<<max<<"\t"<<mid<<"\t"<<min<<endl;
system("pause");
return 0;
}

④:三目运算符
语法格式:表达式1?表达式2:表达式3
语法解释:如果表达式1成立,执行表达式2;
如果表达式1不成立,执行表达式3;
注意点:三目运算符返回的值本身为一个变量,可以继续赋值;

#include<iostream>
#include<string>
using namespace std;
int main()
{ 
 int a, b= 0;
 string c;
 cout<<"请玩家一输出你的数字"<<endl;
 cin>>a;
 cout<<"请玩家二输出你的数字"<<endl;
 cin>>b;
  a>b?c="玩家一赢":c="玩家二赢";
  cout<<c<<endl;
  system("pause");
  return 0;
}

c++中三目运算符返回的是变量,可以继续赋值

#include<iostream>
using namespace std;
int main()
{
int a = 0;
int b = 0;
cout<<"请输入两个整数:"<<endl;
cin>>a;
cin>>b;
(a>b?a:b)=666;
cout<<"a的值为:"<<a<<endl;
cout<<"b的值为:"<<b<<endl;
system("pause");
return 0;
}

⑤:switch语句
作用:执行多条件分支语句
语法:
switch(表达式)
{
case 结果一:执行语句;break;
case 结果二:执行语句;break;

default:执行语句;break;

}
注意点:
1:缺点:
switch判断的时候只能是整型或者字符型,不可以是一个区间
2:优点:
结构清晰,执行效率高

循环结构

①:while循环语句
语法:while(循环条件){循环语句}
示例:在屏幕中打印0~9这10个数字:

#include<iostream>
using namespace std;
int main()
{ 
  int num = 0;
  while(num<10)//必须提供退出循环的出口,不能一直死循环
  {
	  cout<<(num++)<<endl;
  }
  system("pause");
  return 0;
}

示例:系统速记生成1到100之间的数字,玩家进行猜测,如果猜错,提示玩家数字过大或过小,如果猜对,恭喜玩家胜利并退出游戏

#include<iostream>
#include<string>
#include<ctime>
using namespace std;
int main()
{ 
  int num ,a = 0;
  string c ;
  srand((unsigned)time(NULL));//播种子
  num = rand()%100+1;
  //cout<<num<<endl;
  cout<<"请输入你猜的数字"<<endl;
  cin>>a;
   while(a!=num)
  {
	 num>a?c="你猜的数小了,请往大值猜":c="你猜的值大了,请往小值猜";
	 cout<<c<<endl;
   	 cout<<"请重新输入你猜的值"<<endl; 
	 cin>>a;
  }
   cout<<"恭喜你猜对了,奖励100元"<<endl;
  system("pause");
  return 0;
}

注意点:
①:break能够跳出当前循环
②:生成随机数的种子为:
scrand((unsigned) time (NULL));
③:do…while语句
与while语句的区别是:
先执行一次循环语句
例子:

在屏幕中输出0到9这10个数字

#include<iostream>
#include<string>
#include<ctime>
using namespace std;
int main()
{ 
  int num =0;
  do {cout<<num++<<endl;}
  while(num<10);
  system("pause");
  return 0;
}

示例:
水仙花数:一个3位数,它的每个位上的数字的3次幂之和等于它本身

#include<iostream>
#include<string>
#include<math.h>
using namespace std;
int main()
{ 
    double a=1,b=1,c=1;
	int e=0;

    //(pow(a,3))+(pow(b,3))+(pow(c,3))!=(a*100+b*10+c)?(c==9?(b==9?++a,b=0,c=0:++b,c=0):++c):e=1;
     if(e==0)
	 {
		 cout<<(a*100+b*10+c)<<endl;
	 }
  system("pause");
  return 0;
}

③:for语句
for语句的语法:for(初始条件;判断条件;循环操作体)
示例:

#include<iostream>
#include<string>
using namespace std;
int main()
{ 
  for(int i=0;i<10;i++)
  {
	  cout<<i<<endl;
  }
  system("pause");
  return 0;
}

吃饭的时候,我们经常玩一个游戏,是敲桌子游戏,从1到100个数字,如果该数字是7的倍数,或者数字中含有7,我们就打印敲桌子,如果不是,直接打印该数字!

#include<iostream>
#include<string>
using namespace std;
int main()
{
for(int a = 1;a<101;a++)
{   
  if(a%7==0||a%10==7||a/10==7)
  //观察个位是不是7:a对7取模
  {
	  cout<<"敲桌子"<<endl;
  }
  else
  {
	  cout<<a<<endl;
  }

}
system("pause");
return 0;
}

④:嵌套循环
//外循环执行一次,内循环执行一周
示例:要求界面输出1010的""号

#include<iostream>
using namespace std;
int main()
{
//外循环
for(int i= 0;i<10;i++)
{
  //内循环
  for(int a = 0;a<10;a++ )
  {
    cout<<"*";
  }
  cout<<endl;
}
system("pause");
return 0;
}

练习:请用代码输出乘法口诀表

#include<iostream>
using namespace std;
int main()
{
//外循环
for(int i= 0;i<10;i++)
{
  //内循环
  for(int a = 1;a<=i;a++ )
  {
    cout<<a<<"x"<<i<<"="<<a*i<<"  ";
  }
  cout<<endl;
}
system("pause");
return 0;
}

跳转语句(break、continue、goto)

①:break语句
作用:用于跳出选择结构或者循环结构
break使用的时机
1:出现在选择结构是switch语句中,用于中止case并且跳出switch
2:出现在循环语句中,作用是跳出当前的循环语句
3:出现在嵌套循环中,跳出最近的内层循环语句

#include<iostream>
using namespace std;
int main()
{
	int select  = 0;
//break的使用时机
//1、switch语句
cout<<"请你选择你输入游戏的难度"<<endl;
cout<<"1:普通"<<endl;
cout<<"2:中等"<<endl;
cout<<"3:困难"<<endl;
int a = 0;
cin>>select;
switch(select)
{
case 1:
   cout<<"你选择的是普通难度"<<endl;
   a = 1;
   break;
case 2:
   cout<<"你选择的是中等难度"<<endl;
   a = 2;
   break;
 case 3:
   cout<<"你选择的是困难难度"<<endl;
   a =3;
   break;
  default:
   cout<<"请你重新选择"<<endl;
   break; 
}
for(int i = 0;i<10;i++)
{
if(i==a)  
{
  break;//退出循环//循环测试结束
}
cout<<i<<endl;
}
int d;
cout<<"请输入你想键入的数字"<<endl;
cin>>d;
for(int c=0;c<10;c++)
{
 for(int e=0; e<10;e++)
 {
   if(e==d)
   {
   break;//跳出内循环,外循环继续
   }
   cout<<"*";
 }
 cout<<endl;
}
system("pause");
return 0;
}

②:continue语句
作用:在循环语句中,跳过本次循环中余下尚未执行的语句,执行下一次循环
continue:与break的区别在于:continue只是退出本次循环,不执行循环中后面的代码,而break是直接终止该循环
示例:请使用continue函数,从0~100中挑出奇数

#include<iostream>
using namespace std;
int main()
{
for(int i =0;i<=100;i++)
{
	//如果是奇数输出,偶数不输出
	if(i%2==0)
	{
      continue;//可以筛选条件,执行到此就不再向下执行,执行下一次循环
		//break;break是退出循环
	}
	cout<<i<<endl;
}
system("pause");
return 0;
}

③:goto 跳转语句

作用:可以无条件跳转语句
语法:goto 标记;//这个标记约定俗成的是大写的命名
解释:如果标记的名称存在,执行goto语句时,会跳转到标记的位置

#include<iostream>
using namespace std;
int main()
{
//goto语句
	cout<<"1"<<endl;
	cout<<"2"<<endl;
	goto FLAGE;
	cout<<"3"<<endl;
	cout<<"4"<<endl;
	FLAGE:
	cout<<"5"<<endl;
system("pause");
return 0;
}

//不建议使用,使用过多的话会使程序混乱

数组

特点一:数组中的每个元素都是相同的数据类型
特点二:数组是由连续的内存位置组成的
数组的三种定义方法:
①:数据类型 数组名[数组长度]
②:数据类型 数组名[数组长度] = {}
如果在初始化数据的时候,没有全部填完的会用0来填补剩余的数据
③:数据类型 数组名[ ]={值1,值2…};
定义数组的时候,必须有初始长度
我们可以通过下标来访问数组中的元素;
数组下标是从0开始的;

一维数组名称的用途:

1:可以统计整个数组在内存中的长度
2:可以获取数组在内存中的首地址

#include<iostream>
using namespace std;
int main()
{

	int arr[5]={1,2,3,4,5};
	cout<<sizeof(arr)<<endl;//sizeof可以统计名称/类型的长度
	cout<<sizeof(arr[0])<<endl;
	cout<<sizeof(arr[1])<<endl;
	cout<<sizeof(arr)/sizeof(arr[0])<<endl;
	cout<<(int)&arr[1]<<endl;//正好与第一个元素相差4个字节
	cout<<(int)&arr[0]<<endl;//数组第一个元素的地址
	cout<<(int)arr<<endl;//直接获取数组在内存中的首地址
	//如果不int类型强制转换的话,他的显示是16进制
system("pause");
//数组名是一个常量,不可以进行赋值
return 0;
}

注意事项:数组名是一个常量,不可以进行赋值;
示例一:
界面记录5个小猪的重量,打印找出最重小猪额重量

#include<iostream>
using namespace std;
int main()
{
	int arr[5],c=0,d=0;
for(int i= 0;i<5;i++)
{
	cout<<"请输入第"<<(i+1)<<"小猪的重量"<<endl;
	int a =0;
	cin>>a;
	arr[i]=a;
}
for( c=0;c<5;c++)
	{
	   int num=0;
		for(int d=0;d<5;d++)
		{
			if(arr[c]>=arr[d])
			{
				num++;
			}
			
		}
		if(num==5)
		{
			d=arr[c];
		}
	}
  cout<<"最重猪的重量为:"<<d<<endl;
system("pause");
//数组名是一个常量,不可以进行赋值
return 0;
}

上面的代码比较复杂,这边我们需要使用算法来找出最大值:
先认定一个最大值,如果数组中的某个数比它大,我们更新这个数值。

#include<iostream>
using namespace std;
int main()
{
	int arr[5],max=0;
for(int i= 0;i<5;i++)
{
	cout<<"请输入第"<<(i+1)<<"小猪的重量"<<endl;
	int a =0;
	cin>>a;
	arr[i]=a;
}
for(int c=0;c<5;c++)
	{
		if(arr[c]>max)
		{
			max=arr[c];
		}

	}
  cout<<"最重猪的重量为:"<<max<<endl;
system("pause");
//数组名是一个常量,不可以进行赋值
return 0;
}

示例二:
键入5个数字,将他们倒序输出

#include<iostream>
using namespace std;
int main()
{
int arr[5],i;
cout<<"请输入需要倒置的5个数:"<<endl;
for(i=0;i<5;i++)
{
	cin>>arr[i];
}
for(i=0;i<5;i++)
{
cout<<arr[4-i]<<"  ";
}
system("pause");
//数组名是一个常量,不可以进行赋值
return 0;
}

示例三:数组元素逆置
(如原数组元素为:1,2,3,5,4;逆置后输出的结果为:4,5,2,3,1);

#include<iostream>
using namespace std;
int main()
{
	
	int arr[]={1,2,3,4,5,6,7,8};
	//1,创建数组
	int start=0,end=(sizeof(arr)/sizeof(arr[0])-1);
	int temp;
	//实现逆序
	for(;start<end;start++,end--)
	{
		temp = arr[start];
		arr[start] = arr[end];
		arr[end] = temp;
	}
	for(int i=0;i<sizeof(arr)/sizeof(arr[0]);i++)
	{
		cout<<arr[i]<<endl;
	}
system("pause");
//数组名是一个常量,不可以进行赋值
return 0;
}

冒泡排序

作用:对组内元素进行排序
1:比较相邻的元素,如果第一个比第二个大,就交换他们两个;
2:对每一对相邻元素做相同的工作,执行完毕之后,找出第一个最大值
3:重复以上步骤,每次比较次数-1,直到不需要比较
比较有意思一点,就是为什么这个算法叫做冒泡排序,因为他像水中气泡一样,每次冒出一个最大值,然后咕噜咕噜的全部出口

#include<iostream>
using namespace std;
int main()
{
	
	int arr[]={8,7,6,5,4,3,2,1};
	//1,创建数组
	int num = sizeof(arr)/sizeof(arr[0]);
	int temp = 0;
	//实现逆序
	for(int i=0;i<num-1;i++)
	{
		for(int c= 0;c<num-i-1;c++)
		{
		  if(arr[c]>arr[c+1])
		  {
		  temp = arr[c+1];
		  arr[c+1] = arr[c];
		  arr[c] = temp;
		  } 
		}
	}
	for(int d=0;d<sizeof(arr)/sizeof(arr[0]);d++)
	{
		cout<<arr[d]<<endl;
	}
system("pause");
//数组名是一个常量,不可以进行赋值
return 0;
}

二维数组的命名:

①:数据类型 数据类型[行数][列数];
②:数据类型 数组名[行数][列数]={{数据1,数据2},{数据3,数据4}};
③:数据类型 数据名[行数][列数]={数据1,数据2,数据3,数据4};
④:数据类型 数组名[][列数] = {数据1,数据2,数据3,数据4};
第二种更加直观,能够提高代码的可读性‘

二维数组数组名的意义

①:查看二维数组所占的内存空间
②:获取二维数组的首地址

#include<iostream>
using namespace std;
int main()
{   
	int i,j,d=0;
	int arr[2][3];
    int arr1[2][3]={{1,2,3},{1,2,3}};
    int arr2[2][3]={1,2,3,4,5,6};
    int arr3[][3]={7,8,9,10,11,12};
     arr[0][0]=1;
     arr[0][1]=2;
     arr[0][2]=3;
     arr[1][0]=4;
     arr[1][1]=5;
     arr[1][2]=6;
    for(i=0;i<2;i++)
    {
    for(j=0;j<3;j++)
    {
    cout<<arr[i][j]<<"  ";
    }
    cout<<endl;
    }
   cout<<"整个数组所占的内存大小:"<<sizeof(arr)<<endl;
   cout<<"数组的首地址为:"<<(int)arr<<endl;
   cout<<"数组的第一行首地址为:"<<(int)arr[0]<<endl;
   cout<<"数组的第一行第一列数据的地址为:"<<(int)&arr[0][0]<<endl;
   //查看数组中具体元素的地址必须在该地址前加上取址符号
   cout<<"数组的第二行首地址为:"<<(int)arr[1]<<endl;
   cout<<"第一行数组所占的内存大小:"<<sizeof(arr[0])<<endl;
   cout<<"第二行数组所占的内存大小:"<<sizeof(arr[0])<<endl;
   cout<<"该数组共有多少列:"<<sizeof(arr[0])/sizeof(arr[0][0])<<endl;
   cout<<"该数组共有多少行:"<<sizeof(arr)/sizeof(arr[0])<<endl;
     for(i=0;i<2;i++)
    {
    for(j=0;j<3;j++,d++)
    {
    arr1[i][j] = d;
    cout<<arr1[i][j]<<"  ";
    }
    cout<<endl;
    }   

	 cout<<endl;
 for(i=0;i<2;i++)
    {
    for(j=0;j<3;j++)
    {
    cout<<arr2[i][j]<<"  ";
    }
    cout<<endl;
    }

system("pause");
//数组名是一个常量,不可以进行赋值
return 0;
}

案例分析:将三个学生的三门课的分数录入系统,然后分别算出他们的分数总和

#include<iostream>
#include<string>
using namespace std;
int main()
{   
	int arr[3][3],k,score[3]={0,0,0};
    string name[3] = {"张三","李四","王五"};
	for(int i = 0;i<3;i++)
	{
		cout<<name[i]<<"的三门分数分别为:"<<endl;
		for(int j = 0;j<3;j++)
		{
		   cin>>k;
		   arr[i][j]=k;
		}
	}
		for(int i = 0;i<3;i++)
	{
		for(int j = 0;j<3;j++)
		{
		  score[i]+=arr[i][j];
		}
	}
	cout<<"三个人的总分数分别为:"<<endl;
	for(int l= 0;l<3;l++)
	{
	    cout<<score[l]<<endl;
	}
system("pause");
//数组名是一个常量,不可以进行赋值
return 0;
}

函数

函数的作用与调用

作用:将经常使用的函数进行封装,减少我们的代码重复
一个较大的函数我们一般由若干个程序块构成,,每个模块实现特定的功能
函数的定义一般由5个步骤:
1:返回值的类型
2:函数名
3:参数列表
4:函数体语句
5:return表达式
函数的具体如何调用可以看下面的代码:

语法:
函数返回值类型 函数名(参数列表)
{
 函数体语句;
 return 表达式;
}

应用实战:
实现一个加大函数,功能是:传入两个整型数据,计算数据相加结果,并且返回。
语法:返回值类型 函数名(参数列表)
{
函数体语句;
return 表达式;
}

#include<iostream>
#include<string>
using namespace std;
//函数定义的时候,a和b没有实际的数据,是一个形参
int add(int a,int b)//行参列表
{ 
		int sum = a+b;
		return sum;
}
int main()
{ 
	//1:函数类型  int
	//2:函数名称  add
	//3:函数参数  (int a,int b)
	//4:函数体语句  int sum = a+b;
	//5:return 表达式  return sum;
	int j=2;
	int i=3;
	//下面这行的i和j为实参
	//调用函数的时候,是将实参的值传给行参
	int c = add(j,i);
	cout<<c<<endl;

system("pause");
//数组名是一个常量,不可以进行赋值
return 0;
}

值传递

值传递的时候,如果形参发生改变,并不会影响实参。
如果函数不需要返回值,声明的时候可以写void;
返回值不需要的时候可不写return,也可以直接写return;
当我们做值传递的时候,函数的形参发生改变,不会影响实参;
但当我们是地址传递的时候,是可以修改实参的值,具体可以参考后面的章节:《指针和函数》
实参和形参不是一个地址指向

#include<iostream>
#include<string>
using namespace std;
//函数定义的时候,a和b没有实际的数据,是一个形参
void  swap(int a,int b)//行参列表
{       
	    cout<<"交换前的i = "<<a<<endl;
		cout<<"交换前的j = "<<b<<endl;
		int temp =a;
		a = b;
		b = temp;
		cout<<"交换后形参的i = "<<a<<endl;
		cout<<"交换后形参的j = "<<b<<endl;
		return;
}
int main()
{ 
	//1:函数类型  int
	//2:函数名称  add
	//3:函数参数  (int a,int b)
	//4:函数体语句  int sum = a+b;
	//5:return 表达式  return sum;
	int i=2;
	int j=3;
	//下面这行的i和j为实参
	//调用函数的时候,是将实参的值传给行参
     swap(i,j);
	cout<<"实参i = :"<<i<<endl;
	cout<<"实参j = :"<<j<<endl;
system("pause");
//数组名是一个常量,不可以进行赋值
return 0;
}

函数的常见样式

常见的函数有4种:
①:无参无返
②:有参无返
③:无参有返
④:有参有返

#include<iostream>
#include<string>
using namespace std;
//函数定义的时候,a和b没有实际的数据,是一个形参
//1:无参无返:
void test0()
{
	 cout<<"This is test0"<<endl;

}
//2:有参无返:
void  swap(int a,int b)//行参列表
{       
	    cout<<"交换前的i = "<<a<<endl;
		cout<<"交换前的j = "<<b<<endl;
		int temp =a;
		a = b;
		b = temp;
		cout<<"交换后形参的i = "<<a<<endl;
		cout<<"交换后形参的j = "<<b<<endl;
		return;
}
//3:无参有返:
int test03()
{
	cout<<"this is 03"<<endl;
	return 1000;
}
int test04(int a)
{
	a=10000;
	return a;
}
int main()
{ 
	//1:函数类型  int
	//2:函数名称  add
	//3:函数参数  (int a,int b)
	//4:函数体语句  int sum = a+b;
	//5:return 表达式  return sum;
	//①:无参无返函数调用:
	test0();//调用无形无参的时候,后面函数的括号也需要保留
	int i=2;
	int j=3;
	//下面这行的i和j为实参
	//调用函数的时候,是将实参的值传给行参
     swap(i,j);
	cout<<"实参i = :"<<i<<endl;
	cout<<"实参j = :"<<j<<endl;
	int num1 = test03();
	cout<<"num1 = "<<num1<<endl;
	int num2 = test04(10);
	cout<<num2<<endl;

system("pause");
//数组名是一个常量,不可以进行赋值
return 0;
}

函数的声明

提前编译器函数的存在,声明没有具体的代码实现。
声明可以有多次,但是定义只能有一次;

#include<iostream>
#include<string>
using namespace std;
//函数定义的时候,a和b没有实际的数据,是一个形参
//1:无参无返:
int max(int a,int b);
int main()
{ 
	int a = 10;
	int b = 20;
	cout<<max(a,b)<<endl;


system("pause");
//数组名是一个常量,不可以进行赋值
return 0;
}
int max(int a,int b)
{
	return a>b?a:b;

}

函数的分文件编写

作用:让代码的结构更加清晰
函数分文件的编写一般分为4个步骤
1.创建后缀为.h的头文件
2.创建后缀为.cpp的源文件
3.在头文件中写函数的声明
4.在源文件中写函数的定义
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

指针

指针的定义和作用

1:指针的作用:可以通过指针间接访问内存
2:内存的编号一般是从0开始记录的,一般使用的是十六进制的数字进行表示;
3:可以用指针变量来保存地址

#include<iostream>
using namespace std;
int main()
{
//一:定义指针
 //定义一个变量
 int  a = 10;
 //指针定义的语法:数据类型*指针变量名
 int * p;
 //让指针记录变量a的地址
 p = &a;
 cout << "a的地址为: "<<&a<< endl;
 cout << "指针p为: " << p << endl;
//2:使用指针:
 //可以通过解引用的方式来找到指针指向的内存
 //指针前加一个*代表解引用,找到指针指向的内存中的数据
 * p = 1000;
 cout << "a : " <<a <<endl;
 cout << "*p : " <<*p<< endl;
 system("pause");
 return 0;
}

注意点:
①:定义一个指针:
数据类型 * 指针变量名
②:
指针变量名 = &内存的别名;
③:
*指针变量名:解引用,代表所指向内存的内容

指针所占的内存空间

指针也是种数据类型,这种数据类型占多少内存?
在32位的操作系统下,无论什么指针类型,指针都是占用4个字节,在64位的操作系统下,指针占有8个字节
指针的定义的另一种办法:

int a =100;
int *p = &a;

在这里插入图片描述如上图所示:方框勾选出的地方是我们选择编译器选择处理器的字长!说道这边我们来及时一下我们通常所说的32位和64位是指的什么?在说这个问题之前,我们先知道两个概念:
①:字长是指cpu单位时间内(同一时间内)处理二进制的位数
②:这里所说的多少位的处理器是指:寄存器的位宽
③:上图中方框中的X86指的是32位,X64位是指64位的处理器


#include<iostream>
using namespace std;
int main()
{
//一:定义指针
 //定义一个变量
 /*
 int  a = 10;
 //指针定义的语法:数据类型*指针变量名
 int * p;
 //让指针记录变量a的地址
 p = &a;
 */
 int a = 10;
 int *p = &a;
 //cout << "a的地址为: "<<&a<< endl;
 //cout << "指针p为: " << p << endl;
 cout << "(int*)的占用的内存空间为:" << sizeof(int *) << endl;
 cout << "(int*)的占用的内存空间为:" << sizeof(p) << endl;
//2:使用指针:
 //可以通过解引用的方式来找到指针指向的内存
 //指针前加一个*代表解引用,找到指针指向的内存中的数据
 * p = 1000;
 cout << "a : " <<a <<endl;
 cout << "*p : " <<*p<< endl;
 system("pause");
 return 0;
}

空指针和野指针

空指针:指针变量指向内存中编号为0的空间;
用途:初始化指针变量
注意:空指针指向的内存是不可以访问的

#include<iostream>
using namespace std;
int main()
{
   //空指针
 //1:空指针用于给指针变量进行初始化
 int *p = NULL;
 //*p= 100;
 //0~255之间的内存编号是系统占用的,因此不可以访问
 system("pause");
 return 0;
}

野指针:
指针变量指向的是一块非法的内存空间

#include<iostream>
using namespace std;
int main()
{
   //野指针
 //在程序中,尽量避免野指针
 int *p =(int*)0x1100;
 //cout << *p << endl;
 system("pause");
 return 0;
}

这边野指针相当于:你在外面开房,宾馆给你了一个房间的钥匙,但你确拿着这个钥匙去开一个房间
空指针和野指针都不是我们自己申请的内存空间,所以我们不能直接访问它

const修饰指针

1:const修饰指针——常量指针
2:const修饰常量——指针常量
3:const既修饰指针,又修饰常量

#include <iostream>
using namespace std;
int  main( )
{
 int a=438;
 //const修饰的是指针,指针的指向是可以更改,指针的指向的值不可以更改
 const int *p1 = NULL;
 // *p1 = 100;//报错
  p1 = &a;//正确
  cout << *p1<< endl;
 system("pause");
 return 0;
}
#include <iostream>
using namespace std;
int  main()
{
 int a = 438;
 int b = 300;
 //const修饰的是常量,指针的指向不可以更改,指针的指向的值可以更改
 int *const p1=&a;
  *p1= b ;
  cout << *p1<< endl;
 system("pause");
 return 0;
}
#include <iostream>
using namespace std;
int  main()
{
   int a = 438;
  int b = 300;
 //const修饰的是常量,指针的指向不可以更改,指针的指向的值可以更改
      const int * const p1=&a;
      // *p = 100;//错误:常量指针,指针可以更改指向,但不可以修改值
   //p = &a;//错误:指针常量,指针不可以更改指向,但可以修改值
  cout << *p1<< endl;
 system("pause");
 return 0;
} 

记忆技巧:
①:
const记忆为常量,*记忆为指针
如:
const int *p :常量指针
int const p:指针常量
②:
const修饰的是什么:看const后面有没有
,有的话修饰的是指针
const int *p:const修饰的是:指针

int * const p:const修饰的是:常量

③:
常量指针和指针变量他们两者的区分:
常量指针:指针被const修饰,*p在const后面,故其值是不可以改变,其指向是可以改变的;
指针常量:p地址被const修饰,所以其地址不可以改变,其指针指向的值是可以改变的

指针和数组

作用:利用指针来访问数组中的每一个元素


```cpp
#include <iostream>
using namespace std;
int  main()
{
    //指针和数组
 //利用指针访问数组中的元素
 int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
 /*
 cout << "数组中的一个元素:" << arr[0] << endl;
 int *p = arr;//数组名就是数组的首地址
 cout << "利用指针访问第一个元素:" << *p << endl;
 p++;//让指针向后偏移4个字节
 cout << "利用指针访问第二个元素:" << *p << endl;
 */
 /*
 int *p = arr;
 for (int i = 0; i < 10; i++)
 {
  cout << *p << endl;
  p++;
 }*/
    
    for (int *p = arr; p<=&arr[9]; p++)
    {
 cout << *p << endl;
    }
 system("pause");
 return 0;
} 

```cpp
#include <iostream>
using namespace std;
int  main()
{
    //指针和数组
 //利用指针访问数组中的元素
 int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
 /*
 cout << "数组中的一个元素:" << arr[0] << endl;
 int *p = arr;//数组名就是数组的首地址
 cout << "利用指针访问第一个元素:" << *p << endl;
 p++;//让指针向后偏移4个字节
 cout << "利用指针访问第二个元素:" << *p << endl;
 */
 /*
 int *p = arr;
 for (int i = 0; i < 10; i++)
 {
  cout << *p << endl;
  p++;
 }*/
    
    for (int *p = arr; p<=&arr[9]; p++)
    {
 cout << *p << endl;
    }
 system("pause");
 return 0;
} 

指针和函数

作用:利用指针作为函数的参数,可以修改实参的值

#include <iostream>
using namespace std;
//实现两个数组进行交换
void  swap(int a, int b)
{
   //形参
 int temp = a;
 a = b;
 b = temp;
 cout << "swap中的a = " << a << endl;
 cout << "swap中的b = " << b << endl;
}
void  swap02(int *p, int *p1)
{
 int temp = *p;
 *p = *p1;
 *p1= temp;
 cout << "swap02中的a = " << *p<< endl;
 cout << "swap02中的b = " << *p1<< endl;
}
/*int  main()
{
    //指针和函数
 //1:值传递:实参
 int  a = 100;
 int  b = 50;
 swap(a,b);
 cout << "a = " << a<<endl;
 cout << "b = " << b << endl;
 system("pause");
 return 0;
} */
int  main()
{
 //指针和函数
 //1:值传递:实参
 int  a = 100;
 int  b = 50;
 //2:地址传递
 //如果是地址传递是可以修饰实参的
 swap02(&a,&b);
 cout << "a = " << a<<endl;
 cout << "b = " << b << endl;
 system("pause");
 return 0;
} 

指针、函数以及数组实操

题目:封装一个函数,利用冒泡排序,实现对整形数组的升序排序

#include <iostream>
using namespace std;
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;
   }
  }
 }
 for (int j = 0; j < len; j++, arr++)
 {
  cout << *arr << "  ";

 }

}

int  main()
{
 int a,c = 0;
 int b = 0;
 cout << "请你输入你想排序的数组长度:" << endl;
 cin >> a;
 int * arr =&b;
 cout << "请输入数组中的值:" << endl;
 for ( int  i = 0; i < a; i++)
 { 
  cin>>c;
  *arr = c;
  cout <<"输出为:"<< *arr << endl;

  arr++;
 }
 arr = arr -  a;
 //bubblesort(arr, a);
 cout << "冒泡排序后的顺序为:" << endl;
 for (int j= 0; j < a;j++,arr++)
 {
  cout << *arr << "  ";

 }
 system("pause");
 return 0;
} 

结构体

结构体的概念及其定义

   结构体属于用户自定义的数据类型,允许用户存储不同的数据类型。 

语法:
struct 结构体名 { 结构体成员列表 };
通过结构体创建变量的方式有三种:
①:
struct 结构体名 变量名
②:
struct 结构体 变量名 = {成员1值,成员2值…}
③:
定义结构体时顺便创建变量

//结构体定义
struct Student
{
string name;//必须要有头文件#include<string>
int age;
int score;
};
//创建结构体变量
①:
struct Student liming;//这边注意一点,就是在C++中,我们进行结构体变量创建的时候,我们可以将省略struct关键字!但在结构体定义的时候不可以省略
liming.name="liming";//字符串型有双引号
liming.age = 10;
liming.score = 70;
②:
struct Student  s2 = {"王浩名",19,78};
cout<<"姓名 :"<<s2.name<<"年级 :"<<s2.age; 
③:
struct Student
{
string name;//必须要有头文件#include<string>
int age;
int score;
}s3;

注意:结构体变量可以通过操作符’’."访问成员!

结构体数组

作用:将自定义的结构体放入数组中方便维护
语法:struct 结构体名 数组名[元素个数]={{},{},{}}
当结构数组作为指针传递的时候,其本质为数组!

//定义一个结构体
struct student
{
//成员变量
string name;
int age;
int score;
};
//创建结构体数组
student nb[3]=
{
{"张三"12,54},
{"李四",23,89},
{"鬼五",23,90}
}//注意:这边每个大括号是以,隔开的
//给结构体数组中的元素赋值
nb[2].name = "王刚";
nb[2].age = 10;
nb[2].score=90;
//遍历结构体数组:
for(i=0;i<3;i++)
{
cout<<"姓名: "<<nb[2].name
    <<"年级: "<<nb[2].age
    <<"分数: "<<nb[2].score<<endl;
}

结构体指针

作用:通过指针访问结构体的成员
利用操作符:
—>可以通过结构体指针访问结构体属性

#include<iostream>
#include<string>
using namespace std;
struct student 
{
  string name ;
  int age;
  int score;
};
int main()
{ 

	//创建学生结构体变量
	student S1;
	S1.name="侯志鹏";
	S1.age = 23;
	S1.score = 67;
	//通过指针指向结构体变量
    student *p = &S1;
	p->score = 80;
	cout<<"名字 "<<p->score<<" 年龄 "<<p->age<<" 分数 "<<p->score<<endl;
system("pause");
return 0;
}

结构体做函数参数

传递方式分为两种:
①:值传递
②:地址传递

#include<iostream>
#include<string>
using namespace std;
struct student 
{
  string name ;
  int age;
  int score;
};

void addage(struct student * s1)
{
	s1->age++;//用指针传递函数的时候,其操作符为“->”
	cout<<"姓名 : "<<s1->name<<"   年级 :"<<s1->age<<"   分数: "<<s1->score<<endl;
}

int main()
{ 

	//创建结构体变量
	student S1= {"王浩明",12,34};
	//通过指针访问结构体变量
	addage(&S1);

system("pause");
return 0;
}

结构体嵌套

#include<iostream>
#include<string>
using namespace std;
struct student
{
 string name;
 int age;
 int score;
};
struct techer
{
 string name;
 int age;
 int workcard;
 struct student S1[3] ;
};
int main()
{
techer  t1={"zhubingzhang",85,110110};
t1.S1[0]={"张三",12,100};
cout << "  老师名字: "<<t1.name<<"  所带学生名字 :"<<
 t1.S1[0].name;
 }

结构体const的使用

作用:值传递的时候,虽然不会改变实参的值,但他占用内存的效率!
所以我们形参改为指针,可以减少内存空间,且调用函数时,不会复制新的副本;

void print(const struct student s1);

结构体实操

案例一:毕设项目:
一个老师带5个学生,共3个老师
要求:老师的结构体嵌套学生信息(姓名,考试分数),且要求通过封装打印函数和赋值函数来实现该功能

#include<iostream>
#include<string>
using namespace std;
struct student
{
 string name;
 int score;
};
struct techer 
{  
 string name;
 student s1[3];
};
 string a= ""; 
 double b = 0;
void assign(struct techer *t1) 
{
 for(int i=0;i<3;i++)
    { 
  cout << "请输入" << t1[i].name<< "的学生的姓名和分数 :"<<endl;
   cin>>a; 
     t1[i].s1[i].name=a;
  cin>>b;
  t1[i].s1[i].score=b; 
 } 
 } 
int main()
{
 techer t1[3];
 t1[0].name = "王浩明"; 
    t1[1].name = "许纯"; 
    t1[2].name = "侯智鹏"; 
 assign(t1);
 system("pause");
 return 0;
}

第二次书写:

#include<iostream>
#include<string>
#include<Ctime>
using namespace std;
struct student
{
 string name;
 int score;
};
struct teacher
{
 string name;
 student s1[3];
};
string a = "";
double b = 0.0;
void allocatespace(struct teacher t1[], int len)
{
 for (int i = 0; i < len; i++)
 {
  string suffix = "ABCDEFG";
  t1[i].name = "teacher_";
  t1[i].name += suffix[i];
  for (int j = 0; j < 3; j++)
  {
   t1[i].s1[j].name = "student_";
   t1[i].s1[j].name += suffix[j];
   int randroom = rand() % 100;
   t1[i].s1[j].score = randroom;
  }
 }
}
void print(teacher t1[], int len)
{
 for (int i = 0; i < len; i++)
 {
  cout << "老师的名字: " << t1[i].name << endl;
  for (int j = 0; j < 3; j++)
  {
   cout << "学生的名字: " << t1[i].s1[j].name << "  学生的分数:  " << t1[i].s1[j].score << endl;
  }
 }
}
int main()
{
 srand((unsigned int)time(NULL));
 teacher t1[3];
 int len = sizeof(t1) / sizeof(t1[0]);
 allocatespace(t1, len);
 print(t1, len);
 system("pause");
 return 0;
}

这边注意的一点是:
随机生成时间的种子

#include<Ctime>
srand((unsigned int)time(NULL));
int random=rand() % 100;

案例二:
设计一个英雄的结构体,包括成员姓名,年龄,性别;创建结构体数组,数组中存放5名英雄。通过冒泡排序算法,将数组中的英雄按照年龄进行升序排序,最终打印排序后的结果

#include<iostream>
#include<string>
using namespace std;
struct hero
{
 string name;
 int age;
 string gender;
};
int input(hero man[])
{
 string a = "否";
 int num = 0;
 int k = 0;
 do
 {
  cout << "请输入英雄的名字: ";
  cin >> man[k].name;
  cout << "请输入英雄的年纪: ";
  cin >> man[k].age;
  cout << "请输入你英雄的性别: ";
  cin >> man[k].gender;
  cout << "是否继续键入英雄:   ";
  cin >> a;
  k ++;
  num++;
 } while (a=="是");
 return num;
}
void order(hero  man[], int len)
{
 for (int i = 0; i < len - 1; i++)
 {
  for (int j = 0; j < len - i - 1; j++)
  {
   if(man[j].age>man[j+1].age)
   { 
    string  tempname;
    int tempage;
    tempage = man[j].age;
    man[j].age = man[j + 1].age;
    man[j + 1].age = tempage;
    tempname = man[j].name;
    man[j].name = man[j+1].name;
    man[j+1].name = tempname;
    string tempgender;
    tempgender= man[j].gender;
    man[j].gender = man[j + 1].gender;
    man[j + 1].gender = tempgender;
   }  
  }
 }
}
void print(hero man[], int len)
{
 for (int i = 0; i < len; i++)
 {
  cout << man[i].name << "  "<<man[i].age<<"  "<<man[i].gender<<endl;
 }
}
int main()
{
 hero man[1000];
 int len = input(man);
 order(man, len);
 print(man, len);
 system("pause");
 return 0;
}

上面有一个地方可以简略,由于相关概念还没学习,不做解释,不过大家可以依葫芦画瓢:

struct hero
{
 string name;
 int age;
 string gender;
};
void order(hero  man[], int len)
 {
 for (int i = 0; i < len - 1; i++)
 {
  for (int j = 0; j < len - i - 1; j++)
  {
   if(man[j].age>man[j+1].age)
   { 
    struct hero temp;
     temp = man[j];
     man[j] = man[j+1];
     man[j+1] = temp; 
   }
  }
  }
 }

到现在为此,c++学习的第一阶段完成了,即是你完成了初步入门,即将一起开启第二阶段

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值