【C Primer Plus】1-3章学习笔记第一章 预备知识C总览简介C的组成部分第二章 开始学习 C第三章 处理数据3.1 简单变量3.1.1 变量名3.1.2 整型3.1.3 整型short、int、long和long long3.1.4 无符号类型3.1.5 选择整型类型3.1.6 整型字面值3.1.7 C如何确定常量的类型3.1.8 char类型字符和小整数3.2 const 限定符3.3 浮点数3.3.1 书写浮点数3.3.2 浮点类型3.3.3 浮点常量3.3.4 浮点数的优缺点3.4 C算术运算符3.4.1 运算符优先级和结合性3.4.2 除法分支3.4.3 求模运算符3.4.4 类型转换3.4.5 C11中的auto声明3.5 总结第一章 预备知识C总览简介C 是一种静态类型的、编译式的、通用的、大小写敏感的、不规则的编程语言支持过程化编程、面向对象编程和泛型编程。C 被认为是一种中级语言它综合了高级语言和低级语言的特点。C 是由 Bjarne Stroustrup 于 1979 年在新泽西州美利山贝尔实验室开始设计开发的。C 进一步扩充和完善了 C 语言最初命名为带类的C后来在 1983 年更名为 C。C 是 C 的一个超集事实上任何合法的 C 程序都是合法的 C 程序。注意使用静态类型的编程语言是在编译时执行类型检查而不是在运行时执行类型检查。面向对象程序设计C最大的亮点就是面向对象程序设计理念的运用。包括面向对象开发的四大特性封装抽象继承多态C的组成部分标准的 C 由三个重要部分组成核心语言提供了所有构件块包括变量、数据类型和常量等等。C 标准库提供了大量的函数用于操作文件、字符串等。标准模板库STL提供了大量的方法用于操作数据结构等。第二章 开始学习 C略这一章很简单只是讲解了C基本的代码框架就像C语言的hello world以及函数、类的基本概念后面的学习会详细给出这里就不说明了。下面给出一个基本的代码结构便于读者理解/* displays a message */ #include iostream // a PREPROCESSOR directive int main() { // function header // start of function body using namespace std; // make definitions visible cout Hello world! endl; // message cout Comme up and C me some time. endl; cout You wont regret it! endl; // If the output window closes before you can read it, // add the following code: cout Press any key to continue. endl; cin.get(); return 0; // terminate main() } // end of function body第三章 处理数据注这一章给出了许多数据的存储类型可以学会一种存储类型的使用其他的都大同小异。面向对象编程OOP的本质是设计并扩展自己的数据类型。设计自己的数据类型就是让类型与数据匹配。内置的C类型分两组基本类型和复合类型。本章将介绍基本类型即整数和浮点数。似乎只有两种类型但C知道没有任何一种整型和浮点型能够满足所有的编程要求因此对于这两种数据它提供了多种变体。3.1 简单变量把信息存储在计算机中程序必须记录3个基本属性信息将存储在哪里要存储什么值存储何种类型的信息。实际上程序将找到一块能够存储整数的内存将该内存单元标记为braincount并将5复制到该内存单元中然 后您可在程序中使用braincount来访问该内存单元。可以使用运算符来检索braincount的内存地址。3.1.1 变量名C 提倡使用有一定含义的变量名并遵循几 种简单的 C 命名规则在名称中只能使用字母字符、数字和下划线 ( _ )名称的第一个字符不能是数字区分大写字符与小写字符不能将C关键字用作名称以两个下划线或下划线大写字母打头的名称被保留给实现编译器及其使用的资源使用以一个下划线开头的名称被保留给实现用作全局标识符C对于名称的长度没有限制名称中所有的字符都有意义但有些平台有长度限制。倒数第二点与前面几点有些不同因为使用像 __time_stop 或 _Donut 这样的名称不会导致编译器错误而会导致行为的不确定性。换句话说不知道结果将是什么。不出现编译器错误的原因是这样的名称不 是非法的但要留给实现使用。如果想用两个或更多的单词组成一个名称通常的做法是用下划线字符将单词分开如 my_onions (推荐用这类)或者从第二个单词开始将每个单词的第一个字母大写如 myEyeTooth。在 C 所有主观的风格中一致性和精度是最重要的。3.1.2 整型不同C整型使用不同的内存量来存储整数。使用的内存量越大可以表示的整数值范围也越大。C的基本整型按宽度递增的顺序排列分别是char、short、int、long和C11新增的long long其中每种类型都有符号版本和无符号版本因此总共有10种类型可供选择。3.1.3 整型short、int、long和long longC 的short、int、long和long long类型通过使用不同数目的位来存储值最多能够表示4种不同的整数宽度short至少16位int至少与short一样长long 至少32位且至少与int一样长long long至少64位且至少与long一样长。这意味着可以把16位单元设置成65 536个不同的值把 32位单元设置成4 294 672 296个不同的值把64位单元设置为18 446 744 073 709 551 616个不同的值。作为比较unsigned long存储不了地球上当前的人数和银河系的星星数而long long 能够。当前很多系统都使用最小长度即short为16位long为32位。这仍然为int提供了多种选择其宽度可以是16位、24位或32位同时又符合标准甚至可以是64位因为long和long long至少长64位。类型的宽度随实现而异这可能在将C程序从一种环境移到另一种环境包括在同一个系统中使用不同编译器时引发问题。首先sizeof运算符返回类型或变量的长度其次头文件climits在老式实现中为limits.h中包含了关于整型限制的信息。具体地说它定义了表示各种限制的符号名称。例如INT_MAX为int的最大取值CHAR_BIT为字节的位数。在我的设备上数据类型是这样的:int is4bytes. short is2bytes. long is8bytes. long long is8bytes. Maximum values: int:2147483647short:32767long:9223372036854775807long long:9223372036854775807Minimum int value-2147483648Bits per byte8赋值与声明合并在一起叫做初始化。如果知道变量的初始值应该是什么则应对它进行初始化。如果不对函数内部定义的变量进行初始化该变量的值将是不确定的。这意味着该变量的值 将是它被创建之前相应内存单元保存的值。3.1.4 无符号类型要创建无符号版 本的基本整型只需使用关键字 unsigned 来修改声明即可。注意unsigned本身是unsigned int的缩写。3.1.5 选择整型类型通常int被设置为对 目标计算机而言最为“自然”的长度。自然长度natural size指的是计 算机处理起来效率最高的长度。如果没有非常有说服力的理由来选择其 他类型则应使用int。如果知道变量可能表示的整数值大于16位整数的最大可能值则使用long。即使系统上int为32位也应这样做。这样将程序移植到16位系统时就不会突然无法正常工作参见图3.2。如果要存储的值超过20亿可使用long long。所以对于基因组数据上的位置信息最好是 long 类型咯即便 unsigned int 类型已经足够。不过我可能还是希望用 unsigned int 如果short比int小则使用short可以节省内存。通常仅当有大型整 型数组时才有必要使用short。如果只需要一个字节可使用char。3.1.6 整型字面值整型字面值常量是显式地书写的常量如212或1776。诸如couthex;等代码不会在屏幕上显示任何内容而只是修改 cout显示整数的方式。因此控制符hex实际上是一条消息告诉cout采 取何种行为。另外由于标识符hex位于名称空间std中而程序使用了 该名称空间因此不能将hex用作变量名。然而如果省略编译指令 using而使用std::cout、std::endl、std::hex和std::oct则可以将hex用作 变量名。3.1.7 C如何确定常量的类型3.1.8 char类型字符和小整数char类型是专为存 储字符如字母和数字而设计的。char类型是另一种整型。实际上很多系统支持的字符都不超过128个因此用一个字节就可以表示所有的符号。因此虽然char最常被用来处理字符但也可以 将它用做比short更小的整型。C对字符用单引号对字符串使用双引号。 cout对象能够处理这两种情况但正如第4章将讨论的这两者有天壤之别。与int不同的是char在默认情况下既不是没有符号也不是有符号。是否有符号由C实现决定这样编译器开发人员可以最大限度地将这种类型与硬件属性匹配起来。如果char有某种特定的行为对您来说 非常重要则可以显式地将类型设置为signed char 或unsigned char。如果将char用作数值类型则unsigned char和signed char之间的差异将非常重要。unsigned char类型的表示范围通常为0255而signed char 的表示范围为−128到127。例如假设要使用一个char变量来存储像200这样大的值则在某些系统上可以而在另一些系统上可能不可以。但 使用unsigned char可以在任何系统上达到这种目的。如果大型字符 集是实现的基本字符集(如中文日文系统)则编译器厂商可以将char定义为一个16位的字节或更长的字节。其次一种实现可以同时支持一个小型基本字符集和 一个较大的扩展字符集。8位char可以表示基本字符集另一种类型 wchar_t宽字符类型可以表示扩展字符集。wchar_t类型是一种整数类型它有足够的空间可以表示系统使用的最大扩展字符集。这种类 型与另一种整型底层underlying类型的长度和符号属性相同。对底层类型的选择取决于实现因此在一个系统中它可能是unsigned short而在另一个系统中则可能是int。3.2 const 限定符C有一种比#define更好的处理符号常量的方法这种方法就是使用 const 关键字来修改变量声明和初始化。const int Months 12;常量如Months被初始化后其值就被固定 了编译器将不允许再修改该常量的值。如果您这样做g将指出程 序试图给一个只读变量赋值。关键字const叫做限定符因为它限定了声 明的含义。#define 定义符号常量的方式应抛弃。一种常见的做法是将名称的首字母大写以提醒您Months是个常量。这决不是一种通用约定但在阅读程序时有助于区分常量和变量。另一种约定是将整个名称大写使用#define创建常量时通常使用这种约定。注意如果在声明常量时没有提供值则该常量的值将是不确定的且无 法修改。3.3 浮点数使用浮点类型可以表示诸如2.5、3.14159和122442.32这样的数字即带小数部分的数字。计算机将这样的值分成两部分存储。一部分表示值另一部分用于对值进行放大或缩小。下面打个比方。对于数字34.1245和34124.5它们除了小数点的位置不同外其他都是相同的。 可以把第一个数表示为0.341245基准值和100缩放因子而将第二个数表示为0.341245基准值相同和10000缩放因子更大。缩放因子的作用是移动小数点的位置术语浮点因此而得名。C内部表示浮点数的方法与此相同只不过它基于的是二进制数因此缩放因 子是2的幂不是10的幂。3.3.1 书写浮点数C有两种书写浮点数的方式第一种是使用常用的标准小数点表示法第二种表示浮点值的方法叫做E表示法其外观是像这样的 3.45E6这指的是3.45与1000000相乘的结果E6指的是10的6次方即 1后面6个0。因此3.45E6表示的是34500006被称为指数3.45被称为 尾数。E表示法确保数字以浮点格式存储即使没有小数点。注意既可 以使用E也可以使用e指数可以是正数也可以是负数不要有空格。电子的质量是 9.11e-31 kg 表示 0.000000000000000000000000000000911 kg 而美国报警电话 911 竟然很巧合地与此相同。3.3.2 浮点类型C也有3种浮点类型float、double 和 long double。事实上C和C对于有效位数的要求是float至少32位double至少48位且不少于floatlong double至少和double一样多。这三种类型的有效位数可以一样多。然而通常float为32位double为64位 long double为80、96或128位。另外这3种类型的指数范围至少是−37到37。可以从头文件cfloat或float.h中找到系统的限制。3.3.3 浮点常量在默认情况下像8.24和2.4E8这样的浮点常量都属于double类型。如果希望常量为float类型请使用f或F后缀。对于long double类型可使用l或L后缀由于l看起来像数字1因此L是更好的选择。3.3.4 浮点数的优缺点与整数相比浮点数有两大优点。首先可以表示整数之间的 值。其次由于有缩放因子它们可以表示的范围大得多。另一方面浮点运算的速度通常比整数运算慢且精度将降低。如: 2.34E22是一个小数点左边有23位的数字。加上1就 是在第23位加1。但float类型只能表示数字中的前6位或前7位因此修改第23位对这个值不会有任何影响。3.4 C算术运算符11.17 50.25应等于61.42但是输出的却是61.419998。这不是运算问题而是由于float类型表示有效位数的能力有限。记住对于floatC只保证6位有效位。如果将 61.419998四舍五入成6位将得到61.4200这是在保证精度下的正确值如果用double 则精度足够所以直接可以获得 61.42 的值。通常来说 double 都比 float 更精准应尽量使用 double。3.4.1 运算符优先级和结合性算术运算符遵 循通常的代数优先级先乘除后加减。3.4.2 除法分支除法运算符/的行为取决于操作数的类型。如果两个操作数都 是整数则C将执行整数除法。这意味着结果的小数部分将被丢弃 使得最后的结果是一个整数。如果其中有一个或两个操作数是浮点 值则小数部分将保留结果为浮点数。浮点常量在默认情况下为 double类型。3.4.3 求模运算符求模运算符返回整数除法的余数。它与整数除 法相结合尤其适用于解决要求将一个量分成不同的整数单元的问题。3.4.4 类型转换由于有11种整型和3种浮点类型因此计算机需 要处理大量不同的情况C自动执行很多类型转换将一种算术类型的值赋给另一种算术类型的变量时C将对值进 行转换表达式中包含不同的类型时C将对值进行转换将参数传递给函数时C将对值进行转换。C允许将一种类型的值赋给另一种类型的变量。这样做时值将 被转换为接收变量的类型。例如假设so_long的类型为longthirty的类 型为short。将一个值赋给值取值范围更大的类型通常不会导致什么问题。如将short值赋给long变量并不会改变这个值只是占用的字节更多而 已。然而将一个很大的long值如2111222333赋给float变量将降低 精度。因为float只有6位有效数字因此这个值将被四舍五入为 2.11122E9。因此有些转换是安全的有些则会带来麻烦。如下的报错是一个可能:将0赋给bool变量时将被转换为false而非零值将被转换为true。当同一个表达式中包含两种不同的算术类型时将出现什么情况 呢在这种情况下C将执行两种自动转换首先一些类型在出现 时便会自动转换其次有些类型在与其他类型同时出现在表达式中时 将被转换。在计算表达式时C将bool、char、unsigned char、signed char和short值转换为int。具体地说true被转换为1false 被转换为0。这些转换被称为整型提升integral promotion。int 是一种最自然的类型运算速度也最快要主用。同样wchar_t被提升成为下列类型中第一个宽度足够存储wchar_t 取值范围的类型int、unsigned int、long或unsigned long。将不同类型进行算术运算时也会进行一些转换例如将int和float 相加时。当运算涉及两种类型时较小的类型将被转换为较大的类型。传递参数时的类型转换通常由C函数原型控制。C还允许通过强制类型转换机制显式地进行类型转换。强制类型转换 的格式有两种。如下新格式的想法是要让强制类型转换就像是函数调用。这样对内置类型的强制类型转换就像是为用户定义的类设计的类型转换。更安全的转换方式是使用static_casttypeName (value)函数。Stroustrup认为C语言式的强制类型转换由于有过多的可能性而极 其危险这将在第15章更深入地讨论。运算符static_cast比传统强制 类型转换更严格。3.4.5 C11中的auto声明在初始化声明中如果 使用关键字auto而不指定变量的类型编译器将把变量的类型设置成 与初始值相同。3.5 总结C的基本类型分为两组一组由存储为整数的值组成另一组由存储为浮点格式的值组成。整型之间通过存储值时使用的内存量及有无符号来区分。整型从最小到最大依次是bool、char、signed char、 unsigned char、short、unsigned short、int、unsigned int、long、unsigned long以及C11新增的long long和unsigned long long。还有一种wchar_t 类型它在这个序列中的位置取决于实现。C11新增了类型char16_t 和char32_t它们的宽度足以分别存储16和32位的字符编码。C确保了char足够大能够存储系统基本字符集中的任何成员而wchar_t则可以存储系统扩展字符集中的任意成员short至少为16位而int至少与short一样长long至少为32位且至少和int一样长。确切的长度取决于 实现。浮点类型可以表示小数值以及比整型能够表示的值大得多的值。3种浮点类型分别是float、double和long double。C确保float不比double 长而double不比long double长。通常float使用32位内存double使用 64位long double使用80到128位。型char16_t 和char32_t它们的宽度足以分别存储16和32位的字符编码。C确保了char足够大能够存储系统基本字符集中的任何成员而wchar_t则可以存储系统扩展字符集中的任意成员short至少为16位而int至少与short一样长long至少为32位且至少和int一样长。确切的长度取决于 实现。浮点类型可以表示小数值以及比整型能够表示的值大得多的值。3种浮点类型分别是float、double和long double。C确保float不比double 长而double不比long double长。通常float使用32位内存double使用 64位long double使用80到128位。对变量赋值、在运算中使用不同类型、使用强制类型转换时C将把值从一种类型转换为另一种类型。