题记:本系列学习笔记(C++ Primer学习笔记)主要目的是讨论一些容易被大家忽略或者容易形成错误认识的内容。只适合于有了一定的C++基础的读者(至少学完一本C++教程)。
作者: tyc611, 2007-01-13
--------------------------------------------------------------------------------
本文主要讨论C++中关于变量及其类型的一些讨论。
如果文中有错误或遗漏之处,敬请指出,谢谢!
--------------------------------------------------------------------------------
算术类型(arithmetic type)
C++标准规定了每个算术类型的最小存储空间,但允许编译器使用更大的存储空间。事实上,对于int型,几乎现在所有的编译器使用的存储空间都比所要求的大(也表明,在编写程序时不能对这些类型的大小做任何假设)。C++算术类型最小存储空间规定如下:
(注:要特别注意int型,并且这里没有long long类型,基本上所有编译器都有这个扩展)
类型 含义 最小存储空间
bool 布尔型 -
char 字符型 8位
wchar_t 宽字符型 16位
short 短整型 16位
int 整形型 16位
long 长整型 32位
float 单精度浮点型 6位有效数字
double 双精度浮点型 10位有效数字
long double 扩展精度浮点型 10位有效数字
整型(integral type)
表示整数、字符和布尔值的算术类型合称为整型(与浮点型相对应)。
字符型(char)
有三种类型:plain char, signed char, unsigned char,但只有两种表示方式:signed char和unsigned char。plain char用这两个表示方式之一来表示,至于用那种方式来表示取决于编译器,是实现定义的。
--------------------------------------------------------------------------------
signed与unsigned类型
C++标准并没有定义signed类型如何用位来表示,编译器通常用其中一位作为符号位来表示。
对于unsigned 整型(unsigned char,unsigned short int, unsigned int, unsigned long int),编译器会将越界值对2^n取模(n为该类型的位数)使其满足大小要求。因此,unsigned整型在计算时不会发生溢出。
例如:(假设char类型为8位,2^8 = 256)
unsigned char ch = 300; 等价于 unsigned char ch = 44 (300 mod 256)
unsigned char ch = -1; 等价于 unsigned char ch = 255 (-1 mod 256)
而对于越界的signed类型赋值的情形,标准没有明确说明,也就是未定义行为。很多编译器采用与unsigned类型一样的处理方式。
--------------------------------------------------------------------------------
字面值(literal, or literal constant)
只有内置类型存在字面值,每个字面值都有相应的类型。例如:0是int型,2.718是double型。
整形字面值
整型字面值的类型依赖于它的形式、值和类型后缀:
如果它是十进制形式并且没有类型后缀,那么它的类型是下面第一个能表示它的类型:int、long int。
如果它是八进制或十六进制形式并且没有类型后缀,那么它的类型是下面第一个能表示它的类型:int,unsigned int,long int, unsigned long int。
如果它有类型后缀u或者U,那么它的类型是下面第一个能表示它的类型:unsigned int, unsigned long int。
如果它有类型后缀l或者L,那么它的类型是下面第一个能表示它的类型:long int, unsigned long int。
如果它有类型后缀ul,lu,uL,Lu,Ul,lU,UL或者LU,那么它的类型是unsigned long int。
如果一个字面值不能够被它所有可能类型所表示,那么将产生未定义行为。
字符串字面值(string literal)
形如"..."或者L"..."的字符串。
不是以L开头的字符串字面值,叫作平凡字符串字面值(ordinary string literal),也叫作窄字符串字面值(narrow string literal)。对于平凡字符串字面值,其类型是const char[num],静态存储区,并用所给字符串初始化。
以L开头的字符串字面值,例如:L"foo",是宽字符串字面值。它的类型是const wchar_t[num],静态存储区,并用所给字符串初始化。
(注意上面的num值为所给字符串中字符个数 + 1)
所有字符串字面值的存储是否是不重叠的,这个问题是由实现定义的(implementation-defined)。试图去修改字符串字面值的行为所产生的结果是未定义的。
在编译时,相邻的窄字符串字面值被连接成一个窄字符串字面值,相邻的宽字符串字面值也被连接成一个宽字符串字面值。如果一个窄字符串字面值和一个宽字符串字面值相邻,其结果是未定义了。
--------------------------------------------------------------------------------
变量及其类型
C++没有规定变量名的长度。
一些特殊的标识符为实现专用的保留标识符:
1)包含两个连续下划线的标识符以及以下划线开头紧跟一个大写字母的标识符。
2)在函数外定义的以下划线开头的标识符。
初始化
初始化有两种方式:
1)拷贝初始化(copy-initialization),例如:int var = 6;
2)直接初始化(direct-initialization),例如:int var(6);
两种方式对于内置类型是没区别的,而对于类类型是有区别的,详见构造函数章节。
extern与const
如果extern声明有初始化表达式,那么它被认为是定义,而忽略extern。例如: extern int var = 6; //definition (只有当extern 声明位于函数外部时,才可以含有初始化表达式)
const限定符
在全局作用域内声明的const变量为内部连接属性,即是文件域变量,所以可以把const变量定义放在头文件中(如果这样做,那么在每个包含该头文件中的文件中都会有一个该变量的定义,这样可能造成存储空间的大量浪费。事实上,当const变量是用常量表达式初始化时,大部分编译器在编译时都会用相应的常量表达式替换这些const变量的任何使用。也就不会有空间用于这类const变量的存储)。
可以指定const变量为extern,从而使其变成外部连接属性,可以在整个程序中访问const对象(需要在定义和使用处都用extern声明)。如果定义了一个extern const变量,那么在其它文件中就不能再在全局域定义该变量(一个例外是,可以定义一个内部连接属性的const变量)。例如: // file1.cpp
extern const int var = 6;
// file2.cpp
extern const int var; //legal: refer to the var in file1
// file3.cpp
const int var = 9; //legal: internal linkage, only used in this file
// file4.cpp
extern const int var = 2; //illegal: redefinion of var (already defined in file1)
// file5.cpp
int var; //illegal: redefinion of var (already defined in file1)
非const引用只能绑定到与该引用同类型的对象;const引用则可以绑定到不同但相关的类型(该类型能够转换到引用的类型)的对象、甚至绑定到右值。例如:
int var = 6;
//int& r = 9; // error!
const int& r1 = 9; // ok
const int& r2 = var + r1; // ok
为什么const引用则可以绑定到不同但相关的类型的对象、甚至绑定到右值呢?
因为如果是绑定到不同类型的对象或右值,会先生成一个与引用类型相同的临时对象(必要时进行类型转换),然后引用变量再与该临时对象绑定。由于临时对象是右值,所以只能进行const引用。
另外,还可以从另一个角度来解释,先看下面的例子:
double var = 2.718;
const int& r = var;
上面的代码等价于:
double var = 2.718;
int tmp = var;
const int& r = tmp;
如果r不是const引用,那么可以修改r的值。这样做,事实上是修改了临时变量tmp的值,而与程序员试图修改var的值的意愿完全偏离。这种错误是很难察觉的。而const引用不能修改,就完全避免了这种错误的发生。
--------------------------------------------------------------------------------
枚举类型
枚举类型的对象的初始化或赋值只能通过其枚举成员或同一枚举类型对象进行。
当需要整形常量时,用枚举类型(匿名枚举类型)代替#define预处理命令是一个不错的选择。--------------------------------------------------------------------------------
-------------------------------------------------------------------------------- 如果文中有错误或遗漏之处,敬请指出,谢谢!--------------------------------------------------------------------------------
--------------------------------------------------------------------------------参考资料:[1] C++ Primer(Edition 4)[2] International Standard:ISO/IEC 14882:1998 --------------------------------------------------------------------------------
分享到:
相关推荐
这篇学习笔记主要涉及了C++编程的一些核心概念,包括程序结构、变量、基本类型、初始化与赋值、可读性、常量与引用、typedef、枚举以及标准库中的字符串和向量类型。 1. **程序结构**: - 每个C++程序都必须包含`...
《C++ Primer学习笔记》是一份详尽的资料,涵盖了C++编程语言的基础到高级概念。这份笔记旨在帮助初学者和有一定经验的开发者深入理解C++的语法、特性以及最佳实践。C++ Primer是C++编程领域的一本经典教材,以其...
#### 第2章 变量和基本类型 - **类型检查**:动态类型语言(如Smalltalk、Python)在运行时执行类型检查,而静态类型语言(如C++)在编译时执行类型检查,这意味着在使用一个名字之前,必须明确告诉编译器它的类型...
《C++ Primer 学习笔记》是一份针对C++初学者的重要参考资料,它基于C++ Primer第三版的内容,旨在帮助读者深入理解C++这门强大的编程语言。C++ Primer是学习C++的经典书籍,以其全面、深入且易于理解的讲解闻名,这...
第二章《变量和基本类型》深入探讨了变量、常量和基本类型的使用。笔记中提到,C++是一种静态类型语言,这意味着在编译时会进行类型检查,有助于早期发现错误。区分左值和右值的概念也被提及,左值可以出现在赋值的...
在C++编程中,`C++ Primer`是一本经典的入门教材,主要介绍C++的基础概念和技术。本篇学习笔记主要涵盖了前三章的内容,重点关注STL(Standard Template Library,标准模板库)中的容器、特别是vector的使用,以及...
C++ primer plus学习笔记之三,分为一下几个部分: 函数参数:介绍了函数的生命规则以及定义 数组函数:数组作为变量时的使用方法 指针和const:灵活运用指针和const 函数和二维数组:二维数组作为变量时声明以及定义...
以上是C++ Primer第四版学习笔记中涉及的一些核心知识点。这些知识点涵盖了C++编程的基础语法、数据类型、容器、指针、内存管理以及控制结构等多个方面,对于初学者理解和掌握C++语言具有重要意义。希望这些内容能够...
《C++ Primer 全书笔记》是一份专为C++初学者设计的学习资源,由一位计算机专业学生在找工作的过程中为了复习C++ Primer而编写的详细笔记。笔记以易懂的方式介绍了C++的基础概念和核心特性,对于那些基础知识不扎实...
根据给定的信息,“c++ primer笔记”主要围绕经典著作《C++ Primer》展开,这是一本深受程序员喜爱的书籍,旨在帮助读者系统地学习和掌握C++编程语言的基础及高级特性。下面将从几个关键方面对C++的核心知识点进行...
《C++ Primer 第4版》是一本经典的C++编程...这份“C++ Primer 第4版”学习笔记包含了所有这些知识点的详细解释和示例,是深入学习C++的理想资料。通过学习和实践,你可以掌握C++编程的基础,并逐步提升到高级水平。
### C++ Primer 笔记知识点概述 ...以上是对C++ Primer笔记中涉及的知识点的详细总结,涵盖了文件类型、预处理器指令、注释、数据类型及内存管理等方面的基础知识,对于初学者来说是非常宝贵的学习资源。
### 《C++ Primer》学习笔记(27)顺序容器 #### 9.1 顺序容器概述 在C++中,顺序容器是一类用于存储数据的容器,其中元素的位置依赖于其添加到容器中的顺序。这与关联容器形成了对比,关联容器中的元素位置是由其...
C++ Primer 是一本深入学习C++语言的经典教材,这份笔记虽然不完整,但涵盖了书本的前十个章节,提供了关于C++基础语法和核心概念的概述。 1. **变量与初始化** - C++中未初始化的变量使用是一个潜在的问题,因为...
1. 变量和基本类型 C++语言中有多种基本类型,包括整型、浮点型、字符型等。在整型中, unsigned char 类型的取值范围是0到255,如果赋值超过这个范围的值,那么编译器将会取该值对256求其模后的值。signed类型的...
首先,C++ Primer 笔记会涵盖C++的基础语法,包括变量、数据类型(如int、char、float等)、运算符(算术、比较、逻辑、位操作等)以及流程控制(如if语句、switch语句、for循环、while循环)。这些构成了任何编程...
3. **变量和基本类型**: C++中的变量表示程序中的数据存储单元,其类型决定了可以存储的数据种类及占用的内存大小。算术类型包括整型和浮点型,如`bool`、`char`、`short`、`int`、`long`、`float`、`double`等。...