C++ primer复习(二、变量和基本类型)

昨天和强大的群友们讨论了一个问题,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,大家当理解看看就行、

猜你喜欢

转载自blog.csdn.net/weixin_45743162/article/details/115053008