栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C++ Primer Plus学习(三)—— 复合类型

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++ Primer Plus学习(三)—— 复合类型

复合类型

数组字符串string类简介结构简介共用体枚举指针和自由存储空间指针、数组和指针算术数组的替代品


数组

    数组(array)是一种数据格式,能够存储多个同类型的值。

    数组声明
    数组声明应该指出:
    - 存储在每个元素中的值的类型;
    - 数组名;
    - 数组中的元素数。
    通用格式如下:
    typeName arrayName[arraySize];
    如:
    short months[12]; // short数组

    数组初始化
    - 只有在定义数组时才能使用初始化,此后就不能使用了,也不能将一个数组赋给另一个数组;
    - 可以使用下标分别给数组中的元素赋值;
    - 如果只对数组 一部分进行初始化,则编译器将把其他元素设置为0;
    - 如果初始化数组时方括号内([])为空,C++编译器将计算元素个数。
    - 列表初始化禁止缩窄转换(not allowed: long arr[] = {25, 92, 3.0};)

字符串
    字符串是存储在内存的连续字节中的一系列字符。C++处理字符串的方式有两种。第一种来自C语言,常被称为C-风格字符串串,另一种是基于string类库的方法。C-风格字符串具有一种特殊性质:以空字符结尾,空字符被写作,其ASCII码为0,用来标记字符串的结尾。
    如:
    char dog[8] = {'f', 'a', 't', 'e', 's', 's', 'a', ''};用引号括起的字符串隐式地包括结尾的空字符,因此不用显式地包括它。
    如:
    char fish[] = "Bubbles";字符串常量(使用双引号)不能与字符常量(使用单引号)互换。下面的语句将83赋给shirt_size:
    char shirt_size = 'S';
    但"S"不是字符常量,它表示的是两个字符(字符S和)组成的字符串。实际上"S"表示的是字符串所在的内存地址。sizeof()运算符指出整个数组的长度,但strlen()函数返回的是存储在数组中的字符串的长度,且只计算可见字符,不把空字符计算在内。getline()和get()
    istream中的类提供了一些面向行的类成员函数:getline()和get()。这两个函数都读取一行输入,直到到达换行符。然而,随后getline()将丢弃换行符,而get()将换行符保留在输入序列中。
string类简介

要使用string类,必须在程序中包含头文件string。string类位于名称空间std中,因此您必须提供一条using编译指令,或者使用std::string来引用它。

更多关于string的测试代码见下一篇博客:string简介

结构简介
    结构是一种比数组更灵活的数据格式,因为同一个结构可以存储多种类型的数据。可以将结构作为参数传递给函数,也可以让函数返回一个结构。还可以使用赋值运算符(=)将结构赋给另一个同类型的结构,这样结构中每个成员都将被设置为另一个结构中相应成员的值,即使成员是数组。这种赋值被称为成员赋值。struct和class类似,唯一区别就是struct和里默认是public,而class里默认是private;一般如果包含方法,则可用class,如果只有数据,则可用struct。
共用体
    共用体(union)是一种数据格式,它能够存储不同的数据类型,但只能同时存储其中的一种类型。由于共用体每次只能存储一个值,因此它必须有足够的空间来存储最大的成员,所以,共用体的长度为其最大成员的长度。共用体的用途之一是,当数据项使用两种或多种格式(但不会同时使用)时,可节省空间。
枚举
    枚举类型(enumeration)是 C++ 中的一种派生数据类型,它是由用户定义的若干枚举常量的集合。定义格式:枚举类型的定义格式为:
    enum <类型名> {<枚举常量表>};
    关键字enum——指明其后的标识符是一个枚举类型的名字。
    枚举常量表——由枚举常量构成。“枚举常量"或称"枚举成员”,是以标识符形式表示的整型量,表示枚举类型的取值。枚举常量表列出枚举类型的所有取值,各枚举常量之间以","间隔,且必须各不相同。取值类型与条件表达式相同。
指针和自由存储空间
    指针概览
    int update = 6;   // declare a variable
    int * p_update;  // declare pointer to an int
    p_update = &update;  // assign address of int to pointer
    *p_update += 1;   // update value of int
    
    注意,以上*运算符两边的空格是可选的,而很多都是采用如下格式:
    int* p_update
    这强调的是:int*是一种类型——指向int的指针。一定要在对指针应用解除引用运算符(*)之前,将指针初始化为一个确定的、适当的地址。以下就是一个错误例子:
    long* fellow;
    *fellow = 223223;  // 这里没有对fellow这个指针就行有效初始化,所以它可能有任何值
    
    在编译时给数组分配内存被称为静态联编(static binding),意味着数组是在编译时加入到程序中的。但使用new时,如果在运行阶段需要数组,则创建它;如果不需要,则不创建。还可以在程序运行时选择数组的长度。这被称为动态联编(dynamic binding),意味着数组是在程序运行时创建的。这种数组叫做动态数组(dynamic array)。使用new和delete时,应遵守以下规则:

    不要使用delete来释放不是new分配的内存不要使用delete释放同一个内存块两次如果使用new[]为数组分配内存,则应使用delete[]来释放如果使用new为一个实体分配内存,则应使用delete(没有方括号)来释放对空指针应用delete是安全的。 动态数组的使用

    #include 
    using namespace std;
    
    int main()
    {
    	double* p3 = new double [3];
    	p3[0] = 0.2;
    	p3[1] = 0.5;
    	p3[2] = 0.8;
    	cout << "p3[1] is " << p3[1] << ".n";   // p3[1] is 0.5
    
    	p3 = p3 + 1;   // increment the pointer
    	cout << "Now p3[0] is " << p3[0] << " and ";   // Now p3[0] is 0.5
    	cout << "p3[1] is " << p3[1] << ".n";   // p3[1] is 0.8
    	p3 = p3 - 1;    // point back to beginning
    	delete [] p3;   // free the memory
    	return 0;
    }
    
指针、数组和指针算术
    将整数变量加1后,其值将增加1;但将指针变量加1后,其增加的值等于指向的类型占用的字节数。对数组应用sizeof运算符得到的是数组的长度(C++将数组名视为数组的第一个元素的地址),而对指针应用sizeof得到的是指针的长度,即使指针指向的是一个数组。使用方括号数组表示法等同于对指针解除引用;对于指针和数组名,既可以使用指针表示法,也可以使用数组表示法。在cout和多数C++表达式中,char数组名、char指针以及用引号括起的字符串常量都被解释为字符串第一个字符的地址。直接将两个字符串进行赋值操作是不可行的,因为这样只能修改存储在其中的地址,从而失去程序访问新分配内存的唯一途径。需要使用库函数strcpy(): strcpy(ps, animal);,strcpy()函数接受2个参数,第一个是目标地址,第二个是要复制的字符串的地址。在指定结构成员时,如果结构标识符是结构名,则使用句点运算符;如果标识符是指向结构的指针,则使用箭头运算符。自动存储、静态存储和动态存储

    自动存储
    在函数内部定义的常规变量使用自动存储空间,被称为自动变量,这意味着它们在所属的函数被调用时自动产生,在该函数结束时消亡。
    自动变量通常存储在栈中。这意味着执行代码块时,其中的变量依次加入到栈中,而在离开代码块时,将按相反的顺序释放这些变量,这被称为后进先出(LIFO)。因此,在程序执行过程中,栈将不断地增大和缩小。

    静态存储
    静态存储是整个程序执行期间都存在的存储方式。使变量成为静态的方式有两种:一种是在函数外面定义它;一种是在声明变量时使用关键字static。
    自动存储和静态存储的关键在于:这些方法严格地限制了变量的寿命。变量可能存在于程序的整个生命周期(静态变量);也可能只是在特定函数被执行时存在(自动变量)。

    动态存储
    new和delete运算符提供了一种更灵活的方法,它们管理了一个内存池,这在C++中被称为自由存储空间或堆(heap)。堆中的数据生命周期不完全受程序或函数的生存时间控制。
    在栈中,自动添加和删除机制使得占用的内存总是连续的,但new和delete的相互影响可能导致占用的自由存储区不连续,这使得跟踪新分配内存的位置更困难。

数组的替代品
    模板类vector和array是数组的替代品。模板类vector类似于string类,也是一种动态数组。要使用vector对象,必须包含头文件vector,且需要using namespace stdvector类的功能比数组强大,但付出的代价是效率稍低。如果您需要的是长度固定的数组,使用数组是更加的选择,但代价是不那么方便和安全。因此,可以使用模板类array。array对象的长度也是固定的,使用栈(静态内存分配),而不是自由存储区。Example:
    double a1[4] = {1.2, 2.4, 3.6, 4.8};
    
    vector a2(4);
    a2[0] = 1.0/3.0;
    
    array a3 = {3.14, 2.72, 1.62, 1.51};
    array a4;
    a4 = a3;
    
    a1[-2] = 20.2;
    

    无论是数组、vecotr还是array对象,都可使用标准数组表示法来访问各个元素array对象和数组存储在相同的内存区域(即栈)中,而vector对象存储在另一个区域(自由存储区或堆)中可以将一个array对象赋给另一个array对象;而对于数组,必须逐元素复制数据。以上访问存在索引越界行为,可以使用vector和array对象的成员函数at()。中括号表示法和成员函数at()的差别在于,使用at()时,将在运行期间捕获非法索引,而程序默认将中断,这种额外检查的代价是运行时间更长。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/768279.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号