• (原创)谭浩强C++程序设计学习笔记:第二章 数据类型与表达式


    数据结构 指的是数据的组织形式。例如,数组就是一种数据结构。

    C++ 可以使用的数据类型如下:

    布尔型就是逻辑型,空类型就是无值型。

    C++ 的数据包括常量与变量,常量与变量都具有类型。

    例如:利用指针和结构体类型可以构成表、树、栈等复杂的数据结构。

    说明:

            (1) 整型数据分为长整型 (long int) 、 一般整型 (int) 和 短整型 (short int)。 在 int 前面加 long 和 short 分别表示长整型和短整型。

            (2) 整型数据的存储方式为按二进制数形式存储,例如十进制整数 85 的二进制形式为 1010101 ,则在内存中的存储形式如图 2.1 所示。

            (3) 在整型符号 int 和字符型符号 char 的前面, 可以加修饰符 signed(表示 “有符号” ) 或 unsigned( 表示 “无符号” )。如果指定为 signed, 则数值以补码形式存放,存储单元中的 最高位(bit) 用来表示数值的符号。如果指定为 unsigned, 则数值没有符号,全部二进制位都用来表示数值本身。例如短整型数据占两个字节,见图 2.2:

     有符号时,能存储的最大值为 2^15 -1,即 32767,最小值为 -32768。无符号时,能存储的最大值为2^16 -1,即 65535,最小值为0。有些数据是没有负值的,可以使用 unsigned, 它存储正数的范围比用 signed 时要大一倍。

            (4) 浮点型(又称实型)数据分为单精度(float)、 双精度(double) 和 长双精度(long double) 3种,并且 float 和 double 的数值范围不同。对 float 分配 4 个字节,对 double 和 long double 分配 8 d个字节。

            (5) 表中类型标识符一栏中,方括号[]包含的部分可以省写,如 short 和 short int 等效, unsigned int 和 unsigned 等效。

    常量

            常量的值是不能改变的,一般从其字面形式即可判别是否为常量。常量包括两大类,即 数值型常量(即常数) 和 字符型常量。

            这种从字面形式即可识别的常量称为 “字面常量” 或 “直接常量”。

            数值常量就是通常所说的常数。

            为什么将数值常量区分为不同的类别呢?因为在进行赋值或函数的参数虚实结合时要求数据类型匹配。

    整数

            一个整型常量可以用 3 种不同的方式表示:

                    * 十进制整数        * 八进制整数        * 十六进制整数

    浮点数

            一个浮点数可以用两种不同的方式表示:

                    (1) 十进制小数形式。

                    (2) 指数形式(即浮点形式)

                             如 3.14159 可以表示 为  0.314159 × 10^1 , 3.14159 × 10^0 ,31.4159 × 10^-1 , 314.159× 10^-2等形式。在程序中应表示为:0.314159e1, 3.14159e0,31.4159e-1 ,314.159e-2,用字母 e表示其后的数是以 10 为底的幂,如 e12 表示 10^12.

            在程序中不论把浮点数写成小数形式还是指数形式,在内存中都是以指数形式(即浮点形式) 存储的。如图2.3所示:

     < 数字部分必须小于 1 ,同时,小数点后面第一个数字必须是一个非 0 数字。存储单元分为两部分,一部分用来存放数字部分,一部分用来存放指数部分。>

    字符常量

            用单撇号括起来的一个字符就是字符型常量。如 a′。

            注意:① 字符常量只能包括一个字符,如 ′AB是不合法的。 ② 字符常量区分大小写字母,如 ′A′ 和 ′a′ 是两个不同的字符常量。 ③ 撇号( ′ )是定界符,而不属于字符常量的一部分。如 cout<<a; 输出的是一个字母 “a, 而不是 3个字符′ “ ′a′ 

            C++ 还允许用一种特殊形式的字符常量,就是以 \”开头的字符序列,转义字符;

            将一个字符常量存放到内存单元时,是将该字符相应的 ASCII 代码放到存储单元中。

             既然字符数据是以 ASCII 码存储的,它的存储形式就与整数的存储形式类似。这样,在 C++ 中字符型数据和整型数据之间就可以通用。一个字符数据可以赋给一个整型变量,反之,一个整型数据也可以赋给一个字符变量。也可以对字符数据进行算术运算,此时相当于对它们的 ASCII 码进行算术运算。

    // test1
    // 将字符赋给整型变量
    #include <iostream>
    using namespace std;
    int main() {
        int i, j;
        i = 'A';
        j = 'B';
        cout << i << ' ' << j << endl;
        return 0;    
    }
    // 输出:65 66

    可以看到:在一定条件下,字符型数据和整型数据是可以通用的。但是应注意字符数据只占一个字节,它只能存放 0~255范围内的整数。

    // test2
    // 字符数据与整数进行算术运算--将小写字母转换为大写字母
    #include <iostream>
    using namespace std;
    int main() {
        char c1, c2;
        c1 = 'a';
        c2 = 'b';
        c1 = c1 - 32;
        c2 = c2 - 32;
        cout << c1 << ' ' << c2 << endl;
        return 0;
    }
    // 输出:A B

    从 ASCII 代码表中可以看到每一个小写字母比它相应的大写字母的 ASCII 代码大 32。

    字符串常量

            用双撇号括起来的部分就是字符串常量,如 abc″。字符串常量 ″abc″ 在内存中占 4 个字节(而不是 3 个字节),见图 2.5。

     编译系统会在字符串最后自动加一个 ′\0作为字符串结束标志。

            注意:a″ 和 ′a′ 代表不同的含义,″a″ 是字符串常量,′a′ 是字符常量。前者占两个字节,后者占 1 字节。

            请思考:字符串常量 ″abc\n″ 包含几个字符? 不是 5个而是 4个字符,其中 “\n” 是一个转义字符。但它在内存中占 5 个字节(包括一个 “\0” 字符)

            如果在一个字符串中最后一个字符为 “\”,则表示它是续行符,下一行的字符是该字符串的一部分,且在两行字符串间无空格。如

    符号常量

             在 C++ 程序设计中,常用一个符号名代表一个常量,称为符号常量,即以标识符形式出现的常量。

    // test3
    // 符号常量的使用
    #define PRICE 30  // 注意这不是语句,末尾不要加分号
    int main() {
        int num, total;
        num = 10;
        total = num * PRICE;
        cout << "total = " << total << endl;
        return 0;
    }

    程序中用预处理命令 #define 指定 PRICE 在本程序单位中代表常量 30 ,此后凡在本程序单位中出现的 PRICE 都代表 30 ,可以和常量一样进行运算。

            请注意符号常量虽然有名字,但它不是变量。它的值在其作用域(在本例中为主函数)内是不能改变的,也不能被赋值。

            使用符号常量的好处是:

                    (1含义清楚。

                    (2在需要改变一个常量时能做到 “一改全改”

    变量

            在程序运行期间其值可以改变的量称为变量。

            请注意区分变量名和变量值这两个不同的概念,见图 2.6

           

            用来标识变量、符号常量、函数、数组、类型等实体名字的有效字符序列称为标识符( identifier)。

            C++ 规定标识符只能由字母、数字和下划线 3种字符组成,且第一个字符必须为字母或下划线

            应注意变量名不能与 C++ 的关键字、系统函数名和类名相同。

            C++ 没有规定标识符的长度(字符个数),但 有的系统取 32 个字符,超过的字符不被识别。

            在 C++ 语言中,要求对所有用到的变量作强制定义,也就是必须 “先定义,后使用 ”。

            C++ 要求对变量作强制定义的目的是:

                    (1) 凡未被事先定义的,不作为变量名,这就能保证程序中变量名使用得正确。例如,如果在声明部分写了 int student而在执行语句中错写成 statent 。 如 statent = 30在编译时检查出 statent未经定义,作为错误处理。输出 “变量 statent未经声明 ”的信息,便于用户发现错误,避免变量名使用时出错。

                    (2) 每一个变量被指定为一确定类型,在编译时就能为其分配相应的存储单元。如指定a和b为 int 型,一般的编译系统对其各分配 4 个字节,并按整数方式存储数据。

                    (3) 指定每一变量属于一个特定的类型,这就便于在编译时,据此检查该变量所进行的运算是否合法。例如,整型变量 a 和 b , 可以进行求余运算:a%b ,% 是 “求余”,得到 a/b 的余数。如果将 a 和 b 指定为实型变量,则不允许进行 “求余”运算,在编译时会给出有关的出错信息。

            允许在定义变量时对它赋予一个初值,这称为变量初始化。

            如果对变量未赋初值,则该变量的初值是一个不可预测的值,即该存储单元中当时的内容是不知道的。

            初始化 是在程序运行时执行本函数时赋予初值的,相当于执行一个赋值语句。

    常变量

            在定义变量时,如果加上关键字 const, 则变量的值在程序运行期间不能改变,这种变量称为常变量 (constant variable)。 例如,

                    const int a=3; // 用 const 来声明这种变量的值不能改变,指定其值始终为 3

            在定义常变量时必须同时对它初始化(即指定其值),此后它的值不能再改变。

            常变量又称为只读变量(read-only-variable)

            请区别用 #define 命令定义的符号常量和用 const 义的常变量:

                    * 符号常量只是用一个符号代替一个字符串,在预编译时把所有符号常量替换为所指定的字符串,它没有类型,在内存中并不存在以符号常量命名的存储单元。

                    * 常变量具有变量的特征,它具有类型,在内存中存在着以它命名的存储单元,可以用 sizeof 运算符测出其长度。

            

    C++运算符

            C++ 提供了以下运算符:

                    (1) 算术运算符

                    +(加 ) -(减) *(乘 ) /(除 ) %(整除求余 ) ++(自加 ) --(减) 

                    (2) 关系运算符

                     >(大于) <(小于 ) ==(等于) >=(大于或等于) <=(小于或等于) !=(不等于)

                     (3) 逻辑运算符、

                    &&(逻辑与 ) ||(逻辑或 )!(逻辑非) 

                     (4) 位运算符

                     <<(按位左移 ) >>(按位右移 ) &( 按位与 ) |(按位或 ) ∧(按位异或 ) ~(按位取反)

                    (5) 赋值运算符 (=及其扩展赋值运算符)

                    (6) 条件运算符 (?:)

                    (7) 逗号运算符 ( ,)

                    (8) 指针运算符 ( *  )

                    (9) 引用运算符和地址运算符 (& )

                    (10) 求字节数运算符(sizeof)

                    (11) 强制类型转换运算符(( 类型 ) 或类型 ( ) 

                    (12) 成员运算符 ( . 

                     (13) 指向成员的运算符( ->

                     (14) 下标运算符([])

                     (15) 其他(如函数调用运算符())

           +(加法运算符,或正值运算符。如 3+5, +3

            -(减法运算符,或负值运算符。如 5-2, -3

            *(乘法运算符。如 3 5 )

            /(除法运算符。如 5/3

            %(模运算符,或称求余运算符,%两侧均应为整型数据,如7%4的值为3)。

            需要说明,两个整数相除的结果为整数,如 5/3 结果值为 1,舍去小数部分。但是,如果除数或被除数中有一个为负值,则舍入的方向是不固定的。例如, -5/3 在有的 C++ 系统上得到结果 -1,有的 C++ 系统则给出结果 -2。多数编译系统采取 “向零取整” ” ”

    的方法,即 5/3 的值等于 1, -5/3 的值等于 -1,取整后向零靠拢。

             C++ 在运算时对所有 float 型数据都按 double 型数据处理。

    算术表达式

             用算术运算符和括号将运算对象(也称操作数)连接起来的、符合 C++ 语法规则的式子,称 C++ 算术表达式。

            自左至右的结合方向 ”又称 “左结合性 ”即运算对象先与左面的运算符结合。以后可以看到有些运算符的结合方向为 “自右至左 ”,即右结合性(例如赋值运算符)。

            在进行运算时,不同类型的数据要先转换成同一类型,然后进行运算。转换的规则按图 2.7所示。

    自增和自减运算符

             ++i( 在使用 i 之前,先使 i 的值加 1 ,如果 i 的原值为 3,则执行 j=++i 后,j 的值为 4

             --i (在使用 i 之前,先使 i 的值减 1,如果 i的原值为 3,则执行 j=--i 后,j 的值为 2)

             i++ (在使用 i 之后,使 i 的值加 1,如果 i 的原值为 3则执行 j=i++ 后,j 的值为 3,然后 i 变为 4)

             i--(在使用 i 之后,使 i 的值减 1,如果 i 的原值为 3,则执行 j=i-- 后,j 的值为 3,然后 i 变为 2)

             ++是先执行 i = i+1 后,再使用 i 的值;而  i++ 是先使用 i 的值后,再执行 i= i+1。

             请注意:

                     (1) 自增运算符 (++) 和 自减运算符 (--) 只能用于变量,而不能用于常量或表达式。

                     (2) ++ 和 -- 的结合方向是 “自右至左” 

                     (3) 自增运算符( ++)和 自减运算符( --)使用十分灵活,但在很多情况下可能出现歧义性,产生 “想不到 ”的副作用。

                     (4) 自增(减)运算符在 C++ 程序中是经常见到的,常用于循环语句中,使循环变量自动加 1。也用于指针变量,使指针指向下一个地址。

    强制类型转换

              强制类型转换的一般形式为

                   (类型名)(表达式)

              ( int)( x+y( 将 x+y的值转换成整型)

             (int)x+y   则只将x转换成整型,然后与y相加。

             C++ 还增加了以下形式:类型名(表达式),如 int(x) 或 int(x+y)。

             需要说明的是在强制类型转换时,得到一个所需类型的中间变量,但原来变量的类型未发生变化。

    // test4
    // 强制类型转换
    #include <iostream>
    using namespace std;
    int main() {
        float x;
        int i;
        x = 3.6;
        i = (int)x;
        cout << "x = " << x << ", i = " << i << endl;
        return 0;
    }
    // 输出:x = 3.6, i = 3

    由上可知,有两种类型转换,一种是在运算时不必用户指定,系统自动进行的类型转换,如 3+6.5。

    第二种是强制类型转换。当自动类型转换不能实现目的时,可以用强制类型转换。此外,在函数调用时,有时为了使实参与形参类型一致,可以用强制类型转换运算符得到一个所需类型的参数。

    赋值运算符

              赋值符号 “=” 就是赋值运算符,它的作用是将一个数据赋给一个变量。

             如果赋值运算符两侧的类型不一致,但都是数值型或字符型时,在赋值时会自动进行类型转换。

             (1) 将 浮点型数据(包括单、双精度)赋给 整型 变量时,舍弃其小数部分。

             (2) 将 整型 数据赋给 浮点型 变量时,数值不变,但以指数形式存储到变量中。、

             (3) 将一个 double 型数据赋给 float 变量时,要注意数值范围不能溢出。

             (4) 字符型 数据赋给 整型 变量,将字符的 ASCII 赋给整型变量。

             (5) 将一个 int 、 short 或 long 型数据赋给一个 char 变量,只将其低 8 位原封不动地送到 char型变量(发生截断)。例如

                       short int i=289;

                       char c;

                       c=i; //将一个 int型数据赋给一个 char 型变量

               赋值情况见图 2.8。为方便起见,以一个 int 型数据占两个字节 (16位) 的情况来说明。

              (6) 将 signed(有符号)型数据赋给长度相同的 unsigned(无符号)型变量,将存储单元内容原样照搬(连原有的符号位也作为数值一起传送)。

    // test5
    // 将有符号数据传送给无符号变量
    #include <iostream>
    using namespace std;
    int main() {
        unsigned short a;
        short int b = -1;
        a = b;
        count << " a = " << a << endl;
        return 0;
    }
    // 输出:65535

    不同类型的整型数据间的赋值归根结底就是一条:按存储单元中的存储形式直接传送。

    复合赋值操作符

              

    赋值表达式

              由赋值运算符将一个变量和一个表达式连接起来的式子称为 “赋值表达式 ”。

             对赋值表达式求解的过程是:先求赋值运算符右侧的 “表达式 ”的值,然后赋给赋值运算符左侧的变量。一个表达式应该有一个值。

             赋值运算符左侧的标识符称为 “值 ”(left value, 简写为 lvalue)

             出现在赋值运算符右侧的表达式称为 “右值 ”(right value, 简写为 rvalue)

    逗号运算符

              

     

     

  • 相关阅读:
    python3.8安装flask出现错误“ModuleNotFoundError: No module named '_ctypes'”
    利用virtualenvwrapper创建虚拟环境出现错误“/usr/bin/python: No module named virtualenvwrapper”
    CentOS7 下升级Python版本
    Python 定义动态变量
    Linux常用命令
    项目经验之:项目用到LinQ (总结)
    ListBox操作一些总结
    项目经验之:如CSDN一样的分页,我能否做这样的分页吗??????
    记上一笔,listbox展示项中,隐藏其中一项
    项目经验之:SQL一些简单问题中可以使用的技巧
  • 原文地址:https://www.cnblogs.com/wodehao0808/p/12889755.html
Copyright © 2020-2023  润新知