1、基本结构
#include <iostream>
//标准输入输出流,in输入,out输出
using namespace std;
//使用命名空间 std表示打开一个叫std的房间
int main(){}
//函数入口地址
cout << "hello world" <<endl
//cout:标准的输出,在iostream头文件里,cout在std里;<<左移运算符,符号重载,在这里是拼接作用;endl:输出换行并刷新缓冲区
std:: cout << "hello world" <<endl
//如果不打开std房间的写法.::
作用域,std的作用域
system("pause");
//请按任意键继续。。阻塞功能
return EXIT_SUCCESS
//成功离开返回0,正常退出
2、c++头文件没有.h
(1)为什么c++头文件没有.h?
include <cmath>
include <>
3、面向对象三大特性
(1)封装
将成员封装在类中
(2)继承
类与类之间的关系
(3)多态
一个接口,多种方法
4、调用传统c库的方法
#define _CRT_SECURE_NO_WARINGS
5、双冒号作用域运算符
int atk=200; //全局变量
void test01(){
int atk=100;
cout<<"test中的"<<atk<<endl; //输出100
cout<<"全局中的"<<::atk<<endl; //输出200
}
int main(){
cout << atk <<endl; //输出200
test01();
}
双冒号,作用域运算符-> ::全局作用域
6、namespace的使用
命名空间主要是用来解决命名冲突的问题.
命名空间下可以放函数、变量、结构体、类;
命名空间必须定义在全局作用域下;
命名空间可以嵌套命名空间;
命名空间是开放的,可以随时往原先的命名空间添加内容;
可以有无名/匿名命名空间;
namespace {
int c=0;
int d=0;
//无名命名空间。相当于static int c = 0;
//只能在当前文件内使用
}
命名空间可以起别名;
namespace veryLongName{
int A=0;
}
void test04(){
namespace veyShortName = veyLongName;
cout<<veyShortName::A<<endl;
}
(1)新建头文件game1.h
#include <iostream>
using namespace std;
namespace LOL{
void goAtk();
int A;
struct Person{
};
class Animal{};
namespace B{
int A=10; //写法是LOL::B::A
}
}
(2)新建cpp文件game1.cpp
#include "game1.h"
void LOL::goAtk(){
cout<<"LOL攻击"<<endl;
}
(3)在main.cpp中引入
#includ "game1.h"
using namespace LOL;
int main(){
LOL::goAtk();
}
7、using声明和using编译指令
8、c++对c语言的增强
(1)全局变量检测增强
int a;
int a=10;//重定义
在c++中会报错。
(2)函数检测增强,参数类型和函数返回值
int getRectS(w,h){
}
在c++中不能跑,因为没有return,也没有说w,h是什么类型。
(3)函数调用检测增强,参数个数
void test2(){
getRectS(10,10,10);
}
(4)类型转换检测增强,
char * p=(char *)malloc(sizeof(64)) //malloc返回值是void*
c++里要强转
(5)结构体增强
struct Person{
int Age;
void plusAge(){Age++;}; //c中结构体不可以加函数,但c++可
}
(6)c++可以不加入struct关键字
struct Person p1;//c使用时必须加入struct关键字
Person p2; //c++可以不加入struct关键字
p2.Age=10;
p2.plusAge();
(7)bool类型增强
c语言中没有bool类型
bool flag;//true or false
(8)三目运算符增强a>b?a:b
c语言返回”值“,c++返回”变量“。
int a=1;
int b=20;
printf("res=%d",a>b?a:b);//c语言写法
cout << (a>b?a:b) << endl;//c++写法
a>b?a:b=100;//c++写法,100赋值给b。c语言会失败
(9)const增强,一种只读数据,不能修改
c语言仍可以通过指针绕过而修改。伪常量
c++通过指针之后仍不会被修改。真正常量。
c语言中的const默认是外部链接;可以在其他文件访问。
c++中的const默认是内部链接,要使用extern提高作用域。
c语言中const分配内存问题?
c++中const分配内存问题?
在c++中,一个const不必创建内存空间,而在c中,一个const总是需要一块内存空间。
在c++中,是否为const常量分配内存空间依赖于如何使用。一般说来,如果一个const仅仅用来把一个名字用一个值代替(就像使用#define一样),那么该存储局空间就不必创建。
如果存储空间没有分配内存的话,在进行完数据类型检查后,为了代码更加有效,值也许会折叠到代码中。
不过,取一个const地址, 或者把它定义为extern,则会为该const创建内存空间。
1、const分配内存时,取地址会分配临时内存
2、extern编译器也会给const分配临时内存
void test01{
const int a=10;
int *p=(int*)&a;//会分配临时内存
};
3、用普通变量初始化const的变量
void test02(){
int a=10;
const int b=a;//会分配内存
int *p=(int *)&b;
*p=1000;
cout<<b<<endl;
}
4、自定义数据类型,用const初始化也会分配内存
struct Person{
string Name;
int Age;
};
void test03(){
const Person p1;
// p1.Name="aaa";
Person *p= (Person *)&p1;
p->Name="aaa";
(*p).Age=18;
cout<<p1.Name<<p1.Age<<endl;
}
在c++中,出现在所有函数之外的const作用于整个文件(也就是说它在该文件外不可见),默认为内部连接,c++中其他的标识符一般默认为外部连接。
9、尽量以const 替换#define
#define MAX 1024
1、这max会在预处理阶段就被替换为1024,编译器看不到max。无非是想让max成为常量,用const也能实现。
2、define出来的变量没有作用域,从文件头到文件尾都有效(但可以指定生命周期)。如果要定义在指定作用域下有效的常量,需要用const。
3、define没有类型,不可进行类型检测。const有类型,可以进行编译器类型安全检查。
10、引用reference
引用是c++对c的扩充,引用可以直接理解为取别名.
&写早左侧,叫引用;写到右侧,叫取地址。
int &b=a
:![[Pasted image 20220927092746.png]]
1、引用必须初始化
void test01(){
int &A; //会报错,必须初始化
}
2、引用初始化后就不可以修改了
void test01(){
int a=10;
int &A=a;//引用初始化后就不可以修改了
int c=20;
b=c;//赋值失败。
}
3、给数组起别名①
void test02(){
int arr[10];
for(int i=0;i<10;i++){
arr[i]=i;
}
//给数组起别名
int (&pArr)[10]=arr;
for(int i=0;i<10;i++){
cout<<pArr[i]<<" ";
} cout<<endl;
}
给数组起别名②
//一个具有10个元素的int类型的数组
typedef int(ARRAYREF)[10];
ARRAYREF & pArr2=arr;
4、引用的注意事项
①引用必须引一块合法的内存空间
int &a=10
错误,10没有空间
②不要返回局部变量的引用
③如果函数的返回值是引用,那么这个函数调用可以作为左值
5、引用的本质
在c++内部实现是一个指针常量。
int &b=a
,发现是引用,转换为int *b=&a
6、引用的使用场景
①指针的引用(待补充)
用一级的指针引用可以代替二级指针。
②常量的引用:
但最好不要这么写,临时变量找不到
void test(){
const int &ref=10;//加入const后,编译器处理:创建了临时变量tmp=10;再来const int &ref=tmp。会分配内存
// ref=10;//就不能修改了,会报错
//但能绕过编译器进行修改
int *p=(int *)&ref;
*p=1000;
}
常量引用的使用场景,用来修饰形参为只读
void showValue(const int &val){
//如果只是想显示内容,不修改内容,那么就用const修饰这个形参
cout<<"val="<<val<<endl;
}
void test02(){
int a=10;
showValue(a);
}
11、参数的三种传递方式
(1)值传递:不改变值。只是判断
void mySwap(int a,int b){
int tmp=a;
a=b;
b=tmp;
cout<<a<<" "<<b<<endl; //20 10
}
void test02(){
int a=10;
int b=20;
mySwap(a,b);
cout<<a<<" "<<b<<endl; //10 20
}
(2)地址传递:想改变值
void mySwap(int * a,int * b){
int tmp=*a;
*a=*b;
*b=tmp;
cout<<*a<<" "<<*b<<endl; //20 10
}
void test02(){
int a=10;
int b=20;
mySwap(&a,&b);
cout<<a<<" "<<b<<endl; //20 10
}
(3)引用传递:类似于传地址
void mySwap(int & a,int & b){ //给a,b起别名
int tmp=a;
a=b;
b=tmp;
cout<<a<<" "<<b<<endl;
}
void test02(){
int a=10;
int b=20;
mySwap(a,b);
cout<<a<<" "<<b<<endl;
}