笨蛋学C++【C++基础第一弹】

C++基础

1.C++基本语法

1.1C++程序结构

#include <iostream> // 头文件
using namespace std; //使用std命名空间

//程序执行的入口
int main() {
//    std::cout << "Hello, World!" << std::endl;
    
    //输出 HelloWorld
    cout << "hello";
    return 0;
}

  • 为什么main函数的返回值为int,因为一般约定返回0值时表示程序运行无错误,其它值均为程序有错误
  • int main(void) 和 int main() 的区别在前者不能传入参数
  • 为什么使用using namespace std;
    • 因为有些名字会有冲突,然后为了区分冲突,所以C++标准库中的名字都会添加前缀 std:: ,而在引用 标准库中的元素时,就需要在前面添加 std::

1.2C++的分号 & 语句块

  • 每个语句必须以分号 ; 结束,表明一个逻辑实体的结束
  • 如果用分号结束,那么多个语句可以写在同一行,但是不建议,可读性不好

1.3C++标识符

  • 一个标识符以字母A-Z 或 a-z 或下划线_开始,后跟0个或多个字母、下划线和数字(0-9)、$
  • 第一个字符必须是字母或下划线
  • 后续字符可以是字母、数字或下划线
  • 标识符的有效长度不超过247字符
  • 标识符不能和关键字相同
  • 标识符区分大小写
  • 最好也不要和系统预定义标识符同名
  • 标识符命名要做到“见名知义”
  • 应该避免使用可能引起混淆的字母

1.4C++保留字

asmelsenewthis
autoenumoperatorthrow
boolexplicitprivatetrue
breakexportprotectedtry
caseexternpublictypedef
catchfalseregistertypeid
charfloatreinterpret_casttypename
classforreturnunion
constfriendshortunsigned
const_castgotosignedusing
continueifsizeofvirtual
defaultinlinestaticvoid
deleteintstatic_castvolatile
dolongstructwchar_t
doublemutableswitchwhile
dynamic_castnamespacetemplate

1.5三字符组

  • 三字符组就是用于表示另一个字符的三个字符序列,又称为三字符序列。三字符序列总是以两个问号开头
  • 三字符序列不太常见,但 C++ 标准允许把某些字符指定为三字符序列,主要用于表示键盘上没有的字符
  • 不是所有的编译器都支持所有的三字符序列,而且在不同的平台上,相同的三字符序列可能表示不同的字符
三字符组替换
??=#
??/\
??’^
??([
??)]
??!|
??<{
??>}
??-~

1.6C++中的注释

  • 单行注释:// 注释说明

  • 多行注释:/* 注释说明 */

  • 嵌套注释:#if 0 注释说明 #else 注释说明 #end if

    #if 0
        cout << "\nHello, World!" << endl;
    #else
        cout << "\nHello, Chinese!" << endl;
    #endif
    

1.7C++数据类型

类型关键字
布尔型bool
字符型char
整型int
浮点型float
双浮点型double
无类型void
宽字符型wchar_t
    //定义宽字符字面量
    wchar_t wideChar = L'C';
    wchar_t wideChars[] = L"AA";

    //使用宽字符输出流输出宽字符
    wcout << L"\nThe wide character is: " << wideChar;
    wcout << L"\nThe wide character is: " << wideChars;

    cout << "\nThe wide character is: " << wideChar << endl;

    /**
     * The wide character is: C 
     * The wide character is: AA
     * The wide character is: 67
     */
类型范围
char1 个字节-128 到 127 或者 0 到 255
unsigned char1 个字节0 到 255
signed char1 个字节-128 到 127
int4 个字节-2147483648 到 2147483647
unsigned int4 个字节0 到 4294967295
signed int4 个字节-2147483648 到 2147483647
short int2 个字节-32768 到 32767
unsigned short int2 个字节0 到 65,535
signed short int2 个字节-32768 到 32767
long int8 个字节-9,223,372,036,854,775,808 到 9,223,372,036,854,775,807
signed long int8 个字节-9,223,372,036,854,775,808 到 9,223,372,036,854,775,807
unsigned long int8 个字节0 到 18,446,744,073,709,551,615
float4 个字节精度型占4个字节(32位)内存空间,+/- 3.4e +/- 38 (~7 个数字)
double8 个字节双精度型占8 个字节(64位)内存空间,+/- 1.7e +/- 308 (~15 个数字)
long long8 个字节双精度型占8 个字节(64位)内存空间,表示 -9,223,372,036,854,775,807 到 9,223,372,036,854,775,807 的范围
long double16 个字节长双精度型 16 个字节(128位)内存空间,可提供18-19位有效数字。
wchar_t2 或 4 个字节1 个宽字符

1.8typedef声明

  • 为已有的类型取一个新的名字
    • 语法:typedef type newname;
    • 设置新的int:typedef int myInt;
    • 定义整型变量:myInt num;
  • 可以声明各种类型名,不能用来定义变量
  • typedef 和 #define的区别
    • #define发生在编译之前,只进行简单的字符串替换,不会进行检查
    • #define 没有作用域的限制,只要是预定义的宏,在程序中都可以使用
    • typedef会做相应的类型检查
    • typedef有自己的作用域

1.9枚举类型

  • 语法:

    enum 枚举名{ 
         标识符[=整型常数], 
         标识符[=整型常数], 
    ... 
        标识符[=整型常数]
    } 枚举变量;
    
  • 注意:

    • 枚举可以不在main中定义
    • 默认情况下,第一个名称的值为0,后面以此类推
    • 也可以给某个枚举标识符赋值一个特殊的值,只需添加一个初始值,后面若还有枚举标识符则以此类推
    enum Color{
        Red,
        Green,
        Blue
    } c;

    //将Blue赋值给c
    c=Blue;
    cout << "c=" << c << endl;
    

    enum Color2{
        red,
        //添加初始值为5,后面blue就为6
        green=5,
        blue
    } c2;
    
    //将blue赋值给c2
    c2=blue;
    cout << "c2=" << c2 << endl;

    enum Color3{
        reds,
        greens=5,
        //将reds的值赋给blues
        blues = reds
    } c3;

    //将blues赋值给c3
    c3 = blues;
    cout << "c3=" << c3 << endl;

1.10类型转换

  • 静态转换(static_cast)

    • 将一种数据类型的值强制转换为另一种数据类型的值
    • 用于比较类型相似的对象之间转换,例如将int类型转为float类型
    • 不会进行运行时类型检查
        int i =10;
        float f = static_cast<float>(i);
        cout << "f=" << f << endl;
    
        float floats = 188888.0;
        int ints = static_cast<int>(floats);
        cout << "ints=" << ints << endl;
    
  • 动态转换(dynamic_cast)

    • 将一个基类(JJava中的父类)指针或引用转换为派生类(Java中的子类)指针或引用
    • 会进行运行时类型检查,若不能进行转换则返回空指针或引发异常
    class Base {};
    class Derived : public Base {};
    Base* ptr_base = new Derived;
    Derived* ptr_derived = dynamic_cast<Derived*>(ptr_base); // 将基类指针转换为派生类指针
    
    • 参考菜鸟编程 https://www.runoob.com/cplusplus/cpp-data-types.html
  • 常量转换(const_cast)

    • 将const类型的对象转为非const类型的对象

    • 只能用于转换掉const属性,不能改变对象的类型

      int& i = const_cast<int&>(myConst);
      cout << "i=" << i << endl;
      
    • const小解

      • 常量变量:使用const定义的变量不能被修改
      • 常量指针:包括指向常量的指针(常量指针指向的数据不能修改)和常量指针本身(常量指针本身的值不能修改)
      • 常量函数:使用const修饰的成员函数不能修改其所属对象的任何成员的变量
      • 常量引用:使用const定义的引用在绑定某个对象后不能绑定到另一个对象
      • 常量表达式:与constexpr一起使用,表示编译时常量表达式,在编译时就已经确定值
          // 常量变量
          const int myConst = 10;
          cout << "myConst=" << myConst << endl;
      
          // 常量指针
          // 指向常量变量
          const int* ptrToConst = &myConst;
          cout << "ptrToConst=" << *ptrToConst << endl;
          // 指向普通变量
          int value = 12;
          int* const constPtr = &value;
          cout << "constPtr=" << *constPtr << endl;
      
          // 常量函数
          class MyClass{
          public:
              int getValue() const{
                  return value;
              }
          private:
              int value =13;
          };
          MyClass myClass;
          cout << "MyClass.getValue=" << myClass.getValue() << endl;
      
          // 常量引用
           void myFunc(const MyClass& ref){
               //ref 不能绑定其它对象,只能绑定MyClass
           };
      
          // 常量表达式
          constexpr float PI = 3.1415926f;
          cout << "PI=" << PI << endl;
      
  • 重新解释转换(reinterpret_cast)

    • 将一个数据类型的值重新解释为另一个数据类型的值,通常用于在不同的数据类型之间进行转换

    • 不会进行运行时类型检查

          int values = 10;
          float f = reinterpret_cast<float&> (values);
          cout << "f=" << f << endl;
      

1.11变量类型

  • 变量是程序可操作的存储区的名称
  • 每个变量都有指定的类型,类型决定了变量存储的大小和布局,该范围内的值都可以存储在内存中,运算符可应用于变量上,变量的名称可以由字母、数字、下划线、 组成,必须以字母、下划线、 组成,必须以字母、下划线、 组成,必须以字母、下划线、开头
  • 大小写字母的变量是不同的
类型描述
bool布尔类型,存储值 true 或 false,占用 1 个字节。
char字符类型,用于存储 ASCII 字符,通常占用 1 个字节。
int整数类型,通常用于存储普通整数,通常占用 4 个字节。
float单精度浮点值,用于存储单精度浮点数。单精度是这样的格式,1 位符号,8 位指数,23 位小数,通常占用4个字节。img
double双精度浮点值,用于存储双精度浮点数。双精度是 1 位符号,11 位指数,52 位小数,通常占用 8 个字节。img
void表示类型的缺失。
wchar_t宽字符类型,用于存储更大范围的字符,通常占用 2 个或 4 个字节。
C++中可以定义的数据类型
  1. 整数类型(Integer Types):
    • int:用于表示整数,通常占用4个字节。
    • short:用于表示短整数,通常占用2个字节。
    • long:用于表示长整数,通常占用4个字节。
    • long long:用于表示更长的整数,通常占用8个字节。
  2. 浮点类型(Floating-Point Types):
    • float:用于表示单精度浮点数,通常占用4个字节。
    • double:用于表示双精度浮点数,通常占用8个字节。
    • long double:用于表示更高精度的浮点数,占用字节数可以根据实现而变化。
  3. 字符类型(Character Types):
    • char:用于表示字符,通常占用1个字节。
    • wchar_t:用于表示宽字符,通常占用2或4个字节。
    • char16_t:用于表示16位Unicode字符,占用2个字节。
    • char32_t:用于表示32位Unicode字符,占用4个字节。
  4. 布尔类型(Boolean Type):
    • bool:用于表示布尔值,只能取truefalse
  5. 枚举类型(Enumeration Types):
    • enum:用于定义一组命名的整数常量。
  6. 指针类型(Pointer Types):
    • type*:用于表示指向类型为type的对象的指针。
  7. 数组类型(Array Types):
    • type[]type[size]:用于表示具有相同类型的元素组成的数组。
  8. 结构体类型(Structure Types):
    • struct:用于定义包含多个不同类型成员的结构。
  9. 类类型(Class Types):
    • class:用于定义具有属性和方法的自定义类型。
  10. 共用体类型(Union Types):
    • union:用于定义一种特殊的数据类型,它可以在相同的内存位置存储不同的数据类型。

  • 字符’0’、字符’\0’、整数0的区别
    • 字符’0’:在内存中占1个字节共8位,char c = '0';,ASCII码是48,内存中表示8位为48
    • 字符’\0’:在内存中占1个字节共8位,ASCII码为0,是字符串结束的标志,是转义字符,内存中表示8位都为0
    • 整数0:在内存中占4个字节共32位,内存中表示32位都为0
  • 使用 sizeof(数据类型 / 变量) 来获取当前数据类型或变量的内存大小

1.12变量定义

  • 告诉编译器在哪里创建变量的存储,以及如何创建变量的存储

  • 数据类型 变量名 = 值

  • 数据类型必须是一个有效的C++数据类型,可以是char、wchar_t、int、float、double、bool、用户自定义对象

  • 不带初始化的定义:带有静态存储持续时间的变量会被隐式初始化为NULL(所有字节的值都是0),其它所有变量的初始值是未定义的

1.13变量声明

  • 变量声明向编译器保证变量以给定的类型和名称存在

  • extern关键字用于声明一个变量、函数在别处定义的,不是由当前定义点控制的,可以告诉编译器该名称是一个外部链接的全局变量或函数,并且定义在程序的其他地方

    // file1.cpp
    int globalVar = 42; // 定义全局变量
    
    // file2.cpp
    extern int globalVar; // 声明全局变量
    
  • 变量声明可以定义声明多次,但是变量定义只能定义一次

  • 因为编译cpp文件,是从上往下进行编译的,但这时会有其它函数在main函数的下方,这时就需要在main函数上方声明该函数,才能在main函数中去执行其它函数,(被调用的函数要在调用的函数之前声明)

    //
    // Created by 16690 on 2024/4/18.
    //
    #include <iostream>
    using namespace std;
    
    // 变量声明
    extern int a, b;
    extern int c;
    extern float f;
    extern int d();
    
    int main ()
    {
        // 变量定义
        int a,b;
        int c;
        float f;
        // 实际初始化
        a = 10;
        b = 20;
        c = a + b;
    
        cout << c << endl ;
        cout << d() << endl ;
    
        f = 70.0/3.0;
        cout << f << endl ;
    
        return 0;
    }
    
    int d(){
        return 11;
    }
    

1.14左值和右值

  • 左值(lvalue):指向内存位置的表达式被称为左值表达式,左值可以出现在赋值号的左边或右边(左值可以被赋值,也可以被取值
  • 右值(rvalue):指的是存储在内存中某些地址的数值,右值是不能对其进行赋值的表达式,也就是右值只能出现在赋值号的右边,但不能出现在赋值号的左边(右值只能被取值

1.15变量作用域

  • 局部变量:在函数或一个代码块内部声明的变量
  • 形式参数:在函数参数的定义中声明的变量
  • 全局变量:在函数外部声明的变量

  • 静态全局变量也具有全局作用域,只对定义自己的文件里可见
  • 静态局部变量具有局部作用域,只被初始化一次,只对定义自己的函数体里可见

  • 局部作用域:在函数内部声明的变量具有局部作用域,它们只能在函数内部访问。局部变量在函数每次被调用时被创建,在函数执行完后被销毁。

  • 全局作用域:在所有函数和代码块之外声明的变量具有全局作用域,它们可以被程序中的任何函数访问。全局变量在程序开始时被创建,在程序结束时被销毁。

    • 函数对全局变量的修改会改变全局变量的值
    • 对全局变量的引用以及重新赋值,需要在变量名前加上 :: 符号才表示引用的是全局变量
  • 块作用域:在代码块内部声明的变量具有块作用域,它们只能在代码块内部访问。块作用域变量在代码块每次被执行时被创建,在代码块执行完后被销毁。

  • 类作用域:在类内部声明的变量具有类作用域,它们可以被类的所有成员函数访问。类作用域变量的生命周期与类的生命周期相同。

  • 在内部作用域中声明的变量与外部作用域中变量同名,则内部作用域中的变量将覆盖外部作用域中的变量

  • 局部变量
    //
    // Created by 16690 on 2024/4/18.
    //
    #include <iostream>
    using namespace std;
    
    
    int main(void) {
    
        //局部变量声明
        int a, b, c;
    
        //实际初始化
        a = 10;
        b = 20;
        c = a + b;
    
        cout << "c=" << c << endl;
        return 0;
    }
    
  • 全局变量
    //
    // Created by 16690 on 2024/4/18.
    //
    #include <iostream>
    using namespace std;
    
    //全局变量声明
    int f;
    
    int main(void) {
    
        //局部变量声明
        int a, b, c;
    
        //实际初始化
        a = 10;
        b = 20;
        c = a + b;
    
        cout << "c=" << c << endl;
        return 0;
    }
    
  • 变量名相同,局部变量会覆盖全局变量
    //
    // Created by 16690 on 2024/4/18.
    //
    #include <iostream>
    
    using namespace std;
    
    //全局变量声明
    int f = 10;
    
    int main(void) {
    
        //局部变量声明
        int a, b, c;
    
        //实际初始化
        a = 10;
        b = 20;
        c = a + b;
        int f = 20;
    
        cout << "c=" << c << endl;
        cout << "f=" << f << endl;
    
        return 0;
    }
    
  • 块作用域
    //
    // Created by 16690 on 2024/4/18.
    //
    #include <iostream>
    
    using namespace std;
    
    
    int main(void) {
        int a = 10;
        {
            int a = 20;
            cout << "块变量=" << a << endl; //块变量=20
        }
        cout << "外部变量=" << a << endl; //外部变量=10
        return 0;
    }
    
  • 类作用域
    //
    // Created by 16690 on 2024/4/18.
    //
    #include <iostream>
    
    using namespace std;
    
    class MyClass {
    public:
        // 类作用域变量
        static int class_var;
    };
    int MyClass::class_var = 30;
    int main() {
        MyClass myClass;
        cout << "类作用域变量=" << myClass.class_var << endl; //类作用域变量=30
        return 0;
    }
    

1.16初始化局部变量和全局变量

  • 当局部变量被定义时,系统不会对其初始化,必须自行对其初始化
  • 当全局变量被定义时,系统会自动初始化为下列值
数据类型初始化默认值
int0
char‘\0’
float0
double0
pointerNULL

1.17常量

  • 常量是固定值,在程序执行期间不会改变,也不能修改,固定的值又叫做字面量
  • 常量可以是任何的基本数据类型,可分为整型、浮点型、字符型、字符串、布尔值

  • 整数常量
    • 前缀指定基数:0x 或 0X 表示十六进制,0表示八进制,不带前缀默认表示十进制

    • 可以带一个后缀,后缀是U和L的组合,U表示无符号整数(unsigned)L表示长整数(long)

      后缀可以大写,也可以小写,U和L的顺序任意,但是不能重复

  • 浮点常量
    • 整数部分、小数点、小数部分、指数部分组成,可以实用小数形式或指数形式来表示浮点常量
    • 使用小数形式表示时,必须包含整数部分、小数部分,或同时包含两者
    • 使用指数形式表示时,必须包含小数点、指数部分,或同时包含两者(由e或E引入)
  • 字符常量
    • 括在单引号中,若常量以 L 开头,则表示它是一个宽字符常量(例如 L’x’),就必须存储在wchar_t类型的变量中

    • 否则就是一个窄字符变量(例如 ‘x’),就可以存储在char类型的简单变量中

    • 转义字符

      转义序列含义
      \\ 字符
      ’ 字符
      "" 字符
      ?? 字符
      \a警报铃声
      \b退格键
      \f换页符
      \n换行符
      \r回车
      \t水平制表符
      \v垂直制表符
      \ooo一到三位的八进制数
      \xhh . . .一个或多个数字的十六进制数
  • 字符串常量
    • 括在双引号中,一个字符串包含类似于字符常量的字符:普通的字符、转义序列、通用字符

          string greeting = "hello,runob";
          cout << greeting << endl;
          cout << "\n";
          string greeting2 = "hello, \runoob";
          cout << greeting2;
      
  • 布尔值常量
    • true值代表真
    • false值代表假

1.18定义常量

  • 使用 #define预处理器,来定义常量
  • 使用 const 关键字,来定义常量

  • #define
  • 语法:#define 常量名 常量值

    //
    // Created by 16690 on 2024/4/18.
    //
    
    #include <iostream>
    
    using namespace std;
    
    #define LENGTH 10
    #define WIDTH 5
    #define NEWLINE '\n'
    
    int main(void){
        int area;
    
        area = LENGTH * WIDTH;
        cout << area << endl;
        cout << NEWLINE;
    }
    
  • const
  • 语法:const type 常量名 常量值

    //
    // Created by 16690 on 2024/4/18.
    //
    
    #include <iostream>
    using namespace std;
    
    int main(void) {
        const int LENGTHS = 10;
        const int WIDTHS = 5;
        const char NEWLINES = '\n';
    
        int areas;
        areas = LENGTHS * WIDTHS;
        cout << areas << endl;
        cout << NEWLINES;
    
    }
    
  • 定义为const后的常量,程序对其中只能读不能修改

  • const 关键字出现在 * 的左边:指针指向的内容不能被修改。(const int *p;)

  • const 关键字出现在 * 的右边:指针本身不能被修改。(int *const p=&a;)

  • const 关键字出现在 * 的两边:指针指向的内容指针本身都不能被修改。(const int* const p=&a;)

    #include <iostream>
    using namespace std;
    int main()
    {
        int a=1;
        int b;
        
        /**指向const的指针,指针指向的内容不能被修改**/
        const int *p1;
        int const *p2;
       
        /**const指针,指针本身不能被修改,必须初始化**/
        int *const p3=&a;
        
         /*指针本身和它指向的内容都是不能被改变的所以也得初始化*/
        const int* const p4=&a;
        int const* const p5=&b; 
        
         p1=p2=&a; //true  (指针本身的值可以改变)
        *p1=*p2=8; //false(指针指向的内容不能被修改)
        
        *p3=5; //true (指针指向的内容可以改变)
         p3=p1; //false(指针本身的值不能改变) 
        
         p4=p5;//false(指针本身和它指向的内容都是不能被改变) 
        *p4=*p5=4; //false(指针本身和它指向的内容都是不能被改变) 
      
        return 0;
    }
    
  • #define 和 const的区别
    • 宏定义是一个编译时概念,在预处理阶段展开,不能对宏定义进行调试,生命周期结束与编译时期
    • 宏定义是直接替换,不会分配内存,存储于程序的代码段中
    • 宏定义不受定义的作用域限制
    • 宏定义不能作为参数传递给函数
    • const是需要进行内存分配,存储于程序的数据段中
    • const是运行时概念,在程序运行使用
    • const受定义的作用域限制
    • const可以作为参数传递给函数

1.19修饰符类型

  • signed:表示变量可以存储负数。对于整型变量来说,signed 可以省略,因为整型变量默认为有符号类型。
  • unsigned:表示变量不能存储负数。对于整型变量来说,unsigned 可以将变量范围扩大一倍。
  • short:表示变量的范围比 int 更小。short int 可以缩写为 short。
  • long:表示变量的范围比 int 更大。long int 可以缩写为 long。
  • long long:表示变量的范围比 long 更大。C++11 中新增的数据类型修饰符。
  • float:表示单精度浮点数
  • double:表示双精度浮点数
  • bool:表示布尔类型,只有 true 和 false 两个值。
  • char:表示字符类型
  • wchar_t:表示宽字符类型,可以存储 Unicode 字符。
修饰整型修饰字符型修饰双精度型
signed、unsigned、long、shortsigned、unsignedlong

1.20类型限定符

  • 类型限定符提供了变量的额外信息,用于在定义变量或函数时改变它们的默认行为的关键字
限定符含义
constconst 定义常量,表示该变量的值不能被修改。
volatile修饰符 volatile 告诉该变量的值可能会被程序以外的因素改变,如硬件或其他线程。。
restrictrestrict 修饰的指针是唯一一种访问它所指向的对象的方式。只有 C99 增加了新的类型限定符 restrict。
mutable表示类中的成员变量可以在 const 成员函数中被修改
static用于定义静态变量,表示该变量的作用域仅限于当前文件或当前函数内,不会被其他文件或函数访问。
register用于定义寄存器变量,表示该变量被频繁使用,可以存储在CPU的寄存器中,以提高程序的运行效率。
  • const
        //定义常量NUM,值不能修改
        const int NUM = 10;
        //定义指向常量的指针,指针所指的值不可修改
        const int* ptr =&NUM;
        int const* ptr2 =&NUM;
    
  • volatile
        //定义变量num,其值可能会在未知的时间被改变
        volatile int num = 20;
    
    • 往往用于多线程的修饰

      volatile boolean isNext = false;
      
      Thread A() {
          // 第一个工作
          // isNext = true;
      }
      
      Thread B (){
          if (isNext) {
              // 第二个工作
          }
      }
      
  • mutable
    class Example{
    public:
        int get_value() const{
            //const关键字表示该成员函数不会修改对象中的数据成员
            return value_;
        }
        void set_value(int value) const{
            //mutable关键字允许在const成员函数中修改成员变量
            value_ = value;
        }
    private:
        //mutable 修饰成员变量
        mutable int value_;
    };
    
  • static
    void example_function(){
        //static关键字使变量count存储在程序声明周期内都存在
        static int count = 0;
    }
    
  • register
    void example_functions(register int num){
        //register 关键字建议编译器将变量num存储在寄存器中
        //但事实上是否存储在寄存器中由编译器决定
    }
    

1.21存储类

  • 存储类定义C++程序中变量/函数的范围(可见性)和生命周期,说明符放置在它们所修饰的类型之前

    • auto
    • register
    • static
    • extern
    • mutable
    • thread_local (C++11)
  • auto
    • 声明变量时根据初始化表达式自动推断该变量的类型

    • 声明函数时函数返回值的占位符

      auto f1=3.14; //double
          auto s1("hello"); //const char*
          auto z = new auto(9); //int*
          // auto x1 = 5,x2 =5.0,x3 = 'r'; //必须初始化为同一类型
      
          cout << f1 << endl;
          cout << s1 << endl;
          cout << *z << endl;
      
  • register
    • 用于定义存储在寄存器中而不是RAM中的局部变量,不能应用一元的 & 运算符
    • 只用于需要快速访问的变量,比如计数器
    • 意味着变量可能存储在寄存器中,不是一定就存储在寄存器中
    //
    // Created by 16690 on 2024/4/18.
    //
    #include <iostream>
    using namespace std;
    
    
    int main(void){
    
        {
            register int miles;
            miles = 100;
            cout << miles << endl;
        }
        return 0;
    }
    
  • static
    • 指示编译器在程序的生命周期内保持局部变量的存在,而不需要在每次它进入和离开作用域时进行创建和销毁
    • 使用static修饰局部变量可以在函数调用之间保持局部变量的值
    • 使用static修饰全局变量时,会使变量的作用域限制在声明它的文件内
    //
    // Created by 16690 on 2024/4/18.
    //
    #include <iostream>
    using namespace std;
    
    
    //函数声明
    void func(void);
    //定义全局变量
    static int count = 10;
    
    int main(void){
        
        while( count --){
            func();
        }
        return 0;
    }
    
    void func(void){
        //局部静态变量
        static int i = 5;
        i++;
        cout << "变量i为 " << i ;
        cout << ",变量count为 " << count << endl;
    }
    

  • static修饰的成员变量

    • 静态成员变量是先于类的对象而存在

    • 这个类的所有对象共用一个静态成员

    • 如果静态成员是公有的,那么可以直接通过类名调用

    • 静态成员数据在声明时候类外初始化

  • static修饰的成员函数

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

  • extern
    • 用于提供一个全局变量的引用,全局变量对所有的程序文件都是可见的
    • 当有多个文件且定义了一个可以在其它文件中使用的全局变量或函数时,可以在其它文件中使用extern来得到已定义的变量或函数的引用
    • 用来在另一个文件中声明一个全局变量或函数
    • 用于当有两个及以上文件共享相同的全局变量或函数时

    main.cpp

    #include <iostream> // 头文件
    using namespace std; //使用std命名空间
    
    int count;
    //声明全局函数
    extern void write_extern();
    //程序执行的入口
    int main() {
        count = 5;
        //调用support中的write_extern函数
        write_extern();
    
        return 0;
    }
    
    

    support.cpp

    //
    // Created by 16690 on 2024/4/18.
    //
    #include <iostream>
    using namespace std;
    extern int count;
    
    void write_extern(void)
    {
        cout << "count: " << count << endl;
    }
    
  • mutable
    • 适用于类的对象,允许对象的成员替代常量,mutable成员可以通过const成员函数来修改
  • thread_local
    • 仅可以在其上创建的线程上访问,变量在创建线程时创建,在销毁线程时销毁
    • 可以与static 或extern合并,应用于数据声明和定义,不能用于函数声明或定义

1.22数据的输入

  • 用于从键盘获取数据

  • 语法:cin >> 接受输入的变量;

  • 31
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值