sizeof关键字
@sizeof可以用来获得类型所占的字节大小
@sizeof的用法
int i=1;
cout<<sizeof(i)<<endl;
cout<<sizeof(int)<<endl;
浮点型
@ 浮点型类型
float占用4个字节,有效小数7个
doblue占用8个字节,有效小数15~16个
@ float赋值注意
float赋值的最后没有加f否者会转换成doblue类型
@ 科学计数法
@@ 使用规则
float a=3e2;意思就是3乘以10的二次方
字符型
@ 字符型语法与声明
char a=‘a’;
只能写下一个字符不能写一个以上的任何的字符
只能用单引号’’
@ 字符类型对应的编码
每个字符都对应着相应的编码
比如ascii码
utf-8码
@@ 强转
char a='o';
cout<<(int)o<<endl;
转义字符
@ 常用的转义字符
\n换行
\t水平制表
\反斜杠
字符串类型
@ 延续c语言的数组版的字符串
char a[]=“123456789”;
@ C++版字符串
string b=“987654321”;
@@ 使用c++类型的字符串要包含相应的头文件
#include<string>
布尔类型bool
@ bool只有两个值
true真(本质是1)
false加(本质是0)
数据的输入
@ 关键字cin
@@ cin的使用
include<string>
string a;
cin>>a;
运算符
+加
-减
*乘
/除
%取余
i++前置递增
++i后置递增
i–前置递减
–i后置递减
赋值运算符
=//a=b
+=//a=a+b
-=//a=a-b
=//a=ab
/=//a=a/b
%=//a=a%b
比较运算符
如果是真就是1
如果是假就是0
==等于
!=不等于
<小于
>大于
<=小于等于
>=大于等于
@ 比较运算符输出
int a=5;
int b=10;
cout<<(a>b)<<endl;//这里的括号是优先级
逻辑运算符
!逻辑非//如果a为假的那么a就是真
&&逻辑与//如果a与b都为真,结果就是真,否则再而假
||逻辑或//只要有一个是真即为真否则为假
流程控制
— C++最基本的三个结构
顺序结构:程序按顺序执行,不发生跳转
选择结构:依据条件是否满足,有选择的执行相应功能
循环结构:依据条件是否满足,循环多次执行某段代码
选择结构
@ 单行if语句
int fenVshu = 100;
if(fenVshu==100)
{
cout<<"恭喜考上第一名";
}
— 只有达成判断语句条件才能显示,不满足就会跳过
@@ 多行if语句
@@ 多行if语句的语法else关键字的使用
if(条件)
{
条件满足执行的语句
}else{
条件不满足时候的语句
}
— 条件为假的时候就执行else语句块中的语句
int fenVshu=100;
if(fenVshu>=){
cout<<"恭喜你考上第一名"<<endl;
}else{
cout<<"恭喜你考上第三名"<<endl;
}
@@ 多条件语句else if
if(条件满足){
条件满足的时候执行的语句
}else if(条件1){
条件1被满足执行的语句
}else if(条件2){
条件2被满足的时候执行的语句
}else{
都不满住的时候执行的语句块
}
@ switch选择语句
— switch的语法
switch(表达式)
{
case 结果1:执行语句;break;
case 结果2:执行语句;break;
case 结果3:执行语句;break;
default:执行语句;break;
}
— switch的用法
int daVfen = 0;
cin>>daVfen;
switch(daVfen)
{
case 10:
cout<<"极品"<<endl;
break;
case 9:
cout<<"佳作"<<endl;
break;
case 7:
cout<<"普通"<<endl;
break;
case 5:
cout<<"一般"<<endl;
break;
default:
cout<<"烂片"<<endl;
break;
}
— break是跳出的意思
— switch如果没有加break;那么就会那个值的下面的所有的值都会打印出来
比如case 10那么从case 10一直到default之间的所有语句块都会被输出来
— default是以外的值
— switch括号中的是变量而不是表达式
—case的值只能是数值而不是条件表达式
循环结构
@ while循环语句
— while的语法
while(循环条件)
{
循环语句
}
— while的使用
int a= 0;
while(a<10)
{
cout<<a<<endl;
a++;
}
—while循环语句里如果条件是1那么就是真就会进入无限循环
0即为假直接跳出
— do……wihle语句
— do……wihle语法
do{
循环语句
}while(条件语句)
— do……wihle循环会限制性一次循环语句块当中的代码,再来判断条件语句
— 循环语句的变量是在外面声明的
— do……while循环的使用
int a=0;
do
{
cout<<a<<endl;
}while(a<10);
@ for循环语句
— for循环的语法
for(定义一个变量;条件表达式;变量的前++或后++)
{
循环语句;
}
— for循环的使用
for(int a=0;a<10;a++)
{
cout<<a<<endl;
}
定义变量之后判断a是否等于10如果不等于10就输出代码块中的代码,然后是a++
以此直到a=10为止否则会一直循环
跳转语句
@ break语句
— break是终止跳出的选择语句和选择语句还有嵌套循环语句中
@ continue语句
— continue是跳过某一个条件的语句
— continue的使用
for(int a=0;a<100;a++)
{
if(a == 51)
{
continue;
}
cout<<a<<endl;
//这里循环到a的值刚好是51就不会执行cout<<a<<endl;这个语句
//直接跳过继续a++然后输出语句块当中的代码
}
@ goto语句
— goto是可以无条件跳转语句
— goto语法
goto 标记
— goto解释
如果标记名称存在,执行到goto语句时,就会跳转到标记的位置
— goto标记的使用
goto FLAG
cout<<"1"<<endl;
cout<<"2"<<endl;
cout<<"3"<<endl;
cout<<"4"<<endl;
FLAG ;
cout<<"5"<<endl;
//cout<<"1"<<endl;1到4都会被跳过直接输出5
数组
数组就是一个集合,里面存放了相同的类型的数据元素
— 数组里面的所有数据元素都是相同类型
— 素组是由连续的内存位置组成的
— 素组下标索引是从0开始的
— 可以通过下标可以用来访问素组中的元素
@ 数组的定义
数据类型 数组名[数组长度];
数据类型 数组名[数组长度] = {值1,值2 ...};
数据类型 数组名[]={值1,值2...};
第一种
int shuVzu1[5];
cout<<shuVzu[0]<<endl;
cout<<shuVzu[1]<<endl;
cout<<shuVzu[2]<<endl;
cout<<shuVzu[3]<<endl;
cout<<shuVzu[4]<<endl;
第二种
int shuVzu2[5]={11,22,33,44,55};
cout<<shuVzu2[0]<<endl;
cout<<shuVzu2[1]<<endl;
cout<<shuVzu2[2]<<endl;
cout<<shuVzu2[3]<<endl;
cout<<shuVzu2[4]<<endl;
第三种
int shuVzu3[]={11,22,33,44,55,66,77,88,99};
cout<<shuVzu3[0]<<endl;
cout<<shuVzu3[1]<<endl;
cout<<shuVzu3[2]<<endl;
cout<<shuVzu3[3]<<endl;
cout<<shuVzu3[4]<<endl;
cout<<shuVzu3[5]<<endl;
cout<<shuVzu3[6]<<endl;
cout<<shuVzu3[7]<<endl;
cout<<shuVzu3[8]<<endl;
@ 获取数组的总体长度函数sizeof
— 如果一个类型是四个直接那么如果有十个变量在数组里面就是十个四字节
— sizeof的使用
int shuVzu[]={0,1,2,3,4,5,6,7,8,9};
cout<<sizeof(shuVzu)<<endl;
cout<<sizeof(shuVzu[2])<<endl;
— 如果想知道数组中的某一个变量那么就在方括号里输入它的坐标位置
— 输出得出数组的个数
cout<<sizeof(shuVzu)/sizeof(shuVzu[0])<<endl;
@ 获取数组的首地址
— 用法
cout<<shuVzu<<endl;
— 输出的地址都是十六进制的如果要转成十进制的需要加一个被括号扩起来的(int)
cout<<(int)shuVzu<<endl;
— 获取数组中某个变量的地址值
如果需要获得数组中某个变量的地址就要在前面加一个&符号
cout<<&shuVzu[0]<<endl;
— 数组的地址是一个常量不可以修改
二维数组
— 二维数组就像是蛋托,蛋托的一排就普通数组,蛋托的一列就是二维数组
— 数组的四种定义方式
数据类型数组名[ 行数][列数];
int a[2][3]
数据类型数组名[行数][列数]={{数据1,数据2},{数据3,数摑4}};
int b[2][3]=
{
{1,2,3},
{4,5,6}
};
数据类型数组名[ 行数][列数] = {数据1,数据2,数据3,数据4};
int c[2][3]={1,2,3,4,5,6};
数据类型数组名[ ][ 列数] = {数据1,数据2,数据3,数据4};
int d[][3]={1,2,3,4,5,6};
//系统会默认列数分配
— 二位数组的赋值
a[1][0]=1;
a[1][1]=2;
a[1][2]=3;
a[2][0]=4;
a[2][1]=5;
a[2][2]=6;
…………………………
函数
@ 函数的作用
— 将一些可以重复利用的代码封装起来,减少代码量
— 大型程序由若干个程序块来实现特定功能
@ 函数的定义
返回值类型 函数名 参数列表
函数体语句
return 表达式
— 函数定义的语法
int hanVshuVdingVyi(int a,int b)
{
int c = a+b/2;
return c;
}
— return是返回语句,谁调用就返回给谁
— 括号里是形参
是用来接收调用该函数时传递的参数
@ 函数的调用
int jiaVfaVhanVshu(int X,int Y )
{
int xiangVjia= x+y ;
return xiangVjia;
}
int main()
{
int a=10;
int b=20;
int c=jiaVfaVhanVshu(a,b);
}
— 实参
在main函数中定义的a和b是有实体的
通过c调用jiaVfaVhanVshu函数把值放在括号里a和b传递给X和Y这就是实参
— 形参
在jiaVfaVhanVshu的函数的括号里的X与Y没有实体只有被传递的时候才有值所以叫形参
@ 值传递
— 形参如果发生了变化,并不会改变实参里面的值
实参只是把值传递给了形参,他们之间并没有任何关联
形参会开放单独的x与y的内存空间与外面的两个变量的内存空间是独立的
传进去的值只是复制给力X与Y,X与Y怎么变都不会改变外面的实参
@@ void一个不需要返回值的类型
— void的返回值
void的返回值只需要一个return;
不能有其他的返回值比如:
void wuVfanVhuiVhanVshu(int a,int b)
{
return 100.
}
这是一个错误的方法他只能写return ;
— 因为返回值类型不匹配
— 当返回值不需要的时候可以不写return
@ 函数的常见样式
— 函数的四种常见样式
无参无返
wcwf()
{
cout<<"hello world"《《endl
}
wcwf();//调用语句
有参无返
void ycwf(int a)
{
cout<<a<<endl;
}
ycwf(100);//调用语句
无参有返
int wcyf()
{
return 1000;
}
int b =wcyf();//调用语句
有参有返
int ycyf(int x)
{
return x/2;
}
int b=100;
int a=ycyf(b);//调用语句
@ 函数的声明
— 函数声明的作用
告诉编译器函数名称及如何调用函数。
实际的函数主体可以单独定义
— 函数的声明可以多次,但是函数只能定义一次
自定义的函数不能写作main函数下面,因为代码是一行一行执行的
但是可以告诉编译器有这个函数
假设有一个函数叫niVzhaoVbuVdaoVwo(int a,int b);
只要在所有函数的上面输入一行niVzhaoVbuVdaoVwo(int a,int b);这个语句就行
— niVzhaoVbuVdaoVwo(int a,int b);这样的语句可以多次声明
@ 函数的分文件编写
—能让作用让代码结构更加清晰
— 函数分文件编写有4个步骤
创建后缀名为.h的头文件文件
创建后缀名为.cpp的源文件
在头文件中写入函数的声明
在源文件中写函数的定义
— 创建文件
在解决方案资源管理器中的头文件中右键添加新建项目
命名为fenVwenVjian.h的头文件 //假设
再在解决方案资源管理器中的源文件中创建一个fenVwenVjian.cpp的文件
然后再在fenVwenVjian.h头文件里引用方法
假设有一个叫yingVyongVtouVwenVjian(int a,int b);的函数
就在fenVwenVwenVjian.h的文件里直接输入
yinVyongVtouVwenVjian(int a,int b);就行
然后再在fenVwenVjian.cpp里
在最上面输入导入头文件语句#include “fenVwenVjian.h"就好了。
当然如果要是用输入输出也得要引入#include的头文件
还有using namespace std;
在主文件里如果想使用就要包含那个头文件
记住自定义的头文件是”"双引号括起来的C++自带的才能使用尖括号<>
指针
@ 指针的作用
— 指针可以间接访问内存
— 内存里都是有地址编号的从0开始记录
— 用十六进制数字来表示编号
— 可以用指针来记录编号
— 创建int内存的时候就相当于在内存里找了一个4个空间的大小
假设这个int a里存入了10的变量
如果想要操作这个内存空间可以用变量a来操纵
— 为什么有变量的存在
因为在内存中都有它的内存地址编号
比如0x00FF//这是随便写的
就像这样如果每创建一个数据值都去记住一个地址编号
这样就很难记忆所以就有了变量
— 如果知道知道地址值的编号是多少也可以拿到数据
可以再创建一个变量来存放地址
当然这个变量就是指针变量
简单的说指针就是地址
@ 定义指针
数据类型 * 指针变量;
int a=100;
int *p;
— 让指针与建立关系记录地址
p = &a ;
cout<<p<<endl;
— 在定义指针的时候直接可以建立关系
int * p=&a;
@ 使用指针
指针可以通过解引用的方式来找到指针指向的内存
— 解引用
在指针前面加一个*号
p
找到指针指向的内存
— 解引用理解
如果cout输出p那么就是a的内存地址
如果cout输出的是p那么输出的就是变量a的值
@ 指针占的内存
— 在32位下
在32位下所有指针都占用4个字节
— 在64位下
在64位下占用8个字节
— 查看指针占用多少直接
cout<<sizeof(int *)<<endl;
cout<<sizeof(p)<<endl;
@ 空指针
— 指针指向空间为0的地址空间
— 用来初始化指针
— 空指针是没有权限访问的
— 空指针的初始化
一般情况下空指针的赋值是NULL;
NULL在程序中代0
— 空指针不可解引用等访问
int *p = NULL;
*p=1;
这个是错误的代码
解引用就相当于控制变量
但是0这个区域地址编号是不允许被任何人操作的
— 0~255之间的所有地址编号都是由系统控制使用的
@ 野指针
野指针就像是孩子非常野缺乏管教
比如偷拿妈妈的化妆品化妆
偷父母的钱去花等等
再比如开门走错楼栋了,怎么用自己家的要是死活也打不自己家的门(别人家的)
指针指向的地址越界了只想了一个非法的内存空间
— 指向了一个没有被申请到的空间
int *a=0x07FF;
没有得到申请的空间指针是不能操作它的
@ const修饰指针
— const修饰指针三种情况
const修饰指针————常量指针
const修饰指针————指针常量
const及修饰指针,又修饰常量
@@ 常量指针的特点
int a=10;
int b=10;
int *p=&a;
指针的指向可以修改只有指向的值不可以修改
p指向了a还可以再次指向b但是不可以修改他们里面的值
p=&b;
这是对的
假设p已经指向了b
*p=20;
通过*号解引用进行指向变量的操作是不可以的
@@ 指针常量
指针指向的内存地址不可以改,指针指向的变量的值可以改
int a=1;
int b=2;
int * const p=&a
*p=3;//正确
p=&b;//错误
@@ 又修饰指针又修饰常量
指向内存地址和指向的内存变量都不可以修改否则都是错误的
int a=100;
int b=200;
const int const *p=&a;
*p=101;错误
p=&b;错误
@指针和数值
— 作用
用来访问数组中的每个元素
int shuVzu[10]={1,2,3,4,5,6,7,8,9,10};
int *p=shuVzu;
cout<<*p<<endl;
*p解引用指向的shuVzu的首地址的变量
只要++p指针就会往右移动四个字节指向数组中的第二个变量
@ 指针和函数
就是吧变量取地址传进函数形参里面去
void diVzhiVchuanVdi(int *x,int *y)
{
int beiVzi=*x;
*x=*2;
*y=beiVzi;
}
int main()
{
int a=10;
int b=20;
diVzhiVchuanVdi(&a,&b);
return 0;
}
在传递的时候一定要加上取地址符&
beiVzi这个变量使用取地址获取了指针X指向的变量;
x与y都使用了号解引用的来通过x与y个指向地址的变量来进行一个被赋值和一个被取值
y使用号来解引用指向内存地址指向的变量直接通过beiVzi这个变量进行赋值
结构体
— 结构体属于用户自定义的数据类型
— 允许用户存储不同的数据类型
— 自定义数据类型,一些类型集合组成的一个类型
@ 结构体定义和使用
— 语法
struct 结构体名字 变量名
{
结构体成员列表
};
— 结构体的最后一定要加上一个;分号
— 结构体的使用
struct xueVsheng
{
string xingVming;
int nianVling;
char xingVbie;
};
— 创建结构体变量
第一种创建初始化
xueVsheng a;
a.xingVming="小刘";
a.nianVling="18";
a.xingVbie='男';
第二种创建初始化
xueVsheng b={"张三",18,'男'};
第三种创建初始化
在结构体分号与右半边的大括号之间的夹缝中创建一个自定义变量
struct xueVsheng2
{
string xingVming;
int nianVling;
char xingVbie;
}c;
c.xingVming="老王";
c.nianVling=27;
c.xingVbie='男';
— 结构体语句输出
cout<<"姓名"<<c.xingVming<<"年龄"c.nianVling<<"性别"<<c.xingVbie<<endl;
@ 结构体指针
— 可以挺过指针访问结构体中的成员
— 利用->操作符可以通过结构体指针访问结构体属性
struct xueVsheng
{
string xingVming;
int nianVling;
char xingVbie;
};
int main()
{
xueVsheng a={"小红",17,'女'};
xueVsheng *p=&a;
cout<<"姓名"<<p->xingVming<"年龄"<<p->nianVling<<"性别"<<p->xingVbie<<endl;
return 0;
}
@ 结构体嵌套结构体
— 结构体中的成员可以是另一个结构体
— 可以使用别的结构体成为这个结构体的成员
— 要嵌套哪个结构体就要在这个结构体的上面定义好那个结构体
struct xueVsheng
{
string xingVming;
int nianVling;
char xingVbie;
int fenVshu;
};
struct banVzhuVren
{
string laoVshi;
int nianVling;
char xingVbie;
struct xueVsheng fuVdao ;
};
int main()
{
abanVzhuVren a;
a.laoVshi="张美老师";
a.nianVling=23;
a.xingVbie='女';
a.fuVdao.xingVming="刘子墨";
a.fuVdao.nianvling="13";
a.fuVdao.xingVbie='男';
a.fuVdao.fenVshu=98;
}
@ 结构体的函数参数
— 将结构体作为参数向函数中传递
— 传入的方式有两种
— 值传递
值传递不会导致实参改变
void jgths(struct xueVsheng x)
{
x.nianVling=19;
cout<<x.xueVsheng<<x.nianVling<<x.xingVbie<<ednl;
}
struct xueVsheng
{
string xingVming;
int nianVling;
char xingVbie;
};
int main()
{
xueVsheng a;
a.xingVming="张三";
a.nianVling=15;
a.xingVbie='男';
jgths(a);
}
x与main函数里的a是两个不同的内存地址
— 地址传递
如果形参发生改变实参也会发生相应的改变
void jgths(struct xueVsheng *p)
{
cout<<p->xingVming<<p->nianVling<<p->xingVbie<<endl;
}
struct xueVsheng
{
string xingVming;
int nianVling;
char xingVbie;
};
int main()
{
xueVsheng a;
a.xingVming="张三";
a.nianVling=15;
a.xingVbie='男';
jgths(&a);
}
jgths的这个类里的p与main函数的a通过指针连接着的所以p改a也会改变数值
@ 结构体的const应用场景
— 用const来防止误操作
void jgths(const xueVsheng *p)
{
//p->nianVling=20;//这就是错误的
cout<<p->xingVming<<p->nianVling<<p->xingVbie<<endl;
}
struct xueVsheng
{
string xingVming;
int nianVling;
char xingVbie;
};
int main()
{
xueVsheng a;
a.xingVming="张三";
a.nianVling=15;
a.xingVbie='男';
jgths(a);
}
— 使用指针结构体形参会改变实参
— 如果加上const xueVsheng x就不能再修改了只能输出打印
— 这样做的方法就是为了减少创建内存的占用量
— 因为指针占用的内存字节少