C++数据类型、变量类型、修饰符类型

1、命名空间

头文件<iostream>

using namespace std; 告诉编译器使用 std 命名空间

1.1 命名空间(namespace)的意思

可能会出现相同命名的类的功能各不相同,在类前面加上 namespace(名字空间) 以示区分。

std::

std 表示是 C++ 的标准命名空间,是 standard(标准)的缩写,就是编译系统自带有的,按 C++ 标准定义好了的。

比如,在使用输出 std::cout 时,如果它达不到我们想要的效果,我们也可以自己定义一个名字空间。取名 myspace,再在这个空间里写一个 cout 函数来实现。调用时,就成了 myspace::cout

1.2 using namespace std;

这个的作用是曝光整个 std 名称空间,使其中的所有成员皆可直接使用。

1、声明了命名空间 std,后续如果有未指定命名空间的符号,那么默认使用 std,这样就可以使用 cin、cout、vector 等。

2、假设你不使用预处理 using namespace std;  就要加上 std::cin 或者 std::cout。

cin 用于从控制台获取用户输入,cout 用于将数据输出到控制台。

输入流对象cin , cout  是输出流对象,

可以用        >>  和 <<,是因为分别在其类中对相应运算符进行了重载。

1.3 标识符命名

C++ 标识符是用来标识变量、函数、类、模块,或任何其他用户自定义项目的名称。


  1. 一个标识符以字母 A-Z 或 a-z 或下划线 _ 开始,后跟零个或多个字母、下划线和数字(0-9)。
  2. C++ 标识符内不允许出现标点字符,比如 @、& 和 %
  3. C++ 命名是区分大小写
  4. 可以使用带有 $ 的标识符

比如:

有效标识符:mohd zara abc move_name a_123 myname50 _temp j a23b9 retVal

1.4 ::的作用

:: 在 C++ 中表示作用域,和所属关系。 ::运算符中等级最高的,它分为三种

1.4.1 作用域符号

作用域符号 :: 的前面一般是类名称,后面一般是该类的成员名称,C++ 为例避免不同的类有名称相同的成员而采用作用域的方式进行区分。

比如:A、B两个类,都有成员data。那么分别表示

A::data表示A的成员data

B::data表示B的成员data

1.4.2 全局作用域符号:

当全局变量在局部函数中与其中某个变量重名,那么就可以用 :: 来区分,例如

char data;
void sleep()
{
    char data = 97;//a的ASCII码
    ::data = 80;//大写字母P的ASCII码
    
    cout << "局部变量:" << data<< endl;
    cout << "全局变量:" << ::data << endl;
}
打印结果:
局部变量:a
全局变量:P

要注意的是使用 cout 输出 char 类型数据 ,打印的数据是对应的ASCII码,而非定义的数值

1.4.3 作用域分解运算符

比如声明了一个类 A,类 A 里声明了一个成员函数 void f(),但没有在类的声明里给出f的定义,那么在类外定义 f 时,就要写成 voidA::f(),表示这个 f() 函数是类 A 的成员函数。例如

class CA 
{
public:
  int ca_var;
  int add(int a, int b);
  int add(int a);
}
//那么在实现这个函数时,必须这样写:
int CA::add(int a, int b)
{
  return a + b;
}
//另外,双冒号也常常用于在类变量内部作为当前类实例的元素进行表示,比如:
int CA::add(int a)
{
  return a + ::ca_var;
}
//表示当前类实例中的变量ca_var。

1.5 "\n" 与 endl 的区别?

\n表示内容为一个回车符的字符串(不刷新缓冲区)

std::endl 输出一个换行符,并立即刷新缓冲区。(刷新缓冲区)

2、数据类型

2.1 基本数据类型

七种基本的数据类型:

类型

关键字

字节数

布尔型

bool

1

字符型

char

1

整型

int

4

浮点型

float

4

双浮点型

double

8

无类型

void

宽字符型

wchar_t(short int)

2

默认情况下,int、short、long都是带符号的

2.1.1 C++相关函数与头文件

头文件:<limits>

字节大小函数:sizeof(data type);

取值范围函数:numeric_limits<data type>::max(or min)

3、变量

3.1 变量类型

变量的名称可以由字母、数字和下划线字符组成。它必须以字母或下划线开头

大写字母和小写字母是不同的,因为 C++ 是大小写敏感的。

整数类型(Integer Types)

  1. int:用于表示整数,通常占用4个字节。
  2. short:用于表示短整数,通常占用2个字节。
  3. long:用于表示长整数,通常占用4个字节。
  4. long long:用于表示更长的整数,通常占用8个字节。

浮点类型(Floating-Point Types)

  1. float:用于表示单精度浮点数,通常占用4个字节。
  2. double:用于表示双精度浮点数,通常占用8个字节。
  3. long double:用于表示更高精度的浮点数,占用字节数可以根据实现而变化。

字符类型(Character Types)

  1. char:用于表示字符,通常占用1个字节。
  2. wchar_t:用于表示宽字符,通常占用2或4个字节。
  3. char16_t:用于表示16位Unicode字符,占用2个字节。
  4. char32_t:用于表示32位Unicode字符,占用4个字节。

布尔类型(Boolean Type)

        bool:用于表示布尔值,只能取true或false。

枚举类型(Enumeration Types)

        enum:用于定义一组命名的整数常量。

指针类型(Pointer Types)

        type*:用于表示指向类型为type的对象的指针。

数组类型(Array Types)

        type[ ]或type[size]:用于表示具有相同类型的元素组成的数组。

结构体类型(Structure Types)

        struct:用于定义包含多个不同类型成员的结构。

类类型(Class Types)

        class:用于定义具有属性和方法的自定义类型。

共用体类型(Union Types)

        union:用于定义一种特殊的数据类型,它可以在相同的内存位置存储不同的数据类型。

3.2 变量自动转换规则

3.1.1 自动转换规则


1、若参与运算量的类型不同,则先转换成同一类型,然后进行运算。

2、转换按数据长度增加的方向进行,以保证精度不降低。

        如int 型和long型运算时,先把 int 转成 long 型后再进行运算。

        若两种类型的字节数不同,转换成高字节数类型

        若两种类型的字节数相同,有符号转换成无符号类型

3、所有的浮点运算都是以双精度进行的,即使仅含float单精度量运算的表达式,也要先转换成double型,再作运算。

4、char型和short型参与运算时,必须先转换成int型

5、在赋值运算中,赋值号两边量的数据类型不同时,赋值号右边量的类型转换为左边量的类型。如果右边量的数据类型长度比左边长时,将丢失一部分数据,这样会降低精度:


int a ;
float b = 1.24;
a = b;
cour << a;
输出:1

3.1.2 强制转换规则

通过类型转换运算实现。

float b =1.24;
int a =2;
cout << a+(int)b << endl;
输出:3

3.3 变量作用域

三个地方可以定义变量:

函数外部----------------全局变量

函数内部/代码块内部---局部变量

函数参数----------------形参

变量有四种作用域:

范围

生命周期

全局作用域

全局变量 可以被 当下文件的任何函数访问

程序开始创建---程序结束销毁

局部作用域

函数内部声明的变量 可以被 当下函数内部访问

函数每次被调用时被创建,在函数执行完后被销毁。

块作用域

代码块内部声明的变量只能在代码块内部访问

代码块每次被执行时被创建,在代码块执行完后被销毁。

类作用域

类内部声明的变量可以被类的所有成员函数访问

类作用域变量的生命周期与类的生命周期相同。

ps:如果全局变量和局部变量重名,那么局部变量将覆盖全局变量。但是C++可以使用::来引用全局

#include<iostream>
using namespace std;

int a = 10;
int main()
{
    int a = 20;
    cout << ::a << endl;   // 10
    cout << a << endl;     // 20
    return 0;
}

3.3.1 局部变量和全局变量的初始化

定义局部变量系统不会初始化,是随机数。

定义全局变量系统会自动初始化:

4、修饰符类型

数据类型

整形

字符型

双精度型

修饰符

signed、unsigned、long 和 short

(可以不写int,int是隐含的)

signed 、 unsigned

long

4.1 类型限定符(存储类)

限定符

含义

const

常量不能修改

volatile

易变的变量值,每次编译数值去地址中读(常用于多线程)

static

定义静态变量,作用域仅限当前文件/函数,不能被外部访问

register

频繁使用的变量,保存在CPU中加速访问提高效率

restrict

restrict 修饰的指针是唯一 一种访问它所指向的对象的方式。

mutable

表示类中的成员变量可以在 const 成员函数中被修改。

explicit

修饰只有一个参数的类构造函数,表明该构造函数是显式而非隐式。禁止类对象之间的隐式转换,以及禁止隐式调用拷贝构造函数。

 5、存储类

存储类 定义 C++ 程序中变量/函数的范围(可见性)和生命周期,放在修饰类型之前。列举常见的:

5.1 auto类

这是默认的存储类说明符,通常可以省略不写

生命周期:auto 指定的变量具有自动存储期,即它们的生命周期仅限于定义它们的块(block)。auto 变量通常在栈上分配

用于两种情况:

1、声明变量时根据初始化表达式自动推断该变量的类型(很少使用)

auto f=3.14;      //double
auto s("hello");  //const char*
auto z = new auto(9); // int*
auto x1 = 5, x2 = 5.0, x3='r';//错误,必须是初始化为同一类型
2、 声明函数时函数返回值的占位符。

5.2 register类

用于声明变量,并提示编译器将这些变量存储在寄存器中,以便快速访问。使用 register 关键字可以提高程序的执行速度,因为它减少了对内存的访问次数。

注意:在 C++11 及以后的版本中,register 已经是一个废弃的特性,不再具有实际作用。

5.3 static类

 ​​​​5.3.1 修饰局部变量

修饰变量在程序的生命周期内保持局部变量的存在,而不需要在每次它进入和离开作用域时进行创建和销毁。因此,使用 static 修饰局部变量可以在函数调用之间保持局部变量的值。

静态局部变量有以下特点:

  • 该变量在全局数据区分配内存;
  • 静态局部变量在程序执行到该对象的声明处时被首次初始化,即以后的函数调用不再进行初始化;
  • 静态局部变量一般在声明处初始化,如果没有显式初始化,会被程序自动初始化为0;
  • 它始终驻留在全局数据区,直到程序运行结束。但其作用域为局部作用域,当定义它的函数或语句块结束时,其作用域随之结束;

 ​​​​5.3.2 修饰全局变量 

static 修饰全局变量时,会使变量的作用域限制在声明它的文件内。

5.3.3 修饰类数据成员

static 用在类数据成员上时,会导致仅有一个该成员的副本被类的所有对象共享。

修饰类的成员变量:

  • 静态成员变量是先于类的对象而存在
  • 这个类的所有对象共用一个静态成员
  • 如果静态成员是公有的,那么可以直接通过类名调用
  • 静态成员数据在声明时候类外初始化

static 修饰类的成员方法:

  • 静态成员函数是先于类的对象而存在
  • 可用类名直接调用(公有)
  • 在静态成员函数中没有this指针,所以不能使用非静态成员

5.4 extern类

extern 存储类用于提供一个全局变量的引用,全局变量对所有的程序文件都是可见的。(很常用)

5.5 const类

1、 const修饰常量:

const修饰的常量代替宏定义: const double PI = 3.1415;

2、 const修饰成员变量:

const int data;

const 修饰的成员变量必须在构造方法的参数列表初始化,不能在构造函数内部进行赋值操作

const 修饰的成员变量不能被修改

3、 const修饰成员方法:

void showData()const{ }

const 修饰的成员函数中不能修改成员变量,不能调用非 const 修饰的函数。

5.5.1 const 相比 #define 的优点:

const 常量有数据类型,而 #define 没有,编译器可以对const进行类型安全检查,而对define只能进行字符替换,没有安全检查,并且在字符替换时候可能导致意想不到的错误。

有些集成化的调试工具可以对 const 常量进行调试,但是不能对宏常量进行调试。

 5.5.2 const char*, char const*的区别

从右向左读

char  * const cp; ( * 读成 pointer to ) 
cp is a const pointer to char (cp是一个常量指针指向char)
指向的对象可变,指针的指向不可变

const char * p(char const * p); 
p is a pointer to const char; (cp是一个指针指向常量char)
指向的对象只读,指针的指向可变

const 放在 * 的左侧任意位置,限定了该指针指向的对象是只读的;
const放在 * 的右侧,限定了指针本身是只读的,即不可变的。
const 右边修饰谁,就说明谁是不可变的。

​​​​​​​5.6 thread_local类

作用:可以将 thread_local 仅应用于数据声明和定义,thread_local 不能用于函数声明或定义。使用 thread_local 说明符声明的变量仅可在它创建的线程上访问。

周期:变量在创建线程时创建,并在销毁线程时销毁。 每个线程都有其自己的变量副本。

thread_local 说明符可以与 static 或 extern 合并。

thread_local int x;  // 命名空间下的全局变量
class X
{
    static thread_local std::string s; // 类的static成员变量
};
static thread_local std::string X::s;  // X::s 是需要定义的
 
void foo()
{
    thread_local std::vector<int> v;  // 本地变量
}

学习文章:菜鸟C++ 教程 | 菜鸟教程 (runoob.com)

  • 23
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Zhaorming.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值