C++:我写的一个函数,将0既不是奇数也不是偶数分解成3个素数,但执行时发现变量b,c的值不会增加,只停留在1为何

C++编写一个自定义函数判断一个整数是否为素数,在主函数中调用该函数输出1000以_百度知道
C++编写一个自定义函数判断一个整数是否为素数,在主函数中调用该函数输出1000以
答题抽奖
首次认真答题后
即可获得3次抽奖机会,100%中奖。
采纳数:58
获赞数:326
#include&iostream&void fun(int m){ int i=2; while(i&m)
if(m%i==0)
i++; if(i==m) {
cout&&m&&&是素数&&&
} cout&&m&&&不是素数&&&}int main(){
cout&&&请输入一个数:&&& cin&&n; if(n&1)
fun(n); else
cout&&n&&&不是素数&&& return 0;}
撒打算啊是下次
撒打算啊是下次
ccvasdfsdffdsf
本回答被提问者采纳
ge2008ge12
ge2008ge12
采纳数:312
获赞数:798
#include&iostream&#include&Cmath&void prime_Number(int m){ int i,j,k ,n= 0; for(i =2;i&m;i++) {
k= sqrt(i);
for(j= 2;j&=k;j++)
if(i%j==0)
if(j&=k+1)
printf(&%d
printf(&\n&);
printf(&\n&);}int main(){
cout&&&请输入一个大于1的整数:&&& cin&&n; cout&&&输出&&&n&&&以内的所有素数:&&& prime_Number(n); return 0;}
采纳数:51
获赞数:191
#include&iostream&void main(){ int sushu(int a);
for(i=1;i&=1000;i++)
if(sushu(i))
//函数调用
cout&&i&&}int sushu(int a)
for(j=2;j&a;j++)
if(a%j==0)
else return 0;
获赞数:52
#include&stdio.h&main(){int i,j,a;printf(&please input the number:\n&);scanf(&%d&,&a);j=a;i=2;do{
if(i%j==0)}
while(i++&=j);if(i&j)printf(&NO\n&);else printf(&YES\n&);getch();}
其他2条回答
为你推荐:
其他类似问题
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。在c++中编写函数计算一个数n是不是素数,并输入一个数m把它写成素数的乘积_百度知道
在c++中编写函数计算一个数n是不是素数,并输入一个数m把它写成素数的乘积
答题抽奖
首次认真答题后
即可获得3次抽奖机会,100%中奖。
myloneisland
myloneisland
采纳数:132
获赞数:638
#include&iostream&#include&cmath&#include&vector&bool IsPrime(const int &a)//判断是否素数{ for(int i=2;i&=sqrt(static_cast&double&(a));++i) {
if(!(a%i))
} }}void Decompose(const int &b)//分解输入数据{ vector&int& vec1,vec2; int pres=b; if(IsPrime(b)) {
cout&&b&&&= 1 * &&&b&& } else {
for(int i=2;i&=sqrt(static_cast&double&(b));++i)//计算b能整除的素数
if(!(b%i))
vec1.push_back(i);
for(vector&int&::iterator iter=vec1.begin();iter!=vec1.end();)//计算b的分解因子
if(pres%*iter==0)
vec2.push_back(*iter);
for(vector&int&::iterator iter=vec2.begin();iter!=vec2.end();++iter)//打印
if(iter==vec2.begin())
cout&&b&&& = &;
if((iter+1)!=vec2.end())
cout&&& * &;
cout&& }}int main(){ cout&&&Enter an integer:(End with EOF(Ctrl+Z))&&& while(cin&&x) {
if(IsPrime(x))
cout&&x&&& is a prime number!&&&
cout&&x&&& is not a prime number!&&&
Decompose(x); } system(&pause&); return 0;}
为你推荐:
其他类似问题
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。◇ 第一章 引言 - 课前索引 - 第一节 - 第二节 - 第三节 - 第四节 - 本章小结 - 课后习题 ◇ 第二章 C++语言基础 - 课前索引 - 第一节 - 第二节 - 第三节 - 第四节 - 第五节 - 第六节 - 第七节 - 本章小结 - 课后习题 ◇ 第三章 运算符和表达式 - 课前索引 - 第一节 - 第二节 - 第三节 - 第四节 - 本章小结 - 课后习题 ◇ 第四章 流程控制语句 - 课前索引 - 第一节 - 第二节 - 第三节 - 第四节 - 第五节 - 本章小结 - 课后习题 ◇ 第五章 函数 - 课前索引 - 第一节 - 第二节 - 第三节 - 第四节 函数的定义 函数的说明 函数的调用 inline 函数 if 语句 switch 语句 循环语句 break 和 continue 语句 程序举例 C++运算符 优先级和结合性 类型转换 表达式 简单的 C++程序 标识符和关键字 基本数据类型 变量 常量 枚举类型 输入和输出 计算机语言及其发展 程序设计方法 C++语言的特点 Visual C++6 开发环境简介 - 第五节 - 第六节 - 第七节 - 第八节 - 本章小结 - 课后习题函数的递归调用 变量的作用域与存储期 函数的重载 程序举例◇ 第六章 数组与字符串 - 课前索引 - 第一节 - 第二节 - 第三节 - 第四节 - 第五节 - 本章小结 - 课后习题 ◇ 第七章 指针与引用 - 课前索引 - 第一节 - 第二节 - 第三节 - 第四节 - 第五节 - 第六节 - 第七节 - 第八节 - 第九节 - 第十节 - 本章小结 - 课后习题 ◇ 第八章 结构与链表 - 课前索引 - 第一节 - 第二节 - 第三节 - 第四节 - 第五节 - 第六节 - 本章小结 - 课后习题 ◇ 第九章 编译预处理 - 课前索引 - 第一节 宏定义 结构及使用 结构变量作为函数参数 结构数组 指向结构的指针 链表 程序举例 指针变量的定义与使用 动态内存分配 指针运算 指针与常量 指针作函数参数 指针与数组 函数指针 引用 Typedef 程序举例 一维数组 二维数组 字符数组 数组作函数参数 程序举例 - 第二节 - 第三节 - 本章小结 - 课后习题文件包含 条件编译◇ 第十章 类与对象 - 课前索引 - 第一节 - 第二节 - 第三节 - 第四节 - 第五节 - 第六节 - 第七节 - 本章小结 - 课后习题 ◇ 第十一章 继承与多态 - 课前索引 - 第一节 - 第二节 - 第三节 - 第四节 - 第五节 - 第六节 - 本章小结 - 课后习题 ◇ 第十二章 输入输出流 课前索引 - 第一节 - 第二节 - 第三节 - 第四节 - 本章小结 - 课后习题 【学习目标】 本章介绍 C++语言的一些基本知识,包括程序的基本结构、标识符、数据类型、变量、常量、基 本的输入和输出方法等。通过本章的学习,应该能够编写简单的 C++程序。 【重点和难点】 本章内容比较简单,没有难于理解的概念。重点内容包括: ◇ C++语言中的变量和常量的概念和使用; ◇ C++语言中输入输出库的使用。 【学习方法指导】 本章内容简单,但确是重要的基础知识,对基本概念应加强记忆与理解,为以后的学习打下坚实 的基础。 输入输出流类 文件流 字节流类 流错误处理 基类和派生类 虚函数与动态联编 抽象类 虚析构函数 设计继承 程序举例 类与对象概述 构造函数与析构函数 复制构造函数 类作用域 const 成员函数 静态成员 友元 【知识点】 标识符;关键字;变量;整型变量;浮点型变量 字符型变量;布尔型变量;字符串;常量;枚举变量 标准输出;标准输入;printf 输出;scanf 输入 首先看下面这个简单的 C++程序(为了方便起见,程序的每一行都加上了行号)。 程序 2-1: 1.//simple.cpp 是一个简单的 C++程序 2.#include &iostream.h& 3.void main(void) 4.{ 5. 6. cout&&&Hello C++!&; 7. cout&&&请输入一个整数:\n&; 8. cin&&i; 9. cout&&&您输入的整数是:&; 10. cout &&i; 11. cout &&'\n'; 12.} 请学习者自己键入这段程序,并自己编译、连接、运行该程序,输入不同的整数,看能否得到预期的 结果。注意,程序中左边的数字是为了讲解的方便添加的,将该程序键入到开发环境的编辑窗口时,一定 要略去这些数字。 我们对这个程序逐行加以解释: (1)第一行是 C++语言的注释。其中,&//&是 C++语言的一种注释符号,自&//&开始,一直到本行结束, 所有内容都会被当作注释对待。C++注释也可以写成下面的形式: /*注释内容*/ 即夹在&/*&与&*/&号间的部分是要注释的内容,例如,本句可以改为: /*simple.cpp 是一个简单的 C++程序*/ 我们进行程序设计时,这两种注释形式都会经常用到。它们的区别在于:前者只能注释一行内容,而 后者可以注释多行内容。它可以用在程序的任何地方,编译器在编译时将这些信息忽略,注释就是用来帮 助阅读和理解程序的信息,也可使用注释来帮助用户调试程序。 (2)第 2 行使用预处理指令#include 将头文件 iostream.h 包含到程序中来, iostream.h 是标准的 C++ 头文件,它包含了输入和输出的定义。 (3)第 3 行定义了一个称为 main 的函数。 ◇ 一个函数有 0 个或多个参数,它们出现在函数名后的一对圆括号中。 ◇ 括号中的 void 表示 main 没有参数。 ◇ 一个函数可以有一个返回类型,它在函数名的左边。 ◇ main 函数左边的返回类型为 void,表示没有返回值。 ◇ C++程序的执行总是从 main 函数开始的。 (4)第 4 行是一个花括号,是 main 函数体开始的标记。 (5)第 5 行是一个语句。 ◇ 一个语句可能是定义或声明一个变量,也可能是得到一个数值的计算步骤。 ◇ 一个语句用分号(;)结尾,C/C++用分号来分隔语句。 ◇ 这个语句定义了一个整型变量 i。 ◇ 一个变量能够保存一种特定类型的数据,整型变量能够保存一个整型数据。 (6)第 6 行也是一个语句。 ◇ 这个语句将字符串&Hello C++!&发送到 cout 输出流。 ◇ 一个字符串是一个用双引号包围的字符系列。 (7)第 7 行也是一个语句。 ◇ 这个语句将字符串&请输入一个整数:&发送到 cout 输出流。 ◇ 字符串的最后一个字符(\n)是一个换行符。 ◇ 流是执行输入和输出的对象。 ◇ cout 是 C++标准的输出流,标准输出通常是指计算机屏幕。 ◇ 符号&&是一个输出运算符,带一个输出流作为它的左操作数,一个表达式作为它的右操作数。后 者被发送到前者,字符串&请输入一个整数:\n&发送到 cout 的效果是把字符串打印到计算机屏幕上。 (8)第 8 行也是一个语句。 ◇ 这个语句将 cin 输入流抽取到变量 i。 ◇ cin 是 C++标准的输入流,标准输入通常是指计算机键盘。 ◇ 符号&&是一个输入运算符,带一个输入流作为它的左操作数,一个变量作为它的右操作数。前者 被抽取到后者,cin 输入流抽取到变量 i 的效果是将键盘的输入值复制到变量 i 中。 (9)第 9、10、11 行分别是在屏幕上打印&您输入的整数是:&、变量 i 和和换行符。这三行实际上可 以综合为一个语句: cout&&&您输入的整数是:& &&i &&'\n'; 它的效果与使用三个语句是一样的。 (10)第 12 行的花括号是 main 函数体结束的标记。 运用第一章介绍的知识,我们在 Visual C++6 的开发环境里,编译、连接、运行该程序,可以得到 下面的提示: Hello C++!请输入一个整数: 假定我们输入整数 5,即: 5L L表示键入了&ENTER&键(或称为回车键) ,则得到运行结果: 您输入的整数是:5 通过这个实例,我们对 C++程序的结构、语句、变量、函数、预处理指令、输入和输出等,已有了一 个初步的印象,在后面的章节中,我们还将作更详细的介绍。 由于我们定义 main( )函数的返回类型为 void,所以最后就不用返回值了。如果我们定义 main 的返回 类型的 int,则要返回一个整型值: int main() { … return 0; } 要注意的是 C/C++是区分大小写的,不能随便更改,cout 是 C++标准的输出流,而 Cout 不是,如果没 有预先定义,编译器就不认识这个 Cout。大多数 C++命令使用小写字母,大多数常量使用大写字母,而 大多数变量是大小写混合使用。 标识符是一个字符序列,用来标识变量、函数、数据类型等。任何程序都离不开标识符,也就是说, 不可能有没有标识符的 C++程序。在程序 2-1 中,include、void、main、int、i、cin、cout 等都是标识符。 标识符可以由大写字母、小写字母、下划线(_)和数字 0~9 组成,但必须是以大写字母、小写字母或下划 线(_)开头。在 C++语言程序中,大写字母和小写字母不能混用,比如 Name 和 name 就代表两个不同的 标识符。在表 2-1 中,我们给出了几个正确和不正确的标识符实例。 表 2-1:正确和不正确的标识符实例 正确 smart _decision key_board 标识符的命名规则: 1. 所有标识符必须由一个字母(a~z 或 A~Z)或下划线(_)开头; 2. 标识符的其它部分可以用字母、下划线或数字(0~9)组成; 3. 大小写字母表示不同意义, 即代表不同的标识符,如前面的 cout 和 Cout; 在定义标识符时,虽然语法上允许用下划线开头,但是,我们最好避免定义用下划线开头的标识符, 因为编译器常常定义一些下划线开头的标识符。 C++没有限制一个标识符中字符的个数,但是,大多数的编译器都会有限制。不过,我们在定义标识 符时, 通常并不用担心标识符中字符数会不会超过编译器的限制, 因为编译器限制的数字很大 (例如 255) 。 一个写得好的程序,标识符应该尽量有意义。 比如表示年可以用 year,表示长度可以用 length,表示 累加和可以用 sum 等,这样的标识符本身就增加了程序的可读性,使程序更加清晰易懂。 C++语言的标识符经常用在以下情况中: 1. 标识对象或变量的名字 2. 类、结构和联合的成员 3. 函数或类的成员函数 4. 自定义类型名 5. 标识宏的名字 6. 宏的参数 在 C++中,有一些预定义的标识符,称之为关键字,也称之为保留字。例如,程序 2-1 中的 int、void 都是关键字。可见,关键字是一种特殊的标识符。关键字具有特定的含义,不能对它们再定义。例如,int、 void 在 C++中被预定义为特定的数据类型,我们不能把它们再定义为变量的标识符。C++的关键字很多, 不仅仅程序 2-1 中见到的 int 和 void 两个。标准 C++中预定义了 63 个关键字,参见表 2-2。另外,还定义 了 11 个运算符关键字,它们是:and、and_eq、bitand、bitor、compl、not、not_eq、or、or_eq、xor ?、xor_eq。 在我们后面要学习的内容中,并没有涉及到 C++的所有关键字,但会逐步介绍最重要和最常用的一些关键 字。 另外,有些标识符虽然不是关键字,但 C++语言总是以固定的形式用于专门的地方,也不能把它们当 作一般标识符使用,以免造成混乱。这样的标识符有 include、define 等,我们在后面的学习中会逐渐遇到。 2-2 C++关键字 asm auto bool break case default delete do double dynamic_cast float for friend goto if operator private protected public register static_cast struct switch template this union unsigned using virtual void 不正确 5smart(不能数字开头) bomb?(有非法字符?) key.board(有非法字符.) catch char class const const_cast Continueelse enum explicit export extern falseinline int long mutable namespace newreinterpret_cast return short signed sizeof staticthrow true try typedef typeid typenamevolatile wchar_t while . .. ..在 C++中,数据具有不同的类型,类型定义了变量可存储的数值范围以及可进行的操作变量是用于内 存中保存数据的,每个变量都必须有确定的数据类型,C++语言的数据类型如图 2-1 所示。 在图 2-1 中,把数据类型划分为基本的数据类型和复合的数据类型,我们也可把数据类型分为内置的 类型和用户定义的类型两大类,用户定义的类型在使用以前,必须先定义,包括:结构、类、枚举和联合 类型;内置的类型是指直接被 C++提供的类型,也就是说,是除用户定义的类型以外的其它类型。从语法上来说,void 类型也是基本的类型,但是,它不是一个完整的类型,只能作为更复杂类型的 一部分。没有 void 类型的变量,它或者用于指定一个函数(在第五章介绍)没有返回值,或者作为指针(在 第七章介绍)类型,表示该指针指向未知类型的变量,例如: //错误,没有 void 变量 void f( ); //函数 f 不返回值 void * //指针 pv 指向未知类型的变量 布尔型、字符型、整型和浮点型也称为算术类型;枚举、指针、数组、引用、结构、联合和类称之为 复合数据类型,它们能通过其它数据类型进行构造。 在基本的数据类型 char、 int 前可以添加修饰符, 以改变基本类型的意义, 可用的修饰符有 long、 short、 signed 和 unsigned 四种,另外,双精度型前可以加 long 修饰符。基本的数据类型及其表示范围,可参见表 2-3。 表 2-3 基本的数据类型及其表 示范围 类型名 char 类型 字符型 字 节 1 表示范围 -128 ~127 unsigned char signed char int unsigned int signed int short int unsigned short int signed short int无符号字符型 有符号字符型 (与字符型 相同) 整型 无符号整型 有符号整型(与整型相 同) 短整型 无符号短整型 有符号短整型 (与短整型 相同) 长整型 有符号长整型 (与长整型 相同) 无符号长整型 浮点型 双精度型1 1 * * * 2 20 ~255 -128 ~127 与机器有关 与机器有关 与机器有关 -32,768~ 32,767 0~65,5352-32,768~ 32,767 -2,147,483,648 ~2,147,483,647 -2,147,483,648 ~ 2,147,483,647 0~4,294,967,295long int4signed long int unsigned long int float double444 3.4E +/- 38 (7 位有效数字) 8 1.7E +/- 308 (15 位有效数 字) 1.2E +/- 4932 (19 位有效 数字)long double长双精度型10unsigned 和 signed 只用于修饰 char 和 int,且 signed 修饰词可以省略。当用 unsigned 修饰词时,后面 的类型说明符可以省略。例如: //与&&等价 //与&&等价 //与&&等价 //与&&等价 short 只用于修饰 int,且用 short 修饰时,int 可以省略,即: //与&&等价 long 只能修饰 int 和 double。当用 long 修饰 int 时,int 可以省略,即: //与&&等价 int 和 unsigned int 类型占用一个机器一个字(word)的字节。在 16 位操作系统上,它们占用 2 个字节; 在 32 位操作系统上,它们占用 4 个字节。 各种数据类型精度由低到高排列如图 2-2: 图 2-2 如果一个双目运算符两边的操作数类型不同,先要将它们转换为相同的类型,即较低类型转换为较高 类型,然后再参加运算。所谓类型的高低,跟所占的存储空间大小有直接关系,所占存储空间越大的类型, 级别越高。 图中横向的箭头表示必须的转换,如两个 float 型数参加运算,虽然它们类型相同,但仍要先转换成 double 型再进行运算,结果亦为 double 型。纵向箭头表示当运算符两边的操作数为不同类型时的转换,如 一个 long 型数据与一个 int 型数据一起运算,需要先将 int 型数据转换为 long 型,然后两者再进行运算, 结果为 long 型。所有这些转换都是由系统自动进行的,使用时只需了解结果的类型即可。 程序 2-2 #include &iostream.h& void main(void) { char a = 'x'; int b = 3,f = 2; float c = 2.5678; double d = 5.2345 long e = 32L; cout&&a - b + d / c - e * f&& } 下面我们来分析一下这段程序: (1) 进行 d / c 运算时,要将 c 转换成 double 型,运算的中间结果为 double 型; (2) 进行 e * f 运算时,将 f 转换为 long 型,运算的中间结果为 long 型; (3) 进行 a - b 运算时,将 a 转换为 int 型(数值为 ASCⅡ码值 120),运算的中间结果为 int 型; (4) 当(3)的中间结果与(1)的中间结果运算时,将(3)的中间结果转换为 double 型,运算的 中间结果为 double 型; (5) 当(4)的中间结果与(2)的中间结果运算时,将(2)的中间结果转换为 double 型,得出最 后结果。 于是,程序最后的运行结果为 55.038515。 如果数据是从较高类型转换成较低类型,这意味着类型的精度或表示范围降低,可能造成数据丢失。下面 两个表分别列出了有符号数之间和无符号数之间的转换: 1. 有符号数的转换 有符号数的转换中,如果从较低类型转换到较高类型,将进行符号扩展,例如一个值从 short int(16 位)转换到 long 类型,如果这个数是正数,则最高位为 0,从 16 位扩展到 32 位时,扩展的高 16 位用 0 填充,即将符号位 0 进行扩展,这样扩展后的 32 位整数和原来的整数值是一样的。如果该数为负数,则最 高位为 1,从 16 位扩展到 32 位时,扩展的高 16 位用 1 填充,即将符号位 1 进行扩展,这样扩展后的 32 位整数和原来的整数值是也是一样的。 如果从较高类型转换到较低类型,将抛弃高位,直接将低位复制过来,例如一个值从 int(假定为 32 位)转换到 short int 型(16 位),系统将抛弃高 16 位,取低 16 位的值作为转换后的值。 浮点数类型和整数类型转换比较复杂,因为它们的内部表示方式不同,转换时它们不是简单的符号位 扩展或者高位截断,它们首先需要进行内部表示方式的转换。左表是有符号数类型转换的所有情况。 表 2-4 从 char char char char char char char char short short short short short short short short long long long long long long long long 到 short long unsigned char unsigned short unsigned long float double long double char long unsigned char unsigned short unsigned long float double long double char short unsigned char unsigned short unsigned long Float double long double 方法 符号位扩展 符号位扩展 最高位失去符号位意义,变为数据位 符号位扩展到然后从 short 转到 unsigned short 符号位扩展到 然后从 long 转到 unsigned long 符号位扩展到 然后从 long 转到 float 符号位扩展到 然后从 long 转到 double 符号位扩展到 然后从 long 转到 long double 保留低位字节 符号位扩展 保留低位字节 最高位失去符号位意义,变为数据位 符号位扩展到 然后从 long 转到 unsigned double 符号位扩展到 然后从 long 转到 float 符号位扩展到 然后从 long 转到 double 符号位扩展到 然后从 long 转到 double 保留低位字节 保留低位字节 保留低位字节 保留低位字节 最高位失去符号位意义,变为数据位 使用单精度浮点数表示。可能丢失精度。 使用双精度浮点数表示。可能丢失精度。 使用双精度浮点数表示。可能丢失精度。2. 无符号数的转换 无符号数转换相对简单一些,它没有符号位,当低级类型向高级类型转换时,只需要将高位补 0,高 级类型向低级类型转换同有符号数。左表是无符号数类型转换的所有情况 从 到 方法 unsignedcharchar short long unsigned short unsigned long float double long double char short long unsigned char unsigned long float double long double char short long unsigned char unsigned short float double long double最高位作为符号位 0 扩展 0 扩展 0 扩展 0 扩展 转换到 再从 long 转换到 float 转换到 再从 long 转换到 double 转换到 再从 long 转换到 double 保留低位字节 最高位作为符号位 0 扩展 保留低位字节 0 扩展 转换到 再从 long 转换到 float 转换到 再从 long 转换到 double 转换到 再从 long 转换到 double 保留低位字节 保留低位字节 最高位作为符号位 保留低位字节 保留低位字节 转换到 再从 long 转换到 float Convert directly to double 转换到 再从 long 转换到 doubleunsigned char unsigned char unsigned char unsigned char unsigned char unsigned char unsigned char unsigned short unsigned short unsigned short unsigned short unsigned short unsigned short unsigned short unsigned short unsigned long unsigned long unsigned long unsigned long unsigned long unsigned long unsigned long unsigned long变量就是机器一个内存位置的符号名,在该内存位置可以保存数据,并可通过符号名进行访问。变量有三 个特征: ◇ 每一个变量有一个名字,其命名规则与标识符相同。 ◇ 每一个变量有一个类型。 ◇ 每一个变量保存一个值。如果需要变量保存某一个值,就把该值赋给变量。 为了提高程序的可读性,给变量命名时,应该注意使用有意义的名字,以帮助描述变量所保存的值。 最好是一开始就坚持使用小写字母。例如:要用一个变量保存工资总额,可以使用 total_payroll,也可以使 用 XYZ34 作变量名,它们都是合法的名字。但使用前者比使用后者就更好,因为从变量名,就能大致知道 它保存了什么样的值,便于记忆。 在使用一个变量之前,必须先定义。变量的定义的一般格式如下: 数据类型 变量名 1[= 初始值 1], 变量名 2[= 初始值 2], ...; &数据类型&是指 C++有效的数据类型,如 int、double、long 等。方括号中的内容是可选的,它是在变 量定义时,给变量赋初值。下面是几个变量定义的实例:
//定义了一个长整型变量 n,未赋初值 double a, b = 0.5; //定义双精度型变量 a、b,a 未赋初值,b 的初值为 0.5 下面是一个使用变量的程序实例: 程序 2-3: #include &iostream.h& int main (void) { 1. int workDays = 5; 2. float workHours, payRate, weeklyP 3. workHours = 7.5; payRate = 38.55; 4. weeklyPay = workDays * workHours * payR 5. cout && &Weekly Pay = & && weeklyPay && '\n'; } 第一行定义了一个整型变量 workDays,并初始化为 5,表示一周的工作天数。 第二行定义了三个实型变量,分别表示每天工作的小时数、每小时应支付的薪水及每周应支付的薪水。 第三行是两个赋值语句。7.5 赋给变量 workHours,38.55 赋给变量 payRate。 第四行是计算每周的工资,即三个变量 workDays、workHours、payRate 的积,*是乘运算符,结果保 存在变量 weeklyPay 变量中。 第五行输出字符串&Weekly Pay = &、变量 weeklyPay 的值和换行符。 本程序的运行结果如下: Weekly Pay =
如果我们定义一个变量时, 没有给它赋初值, 它的值是不定的。 例如, 在上面的第四行执行前, weeklyPay 的值是不定的。 变量第一次赋值称之为初始化,变量在使用之前应当先初始化。 2.4.1 整型 整型变量可用 short、int、long 定义,区别在于 int 占用机器的字节数比 short 多或一样,而 long 占用 的字节数比 int 多或一样。例如: short age = 20; int salary = 65000; long price = 4500000; 缺省的情况下,整型变量假定为有符号的,但是,使用 unsigned 关键字,也可以把整型变量定义为无 符号的。当然,定义整型变量时,也可以使用 signed 关键字,但是多余的。 unsigned short age = 20; unsigned int salary = 65000; unsigned long price = 4500000; 一个整型数,例如 1984,总是被假定为 int 类型,除非有 L 或 l 后缀,才被处理为 long int 类型。同样, 一个整型数也可以加 U 或 u 后缀,指定为 unsigned 类型。例如表 2-6: 整型数能被表示成 10 进制、8 进制和 16 进制。如果一个整型数有前缀 0,则表示是 8 进制数,有前缀 0x 或 0X,表示是 16 进制数。例如: 92 // 十进制 0134 // 8 进制 0x5C // 16 进制 8 进制数只能使用数字 0~7,16 进制数可用 0~7 及 A~F (或 a~f)表 2-6 l u 1984LU 1984lu整型是常用的一种数据类型,但是,它的大小是不固定的,这是由操作系统决定的。在计算机中任何 信息都是以二进制的形式存储的,二进制数每一位是 0 或 1,八位组成一个字节(byte),两个字节组成一 个字(word),四个字节组成一个双字(dword)。 整数能存储的最大值是由计算机给它分配的存储空间的大小决定的,而整数所占的存储空间因不同的 计算机而异。例如,某种计算机可能用 16 位(两个字节)来存储一个整数,而另一种计算机则可能用 32 位(四个字节)来存储。 当一个整数存储在计算机中时,左起第一位叫做第 0 位,即符号位,它用来表示该数是正数或负数。 如果是负数,符号位被置 1,正数则为 0。 两个字节能表示的整数范围是-3, 四个字节能表示的整数范围则增加到 -~。 由于整数所占的存储空间在不同的计算机上是不同的,所以在代码移植时容易出现问题。图 2-3 2 字节如何表示整型值2.4.2 浮点型 浮点型变量可用 float 或 double 定义,后者在机器内存中占用的字节数更多,所 以有效位数更多,表示的数字范围也更大。例如: float interestRate = 0.06; double pi = 3.; 一个实型数, 0.06 总是假定为 double 型, 如 除非有 F 或 f 后缀, 才被处理为 float 型。若有 L 或 l 后缀,则被处理为 long double 型。例如表 2-7: 实型数也可以表示成指数形式。例如:0.002164 可以写成: 2.164E-3 或 2.164e-3 E 或 e 代表指数。表 2-71984L1984l1984U1984u1984LU1984lu浮点型分为单精度浮点型和双精度浮点型,就是所谓的 float 和 double。下表列出了它们的主要数据: 表 2-8 类型 float double 字节数 4 8 有效位(十进制) 6-7 15-16 指数长度 8bits 11bits 尾数长度 23bits 52bits浮点数是由符号位、指数位和尾数位构成的,上表已列出浮点型的指数位长度和尾数位长度。以单精 度浮点数为例:它是由 1 个符号位、8 位指数位和 23 位尾数组成,共 32 位,4 个字节。2.4.3 字符型 字符变量用 char 定义,一个字符变量仅占用一个字节,存放该字符的编码。该编码是一个数字,并依 赖于所使用的编码系统(即与机器相关)。最普通的编码是 ASCII(American Standard Code for Information Interchange),即美国信息交换标准编码。例如:字符 A 的 ASCII 码为 65,字符 a 的 ASCII 码为 97。 char ch = 'A'; 象整型数一样,字符变量也可被指定为 signed 或 unsigned。大多数机器上,char 与 signed char 意义相 同。有些机器上,char 可能与 unsigned char 意义相同。一个有符号字符变量可以保存-128 ~127 之间的整 数,而一个无符号字符变量可以保存 0 ~255 之间的整数,它们均可用于表示小整数,象整型数一样赋值: signed char offset = -88; unsigned char row = 2, column = 26; 一个字符是用一对单引号包围起来,例如:'A'。C++中还有一些不能打印的特殊字符,称之为转义字 符。例如 2-1: 字符也可以用它们的编码指定,转义字符通常用三位 8 进制数表示,例如 2-2:(假定为 ASCII 码): C++的字符由下列字符组成。 1、大小写英文字母 a~z,A~Z 2、数字字符 0~9 3、特殊符号 空格 ! # % ^ & * _ - + = 图 2-6 2 字节如何表示字符型值C++语言把字符型变量当作一个较小的整型量,可以象整型量一样使用它。下面举一个例子说明: 程序 2-6 #include &iostream.h& void main() { char c1 = 'a'; char c2 = 'b'; char c3,c4; c3 = c1 - ('a' - 'A'); c4 = c2 - ('a' - 'A'); cout&&c3&&c4&& } 运行结果为: AB程序中的'a' - 'A'是大小写字母之间的差值,其值为 32。所以我们也可以把程序写成: c3 = c1 - 32; c4 = c2 - 32; 如果我们想看一看 c3、c4 中到底存储的值是多少,可以这样: cout&&(int)c3&&(int)c4&& 其运行结果为: 65 66 注意:在内存中,字符数据以 ASCII 码存储,即以整数表示,'0'和 0 是不同的。 例 2-1: '\n' // 换行 '\r' // 回车 '\t' // 水平 tab '\v' // 垂直 tab '\b' // 退格 '\f' // 进纸 '\'' // 单引号 (') '\&' // 双引号 (&) '\\' // 反斜杠 (\)例 2-2: '\12' //换行(10 进制编码 = 10) '\11' // 水平 tab (10 进制编码= 9) '\101' // 'A' (10 进制编码= 65) '\0' // null (10 进制编码= 0) 2.4.4 字符串 字符串是一个连续的字符系列,有一个'\0'字符结尾。假定有一个字符串为&HELLO&,它在内存中的存 储,参见图 2-2。 一个字符串用一对双引号包围起来,例如:&HELLO&,编译器在每一字符串的结尾增加'\0' 结尾符。 字符串可以由任意字符组成,例如: &Name\tAddress\tTelephone& // tab-分隔字符 &ASCII character 65: \101& // 'A' 用'101'指定 一个长字符串可以占两行或多行,但在最后一行之前的各行应用反斜杠结尾,例如: &Example to show \ the use of backslash for \ writing a long string& 上面的字符串与下面的单行字符串等价: &Example to show the use of backslash for writing a long string& 需要注意的是: (1) 不要把字符与字符串混淆了。例如:&A&与'A'不等价,前者由两个字节组成(字符'A'与字符'\0') , 而后者只有一个字节。 (2) 最短的字符串是空字符串(&&),它仅由一个结尾符'\0'组成。 (3) C++中,没有字符串类型,而是用字符数组来处理字符串,这将在第六章中介绍。图 2-7 在内存中的字符串字符串常量与字符常量不同,字符串常量是用一对双引号括起来的零个或多个 ASCII 字符的序列,并 以 NULL(ASCII 码值为 0)结束。例如: 例 2-3: &This is a character string.& &CHINA& && &a& &$10000.00& & &(引号中有一个空格) &&(引号中什么也没有) &\n&(引号中有一个转义字符)字符串常量在内存中存储时,系统自动为每个字符串常量的尾部加一个字符\0,用以标识这字符串的 结束,如字符串 &CHINA& 在内存中的形式是:表 2-9 C N I N A \O了解这一点,我们就可以区分字符串&a&和字符'a'有何不同了。它们在内存中的形式分别为:2.4.5 布尔型 布尔类型变量用 bool 关键字定义,其值为 true 或 false,true 和 false 都是 C++的关键字。整 型值也可赋给 bool 变量,但会被隐式转换成 true 或 false。转换规则如下:整型值非 0 时,转换 为 true,整型值为 0 时,转换为 false。 同样,布尔值也可赋值给整型变量,但要进行隐式转换,转换规则为:布尔值为 true 时, 转换为 1,布尔值为 false 时,转换为 0。 布尔值也可插入输出流 cout,当布尔值为 true 时,在屏幕上打印 1,当布尔值为 bool 时, 在屏幕上打印 0。例如 2-5。 C 没有 bool 这个数据类型,C++中定义了 bool 类型,它只有两个值:true 和 false。所有的条件表达式返 回类型都是 bool 型,比如 n!=0(!=是&不等于&运算符,我们在本章后面要介绍)根据不同的 n,返回 true 或 false。true 和 false 有如下关系: !true== !false== !是取反运算符,我们在本章后面要介绍。我们看一个简单的例子:&if (exp1) statement1;&。这个语句 的意思是:如果表达式 exp1 的值是 true,就执行 statement1,否则就不执行。 如果对一个 bool 类型变量使用前缀或后缀自增(++)运算符,不管这个变量是 false 还是 true,这个 变量将变为 true。但是不能对 bool 类型变量使用前缀或后缀自减(DD)运算符(有关自增、自减运算符 的内容在本章的后面介绍)。如:例 2-4: #include &iostream.h& int main(int argc, char* argv[]) { b= cout&&b++; cout&&b++; cout&&b; return 0; } 程序运行结果为: 011一个右值为 bool 型变量将被自动转换成整型,且 false 被转换成 0,true 被转换成 1。所以上面程序中 输出的是 011,代表的意思是 false、true、true。 C++中还有一种比较特殊的类型,它用于定义函数返回类型,或者用于定义&一般类型&的指针,即该指 针可以指向任意类型数据(被 const 和 volatile 修饰的变量除外),但是不能定义空类型的变量。例如, 函数声明:void func(); 指针定义:void *p; 例 2-5: cout && &A true value: &; cout && true; cout && endl; cout && &A false value: &; cout && false; cout && 输出结果为: A true value: 1 A false value: 0 在进行程序设计时,常常需要常量,例如圆周率 π = 3.1416。在需要常量的地方,直接使用常量的数值 的方法非常不好,例如: //计算圆的面积 s = 3.1416*r*r; ... 如果我们需要提高计算精度,将 π 的值改为 3.1415927 进行计算,我们就不得不将程序中所有的 π 值 从 3.1416 改为 3.1415927,这不仅繁琐,更重要的是很容易出错。 C++允许定义符号常量,定义常量的一般形式为: const 类型 名字 = 值; 其中,&类型&是指常量的类型,如 short、long、double 等,&名字& 是指常量的名字,而&值&是指赋给 常量的、合适的数据类型的数值。 参看例 2-7。 下面给出一个有常量定义的实例程序,这个程序是打印给定半径的圆的面积和周长。 例 2-6: void main() { const double PI = 3.8; //定义圆周率常量 PI //定义圆半径变量 //定义圆面积变量
//定义圆周长变量 cout && &Enter radius : &; cin && area = PI*radius* circumference = 2.0*PI* cout && &Area of circle of radius & && radius && & is & && area && & \n&; cout && &and its circumference is & && circumference && & \n&; } 运行该程序,并输入半径值 10.0: Enter radius : 10.0L 则输出结果为: Area of circle of radius 10.0 is 314.159 and its circumference is 62.8319常量就是在程序运行过程中其值不发生变化的量。常量可分为直接常量与符号常量。直接常量就是平 常我们所说的常数,例如: `r` // r 为字符型直接常量 3.1415926 // 3.1415926 为双精度直接常量 符号常量就是用一个标识符代表某个常量。符号常量可用关键字 const 声明,其格式如下: const 数据类型 例如: const int a= 1234; //定义 a 为整型常量其值为 1234 const char b=`a` //定义 b 为字符型常量其值为 a 在程序设计中,尽量使用符号常量来代替常数,这是一种好的编程习惯,这样可以增加程序的可读性、 可维护性。例如,在数值计算中,我们会经常遇到一些常量,比如圆周率。如果把它定义成符号常量,当 需要更改常量值的时候,只需要更改符号常量的定义语句即可。 也可以使用预处理语句定义符号常量,例如我们用: #define PI 3.14159 定义符号常量 PI,然后在程序中使用 PI,跟使用常数 3.14159 的效果是一样的。编译器在编译时,把 符号 PI 替换成 3.14159,当需要修改 PI 的值时,只需要修改上面的语句即可。但是我们不推荐这样做:因 为预定义符号与符号常量不同,在编译时使用常数替代了所有的预定义符号,这样在代码中相应位置实际 都是常数。程序中过多的常数会导致程序代码量变大,而且在多个源文件中定义了同样的符号,会产生符 号重定义的问题。使用常量优于#define 宏,优点在于可指定类型信息。 常量名=常数值;例 2-7: const double PI = 3.1415927; //圆周率 π const long number = 49L; const char TAB = '\t'; const char QUERY = '?'; const double SOM ENUM = 1.235E75; 我们常常需要一些整型常量表示某一个的数据范围。例如,假定需要表示汽车的颜色: const int cRED = 0; const int cBLUE = 1; … int auto_ auto_colour = cBLUE; 上面的程序语句是用整型变量 auto_colour 表示颜色,下面的语句也是合法的: auto_colour = -1; … 显然,-1 并不是所需要的颜色值。如果能够限定 auto_colour 在限定的整数范围(即规定的几种颜色集 合)内取值就比较好,C++中的枚举类型能够让我们做到这一点。枚举类型是一种用户定义的数据类型, 其一般定义形式为: enum 枚举类型名 { 标识符[=整型常数], 标识符[=整型常数], ... 标识符[=整型常数], }; &枚举类型名&右边花括号中的内容称之为枚举表,枚举表中的每一项称之为枚举成员,枚举成员是常 量,也就是说,枚举表是整型常量的集合。枚举成员之间用逗号隔开,方括号中的&整型常数&是枚举成员 的初值。 如果不给枚举成员赋初值,即省掉了标识符后的&=整型常数&时,则编译器为每一个枚举成员给一个不 同的整型值,第一个成员为 0,第二个为 1,等等。当枚举类型中的某个成员赋值后,其后的成员则按依次 加 1 的规则确定其值。下面是一个枚举类型定义实例: enum Colour { eRED, eBLUE, eYELLOW, eGREEN, eSILVERGREY ,eBURGUNDY }; 这样就定义了一个称之为 Colour 的枚举类型,编译器给枚举成员 eRED,…,eBURGUNDY 的值分别 为 0,…,5。 定义了枚举类型,就可以定义枚举类型的变量,其值限定为某一个枚举成员。例如: Colour auto_ … auto_colour = eBURGUNDY; Colour 类型变量 auto_colour 只能取 eRED,…,eBURGUNDY 六个值中的一个,下面的语句将会出现 编译错误: auto_colour = 4; 我们也可以在定义枚举类型时,为枚举成员指定初值,例如: enum Colour { eRED=5, eBLUE, eYELLOW, Egreen=30, Esilvergrey=40,eBURGUNDY }; 这时,eBLUE=6、Eyellow=7、Eburgundy=41。 由上述几种基本数据类型通过各种组合可以得到复合数据类型,这些数据类型在以后章节会有详细讲 解。 如果一个变量只有几种可能的值,就可以把它定义为枚举类型。&枚举&,顾名思义,就是把这种类 型数据可取的值一一列举出来。 例如,可以定义一个表示日期的枚举类型 weekday: enum weekday{sun,mon,tru,wed,thu,fri,sat}; 这里 enum 是关键字,用于定义枚举数据类型,weekday 是枚举类型的名字,枚举元素用标识符表示。 接下来我们可以用 weekday 来定义变量,例如: weekday today, C++语言也允许在定义枚举类型的同时定义枚举变量,例如: enum weekday{sun,mon,tru,wed,thu,fri,sat}today, 这样,变量 today 和 nextday 就具有 weekday 类型,它们的取值只能是 sun,mon,…,sta,例如可有: today = nextday = if(today == sat) nextday = sun //如果 today 是 sat 的话,那么 nextday 赋值为 sun C++编译器对枚举元素实际上是按整型常数处理。所以,就象前面所说的那样,当遇到枚举元素列表 时,编译程序就把其中第一个标识符赋 0 值,第二、三、…个标识符依次赋 1、2、…。因此,当枚举元素 赋给枚举变量时,该变量实际得到一个整数值。例如: today = 是将 0 赋给 today,而不是将字符串&sun&赋给 today。赋值后: cout&& 语句的输出结果是 0。 我们也可以在枚举类型定义时指定枚举元素的值,例如: enum weekday{sun = 7,mon = 1,tue,wed,thu,fri,sat}; 这时 sun 的值是 7,mon 的值是 1,而 tue 以后各元素的值,从 mon 的值开始,每次递增 1,即 tue 的 值为 2,wed 的值为 3,…。如果不写 mon = 1,则 mon 的值为 8,tue 的值为 9,依此类推。 由于枚举元素是常量,所以我们在程序中不能对它们进行赋值,如&sun = 0;mon = 1;&将产生错误。 既然枚举元素就是整型值,那么它有什么存在的必要呢?至少有两个原因:一个是用标识符表示数值 增加了程序的可读性,例如: if(today == sat) next = sun 就比 if(today == 6) nextday = 0; 清楚多了;另一个重要的原因是:它限制了变量取值的范围,如现在 today 只能取 sun~sat 中的值。 注意:enum 在 C++和 C 中使用的不同。下面的 C 语言语句定义了名为 day 的变量: enum Days { M onday, Tuesday, Wednesday, Thursday, Friday }; enum D 在 C++中,定义为: enum Days { M onday, Tuesday, Wednesday, Thursday, Friday }; D C++中定义了枚举类型数据后,程序可以把它当作一种类型使用,不需在类型名 Days 前加 enum 关键 字。 C/C++语言本身并不带输入和输出(即 I/O)功能,而是提供了输入输出库,也称为 I/O 库。通过 I/O 库,我们可以完成输入和输出的操作。大多数 C 程序使用一种称为 stdio(标准 I/O)的 I/O 库,该库也能 够在 C++中使用。但是,在 C++程序中,一种称为 iostream(I/O 流库)的 I/O 库用得更多。 在 C++中,I/O 使用了流的概念-字符(或字节)流。每一个 I/O 设备传送和接收一系列的字节,称之 为流。输入操作可以看成是字节从一个设备流入内存,而输出操作可以看成是字节从内存流出到一个设备。 流是输入输出设备的另一个名字-一个文件、屏幕、键盘等。要使用 C++标准的 I/O 流库的功能,必须包括 两个头文件: #include&iostream.h& #include&iomanip.h& iostream.h 文件提供基本的输入输出功能,iomanip.h 文件提供格式化的功能。通过包含 iostream 流库, 内存中就创建了一些用于处理输入和输出操作的对象。标准的输出流(通常是屏幕)称为 cout,标准的输 入流(通常是键盘)称为 cin。 输出变量 d 的值到标准输出设备的语法形式如下: cout && 注意: (&&)是双小于号,不是左移操作符,它是一种输出操作符,指出程序哪个流发送数据。 本语句表示传送 d 的值到标准的输出设备(由 cout 表示) 。理解这个语句的一种方法是调用了函数 operator&&,d 是函数参数(关于函数调用,在第五章学习) 。明确地说,为了输出 d 的值到 cout,可以使 用语句: cout.operator&&(d); 对于 C 语言的程序中,使用的是 stdio(标准 I/O)库,在这个库中不仅定义了面向控制台(显示器和 键盘)的输入输出,还分别定义了文件输入输出函数和面向内存的输入输出函数。在 C++程序中,我们最 常使用的是 iostream(I/O 流库) ,它是基于面向对象的,可以实现 stdio 库的所有功能,通过它统一了标准 I/O、文件和存储块的函数接口,使得对所有设备的操作看上去都一样,隐藏了内部实现。与标准 C 输入输 出库的各种各样的函数相比,输入输出流更容易、更安全、更有效。为了保证兼容性,I/O 流类和 C 标准 输入输出函数库是可以共同使用的。 使用 stdio 库,需要在程序中包含 stdio.h 头文件,若使用 iostream 库,需要包含 iostream.h 头文件,如 果要带参数的格式化输入输出,还需要包含 iomanip.h 头文件。 使用 stdio 库的标准输入输出,要使用 scanf 和 printf 函数,scanf 函数是从标准输入(键盘)设备读入, printf 是向标准输出设备(显示器)输出。 iostream 库在 iostream.h 中预定义了四个全局的流对象:cout、cerr、clog 和 cin,用于标准输出和输入, cout 和 cin 在程序设计中会经常用到。cout 流对象控制向控制台(显示器)的标准输出,cin 控制从控制台 (键盘)输入。 2.7.1 标准输出 输出内置的数据类型到标准的输出设备,用&&运算符和 cout 输出流。例如: cout && // 输出 d cout && d && // 输出 d 并换行 cout && &This is the value of d : & && d && // 输出字符串、d 并换行 一个语句中多次使用&&等价于&&单独使用多次,即最后一个语句等价于: cout && &This is the value of d : & ; cout && cout && 符号 endl 的功能是换行,并清除输出缓冲区。变量的值以缺省的格式打印,改变打印格式方法在后面 介绍。 C 语言的转义字符在 C++中仍然有效,所以在 iostream 中,我们可以使用转义字符,比如要达到回 车的效果,我们可以使用: cout&& 也可以使用: cout&&'\n'; 如果实现简单的格式化输出,我们可以使用制表符: cout&&&name\tage\tsex&&&2.7.2 标准输入 标准输入的用法与标准输出类似,使用&&运算符和 cin 输入流。语句: cin && 是从标准输入读(或抽取)一个值到变量 d,并与语句中的数据类型匹配。例如:如果 d 是 整型数,上面的命令读数字,直至没有遇到数字为止;如果 d 是浮点数,该命令读数字、小数点、 指数,直至没有遇到合适的字符为止。 假如把输入和输出语句结合在一起使用,可能会发生问题。我们编写程序时,常常先用一个 输出语句打印提示,然后要求用户输入数据。对于一些 C++编译器,在输入语句抽取数据前, 应先输出一个换行符。例如 2-9: 否则,可能达不到目的 经验:如何记&&和&&:cout 是 c 出,出了就小(&&)了; cin 是 c 进,进则收入,就大(&&) 注意:cin 流不使用指针引用变量,不应给 cin 传递一个指向变量的指针,如果这样做 cin 将返回错误。 例如,下面的程序 cin_err.cpp ,当编译它时将返回六个错误: 例 2-8: #include &iostream.h& void main(void) { char name[128]; cout && &Enter your first name age salary: &; cin && &name && &age && & cout && name && & & && age && & & && }例 2-9: cout && & Enter the value of n : & && cin && 而不要写成: cout && & Enter the value of n : &; cin && 2.7.3 格式化 有两种方法设置变量的输出格式:一种方法是直接设置输出流的格式状态,另一种方法是通过输入输 出操纵符。 如果选择前者,需要设置与输出流相关的标志,此后,任何数据输出到该流,将按照标志决定的格式 输出;如果选择后者,可将格式化的命令嵌入到输入输出语句中。 前者也许更好,因为,我们常常为所有的输出选择一种格式,也就是说,常常不需要大量的、不同的 格式。与输出流格式状态相关的标志有许多,我们仅讨论最常用的两种:精度(precision)和宽度(width) 。 精度是指小数点后的数字位数,宽度是指变量输出的总位数。设置精度和宽度的形式如下: cout.precision(4); cout.width(10); 用下面的语句,我们可以得到当前的精度和宽度: n = cout.precision(); m = cout.width(); 一旦设置了 precision,在下一次设置以前,原设置值保持不变。width 有所不同,它是数据输出的最小 位数,如果宽度不够,则会分配更多的位数。也就是说,当 width 位数不够时,输出的数据不会被截断。 而且输出操作完成后,width 会恢复为缺省值。还有一些标志可以设置浮点数的固定或指数表示、输出值的 对齐方法(右、左或中间) 、是否显示尾部 0,这些标志用成员函数 setf 设置。例如,假定要使用标准输出, 指数表示、左对齐及显示尾部 0,可以使用下面的语句: cout.setf(ios::left, ios::adjustfield); cout.setf(ios::showpoint, ios::showpoint); cout.setf(ios::scientific, ios::floatfield); 使用 precision 域可以控制输出的精度。对于整数,precision 域用来控制输出结果的长度,如果整数值长 度小于设置的精度,则输出结果的前面补 0。对于浮点数,precision 域用于控制小数点后面的位数。 例如: printf(&%+10.5f&,f); 输出浮点数 f,带符号,宽度是 10 位(包括小数点) ,小数位是 5 位。 控制符 L 或 l 可以将整数设置为长整型输出,h 可以将整数作为短整型输出。 2.7.4 printf 和 scanf 输出输入 printf 和 scanf 是标准的 C 输出输入语句,在 C 语言标准的头文件 stdio.h 中定义。但在 C++中,它们 也能够被使用。 一、 printf 输出 printf 语句的一般形式如下: printf( &格式字符串&, 表达式, ... ); 该语句将&表达式&按照&格式字符串&给定的格式,显示在屏幕上。&格式字符串&包括文本字符、转义字 符和格式说明符。 如果我们只要打印简单的信息,并不需要包括&表达式&,例如,要打印信息:&今天是星期二&,可以使 用下面的 printf 语句: printf(&Today is Thursday&); 这个语句执行的结果为: Today is ThursdayPress any key to continue 需要注意的是:输出的信息与系统提示连在一起。为了解决这个问题,可以使用转义字符,常用 的转义字符参见 2.4.3 节的内容。 C++使用操纵符(在&iomanip.h&和&iostream.h&中定义),而 C 提供了一系列的说明符,参见表 2-10。这 些说明符用于输出,也可用于输入。 表 2-10: 说明符 %wd 类型 int 或 char w = 宽度 double w = 总的 %w.df 宽度(包括小数 点) d = 小数位 数 %wc char 或 int w = 宽度 char * (字符串) 格式 w = 宽度 unsigned int w = 宽度 八进制 十六进制 指数记数法%ws%wu %wo %wx %m.dddddde± %m.ddddddE± %m.ddddddg±xx %m.ddddddG±xx xx xx下面,我们给出一些格式实例,假定有下面的变量说明:表 2-11: 变量说明 int x = 98; float y = 1.; char letter = 'A'; char word[] = &Hello&;下表给出了输出这些变量的缺省的格式:表 2-12: 语句 结果 printf(&Default formats: %d %f %c %s \n&, x,y,letter,word); Default formats: 98 1.345679 A Hello我们也可以改变缺省的格式。需要注意的是:输出结果是右对齐的,也就是说,当输出结果的宽度小 于指定的宽度时,空格填充到左边:表 2-13: 格式说明 语句 结果 printf(&Width specified: %5d %10.4f %5c %10s \n&, x,y,letter,word); Width specified: 98 1.3457 A Hello我们也可以打印变量的内存地址信息,但要使用 unsigned 格式说明符: 表 2-14: 打印内存地址 语句 结果 printf(&Address of x: %u Address of y: %u\n&, &x, &y); Address of x:
Address of y: 表达式按照格式字符串指定的格式输出。当格式字符串中没有格式说明时,printf 函数就相当于输出 一个普通的字符串。 例如: printf(&this is a string.&); 格式说明符总是以一个百分号(%)引导,当 printf 函数遇到第一个格式说明符时,用第一个表达式 的值来替换它,遇到第二个格式说明符时,就用下一个表达式的值替换,依此类推。如果表达式个数多余 格式说明符个数,则多余的参数就被抛弃。格式说明符的格式是: %[flags][width][.precision][{h|l|L}]type 每个域是由一个字符或者一个数组成,方括号扩起的域是可选项,最基本的格式是:%type。 type 域字符: 表 2-19: 转 换 字 符 C C int int 输出一个字符 同上 类型 含义 D I O U X Xint int int int int int输出有符号十进制整数 同上 输出无符号八进制整数 无符号十进制整数 无符号十六进制整数 同上 以科学计数法输出浮点数 同上 输出十进制浮点数 等效于%e 和%f,取两者之中较短 的 同上 输出指针地址,格式如下: xxxx:yyyy ,xxxx 是段地址,yyyy 是偏移量,它们都是十六进制数 输出字符串e double E double F double G double G double void 指 针 char*PS例如: printf(&%d%x&, n, n) 是将 n 分别按 10 进制和 16 进制整数输出。 我们可以用 flag 任选符来改变输出的格式, 表 2-20: Flag 含义 左对齐 缺省 右对 齐 只显 示负 号 无填 充 不填 充空 格+如果结果是有符号数,则显 示符号0在结果前面填充 0空格 (' ')如果结果是有符号数且为 正,则在前面填充一个空格例如: printf(&%+d&,n); 输出整数 n 时显示符号(包括正号)。 可以使用 width 域设置输出的宽度, 如果输出的宽 度小于设置的宽度, 用空格填充, 如果大于设置的宽度, 则设置的宽度将被忽略,而不会将结果裁剪。 例如: printf(&%+10d&, n); 输出整数 n 时显示符号,且宽度为 10 位,如 n 不 够 10 位,则用空格填充,否则按实际位数显示。 二、 scanf 输入 scanf 语句的一般格式如下: scanf(&格式字符串&, 地址,…); scanf 语句用&格式字符串&控制键盘读入的方式。&格式字符串&中一般只包括 格式说明符,它们与 printf 语句中的一样,而&地址&是指变量在内存中的位置。 我们看看下面的程序实例,它定义了一个 int、float、char 和 char []变量,并使用 了格式说明符:程序 2-4: #include &stdio.h& #define M AX_WORD 20 void main() { char ch, char word[M AX_WORD]; printf(&Enter an integer: &); scanf(&%d&, &x); printf(&Enter a float: &); scanf(&%f&, &a); fflush(stdin); // 清空输入缓冲区 printf(&Enter a character: &); scanf(&%c&, &ch); printf(&Enter a string: &); scanf(&%s&, word); printf(&Your integer was: %d\n&, x); printf(&Your float was: %f\n&, a); printf(&Your character was: %c\n&, ch); printf(&Your word was: %s\n&, word); } 这个程序有几个有趣的特征,总结如下: (1) 地址。整型、浮点型和字符型变量需要使用地址运算符&,而字符串不需要,因为数组名就是数 组在内存中的起始地址,有关数组和字符串的内容,我们在第六章详细介绍。 (2) fflush() 函数。 我们在读字符之前, 调用 fflush() 函数, 这个函数清空标准的输入设备缓冲区 (stdin) 。 如果要删除缓冲区中回车换行符,就必须清空缓冲区。因为它们也是字符,如果不在读入之前清除它们, 就不能正确地读入字符。 (3) 字符串。我们输入字符串&hello there&,但读到空格时,scanf()就停止了,仅&hello&存入了字符串。 下面是说明这种现象的一个实例,运行该程序,并输入。参看例 2-10: 如果需要读取带空格的字符串,可以使用函数 gets 来做这件事情。gets 的作用是读取一行字符到一个 字符串变量中。它会读取空格,直到遇到'\n'或'\0'时才返回。例 2-10: Enter an integer: 10L Enter a float: 1.23456L Enter a character: cL Enter a string: hello thereL 运行结果为: Your integer was: 10 Your float was: 1.234560 Your character was: c Your word was: hello格式说明符的形式是: %[*][width][{h | l | L}] ty pe scanf 的格式说明符与 printf 的类似,最简单的形式如下: %type type 域标识要读取的数据类型,它与 printf 函数的字符是一样的。Width 是读取的最大字符数, 例如,数据为&1.&,我们使用: scanf(&%5lf&,&f); 那么它只会读取 5 个字符,即 1.234 到变量 f 中。 注意:用 scanf 读取字符串的时候,如果字符串中存在空格,那么它将在空格处将该字符串裁 掉,只取前面部分。scanf 在遇到空格,制表符时会认为数据已经读取完毕,并将读取的数据转换成 相应类型,存储到地址所在的存储空间中。【本章小结】 本章讲述了 C++语言的基本知识。 ◇ 在 C++语言中,语句、变量、函数、预处理指令、输入和输出等,是重要的概念,应该在 编程实践中逐渐掌握这些概念和它们的应用。 ◇ 标识符是用来标识变量、函数、数据类型等的字符序列。C++中的标符可以由大写字母、小 写字母、下划线(_)和数字 0~9 组成,但必须是以大写字母、小写字母或下划线(_)开头。C++ 语言中预定义了一些标识符,称之为关键字,它们不能被再定义。 ◇ 布尔型、字符型、整型、浮点型和空类型是基本数据类型。指针、数组、引用、结构和类可 以通过基本数据类型进行构造,称之为复合数据类型。 ◇ 变量就是机器一个内存位置的符号名, 在该内存位置可以保存数据, 并可通过符号名进行访 问。为了提高程序的可读性,给变量命名时,应该注意使用有意义的名字。变量第一次赋值称之为 初始化,变量在使用之前应当先声明。 ◇ 常量是在程序运行过程中,其值不能改变的量。 ◇ C++语言本身没有输入输出功能, 而是通过输入输出库完成 I/O 操作。 程序使用的 stdio 标 C ( 准 I/O)I/O 库也能够在 C++中使用;另外 C++语言还提供了一种称之为 iostream(I/O 流库)的 I/O 库。【学习目标】 熟练掌握 C++各种运算符的使用方法。能熟练运用运算符组成需要的表达式。正确使用操作数 的类型转换和运算符的优先级顺序和结合性。 【重点和难点】 自增、自减运算符的运用;各个运算符的优先级顺序及其结合性;操作数的类型转换。 【学习方法指导】 要在学习中注意区分运算符、表达式和语句的不同;不同类型的操作数赋值时,尽量进行显式 转换,隐式转换容易犯错误;优先级和结合性也容易犯错误,一般说来,表达式中加上圆括号,比 较保险,这也可以提高程序的可读性。 【知识点】 算术运算符;自增、自减运算符;关系运算符;逻辑运算符;位运算符 赋值运算符;求字节数运算符;逗号表达式;短路表达式;显式类型转换;隐式类型转换;优 先级与结合性 所谓运算符就是指运算的符号,例如加运算符(+) 、乘运算符(*) 、取地址运算符(&)等。表达式 与运算符密不可分,它由运算符与操作数组合而成,并由运算符指定对操作数要进行的运算,一个表达式 的运算结果是一个值。本章中,我们将介绍 C++语言基本的运算符、表达式,各种运算符的优先级、结合 性,以及不同数据类型的值之间的转换。 C++语言中的运算符是可以让 C++语言编译器能够识别的具有运算意义的符号。编译器把这些符号及 其组成的表达式翻译成相应的机器代码,就可以由计算机运行得出正确的结果。 其实,就象我们日常生活当中许多东西的名字,如冰箱、电视机等分别代表不同功能的电器设备一样, 运算符就是代表 C++语言中的各个运算功能的名字,这些名字是由制定 C++语言规范的人员确定的。下面 给出由运算符组成的表达式的例子: 下面是几个表达式例子。如: 100+200-300*200+%10 a || b && c || d a = b + c + d*e a += b++ c -= d-只要是按 C++语法写出的表达式,编译器就能够解释其中的运算符和由运算符、操作数组成的表达式 的意义。 C++提供的运算符有以下几种:算术运算符、关系运算符、逻辑运算符、位运算符、条件运算符、赋值 运算符、逗号运算符、sizeof 运算符及其它运算符(这是按功能分的)。不同的运算符,需要指定的操作数的 个数并不相同。根据运算符需要的操作数的个数,可将其分为三种:单目运算符(一个操作数) 、双目运算 符(两个个操作数)和三目运算符(三个操作数) 。下面,我们介绍几种基本的 C++运算符。 3.1.1 算术运算符 C++提供 5 种基本的算术运算符,参见表 3-1。 表 3-1 5 种 基本的算 术运算符 运 算 符 名 字实例12 + + 加 4.9 // 得出 16.9 3.98 - 减 - 4 // 得出 -0.02 2* * 乘 3.4 // 得出 6.8 9/ / 除 2.0 // 得出 4.5 13 % % 取 3 // 余 得出 1这 5 个算术运算符都是双目运算符。除%运算符外,其它算术运算符的两个操作数可以是 整型(short int、int、long int、unsigned short int、unsigned int 或 unsigned long int 型)和实型 (float 或 double 型)的混合类型,运算结果的数据类型是:两个操作数的数据类型中,具有 较高级别的数据类型(数据类型的级别,请参见 3.3 节)。例如,一个 int 型操作数和一个 float 型操作数的运算结果是 float 型;一个 float 型操作数和一个 double 型操作数的运算结果是 double 型。 当除运算符(/)的两个操作数均为整数时,所得的结果总是被圆整化为整数。例如: 9 / 2 // 得出 4, 不是 4.5! -9 / 2 // 得出 -5, 不是-4! 在程序设计中,我们有时可以利用整数除法获得所需要的结果,但也容易产生错误。如果两个操作数 是整数,要获得实数除法,我们应当将两个或任一个整型操作数强制转换为实型数,例如: int cost = 100; int volume = 80; double unitPrice = cost / (double) // 得出 1.25 执行除法运算时,如果除数为零,程序运行时,会产生一个被零除的错误。 取余运算符(%)的两个操作数都必须是整型数,运算结果是整除后的余数。例如 13%3 的结果是 1。 算术运算的结果可能太大,而不能存储在一个指定的变量中,这种情形称之为溢出。例如: unsigned char k = 10 * 92; // 溢出: 920 & 2553.1.2 自增、自减运算符 ++是自增运算符,DD自减运算符,这两个运算符都是单目运算符,且功能相近,都是将数值 变量的值加 1 或减 1,用户只能将这类操作符应用于变量而不能应用于常量。要替代下列代码 valuel=valuel+1; 可使用 ++valuel; 或 valuel++; 这里前一种方式称为前缀方式,后一种称为后缀方式,其目的都是使 valuel 加 1。二者的区别是: 前缀式先将操作数增 1(或减 1),然后取操作数的新值参与表达式的运算。后缀是先将操作数增 1 (或减 1)之前的值参与表达式的运算,到表达式的值被引用之后再做加 1(或减 1)运算。 参见表 3-3。 我们可以看出, 自加和自减运算符可在变量名前,也可在变量名后,即都可以用于前缀和后缀的 形式,但含义并不相同。对于前缀的形式,变量先作自加或自减运算,然后将运算结果用于表达式中; 而对于后缀的形式, 变量的值先在表达式中参与运算,然后再作自加或自减运算。 可以作自加或自减的变量类型也可以是实型,但是,实型变量自加或自减运算的用处不大,我们 很少使用。通常,我们对整型变量作自加或自减运算。以后,我们还会看到,指针变量也可以作自加 或自减运算。3.1.2 自增、自减运算符 ++是自增运算符,DD自减运算符,这两个运算符都是单目运算符,且功能相近,都是将数值 变量的值加 1 或减 1,用户只能将这类操作符应用于变量而不能应用于常量。要替代下列代码 valuel=valuel+1; 可使用 ++valuel; 或 valuel++; 这里前一种方式称为前缀方式,后一种称为后缀方式,其目的都是使 valuel 加 1。二者的区别是: 前缀式先将操作数增 1(或减 1),然后取操作数的新值参与表达式的运算。后缀是先将操作数增 1 (或减 1)之前的值参与表达式的运算,到表达式的值被引用之后再做加 1(或减 1)运算。 参见表 3-3。 我们可以看出, 自加和自减运算符可在变量名前,也可在变量名后,即都可以用于前缀和后缀的 形式,但含义并不相同。对于前缀的形式,变量先作自加或自减运算,然后将运算结果用于表达式中; 而对于后缀的形式, 变量的值先在表达式中参与运算,然后再作自加或自减运算。 可以作自加或自减的变量类型也可以是实型,但是,实型变量自加或自减运算的用处不大,我们 很少使用。通常,我们对整型变量作自加或自减运算。以后,我们还会看到,指针变量也可以作自加 或自减运算。3.1.3 关系运算符 C++提供 6 种关系运算符,用于数值之间的比较,表达式的值或为 1(表示 true),或为 0(表 示 false),参见表 3-3。 应该注意:&= 和 &= 运算符不能写成=& 和 =&,=& 和 =&是无效的运算符。关系运算符的操 作数应当是一个数值,字符是有效的操作数,因为它们是用数值来表示的。例如(假定采用 ASCII 编码): 'A' & 'F' // 得出 1 (它等价于 65 & 70) 字符串不应当用关系运算符比较,因为被比较的不是字符串的内容本身,而是字符串的地址。例 如: &HELLO& & &BYE& 引起&HELLO&的地址与&BYE&的地址进行比较。由于字符串的地址是由编译器决定的,所以,表 达式的结果或为 0,或为 1,并不确定。我们以后会看到:可以用 C++的库函数 strcmp,比较两个字 符串。表 3-4 关系运算符 运算符 == != & &= & &= 名字 等于 不等于 小于 小于或等于 大于 大于或等于 实例 5 = = 5 // 得出 1 5 != 5 // 得出 0 5 & 5.5 // 得出 1 5 &= 5 // 得出 1 5 & 5.5 // 得出 0 6.3 &= 5 // 得出 1由关系运算符组成的关系表达式的值是逻辑型的,即 bool 型。在 C++中常常将逻辑真用非 0 表 示(一般为 1),逻辑假用 0 表示。 其中: '=='用于判断其前后数值或表达式的结果 a 和 b 是否相等。如 a 为 2001,b 为 667*3,则表示 a 等 于 b 是真的。 '!='用于判断其前后数值或表达式的结果 a 和 b 是否不相等。如 a 为 2002,b 为 667*3,则表示 a 不等于 b 是真的。 '&'用于判断其前后数值或表达式的结果 a 是否小于 b。如 a 为 2002,b 为 667*3,则表示 a 小于 b 是假的。 '&='用于判断其前后数值或表达式的结果 a 是否小于或等于 b。 如 a 为 2002,b 为 667*3,则表 示 a 小于或等于 b 是假的。 '&'用于判断其前后数值或表达式的结果 a 是否大于 b。如 a 为 2002,b 为 667*3,则表示 a 大于 b 是真的。 '&='用于判断其前后数值或表达式的结果 a 是否大于或等于 b。 如 a 为 2002,b 为 667*3,则表 示 a 大于或等于 b 是真的。 关系运算符组成的表达式,一般是和逻辑运算符组合用在条件表达式中的。条件表达式用于程序 的分支处理。 注意: 1.关系运算符两边的数值结果必须是类型相同的,否则会容易出现关系判断的错误。如: char a = '0xa2'; a & '0xa1' 的结果是 a 小于'0xa1'。因为 a 是符号整数,而'0xa1'是无符号整数。给 a 赋值后其 实是小于 0 的。 2.字符串不应当用关系运算符比较,因为被比较的不是字符串的内容本身,而是字符串的地址。 例如: &Welcome& & &Beijing& 引起&Welcome&的地址与&Beijing&的地址进行比较。由于字符串的地址是由编译器决定的,所以, 表达式的结果或为假,或为真,并不确定。我们以后会看到:可以用 C++的库函数 strcmp,比较两个 字符串。3.1.4 逻辑运算符 C++提供了 3 种逻辑运算符,参见表 3-5。如同关系运算符,用逻辑运算符组成的表达式的值或为 1 (表示 true),或为 0(表示 false)。 逻辑非(!)是单目运算符,它将操作数的逻辑值取反。即:如果操作数是非零,它使表达式的值为 0;如果操作数是 0,它使表达式的值为 1。 逻辑与(&&)与逻辑或(||)的含义,参见表 3-6。 下面是一些有效的逻辑表达式: !20 // 得出 0 10 && 5 // 得出 1 10 || 5.5 // 得出 1 10 && 0 // 得出 0表 3-5 逻辑运算符 运算符 ! && || 名字 逻辑非 逻辑与 逻辑或 实例 !(5 = = 5) // 得出 0 5 & 6 && 6 & 6 // 得出 0 5 & 6 || 6 & 5 // 得出 1表 3-6 逻辑与(&&)和逻辑或(||)运算 运算符 逻辑与(&&) 操作数 1 true false 操作数 2 true true 表达式的值 true false true false true 逻辑或(||) false true falsefalse false true true false falsefalse false true true true false表 3-5 逻辑运算符 运算符 ! && || 名字 逻辑非 逻辑与 逻辑或 实例 !(5 = = 5) // 得出 0 5 & 6 && 6 & 6 // 得出 0 5 & 6 || 6 & 5 // 得出 1表 3-6 逻辑与(&&)和逻辑或(||)运算 运算符 操作数 1 true 逻辑与(&&) false true false true 逻辑或(||) false true false 操作数 2 true true false false true true false false 表达式的值 true false false false true true true false3.1.5 位运算符 C++提供 6 种位运算符,可以进行二进制位的运算,参见表 3-7。 位运算符要求操作数是整型数,并按二进制位的顺序来处理它们。取反运算符是单目运算符,其它位运算 符是双目运算符。取反运算符(~)将操作数的二进制位逐位取反。逐位与运算符(&)比较两个操作数对应的 二进制位,当两个二进制位均为 1 时,该位的结果取 1,否则取 0。逐位或运算符(|)比较两个操作数对应的 二进制位,当两个二进制位均为 0 时,该位的结果取 0,否则取 1。逐位异或运算符(^)比较两个操作数对应 的二进制位,当两个二进制位均为 1 或均为 0 时,该位的结果取 0,否则取 1。 逐位左移运算符(&&)和逐位右移运算符(&&)均有一个正整数 n 作为右操作数,将左操作数的每一个二 进制位左移或右移 n 位,空缺的位设置为 0 或 1。对于无符号整数或有符号整数,如果符号位为 0(即为正数), 空缺位设置为 0;如果符号位为 1(即为负数),空缺位是设置为 0 还是设置为 1,要取决于所用的计算机系统。表 3-7 位运算符 运算符 ~ & | ^ && &&名字 取反 逐位与 逐位或 逐位异或 逐位左移 逐位右移实例 ~'\011' // 得出 '\366' '\011' & '\027' // 得出'\001' '\011' | '\027' // 得出'\037' '\011' ^ '\027' // 得出'\036' '\011' && 2 // 得出'\044' '\011' && 2 // 得出'\002'位操作运算符是用来进行二进制位运算的运算符。它分为两类:逻辑位运算符和移位运算符。 1、逻辑位运算符 (1)单目逻辑位运算符:~(按位求反) 作用是将各个二进制位由 1 变 0,由 0 变 1。 (2)双目逻辑运算符:&(按位与),|(按位或),^(按位异或) 其中优先级&高于^,而^高于|。 & :两个都为 1 时结果为 1。 | :两个其中有一个为 1 则结果为 1。 ^ :两个不同则结果为 1,否则为 0。 2、移位运算符 移位运算符有两个,&&(左移)、&&(右移)。两个 都是双目运算符。 例. 指出下面表达式的功能。 (p&0377)|(k&0xff)&&8 答:将整数 p 的低字节作为作为结果的低字节,k 的低字节作为结果的高字节拼成一个新的整数。 针对两个操作数 011 和 027,表 3-8 给出各个位运算符的计算实例,运算结果在表 3-7 中。为了避免符 号位的麻烦(它与机器有关) ,我们采用无符号的整数。 unsigned char x = '\011'; unsigned char y = '\027'表 3-8 位运算符如何运算 实例 x y ~x x& y x|y x^y x && 2 x && 2 10 进制值 011 027 366 001 037 036 044 002 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 1 0 二进制值 0 1 1 0 1 1 0 0 1 0 0 0 1 1 0 0 0 1 1 0 1 1 1 0 0 1 1 0 1 1 0 1 1 1 0 1 1 0 0 0位运算符要求操作数是整型数,并按二进制位的顺序来处理它们。位运算符除取反运算符'~'为 单目运算符外,其余的都是双目运算符,这可以从上面的表格中的表达式例子中看出来。具体说来: '&'为逐位与运算符,用于把两个操作数对应的二进制位进行逻辑与操作,逻辑与的操作上一节 已经作了介绍,这里不再赘述。所以 0x011&0x001 其实就是二进制数 0001B 和二进 制数 0001B 每一位都进行逻辑与运算,其结果必然是 0001B 即 0x001。 '|'为逐位或运算符,用于把两个操作数对应的二进制位进行逻辑或操作。所以,根据逻辑或的 运算规则,表达式 0x011|0x001 的结果必然是 0x011。有兴趣的同学可以自己把相应的二进制位进行 逐个的逻辑或运算,看看结果是不是 0x011.。 '^'为逐位异或运算符,用于把两个操作数对应的二进制位进行异或操作。因此,0x011^0x001 的结果是 0000B,即 0x010。 '&&'为逐位左移运算符,用于将左操作数的每一个二进制位左移右操作数位,空缺的位设置为 0 或 1。对于无符号整数或有符号整数,但符号位为 0(即为正数),空缺位设置为 0;如果符号位为 1(即为负数),空缺位是设置为 0,还是设置为 1,要取决于所用的计算机系统。因此,0x011&&2 结果是 0x044。 '&&'为逐位右移运算符, 将左操作数的每一个二进制位右移右操作数位, 空缺的位设置为 0 或 1, 和逐位左移运算符一致。因此,0x011&&2 的结果是 0x004 具体的运算的进行还可以参考表 3-7 位运算符如何运算。 3.1.6 赋值运算符 =是赋值运算符,它的作用是将一个表达式的值赋给一个左值。一个表达式或者是一个左值,或者是一 个右值。所谓左值是指一个能用于赋值运算左边的表达式。左值必须能够被修改,不能是常量。我们现在 是用变量作左值,以后还可以看到,指针和引用也可以作左值。例如: int a, b, a=3; b=4; c = ( a + b )*(2*a - b) // 得出 14 赋值运算符可与算术运算符和位运算符组合,产生许多变种,参见表 3-9(实例中假定 n 是一个整型变 量) 。 赋值运算本身也是一个表达式,即赋值表达式,该表达式的值是存储在赋值运算符左边变量中的值。 一个赋值表达式能作为另一个赋值表达式的右操作数,多个赋值运算符能够连接在一个表达式中。例如: int m, n, m = n = p = 100; // 即: n = (m = (p = 100)); m = (n = p = 100) + 2; // 即: m = (n = (p = 100)) + 2; m += n = p = 10; // 即: m = m + (n = p = 10); 表 3-9 赋值运算符 运算符 = += -= *= /= %= 实例 n = 25 n += 25 n -= 25 n *= 25 n /= 25 n %= 25 n = n + 25 n = n - 25 n = n * 25 n = n / 25 n = n % 25 等价于 &= |= ^= && = && =n &= 0xF2F2 n |= 0xF2F2 n ^= 0xF2F2 n &&= 4 n &&= 4n = n & 0xF2F2 n = n | 0xF2F2 n = n ^ 0xF2F2 n = n && 4 n = n && 4赋值运算符分为两种:一种是简单的最常用的=运算符;二是复合的赋值运算符,又称为带有运算 的赋值运算符,也叫赋值缩写。 例如:i=i+j;可表示为 i+=j;这里+=是复合赋值运算符。 同样的共有 10 种这样的运算符,它们是: += 加赋值 -= 减赋值 *= 乘赋值 /= 除赋值 %= 求余赋值 &= 按位与赋值 | = 按位或赋值 ^= 按位异或赋值 &&= 左移位赋值 &&= 右移位赋值 && 当右操作数又是一个赋值表达式时,形成多重赋值表达式。例如: i=j=0; //结果 i、j 的值都为 0 注意:多重赋值表达式不能出现在变量说明中。例如: int i=j=0; 是非法的。 例:有变量说明 int a=2,b; 指出下面表达式运算后 a 和 b 的结果。 b+=b=++a; 答:a 为 3,b 为 6。 && 有时将赋值运算与比较运算结合在一起形成嵌入赋值。例如: while ((ch=getchar())!='\n'); 这条语句的含义是:等待用户按下回车键后程序向下执行。 需要注意的是: x *= y+8 等价于 x=x*(y+8),不等价于 x = x*y+8。 同样:z &= y-x 等价于 z = z & (y-x),而不等价于 z = z &y -x。3.1.7 求字节数运算符 C++提供了一个有用的运算符 sizeof,它是一个单目运算符,用于计算表达式或数据类型的字节数, 其运算结果与不同的编译器和机器相关。当编写用于进行文件输入/输出操作或给动态列表分配内存的程 序时,用户将发现,如能知道程序给这些特定变量所分配内存的大小将会很方便。 例如 3-1: 当我们进行算术运算时, 如果运算结果超出变量所能表达的数据范围时, 就会发生溢出。 而利用 sizeof 运算符计算变量所占的字节数,也就是说,可以算出变量的数据范围,从而可以避免可能出现的错误。例 3-1 #include &iostream.h& int main (void) { cout && &char size = & && sizeof(char) && & bytes\n&; cout && &char* size = & && sizeof(char*) && & bytes\n&; cout && &short size = & && sizeof(short) && & bytes\n&; cout && &int size = & && sizeof(int) && & bytes\n&; cout && &long size = & && sizeof(long) && & bytes\n&; cout && &float size = & && sizeof(float) && & bytes\n&; cout && &double size = & && sizeof(double) && & bytes\n&; cout && &1.55 size = & && sizeof(1.55) && & bytes\n&; cout && &1.55L size = & && sizeof(1.55L) && & bytes\n&; cout && &HELLO size = & && sizeof(&HELLO&) && & bytes\n&; } 我们运行这个程序,产生下面的结果(在作者的 PC 机上): char size = 1 bytes char* size = 2 bytes short size = 2 bytes int size = 2 bytes long size = 4 bytes float size = 4 bytes double size = 8 bytes 1.55 size = 8 bytes 1.55L size = 10 bytes HELLO size = 6 bytes表 3-10 类型 求字节数运算符 运算 求字节大小 运算符 sizeof下表给出了常用数据类型的字节数。具体的例子可参考书中给出的例子。当我们进行算术运算时, 如果运算结果超出变量所能表达的数据范围时,就会发生溢出。如果我们能够利用 sizeof 运算符计算变 量所占的字节数,就可算出变量的数据范围,从而可以避免可能出现的错误。 下表给出了常用数据类型的字节数。具体的例子可参考书中给出的例子。表 3-11 数据类型 占用字节数 Char Char * Short Int Long Float Double1 4 2 4(VC 6.0)2 (VC 1.5x) 4 4 83.1.8 条件运算符 条件运算符是 C++中唯一的三目运算符,也称为三元运算符,它有三个操作数: 操作数 1 ? 操作数 2 : 操作数 3 条件运算符又可以称为'?'号运算符。操作数 1 一般是条件表达式,若表达式成立,即为真,则整个表 达式的值为操作数 2,否则为操作数 3。表中的例子:若 a&=b, 则例子的结果为 a ,否则就为 b。 例如、cout &&('A'&=ch && ch&='Z')? ('a'+ch-'A'):ch 结果是输出一个小写字母。 如果第一个操作数非零,表达式的值是操作数 2,否则表达式的值取操作数 3。例如: int m = 1, n = 2; int min = (m & n ? m : n); // min 取 1 由于条件运算本身是一个表达式,即条件表达式,它可以作为另一个条件表达式的操作数。也就是说, 条件表达式是可以嵌套的。例如: int m = 1, n = 2, p =3; int min = (m & n ? (m & p ? m : p) : (n & p ? n : p)); 再看看其它的例子: int a=10,b=20; int min = (a&=b? a: b); 则 min 取值为 20。 由条件运算符组成的条件表达式,可以作为另一个条件表达式的操作数,即条件表达式是可以嵌套的, 如: int a=10,b=20,c=30; int min=(a&=b ?) (b&=c ? b: c): (a&=c ? a : c) // 结果为 10。 3.1.9 逗号运算符 多个表达式可以用逗号组合成一个表达式,即逗号表达式。 逗号运算符带两个操作数,返回值是右操作数。 逗号表达式的一般形式是:&表达式 1,表达式 2,……,表达式 n&,它的值是取表达式 n 的值。 逗号运算符的用途仅在于解决只能出现一个表达式的地方却要出现多个表达式的问题。 例如: d1,d2,d3,d4 这里 d1、d2、d3、d4 都是一个表达式。整个表达式的值由最后一个表达式的值决定。计算顺序 是从左至右依次计算各个表达式的值,最后计算的表达式的值和类型便是整个表达式的值和类型。例 3-2 int m, n, int mCount = 0, nCount = 0; // ... min = (m & n ? mCount++, m : nCount++, n); 当 m 小于 n 时,计算 mCount++,m 存储在 min 中。否则,计算 nCount++,n 存储在 min 中。 表 3-12 类型 逗号运算符 运算 逗号运算符 运算符 , 例子 a=10,11,12表中例子的结果是 a 为 12。 除了上面介绍的一些常用的基本运算符之外,C++还有一些比较特殊的运算符如下:表 3-13 类型 全局变量或全局函数 类中的域变量或函数 括号及函数调用 指针指向的结构或类种的域变量 结构或类中的域变量 数组下标运算符 内存分配运算符 内存释放运算符 运算符 : :(全局) : :(类域) () -& . [] new delete 例子 : : GetSystemDirectory CWnd::FromHandle (a+b)*(a-b) (CWnd *wnd)-& FromHandle (CWnd wnd). FromHandle nYearsM onthsDays[10][12][366] new CWnd delete (CWnd *wnd)当不同的运算符混合运算时,运算顺序是根据运算符的优先级而定的,优先级高的运算符先运算, 优先级低的运算符后运算。在一个表达式中,如果各运算符有相同的优先级,运算顺序是从左向右,还是 从右向左,是由运算符的结合性确定的。所谓结合性是指运算符可以和左边的表达式结合,也可以与右边 的表达式结合。C++运算符的优先级和结合性参见表 3-14。 在表 3-14 中,&单&表示是单目运算符,&双& 表示是双目运算符,&三& 表示是三目运算符。表中有一 些运算符,我们还没有介绍,以后我们会在有关的内容中学习。表 3-14 C++运算符的优先级和结合性 优先级 最高 最高 : :(全局) : :(类域) 运算符 种类 单 双 结合性 从右到左 从左到右 . . . . . . . . . . . . . . . 最低 & + -( )(括号及函数调用) ++ -! * new delete- & . .[ ] sizeof (类型) .*双 单 双 双 双从左到右 从右到左 从左到右 从左到右 从左到右 从左到右 从左到右 从左到右 从左到右 从左到右 从左到右 从左到右 从左到右 从左到右 从右到左 从左到右~ & -&*+ + && &= ==/ -%&& & != & ^ | && || ?: = , &=双 双 双 双 双 双 双 双 三 双 双每种运算符都有一个优先级,优先级是用来标志运算符在表达式中的运算顺序的。优先级高的 先做运算,优先级低的后做运算,优先级相同的右结合性决定计算顺序。 大多数运算符都是按从左到右计算,只有三类运算符的结合性是从右到左。他们是:单目、三 目和赋值。这一点一定要记住。 3.3 类型转换 C++中,一种数据类型能够被转化为另一种数据类型。例如 3-3: 从上面实例我们可以看到:类型标识符能被用于类型运算符。类型运算符是单目运算符,并位于其操 作数的左边的圆括号里,称之显式类型转换,或强制类型转换。显式类型转换的一般形式为: (类型名) (表达式) 需要注意的是: (int)(x+y)是将(x+y)转换为 int 型,而(int)x+y 是将 x 转换为 int 型后再与 y 相加。 显式类型转换只是得到一个所需类型的中间变量,原来变量的类型并不发生变化。例 3-3 (int) 3.14 // 3.14 转换成整型数 3 (long) 3.14 // 3.14 转换成长整型数 3L (double) 2 // 2 转换成双精度数 2.0 (char) 122 // 122 转换成 Unicode 码为 122 的字符 (unsigned short) 3.14 // 3.14 }

我要回帖

更多关于 vlookup函数怎么用 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信