昨天和强大的群友们讨论了一个问题,C++的delete和delete[]的区别,我的理解是delete只删除一个元素,delete[]可以迭代删除整个数组的元素。
2.1、基本内置类型
算术类型:
类型 | 含义 | 最小尺寸 |
---|---|---|
char | 字符 | 8位(和一个机器字节一样大) |
wchar_t | 宽字符 | 16位 |
char_16t | Unicode字符 | 16位 |
char_32t | Unicode字符 | 32位 |
short | 短整型 | 16位 |
long | 长整型 | 32位 |
long long | 长整型 | 64位 |
float | 单精度浮点数 | 6位有效数字 |
double | 双精度浮点数 | 10位有效数字 |
long double | 扩展精度浮点数 | 10位有效数字 |
有符号和无符号类型:signed+算术类型,unsigned+算术类型
ps:unsigned不存在负数,然后如果是负数就会取模。
#include <iostream>
#include <windows.h>
using namespace std;
int main()
{
unsigned a = 10;
int b = -20;
cout<<a + b<<endl;
system("pause");
return 0;
}
字符值常量:0开头是八进制,0x开头是16进制
空字符:’\0’
数字+e+数字表示yex
#include <iostream>
#include <windows.h>
using namespace std;
int main()
{
cout<<0e0<<'\0'<<1e0<<endl;
system("pause");
return 0;
}
分多行输出字符串:
#include <iostream>
#include <windows.h>
using namespace std;
int main()
{
cout<<"我"
"爱你"<<endl;
system("pause");
return 0;
}
转义字符:有点多。链接
指定字面值的类型:
字符和字符串字面值(前缀) | 类型 |
---|---|
u | char_16t |
U | char_32t |
L | 宽字符 |
u8 | char(utf-8) |
整型字面值 (后缀) | 类型 |
---|---|
u or U | unsigned |
l or L | long |
ll or LL | long long |
浮点型字面值(后缀) | 类型 |
---|---|
f or F | float |
l or L | long double |
#include <iostream>
#include <windows.h>
using namespace std;
int main()
{
cout<<L'a'<<"这是一个wchar_t类型的字符"<<endl;
cout<<"谁\?\x4D";
system("pause");
return 0;
}
2.2、变量
一些概念:
- 对象:是指一块能存储数据并具有某种类型的空间。
- 变量:把对象和值区分开来,把命了名的对象称为变量。
- 值:只读的数据
ps:这里强调一下,初始化和赋值不是一个概念,初始化是在创建变量的时候往里面填值。赋值是把以前的值去掉,然后在填值。
初始化数据的四个方式:
#include <iostream>
#include <windows.h>
using namespace std;
int main()
{
int a(0);
int b{
1};
int c = 3;
int d = {
2};
cout<<a<<'\0'<<b<<'\0'<<d<<'\0'<<c;
system("pause");
return 0;
}
默认初始化:如果你创建了变量,但是没有往里面填值,这时候系统会自动往里面填。类如果你不去写带参构造函数,也会调用默认的构造函数去初始化。
#include <iostream>
#include <windows.h>
using namespace std;
int main()
{
int a;
string b;
cout<<a<<'\0'<<b;
system("pause");
return 0;
}
作用域:变量实际有效的区域,在所以花括号外边是全局作用域有效区域是整个代码,在花括号内部的是局部作用域,有效区域是花括号内部。
如果你多个函数想用同一个变量名咋办??
用extern
#include <iostream>
#include <windows.h>
using namespace std;
extern int j;//仅仅是声明,并没有定义。
void a(){
int j = 2;
}
int main()
{
int j = 1;
int i = 1;//声明并定义
a();
cout<<j;//虽然j在全局,但是主要是看你定义的在哪,j在a中定义是在局部(函数a内),所以不受a内定义的影响。
system("pause");
return 0;
}
2.3、复合类型
- 引用:就是给变量起另外的名字。(绑定,并没有开辟新内存)
- 指针:本身是一个对象,存的是指针对象的地址。(当年俺大一加实验室,他们问指针是什么,我就说地址= =结果被刷了,可能是C++当年分太低???)
- 空指针:这里说一下个人多年刷题理解(愚蠢的树)nullptr是真正的空指针,我个人也喜欢用这个,NULL和0效果是一样的。
- void* :可以存任意类型的指针。(里面存的东西不好拿出来)
ps:指针的比较其实就是比较的指针存的地址。
#include <iostream>
#include <windows.h>
using namespace std;
int main()
{
int a = 1;
int *b = nullptr;
int *c = NULL;
int *d = 0;
cout<<"*b = "<<b<<"*c = "<<c<<"d ="<<d<<endl;
int &a1 = a;
cout<<"引用"<<a1<<endl;
int *a2 = &a;
cout<<"指针存的地址"<<a2<<"指针指向的内容"<<*a2<<endl;
void *a3 = a2;//可以放任意类型的
system("pause");
return 0;
}
至于什么指向指针的指针啊,大家应该搞明白我说的指针是存什么东西的就很简单了吧,*P ,很明显(P)存的是P这个指针的地址,然后*P存的是P的地址。理解源头就好了,也别听一些简便方法。
2.4、const限定符
- const:表示数据不能被删除重写,也就是赋值,只能被初始化。(默认情况下const只在本文件内有效),这是内存上的禁止重写,所以变量的引用也是不能赋值的。
- const引用:const int &a可以赋值int b这种非常量,int b不可以赋值const int &a这种常量。同样const int &a也不可以更改值。但是可以用另一个名字int b更改值,这就是定义上的区别。
- 指向常量的指针:不能通过指针改变指针指向对象的值,但是可以改变指针指向的变量。const int *a
- 常量指针:可以改变指针指向对象的值,但是不能改变指针存的地址。int *const a。
- 顶层cosnt:指针本身是一个常量。也就是不能改变指针存的地址,也就是常量指针。
- 底层const:指针指向一个常量。指针不能改变指向对象的值,也就是指向常量的指针。
- constexpr:声明的变量一定是一个常量,而且是常量表达式初始化。constexpr指针的初始值必须是nullptr或0或者是存在某个固定地址的对象。(也就是顶层const)
ps:const int a = b();这个不是一个常量表达式,因为运行的时候常量a才知道b()运行的结果。
#include <iostream>
#include <windows.h>
using namespace std;
int main()
{
int a = 1;
int b =2;
const int *a1 = &a;//指向一个的数据是常量,不能用指针改变a的值。
cout<<"指向常量的指针,地址"<<a1<<"值"<<*a1<<'/0';
a1 = &b;//可以改变指针指向的地址
cout<<"改变地址只后,地址"<<a1<<"值"<<*a1<<endl;
int *const a2 = &a;
cout<<"常量指针指针存的数据"<<*a2<<'\0';//不可以改变指针存的地址,但是可以改变地址对应的内存中的数值
*a2 = 3;
cout<<"改变后的数据"<<*a2<<endl;
constexpr int *p = nullptr;
system("pause");
return 0;
}
2.5、处理类型
- 类型别名:就是给一个单词定义另一个同义词,用的时候一样。(typedef和using)
- auto:系统给你判断数据类型。(个人很喜欢用,auto会忽略const、指针和引用等特性)
- decltype:希望新的数值的类型和原有的数据类型相同也可以用这个。这个不会和auto一样忽略特性。
#include <iostream>
#include <windows.h>
using namespace std;
int main()
{
int a = 1;
int& b = a;
decltype(b) c = a;//类型是int &
auto d = b;//类型是int
cout<<"d"<<d<<"c"<<c<<endl;
typedef double pp;
pp e = 1.1;//类型是double
using s = long;
s f = 1;//类型是long
system("pause");
return 0;
}
2.6、自定义数据结构
也就是struct我写个节点你们看看:
#include <iostream>
#include <windows.h>
using namespace std;
struct Node{
int value;
Node * left = nullptr;
Node * right = nullptr;
};
int main()
{
Node a;
a.value = 1;
cout<<a.value;
system("pause");
return 0;
}
我们有时候多次定义相同的头文件,用预处理器去解决
#include <iostream>
#include <windows.h>
#ifdef S//当变量定义S定义时为真
#define S//把S设定为预处理变量
#include<string>
struct S{
std::string a
}
#endif//指令定停止
int main()
{
system("pause");
return 0;
}
这个玩意没有结果的,我没引入S,大家当理解看看就行、