C++学习笔记(2)~数据类型和表达式

        从这篇博客开始,真正迈入C++大门吧~٩( 'ω' )و 

        本文章较长,建议分多次阅读欧~

1.预备知识

(1)注释写法

        C++的注释写法相对于C语言无特殊之处:

/*这
里是
多行注释*/

//这是单行注释

(2)函数的简单介绍

        ①C++程序由一个或多个函数组成,有且仅有一个main函数,其余为库函数和自定义函数;         ②main函数是C++程序执行入口,其位置不限,但为了便于阅读,通常位于程序的开始或尾部。

        ③函数体以“{”开始,以“}”结束。函数体内可由零个或若干语句组成,每一语句均以“;”结束。

(3)输入输出语句

        由于C++语言没有专门的输入/输出(简称I/O)语句,我们通常使用头文件iostream.h中预定义的标准输入对象cin(默认为键盘)和标准输出对象cout(默认为显示器)实现数据I/O,因此需要包含头文件iostream.h。

#include <iostream>
#include <string>
using namespace std;

int main()
{	cout << "我是输出语句 " << endl;

	string output;
	cin >> output;
	cout << output << endl;
	return 0;
}

运行结果如下:

        其中,endl意为换行符;

2.C++的字符集

        在编写C++程序的过程中,我们必须要使用C++语言字符集中的字符

      (这是不可以商量滴~(∩❛ڡ❛∩)):

         ⑴大写、小写英文字母各26个;

         ⑵阿拉伯数字10个;

          ⑶运算符、标点符号及其他字符30个:  

                  +  -  *  /  %  =  !  &  |  ~  ^     <  >  ;  :  ?  ,  .  ‘  “  \     (  )  [  ]  {  }  #  _  空格

       ((∩❛ڡ❛∩) 但凡事总有例外对吧~)

        例外: ①源程序注释中可以包含字符集以外的字符。

                    ②字符串作为数据也可以包含字符集以外的字符。 

3.标识符

        标识符的用途:程序中的变量名、函数名、数组名、类型名、命名空间名等的命名。

        标识符的构成:由大小写字母、数字和下划线组成,且首字符必须是字母或下划线,不能与关键字同名。

        说明: ⑴标识符中不能含有空格、标点符号和其他字符。

                    ⑵标识符区分大小写。例如,d和D是不同的标识符。

                    ⑶标识符的有效长度取决于具体的C++编译系统。 ⑷标识符应体现“见名知义”原则,注重可读性。

   (这里给大家介绍几种常用的命名法哈~不知道你喜欢哪一种呢?(´。・v・。`)

       ①驼峰命名法

        驼峰法是一种较为常见的变量名和函数名命名规则,其命名方式是将每个单词的首字母大写,其他字母小写(第一个单词首字母小写)。

       ②下划线命名法

        下划线命名法是一种将单词用下划线 _ 分隔的命名方式。它可以增加变量名和函数名的可读性,特别是在变量名和函数名比较长时,更容易让人理解。

       ③匈牙利命名法

        匈牙利命名法以数据类型作为前缀,后跟描述变量用途的单词。

        这种命名法的可读性比较强,但是随着代码复杂度的提升,长度增长会使得命名比较冗繁。

4.关键字

关键字又称保留字,是编程语言预定义的具有专门用途的标识符,不允许用作用户的标识符。 C++语言关键字:

C++11新增关键字:

1. constexpr 2. decltype 3. final 4. override 5. delete 6. default

传统关键字:

1. asm 2. auto 3. bool 4. break 5. case 6. catch 7. char 8.class 9. const 10. const_cast

11. continue 12. default 13. delete 14. do 15. double 16. dynamic_cast 17. else 18. enum

19. explicit 20. export 21. extern 22. false 23. float 24. for 25. friend 26. goto 27. if 28. inline

29. int 30. long 31. mutable 32. namespace 33. new 34. operator 35. private 36. protected

37. public 38.register 39. reinterpret_cast 40. return 41. short 42. signed 43. sizeof 44. static

45. static_cast 46. struct 47. switch 48. template 49. this 50. throw 51. true 52. try 53. typedef

54. typeid 55. typename 56. union 58. using 59. virtual 60. void 61. volatile 62. wchar_t

5.C++的基本数据类型

        C++是静态类型语言,必须在程序运行前为每个数据指定类型,采用编译执行,具有运行效率高的特点。

        (1)整数类型

                整数类型(整型)用于描述整数。

                   一字节整型:char,signed char,unsigned char
                   双字节整型:short int,short,signed short,signed short int,unsigned short,unsigned short int
                    四字节整型:int,signed int,unsigned int, unsigned,long int,long,signed long,signed long int,unsigned long,unsigned long int

        (2)实数类型(浮点型)

                     float:单精度浮点数,4字节

                     double:双精度浮点数,8字节

                      long double:多精度浮点类型,对 long double 的处理,取决于编译器。

        (3)字符类型

                     用char表示,用于描述单个字符数据。

                     char字符用ASCII码表表示,在储存时占用一个字节。

                     C++允许把char型数据当作整型数据,因此,C++允许用signed和unsigned修饰char,即可以有signed char和unsigned char类型。 

                     在C++中,字符串string是单独定义的一个类而非数据类型,我写了一篇专门的文章放在专栏里面来详细的介绍C++中string类的使用方法,感兴趣的小伙伴们可以去看一看。

        (4)空值(void)

 使用场景:         

  • 构造无参函数;
  • 描述函数无返回值;
  • 无类型指针;

         (5)布尔类型(boolean)

                用于描述“真”和“假”。

                只有两个值,0表示假,1表示真。

6.构造数据类型

(1)枚举类型

         ① 什么是枚举

        枚举类型是一种可以由用户自定义数据集的数据类型,可以将一组整型常量组织在一起。

        (bool类型可以看成是C++语言提供的一个预定义的枚举类型。)

          ②使用场景 
  • 表示有限集合 

          枚举非常适合用来表示一组有限的、固定的值,如一周的七天、一年的四个季节等。

  • 单例模式的实现

        枚举可以作为实现单例模式的一种方式,因为它在C++中保证了只会有一个实例,且线程安全。

  • 配置选项

        在配置文件中,可以使用枚举来表示不同的选项或设置。

        枚举类型在C++中具有极其重要的作用,它的重要性主要体现在这些方面:    

  •         增加代码可读性和可维护性
  •         增加代码的类型安全性
  •         使代码易于扩展
  •         便于与其他编程概念的集成        
          ③枚举类型入门:
  •         枚举类型是一种用户定义的类型,它包含了一组命名的整型常量。使用enum关键字来定义枚举类型。        
enum Weekend { Saturday,Sunday };
  • 使用枚举常量
Weekend tomorrow = Sunday;
  • 枚举常量的默认值

        默认情况下,枚举常量的默认值从0开始

enum Color { RED, GREEN, BLUE };
//RED = 0,GREEN = 1,BLUE =2;
          ④进阶理解
  • 显式赋值

        可以为枚举常量显式的指定整数值

enum Weekend { Saturday = 6,Sunday = -1 };

        还可以部分指定,未指定的枚举常量的值默认为前一个值加一

enum Color { RED, GREEN = -1, BLUE };
//RED = 0,GREEN = -1,BLUE = 0;

        还可以重复指定

enum Color { RED, GREEN = 9, BLUE =9};
//RED = 0,GREEN = 9,BLUE = 9;
  • 枚举的作用域

        枚举常量具有作用域,它们的作用域限于定义它们的枚举类型。

enum Type1 { A };  
enum Type2 { A }; // 合法,因为A属于不同的作用域
  • 枚举与switch语句

        在C++中,可以使用枚举常量作为switch语句的条件。

enum Operation { ADD, SUBTRACT, MULTIPLY, DIVIDE };  
  
void performOperation(Operation op, int a, int b) {  
    switch (op) {  
        case ADD:  
            // ...  
            break;  
        // 其他case...  
    }  
}
          ⑤高级特性
  • 枚举类(C++11及以后)

        C++11引入了枚举类(enum class),它提供了更强的类型安全性。枚举类中的枚举常量不会自动转换为整型,需要显式转换。

        该值与枚举类型的显式赋值无区别

enum class TrafficLight { RED, YELLOW, GREEN };  
TrafficLight light = TrafficLight::RED; // 正确  
// int val = light; // 错误,需要显式转换

int val = static_cast<int>(light);
//显式转换为int类型
  • 枚举类的作用域

        枚举类中的枚举常量具有强作用域,必须使用枚举类名加作用域解析运算符::来访问。

TrafficLight::RED; // 正确访问枚举常量

(2)数组类型

①数组介绍
        数组,简单来说,就是一个能够存储多个同类型数据的容器。你可以把它想象成一个排列整齐的箱子,每个箱子里面都可以放相同类型的东西,比如都是苹果或者都是书。

        数组有一个重要的特点,那就是它里面的数据是有顺序的,也就是说,第一个箱子、第二个箱子、第三个箱子……都是按照一定的顺序排列的。因此,当你想要找某个数据时,只需要知道它在数组中的位置(也就是“第几个箱子”),就可以很快地找到它。

        数组具有两个特点:

        特点1: 数组中的每个数据元素都是相同的数据类型

        特点2:计算机为数组内的元素储存所分配的内存是连续的

②数组的定义
  •         一维数组:
//数组的定义是这样子的
//数据类型 数组名[数组大小]

int num[10];

//这样就定义了一个名为num,大小为10的int类型数组,数组的每一个元素都是int类型的
  •         二维数组:

        所谓二维数组,可以看为一个数组的数组,外层数组的每一个元素都是一个新的数组

定义如下:

int num[5][5];

        这样就定义了一个5*5的二维数组

③数组的初始化
  •         初始化数组时,可以直接写出每个元素用于初始化数组
int num[3] = {1,2,3};
  •          也可以写出部分元素,此时,num[1]与num[2]的值都为0(数组使用时下标从0开始计算)
int num[3] = {1};
  •           也可以不写数组大小并初始化,此时数组大小默认为初始化的数组大小
int num[] = {1,2,3};
④ 数组名的作用
  1. 可以统计整个数组在内存中的长度,使用sizeof方法
  2. 可以获取数组在内存中的首地址(直接使用即代表数组所占内存的首地址)

(3)结构类型

        (对于内存浪费的现象,我们常使用位域类型来解决,具体我将会专门写一篇博客放在本专栏下来介绍它的使用,位域类型即含有位域的结构体类型。)

①结构类型介绍

        在C++中,结构类型(通常称为“结构体”)是一个用户自定义的数据类型,它可以包含多个不同类型的数据成员。你可以将结构体看作是一个容器,这个容器里可以存放多种不同类型的东西。

        使用结构体有很多的好处。首先,它可以帮助我们将相关的数据组织在一起,使得代码更加清晰和易于理解。其次,通过定义结构体,我们可以创建多个具有相同数据结构的变量,而不需要为每个变量重复定义相同的数据成员。最后,结构体还可以包含其他结构体作为成员,从而实现更复杂的数据结构。

②结构类型的定义
  • 一般定义方法

         结构体类型需先定义后使用,其定义格式:

struct  结构体类型名{        
            类型1  成员1;
            类型2  成员2;  
               ……    
 };

说明:1.结构体类型名用标识符表示。

           2.成员可以是基本类型或导出类型的变量,不能指定存储类型为auto、register、extern,但可指定存储类型为static。

           3. 定义结构体类型用分号“;”表示结束。

           4.结构体类型是一个存储模型,本身不占内存,仅当定义其变量时,系统才按此存储模型为其变量分配相应的内存。

  • 结构体变量定义的其他形式
       结构体类型变量也可在声明结构体类型的同时定义。
 struct day{
       int year,month,day;
    }today,yesterday;

        无名结构类型

    struct{      //定义一个无名结构类型
       int num1;
       float num2;
    }x,y;
  //无名结构体类型不能在该类型定义之外定义其变量。
③结构体变量的初始化

        结构体变量的初始化:与数组的初始化方式类似,在花括号中,按结构体成员说明的顺序依次列出其值。

        例如:

struct student{
    char name[20];
    int age;
    int grade;
}

int main(){
    
    student xiaoming={"xiaoming",17,3};
    return 0;
}
④结构体变量的使用

      Ⅰ.  访问结构体变量成员的格式为:  

                    结构体变量.成员名  

其中“.”是成员访问运算符。

例如:       xiaoming.age   表示访问结构体变量xiaoming的成员age。

        Ⅱ.相同结构体类型的变量之间可直接赋值。

例如:

student xiaohong;
xiaohong = xiaoming;

此时xaohong与xiaoming的每一个值都相同。

        Ⅲ.结构体类型变量不能直接输入/输出,其成员能否直接输入/输出,取决于其成员的类型,若是基本类型或字符数组,则可直接输入/输出。

对于其他类型

  1. 自定义类型
    如果结构体成员是另一个结构体或类,你需要为每个子成员分别进行输入输出。

  2. 指针
    如果结构体包含指针成员,通常你需要先为指针分配内存(例如使用newmalloc),然后再对分配的内存进行输入输出。

  3. 动态数组
    如果结构体包含动态数组(例如通过指针指向的数组),你需要遍历数组并逐个元素地进行输入输出。

  4. 标准库容器
    对于C++标准库中的容器,如std::vectorstd::string等,你可以直接使用容器提供的成员函数或操作符来进行输入输出。

  5. 自定义类
    如果结构体成员是一个类,并且该类没有提供输入输出操作符的重载,你可能需要调用该类的成员函数来进行输入输出。

        Ⅳ.结构体类型变量做函数的形参时,调用函数的实参必须是相同结构体类型的变量。参数的传递方式为值传递,系统将实参的每个成员逐个拷贝给对应的形参成员。结构体类型变量也可做函数的返回值。

(4)联合类型

①联合类型的介绍 

        联合体是一种特殊的数据类型,用于存储不同类型的变量在同一内存位置。联合体的所有成员都共用同一段内存,即这些成员共享相同的起始地址。在联合体中,只有一个成员可以是活跃的,其他的都是不可用的。这意味着在某一时刻,只有一个成员的值是有效的。如果改变联合体中某个成员的值,其他成员的值也可能会改变,因为它们共享同一块内存空间。

        与结构体(struct)不同,结构体中的每个成员都有自己的内存空间,因此结构体变量的总长度通常大于或等于各成员长度之和。而联合体的长度则等于其成员中最长的长度,因为它的所有成员共享同一段内存。

②联合体的定义

        联合体类型的定义格式:    

                union 共用体类型名{      

                                                数据类型  成员名1;      

                                                数据类型  成员名2;        

                                                         ……    };

                共用体类型定义后,即可定义其变量、数组、指针和引用等。

例如:

union num{
    int a;
    float b;
    char c;
}

int main(){
    
    num n1;
    num n2[10];
    num *p;

return 0;
    }
③常用操作

        对共用体变量的操作与结构体变量类似。

例如:  

    n1.a=17;
    n1.b=23.5;
    n1.c="杉";

 

  注意,当对变量n1的成员b赋值时,覆盖了成员a的值;类似的当对成员c赋值时,又覆盖了成员b的值。同一时刻,只可使用其中的一个成员。 共用体可做函数的参数和返回值。

(5)指针类型

①指针引入

        首先,我们要理解“内存”这个概念。你可以把内存想象成一个大仓库,里面有很多小房间,每个房间都有一个唯一的编号,这个编号就是地址。每个房间都可以存放东西,比如整数、字符、浮点数等。

        在C++中,变量就是用来存储数据的。当我们声明一个变量时,计算机就会在内存中为它分配一个房间,并且给它一个编号(地址)。这个编号我们是看不到的,但是C++提供了一种特殊的变量,叫做指针,它可以用来存储这个编号(地址)。

        所以,指针就是一个变量,它的值就是另一个变量的地址。你可以通过指针找到那个地址对应的房间,从而访问或修改那个房间里的数据。

②指针的声明与初始化
  • 声明指针:使用星号(*)作为指针的标识符。例如,int* ptr; 声明了一个指向整数的指针。
  • 初始化指针:你可以将另一个变量的地址赋给指针,使用取地址符(&)来获取变量的地址。例如,int num = 10; int* ptr = &num; 将num的地址赋给了ptr指针。
③解引用指针

        使用解引用运算符(*)可以访问指针指向的内存地址上的值。例如,*ptr 就是访问ptr指针指向的值。

        注意,解引用一个未初始化的指针或指向无效内存的指针是危险的,可能导致程序崩溃。

④指针与数组

        数组名本身就是一个指针,指向数组的第一个元素。你可以使用指针来遍历和访问数组的元素。例如,int arr[5] = {1, 2, 3, 4, 5}; int* p = arr; 现在p指向arr的第一个元素,你可以通过*(p+i)p[i]来访问数组的元素。

⑤指针作为函数的参数

        在C++中,你可以将指针作为函数的参数,这样在函数内部就可以修改指针指向的值。这样的使用很常见,比如交换两个变量的值、在函数中修改数组的元素等。

⑥指向函数的指针

        函数名在大多数上下文中会转换为指向该函数的指针。我们可以声明一个指向函数的指针,并通过这个指针来调用函数。这在实现回调函数、函数表等功能时非常有用。

指针的高级用法
  • 指针数组:一个数组,其元素都是指针。例如,int* ptrs[5]; 声明了一个包含5个整数指针的数组。
  • 指向指针的指针:也就是二级指针。例如,int** p; p指向一个整数指针。这种指针在进行动态内存分配、二维数组操作等的时候非常有用。
  • void指针:void指针可以指向任何类型的数据,但不能直接进行解引用操作。通常用于泛型编程和作为中间类型进行类型转换
使用指针时要尤其注意内存安全

1.C++允许将一个整型常数经强制类型转换后赋给一个指针变量。

例如:        float *p1;        p1=(float*)10000;

但这种方法仅在设计系统程序或对计算机内存分配非常清楚,且有明确目的时才有意义,否则可能产生严重后果。 初学者不应使用这种方法初始化指针变量。

2.向一个未初始化的指针变量所指存储单元赋值是极其危险的。

原因:未初始化指针的值是随机的,它所指存储单元可能是未分配的内存,也可能是已分配的内存。若是后者,把数据写入该存储单元,轻者导致程序运行结果出错,重者导致系统出错或崩溃。

3.不同类型的指针变量之间的赋值经强制类型转换后是允许的,但应有明确的目的和意义。

4.指针允许进行算数操作

(6)引用类型

①引用的概念

        引用允许我们为已有的变量创建一个别名。换句话说,引用就是变量的另一个名字,通过这个别名,我们可以直接访问和修改原变量的值。

引用的声明与初始化
  • 声明引用:引用的声明方式与变量类似,只是需要在变量名前加上一个&符号。例如:

        int a = 10;

        int& ref = a;

     声明了一个名为ref的引用,它引用了变量a

  • 引用必须初始化:引用在声明时必须被初始化,即它必须指向一个已存在的变量。一旦引用被初始化,它就不能再指向其他变量。这是因为引用本质上是一个已经存在的变量的别名,它不能脱离这个变量而存在。
引用的特性
  • 引用和原变量共享内存地址:引用和它所引用的变量在内存中是同一个地址,因此通过引用修改变量的值,原变量的值也会改变。
  • 引用一旦初始化,不能重新赋值:由于引用是变量的别名,它必须始终指向同一个变量。因此,你不能将一个引用重新指向另一个变量。
引用与指针的区别
  • 存储方式:指针是一个变量,它存储的是另一个变量的内存地址。而引用本身并不存储任何值,它只是原变量的别名,与原变量共享同一块内存空间。
  • 操作方式:你可以改变指针的值,使其指向不同的内存地址。但你不能改变引用的值,使其指向不同的变量。
  • 空值:指针可以为空(即不指向任何变量),但引用必须指向一个有效的变量。
引用的使用场景
  • 函数参数:使用引用作为函数参数可以避免复制大型对象,提高效率。同时,通过引用传递参数,函数内部可以直接修改原变量的值。
  • 返回值:使用引用作为函数的返回值可以返回大型对象或数组,而不需要复制整个对象或数组。
  • 常量引用:常量引用可以用于防止函数内部修改传入的参数,保证参数的安全性。
⑥注意

         使用引用时需要注意避免野引用(未初始化的引用)和悬空引用(引用所指向的变量被销毁后,引用仍然存在)等问题。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值