目录
一:std标准命名空间
using namespace std; //std标准命名空间 示例
#include<iostream> //C++输入输出库
using namespace std; //std标准命名空间
int main()
{
//std::(域运算符号)<<内容<<
std::cout<<"hello C++"<<endl;//hello C++
return 0;
}
endline 换行 打印出变量i的值为5 示例
#include<iostream> //C++输入输出库
using namespace std; //std标准命名空间
int main()
{
int i=5;
cout<<i<<endl; //endline 换行
return 0;
}
控制台输出全局变量 使用域运算符 如cout<<::i<<endl; 示例 可以打印全局变量i的值100
#include<iostream> //C++输入输出库
using namespace std; //std标准命名空间
int i=100; //全局变量
int main()
{
int i=5; //局部变量
cout<<i<<endl;
cout<<::i<<endl; // 域运算符变量名--全局变量
//类去访问成员变量中也使用到域运算符 类::成员变量
return 0;
}
二:自定义命名空间
自定义命名空间 应用场景:项目开发中使用变量 函数重叠-如下相同的变量名a
示例如下
#include<iostream> //C++输入输出库
using namespace std; //std标准命名空间
namespace sa //自定义命名空间:项目开发中使用变量 函数重叠
{
int a=100;
void cprint()
{
cout<<a<<endl;
}
}
namespace sc
{
int a=200;
void cprint()
{
cout<<a<<endl;
}
}
int main()
{
sa::cprint();//100
sc::cprint();//200
return 0;
}
通过自定义命名空间,对于相同的变量名a,仍然可以输出不同的值
三:bool数据类型
bool数据类型设置标志位 true 为真 输出值为1 C++中的bool数据类型 非0都是真
#include<iostream> //C++输入输出库
using namespace std; //std标准命名空间
void demo_bool();
int main()
{
demo_bool();
return 0;
}
void demo_bool()
{
bool flag = true;//真
if(flag)//如果为真
{
cout<<"是真的"<<flag<<endl; //是真的1
}
else
{
cout<<"假的"<<flag<<endl;
}
}
bool数据类型设置标志位 false 为假 输出值为0
#include<iostream> //C++输入输出库
using namespace std; //std标准命名空间
void demo_bool();
int main()
{
demo_bool();
return 0;
}
void demo_bool()
{
bool flag = false;//假
if(flag)
{
cout<<"是真的"<<flag<<endl;
}
else
{
cout<<"假的"<<flag<<endl;//假的0
}
}
四:结构体位段
位段的处理:
int year:20;
int month:4;
int day:6
打印出 4字节
结构体位段 设置合理:能够使得结构体内存分配的使用变得更加合理
设置结构体位段 不超过32,结构体内存占用为4字节,示例如下
#include<iostream> //C++输入输出库
using namespace std; //std标准命名空间
typedef struct date_t //定义时间结构体
{
int year:20; //4个字节是2的31次方(32位)
int month:4; //2的4次方 16 最多才12月
int day:6; //2的5次方 32 最多31天
//20+4+6=30 一共30位 不超过32->4字节
}DATE_T;
int main()
{
cout<<sizeof(DATE_T)<<"字节"<<endl;//4字节
return 0;
}
设置结构体位段 超过32,结构体内存占用为8字节 ,示例如下
由此可见,结构体位段设置合理,可以有效节省结构体的内存占用,节省内存
#include<iostream> //C++输入输出库
using namespace std; //std标准命名空间
typedef struct date_t
{
int year:20; //2的20次方
int month:8; //2的8次方
int day:6; //2的6次方
//20+8+6=34 超过32 -> 8字节
}DATE_T;
int main()
{
cout<<sizeof(DATE_T)<<"字节"<<endl;//8字节
return 0;
}
五:强制类型转换
如下:
将char数据类型强制转换为int数据类型
将char数据类型强制转换为bool数据类型 [C++中bool数据类型 非0都是真 输出值为1]
#include<iostream> //C++输入输出库
using namespace std; //std标准命名空间
int main()
{
char c='a';
cout<<(int)c<<endl; //强制转化 97
//把c转为bool类型
cout<<static_cast<bool>(c)<<endl; //1 非0都是真
return 0;
}
六:动态分配内存
C的动态分配内存空间 示例
指针变量定义并初始化NULL
malloc动态开辟内存空间
内存初始化memset
对开辟并初始化的内存空间操作,如 赋值
程序员手动释放内存空间free
#include<iostream> //C++输入输出库
using namespace std; //std标准命名空间
void demo_space();
int main()
{
demo_space();
return 0;
}
void demo_space()
{
int *p=NULL;
p=(int *)malloc(sizeof(int));//开空间 强制转换为int*
memset(p,0,sizeof(int)); //内存初始化
*p=10;// *取值
cout<<*p<<endl;//10
free(p);//释放指针变量
}
C++动态分配内存空间 示例
指针变量定义并初始化NULL
new动态开辟内存空间
对开辟并初始化的内存空间操作,如 赋值
程序员手动释放内存空间delete
#include<iostream> //C++输入输出库
using namespace std; //std标准命名空间
void demo_space();
int main()
{
demo_space();
return 0;
}
void demo_space()
{
int *p1=NULL;
p1=new int; //第一步: new 开空间
*p1 = 20;
cout<<*p1<<endl; //20
delete p1; //第二步: 释放 delete
}
C/C++ 数组的动态开辟内存空间
示例
#include<iostream> //C++输入输出库
using namespace std; //std标准命名空间
#include<string.h>
void demo_space();
int main()
{
demo_space();
return 0;
}
void demo_space()
{
//C的数组的分配空间写法
char *name=NULL;
name = (char *)malloc(sizeof(char)*20);//开空间
memset(name,0,sizeof(char)*20);//内存初始化
strcpy(name,"admin");//字符串赋值 头文件记得引用
cout<<name<<endl; //admin
free(name);
//C++的数组的分配空间写法
char *name1 = NULL; //定义
name1 =new char[20]; //数组 连续开多少个内存的空间
strcpy(name1,"lily"); //赋值
cout<<name1<<endl; //lily
delete []name1; //数组释放 []释放整个数组
}
小结:
1. malloc free(函数) new delete(运算符) 都开在堆区
2. malloc 指定开辟空间大小 new不需要 类型知道即可
3. malloc 返回void*,所以一般强制转换 new不需要
4. malloc开free收 new开delete释放
5. 对象---new执行构造函数 delete执行析构函数
七:函数重载
函数重载 又称为函数的多态性
示例如下 函数名相同, 函数类型不同,形参类型 形参顺序不同
#include<iostream> //C++输入输出库
using namespace std; //std标准命名空间
#include<string.h>
//函数重载:函数名相同 函数类型不同 形参个数不同 形参类型不同 顺序不同
int add(int a,int b)
{
cout<<"add1"<<endl;
return a+b;
}
float add(float a,float b)
{
cout<<"add2"<<endl;
return a+b;
}
char add(int a,char b)
{
cout<<"add3"<<endl;
return a+b;
}
char add(char a,int b)//与第3个 顺序不同
{
cout<<"add4"<<endl;
return a+b;
}
//char接收 结果是char类型的 d
int main()
{
char res = add(3,'a'); //调用函数
cout<<res<<endl; //add3 d
return 0;
}
注意:只有函数类型不相同,其他都相同,不是函数重载!
如下示例编辑器就会给出报错提示
int add(int a,int b)
{
cout<<"add1"<<endl;
return a+b;
}
char add(int a,int b)
{
cout<<"add12"<<endl;
return a+b;
}
调用重载函数时,编译器通过检查实际参数的个数,类型和顺序来确定相应的被调用函数
八:带默认形参值的函数
带默认形参值的函数,若给值,一定要从右往左
#include<iostream> //C++输入输出库
using namespace std; //std标准命名空间
#include<string.h>
char add(char a,int b=5);// 带默认值的形参 若给值 一定要从右往左
//函数调用时,实参与形参按从左到右的顺序进行匹配
char add(char a,int b)
{
cout<<"add4"<<endl;
return a+b;
}
int main()
{
char res = add('a');
cout<<res<<endl; //add4 f
return 0;
}
带默认形参可能会出现二义性 编辑器会给出报错提示
如下情况 二义性 就会出现报错,需要引以为戒!!!
#include<iostream> //C++输入输出库
using namespace std; //std标准命名空间
#include<string.h>
char add(char a='b',char b='3'); //带默认形参值的函数的二义性
char add(char a='a',int b=5);
char add(char a,char b)
{
cout<<"add4"<<endl;
return a+b;
}
char add(char a,int b)
{
cout<<"add4"<<endl;
return a+b;
}
int main()
{
char res = add('a');
cout<<res<<endl;
return 0;
}
九:内联函数
内联函数 修饰词:inline
函数本身简单,但是却频繁调用 影响效率 故采用内联函数
一些简单的函数,即便没有inline修饰,编译器也会自己给它内联
示例如下
#include<iostream> //C++输入输出库
using namespace std; //std标准命名空间
#include<string.h>
inline int area(int a,int b)//内联函数
{
return a*b; //要求代码一定要少 5行以内 不能有循环
}
//输入 cin的使用
int main()
{
int width=0,height=0;
cout<<"请输入width:"<<endl;
cin>>width; //20
cout<<"请输入height:"<<endl;
cin>>height; //30
cout<<"面积:"<<area(width,height)<<endl; //600
return 0;
}
十:引用
引用(共用同一个内存空间)
示例如下 变量a1和变量a共用一个内存空间,可以通过a1直接访问获取变量a的数据
#include<iostream> //C++输入输出库
using namespace std; //std标准命名空间
#include<string.h>
void demo2();
int main()
{
demo2();
return 0;
}
void demo2()
{
int a=50; //变量
int *pa=&a; //指针变量 存储别人的地址
//引用
int &a1 = a; //a1与a共用一个内存空间
cout<<a1<<endl; //50
}
以两数交换为例 知道引用【共享一片内存空间】
形参指针、形参引用,都可以函数内部改变,外部也可以改变,不局部不消亡
如下实例
#include<iostream> //C++输入输出库
using namespace std; //std标准命名空间
#include<string.h>
void swap(int *a,int *b)//形参指针 指针作为形参 内变外也变
{
int tmp=0;
tmp = *a;
*a = *b;
*b = tmp;
}
void swap(int &a,int &b)//形参引用 形参引用 函数内不用*取值
{ //也可以实现函数内部改变 函数外也改变
int tmp=0;
tmp = a;
a = b;
b = tmp;
}
int main()
{
int a=10,b=30;
cout<<"交换前"<<"a="<<a<<"b="<<b<<endl;//交换前a=10b=30
// swap(&a,&b); //形参指针 调用到取地址
swap(a,b); //形参引用 调用不用取地址 给具体的值
cout<<"交换后"<<"a="<<a<<"b="<<b<<endl;//交换后a=30b=10
return 0;
}
空指针 指针变量定义初始化为NULL ,指向0地址
野指针是指针变量只声明没有初始化,野指针的情况很危险
引用的好处:不会出现野指针的危险情况
因此如果可以使用 引用的话就不使用指针
引用和指针有什么区别:
1. 指针保存存储地址 一般指针变量定义并初始化NULL
2. 引用是取别名 定义时一定要初始化,不能初始化为NULL
//int a=50; int &a1 = a;//a1和a共用一个内存空间
3. 引用不可以改变 引用和变量指向同一片内存(用的同一个地址)
指针4个字节 指针可以指向不同的地址 (指针可以变)
4. 引用比指针更加安全 (指针变量只定义没有初始化就会出现野指针的危险情况)
有指针的指针 因为指针变量是变量 也有地址
不能有引用的引用 因为引用两个用的是同一个内存地址