C++启蒙笔记(二)---数据类型

一、通用设置

1.1 基本概念

  • 内存概念

    名称意义
    位(bit)计算机物理存储基本单位,可以看做电子开关,关(0),开(1)
    字节(Byte)计算机内存使用的最小单位,1 Byte = 8 bit,1字节可表示256个数(2的8次方),对应ASCII码
    常规存储1GB = 1024MB = 1024x1024 KB = 1024X1024X1024 B = 1024^3 * 8bit
  • 变量命名规则

    关键字规则
    变量前缀s(字符串)、c(单个字符)、p(指针)、b(布尔值)、无(整形、浮点型);例:pmy_num
    大小写类名MyClass()、函数myFunction、普通变量名:my_num
    常量大写MY_NUM
  • 强制类形转换

    关键字说明
    static_cast常规:编译期间转换,一般不会导致意外发生,风险很低
    const_cast常规:用于 const 与非 const、volatile 与非 volatile之间的转换
    reinterpret_cast高危:这种转换仅仅是对二进制位的重新解释,不会借助已有的转换规则对数据进行调整,但是可以实现最灵活的 C++ 类型转换
    dynamic_cast进阶:程序运行期间借助 RTTI 进行类型转换,用于类型安全的向下转型(Downcasting)

1.2 强制类型转换

  • 常用初级转换(其他的进阶了再学)
    // C 风格的强制类型转换,C++ 中编译器渐渐不支持了
    double scores = 95.5;
    int n = (int)scores;
    // C++ 风格写法,功能同上
    double scores = 95.5;
    int n = static_cast<int>(scores);
    

    超界:默认超界会产生不可预知错误

二、数字

2.1 整型、浮点型、const限定符

  • 整形

    名称范围unsigned
    short型2字节,(-215) ~ (215 -1),3万级别16比特,第一比特是符号位,unsigned short:没有负数,范围扩大一倍,无符号位
    int型4字节,(-231) ~ (231 -1),,21亿级别unsigned:没有负数,范围扩大一倍
    long型同上同上
    long long型8字节,(-263) ~ (263 -1),,9百万兆级别unsigned long long:没有负数,范围扩大一倍
  • 浮点型

    名称范围写法
    float型上限极值:3.40282e38
    下限极值:1.17549e-38
    标准用法:float num = 3.1415926f
    科学计数法:3.14159e10f
    double型上限极值:1.79769e308
    下限极值:2.22507e-308
    标准小数型:double num = 3.1415926
    科学计数法型:3.14159e10
  • 以上两者写法

    // 定义:type 变量名;
    int n;
    double dn;
    // 赋值
    n = 3;
    dn = 3.14;
    // 定义、初始化:type 变量名 = 值;
    int n = 3;
    double dn = 3.14;
    
  • const限定符

    // 常量必须定义同时初始化,且相应生命周期内不可改变
    // 限定符只在仅在执行改变常量的操作时才会发挥作用
    // 写法:const type 常量名 = 值;	
    const int n = 3;
    const double dn = 3.14;
    

2.2 C++内置函数声明

  • 列表
    写法参数解释
    double cos(double)形参是弧度值,返回值为余弦值(浮点型),sin、tan同样
    double log(double)返回参数的自然对数(浮点型)
    double pow(double, double)假设首参数为x,次参数为y,返回x的y次方(浮点型)
    double sqrt(double)返回参数的平方根(浮点型)
    int abs(int)返回整数的绝对值(整型)
    double round(double)四舍五入,返回浮点型,3.5=>4.0
    double floor(double)向下取整,3.5=>3.0
    double ceil(double)向上取整,3.5=>4.0

2.3 生成随机数

  • 代码示例
    #include <iostream>
    // time()函数显示现在到1970年1月1日午夜的秒数(int)
    #include <ctime>
    // 随机函数的头文件
    #include <cstdlib>
    
    using namespace std;
    
    int main()
    {
        /* strand()为种子函数,相同的种子,生成的随机数相同,
    	每次运行用time()函数初始化种子函数,放入内存中 */
        srand(time(NULL));
        for (int i = 0; i <= 7; i++)
        {
        	/* 
        	1、rand()产生一个随机整数:若种子相同,序列顺序及值也相同,
    		在0~(int)RAND_MAX之间 
    		2、自定义随机数区间:6是随机集合整数的个数,-3是起始整数,
    		代表-3~2,注意包含0
    		*/
            int y = rand() % 6 - 3;
            cout << y << endl;
        }
    }
    

四、数组及枚举

4.1 数组

  • 定义
    // 定义、初始化:大括号只可在此初始化情况下用
    // 二选一:不可重复定义
    int num_arr[3] = {10, 30, 40};					
    int num_arr[3] = {};						
    
    // 定义
    int num_arr[3]; 					
    // 赋值:为单个元素赋值,序号为0、1、2			
    num_arr[2] = 40;								
    
  • 长度计算(sizeof 函数)
    // 显示数组占用的内存总长:12字节
    int size_of_array = sizeof(num_arr);		
    // 显示其中一个元素占用的长度(每个占用的都一样):4字节	
    int size_of_element = sizeof(num_arr[1]);	
    // 相除,得有几个元素:3个	
    int num = size_of_array / size_of_element ;		
    
  • 指针前导(具体看指针篇)
    int arr[3] = {1,3,5};
    int * pt, * pt_1;
    // pt指向数组的第一个元素的首地址
    pt = arr;			
    // pt_1指向数组第二个元素的地址
    pt_1 = &arr[1];		
    // 打印数组第一个元素的值:1
    cout << *arr << endl;
    

4.2 枚举(类似批量const功能)

  • 初始化
    // 以下二选一,不可重复定义
    // enum叫枚举型,elist 叫枚举,red为符号常量,0为枚举值
    enum elist {red, yellow, blue, orange};					
    // 其值为     0     1       2      3
    enum elist {red = 2, yellow = 0, blue, orange};
    // 其值为     2         0         1      2
    
  • 赋值
    // 以下二选一,不可重复定义
    // 枚举变量的定义、初始化,不可用 band = 2,也不可加减
    elist band = blue;			
    // 枚举变量定义
    elist band_2;				
    
    // 赋值方法一:
    band_2 = band;		
    // 赋值方法二:
    // 此方法是选择值为2的符号常量,即blue赋给band_2
    band_2 = elist(2);	
    		
    // 输出枚举值:整型,结果为2
    cout << band_2 << endl;			
    

五、字符类

5.1 C风格字符串

  • 字符(相当于下面一个格子)

    名称范围
    char型1字节存储一个字符,单字节字符,局限性最大,能表示256个字符
    wchar_t型2字节存储一个字符,宽字节字符,老版本
    char_16型2字节存储一个字符,unicode字符
    char_32型4字节存储一个字符,unicode字符

    编码:字节里存整型,每个数字对应一个字符,其映射表刻在cpu中。
    局限:char只能应用于英语国家,宽字节及unicode编码用于世界各国。

  • 以下是 C/C++ 中定义的字符串的内存表示:
    在这里插入图片描述

  • 本质:C风格字符串本质为字符数组,变量名为数组首元素的地址(指针篇详解)

5.1.1 初始化

  • 写法
    // 内存存储:'1'、'2'、'3'、'\0'、'\0',内存浪费
    char charr_1[5] = "123";		
    // 内存存储:'1'、'2'、'3'、'\0',刚刚好	
    char charr_2[4] = "123";		
    // 内存存储:'1'、'2'、'\t'、'3'、'\0',刚刚好	
    char charr_3[5] = "12\t3";			
    // 报错:数组界限溢出
    char charr_4[3] = "123";			
    	
    // 编译器自动选择合适数组位数,同charr_2
    char charr_5[] = "123";				
    // 在Unicode中常会被用到,使用方法相同
    wchar_t title[] = L"宽字符串"
    • 末尾隐式追加:’\0’会自动隐式的添加到字符数组尾,显示定义数组位数时需注意
    • wchar_t:宽字符类型(老版本)
      • 初始化字符变量:wchar_t words = L'a';
      • 输入输出字符串:wcout << L"abcd" << endl;,同理wcin
    • C++新增类型:
      • 写法一:char16_t ch1 = u'a';
      • 写法二:char32_t ch2 =U'a';

5.1.2 常用方法

  • 头文件:#include <cstring>,针对后缀有_s方法
  • 字符串赋值
    char charr_0[3] = {};
    char charr_1[5] = "abcd";
    // 字符串指针初始化(看完指针篇回看)
    // "abcd"为字符串字面量,存储在只读内存区的字面量池中,因为只读
    // 所以可以用const指针指向此字符串字面量值
    const char * charr_n = "cdefg";
    
    // 常规方法:直接赋值字符串,注意跟初始化区别,这是深拷贝
    strcpy(charr_0, "ef");
    
    // 方法1:将charr_1复制给charr_0,控制2个字符(自动追加\0),若超则报错
    strcpy_s(charr_0,2,charr_1);	 
    
    //方法2:起始复制--将charr_1取出2个字符复制给charr_0,若超出则报错
    strncpy_s(charr_0, 3, charr_1, 2);	
    // 手动尾部追加\0
    charr_0[2] = '\0';			
    
    // 方法2:非起始复制--从charr_1第2个字符起复制3个字符给charr_0,即"bcd"
    //	sizeof为C++关键字,它是一个编译时运算符,用于判断变量或数据类型的字节大小
    strncpy_s(charr_0, sizeof(charr_0), charr_1+1, 3);		
    

    此处涉及到数组指针相关,建议看完指针回看
    strcpy_s:是strcpy的安全版本,新的C++编译器强制使用这个,strcat同
    strncpy的原型为:char * strncpy(char * str2, char * str1, int size);

  • 拼接、长度、比较
    // 将charr_1追加到charr_0尾部,且总长不超过10,程序员控制charr_0的长度
    strncat(charr_0, charr_1, 3);	
    // 字符数组长度,不包含'\0',但字符数组尾部至少有一个格子存\0
    int num = strlen(charr_1);		
    // 比较两个字符串,实参为字符串指针:
    // 	若返回负数,a,b为正序
    // 	若返回正数,a,b为逆序
    if (strcmp(a, b) == 0) cout << "两字符串相同" << endl;
    

5.2 string类库

5.2.1 基础操作

  • 调用文件
    • 头文件:#include<string>
    • 名称空间:using namespace std;
  • 初始化、赋值
    // 常规初始化
    string str_1 = "123";			
    // 默认为空
    string str_2;
    // 拷贝赋值:str_3为str_1的副本,两个值隔离
    string str_3(str_1);
    // 缩写法:“***”
    string str_4(3,'*');
    
    // 赋值:区别于定义(初始化)
    str_4 = "123";	
    
  • 转换为char*
    string str_3 = "help";
    // 方法1:c_str函数返回的字符串字面量,即const char*类型
    const char *c_1 = str_3.c_str();
    // 方法2:const_cast:强制类型转换,去掉const属性,返回char*变量
    char *c_2 = const_cast<char *>(str_3.c_str());
    // 方法3:使用堆内存动态存储
    char * c_3;
    c_3 = new char [str_3.size()+1];
    strcpy (c_3, str_3.c_str());
    
    // 下面错误赋值原因:因为c_str函数创建一个副本并赋值
    // 随后副本被析构,temp指向垃圾内存,编译错误
    char* temp; 
    string s="1234"; 
    // 错误:temp = s.c_str();
    strcpy(temp, s.c_str());
    

    函数字符串传递:形参定义为:const string & ,可以接收实参为: string,char * ,const char *,字符串字面值

  • 字符串转string:可以直接赋值
    const char * charr_n = "cdefg";
    string str = charr_n;
    
  • 计算
    // 拼接,输出:123123
    string str_3 = str_1 + str_2;	
    // 拼接2:尾部附加
    str_3 += "end";					
    // 字符串长度,不包含'\0'
    int num = str_3.size();			
    

5.2.2 进阶操作

  • 列表释义
    写法意义
    cout << s;直接在屏幕打印字符串
    cin>>s1>>s2;键盘连续赋值,可空格或enter区隔
    getline(cin,s);将一行输入string变量s中
    s.empty();若s为空,返回true
    s.size();返回字符串字符个数
    s[n];第n个字符,0开始
    s1 + s2;字符串拼接
    s1 = s2;赋值操作
    s1 == s2判断两字符串是否值相同

六、自定义组合类型

6.1 结构

  • 定义:结构是用户定义的类型(模板),通过将一组简单的数据类型组合成一个新的数据类型
  • 声明
    // goods为特定的结构类型
    struct goods							
    {
    	// 用于存储商品名称
    	char name[20];		
    	// 用于存储商品个数				
    	int store;				
    	// 用于存储产品单价			
    	double price_per;					
    };	// 分号很重要,别落了
    
    struct goods
    {
    	char name[20];
    	int store_num;
    	double price_per;
    // 声明同时定义两个变量
    } fruit_0,fruit_1; 						
    

    注:可以放在函数外,全局可用,也可以在内部,仅当前函数内可用

  • 赋值
    // 定义、初始化
    goods fruit_0 = {};						
    // fruit_1数据类型是goods结构,定义、初始化
    goods fruit_1 = {"apple", 135, 4.5};		
    
    // 结构化数组,定义、初始化
    goods food[3] = 						
    	{
    		{"rice", 123, 23.5},
    		{"bread", 503, 10.0},
    		{"egg", 1350, 13.5}
    	};	    // 注意结尾分号
    
  • 调用
    // 普通结构
    cout << fruit_1.store << endl;			
    // 结构列表
    cout << food[2].price_per << endl;		
    

6.2 共用体

  • 定义:一种数据格式,能同时存储int,long或double,当数据项使用两种或多种格式(但不会同时使用),可节省空间
  • 声明
    // 方法1:
    // 可以用此语句块替换结构声明中的 int store; 行
    union store								
    {
    	int int_store;
    	double double_store;
    };	// 分号很重要										
    
    // 方法2:声明定义共用体,同时定义共用体变量
    union store					
    // 可以用此语句块替换结构声明中的 int store; 行			
    {
    	int int_store;
    	double double_store;
    } store_egg;	// 分号很重要						
    
  • 赋值及调用
    // 定义共用体变量store_egg
    store store_egg;		
    // 变量赋值				
    store_egg.int_store = 1590;					
    

上一篇:C++启蒙笔记(一)—编程语言通用部分
下一篇:C++启蒙笔记(三)—指针

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值