一、数据类型
1、整型
(1)整型int
内存占用:4字节
范围:-231~231-1
(2)短整型short
内存占用:2字节
范围:-215~215-1
(3)长整型long
内存占用:Windows系统4字节,Linux系统4字节(32位)或8字节(64位)
范围:-231~231-1
(4)长长整型long long
内存占用:8字节
范围:-263~263-1
2、浮点型
(1)float
内存占用:4字节
有效数字:7位
(2)double
内存占用:8字节
有效数字:15~16位
3、字符型
(1)char
内存占用:1字节(会将对应ASCII码放入存储单元)
注:定义时要用单引号
char ch='a';
4、字符串型
(1)C风格:
char ch="abcd";
(2)C++风格
#include<string>
string str="abcd";
注:
字符串常量常以“\0”作为结束符,但在字符串常量存放到字符串变量时,只存放字符串本身而不包括“\0”。
在读取操作时,string对象会自动忽略开头的空白(即空格符、换行符等),并从第一个真正的字符开始读起,知道遇到下一个空白为止。
5、布尔型
(1)bool
内存占用:1字节
只有True和False两种结果,其中True=1,False=0
sizeof关键字
利用sizeof(数据类型/变量)可统计数据类型所占空间大小
二、常量
1、#define宏常量
通常在文件上方定义
#define 常量名 常量值
2、const修饰变量
const 数据类型 常量名=值
三、输入输出
头文件:
#include<iostream>
#include<cstdio>
1、cin和cout
cin>>a;
cout<<a;
注:cin输入以空格作为分界,适用于输入内容无空格时
2、scanf和printf
scanf("%d %d",&a,&b);
printf("%d %d",a,b);
%d:传入一个十进制整数
%lld:传入一个长整型数
%c:传入一个字符
%s:传入一个字符串
%f:传入一个单精度浮点数
%lf:传入一个双精度浮点数
3、字符串的输入输出
(1)cin和scanf输入
接收一个字符串,遇到空格和tab键结束接收,回车键表示输入结束;
(2)cin.get(),getchar()输入字符
接收第一个字符并赋值给变量,不论第一个字符是空格、tab键抑或是回车键。
(3)cin.get(字符数组名,接收字符数)输入字符串
cin.get()接收一行字符串包括空格和tab键(接收数量需减一,留一个位置给‘\0’)
(4)cin.getline()输入字符串
与cin.get()区别在于当cin.getline()传入第三个参数时cin.getline(a,20,’f’),接收字符串到’f’为止
(5)getline()输入字符串
getline(cin,字符串名字),getline()接收一个字符串,包括空格与tab键,唯一要注意的是,getline()属于string流,需要头文件#include,求字符串长度时不能用strlen(),应该用str.length()。
(6)gets_s()输入字符串
gets_s(字符串名字)输入字符串可以接收空格和tab键,回车结束
注意:
所有字符串的输入(包括cin.get()、cin.getline()、getline、gets_s),如果接在cin>>a输入流后,中间必须增加cin.ignore()用以吞掉换行符。
四、选择结构
1、if语句
(1)if(条件){语句}
(2)if(条件){语句}
else if(条件){语句}
else{语句}
2、switch语句
switch(表达式)
{case1 结果1:执行语句;break;
case2 结果2:执行语句;break;
default:执行语句;break;}
五、循环结构
1、while
while(循环条件){语句}
当循环条件为真时一直执行
2、do…while
do{循环条件}while(循环条件);
do…while语句会先执行一次循环语句再判断循环条件
3、for
for(起始表达式;条件表达式;末尾循环体){语句}
4、退出循环
(1)break
常用于退出选择结构或循环结构
(2)continue
跳过本次循环未执行的语句,继续执行下一次循环
六、一维数组
1、数组特点
元素都是相同的数据类型,数组是由连续的内存位置组成的
2、定义方式
int a[5];
int a[5]={1,2,3,4,5};
int a[]={1,2,3,4,5};
注:初始化数据时若没有填满会用0补充,定义数组时必须有初始长度
3、一维数组名的使用
(1)计算数组长度len
int a[5]={1,2,3,4,5};
len=sizeof(a)/sizeof(a[0]);
sizeof(a):整个数组占的内存空间
sizeof(a[0]):每个元素占的内存空间
(2)获取数组首地址
int a[5];
cout<<a;
cout<<&a[0];\\第一个元素的地址
七、二维数组
1、定义方式
int a[2][3];
int a[2][3]={
{1,2,3},
{4,5,6}};
int a[2][3]={1,2,3,4,5,6};
int a[][3]={1,2,3,4,5,6};
2、二维数组名的使用
(1)计算行数列数
hang=sizeof(a)/sizeof(a[0]);
lie=sizeof(a[0])/sizeof(a[0][0]);
(2)查看首地址
int a[5][5];
cout<<a;
cout<<&a[0];\\第一行的首地址
cout<<&a[0][0];\\第一个元素的地址
八、指针
可以使用指针间接访问内存,也可以用指针变量保存地址
1、定义方式
int *p;
p=&a;
int *p=&a;
在32位操作系统下,指针占用4个字节,64位操作系统下指针占用8个字节
2、空指针与野指针
(1)空指针:指针变量指向内存中编号为0的空间
用途:初始化指针变量
int *p=NULL;
(2)野指针:指针变量指向非法内存空间
在程序中应当避免出现野指针
注:(1)空指针指向的内存是不可访问的
(2)0~255之间的内存编号是系统占用的,不可访问
(3)不要访问空指针和野指针
3、const与指针
(1)常量指针:const修饰指针
const int *p=&a;
指针指向可修改,但指针指向的值不能改变
int a=10;
const int *p=&a;
*p=20;\\错误
p=&b;\\正确
(2)指针常量:const修饰常量
int *const p=&a;
指针指向不可修改,但指针指向的值能改变
int a=10;
int *const p=&a;
*p=20;\\正确
p=&b;\\错误
(3)const既修饰指针也修饰常量
const int *const p=&a;
指针指向和指针指向的值都不可改变
4、指针与数组
(1)一维数组的地址
int a[10];
a\\数组首地址
&a[0]\\数组首地址
&a\\整个数组的地址
&a+1\\跳过整个数组,指向数组末尾处
(2)二维数组的地址
二维数组首地址/第一个元素地址:a[0]或&a[0][0]
二维数组第0行地址:a[0]或a或*(a+i)
二维数组第i行地址/第i行首元素地址:a[i]或a+i或&a[0]+i或*(a+i)
二维数组第i行第j列元素地址:&a[i][j]或*(a+i)+j(解引用:((a+i)+j)
整个数组的地址:&a,&a+1会跳过整个数组,指向数组末尾处
(3)利用指针遍历数组
一维:
int a[5]={1,2,3,4,5};
int *p=a;
for(int i=0;i<5;i++){
cout<<*p<<endl;
p++;}
二维:
int a[3][4]={{1,2,3,4},
{5,6,7,8},
{9,10,11,12}};
int *p=a[0];
for(int i=0;i<3;i++){
for(int j=0;j<4;j++){
cout<<*p<<" ";
p++;
}
cout<<endl;
}
九、函数
1、语法
(1)定义
返回值类型 函数名(形参)
{函数体
return 表达式}
没有返回值则返回值类型为void
(2)调用
函数名(实参)
(3)接收返回值
数据类型 变量名=函数名(实参)
2、值传递
函数调用时实参将数值传给形参,形参发生改变,实参不变
void swap(int a,int b){
int temp=a;
a=b;
b=temp;
cout<<"a1="<<a<<" "<<"b1="<<b<<endl;}
int main(){
int a=10;
int b=20;
swap(a,b);
cout<<"a2="<<a<<" "<<"b2="<<b<<endl;
system("pause");
return 0;}
运行结果为:
a1=20 b1=10
a2=10 b2=20
3、地址传递
实参会发生改变
void swap(int *p,int *q){
int temp=*p;
*p=*q;
*q=temp;}
int main(){
int a=10;
int b=20;
swap(&a,&b);
cout<<"a="<<a<<" "<<"b="<<b<<endl;
system("pause");
return 0;}
运行结果为:
a=20 b=10
4、函数的默认参数
(1)语法
返回值类型 函数名 (参数=默认值){}
(2)作用
如果传入了数据,就用传入的数据,如果没有则用默认值
(3)注意事项
如果某个位置已经有默认参数,那么这个位置往后,都必须有默认值
int func1(int a,int b=10,int c);//错误
int func2(int a,int b=10,int c=20);//正确
如果函数声明有默认参数,那么函数的实现中就不能有默认参数,二者只能有一个有默认参数
错误示范:
int func(int a=10,int b=10);
int func(int a=10,int b=10){}
正确示范
int func(int a=10,int b=10);
int func(int a,int b){}
5、占位参数
(1)语法
返回值类型 函数名 (数据类型){}
void func(int a,int){}
void func(int a,int=10){}//占位参数也可以有默认参数
6、函数重载
(1)作用:
函数名可以相同,提高复用性
(2)条件:
a.在同一作用域下
b.函数名相同
c.函数参数类型不同,或个数不同,或数据不同
注:函数返回值不能作为函数重载的条件
(3)引用作为重载条件
void func(int &a){}
void func(const int &a){}
int main(){
int a=10;
func(a);//运行第一个函数
func(10);//运行第二个函数
return 0;
}
(4)重载与默认函数
void func1(int a,int b=10){}
void func2(int a){}
int main(){
func1(10);//会造成混淆,要避免这种情况
return 0;
}
7、函数模板
函数模板适用于函数参数的个数相同而类型不同,且函数体相同的情况。
template<typename T> //常用
template<class T>
template<typename T>
T max(T a,T b) //用T作虚拟类型名
{
if(a>b)
{
return a;
}
else
{
return b;
}
}
8、内置函数
在编译时将所调用的函数代码嵌入主调函数中,能提高运行效率,这种嵌入主调函数中的函数称为内置函数。适用于规模很小且使用频繁的函数。
inline int max(int a,int b)
{
if(a>b)return a;
else return b;
}
十、结构体
结构体属于用户自定义的数据类型,允许用户存储不同数据类型
1、语法
定义:
struct 结构体名{结构体成员列表};
通过结构体创建变量:
(1)struct 结构体名 变量名;
(2)struct 结构体名 变量名={成员1,成员2,…,成员n};
(3)定义结构体时顺便创造变量:
struct 结构体名{结构体成员列表}变量名;
可通过”.“访问结构体中的成员
2、结构体数组
struct 结构体名 数组名[元素个数]{{},{},…,{}};
遍历:
struct student{
string name;
int score;};
int main(){
struct student a[3]={
{"张三",80},
{"李四",90},
{"王五",88}};
for(int i=0;i<3;i++){
cout<<a[i].name<<" "<<a[i].score<<endl;}
return 0;}
3、结构体指针
struct student *p=&s;\\定义
cout<<p->name;\\访问
4、结构体与函数
(1)值传递
void a(struct student s){}
(2)地址传递
void a(struct student *s){}
5、其他注意点
(1)结构体数组交换
struct a b[5];
struct a temp=b[1];
b[1]=b[2];
b[2]=struct a temp;
(2)不允许对结构体本身递归定义
(3)定义结构体类型,只是说明了该类型的组成情况,并没有给它分配存储空间,就像系统不为int类型本身分配空间一样。只有当定义属于结构体类型的变量时,系统才会分配存储空间给该变量
(4)结构体变量占用的内存空间是其成员所占内存之和,而且各成员在内存中按定义的顺序依次排列
(5)相同类型的结构体变量之间可以进行整体赋值
struct Student stu2 = stu1;