《Visual C++ 开发从入门到精通》——2.9 技术解惑

2.9 技术解惑

2.9.1 C++标识符的长度

在几十年前,ANSI C标准规定名字不准超过6个字符,现在的C++/C规则不再有此限制。一般来说,长名字能更好地表达含义,所以函数名、变量名、类名长达十几个字符不足为怪。那么名字是否越长越好?不见得! 例如,变量名maxval maxValueUntilOverflow好用,单字符的名字也有用,常见的有i、j、k、m、n、x、y、z等,它们通常可用作函数内的局部变量。

2.9.2 字符和字符串的区别

字符和字符串的差异很小,因为字符串也是由一个个字符组合而成的,两者的主要区别如下。

字符使用单引号标注,而字符串使用双引号标注。
字符串需要使用转义字符'0'来说明结束位置,而字符则不存在这个问题。
字符是一个元素,只能存放单个字符。而字符串则是字符的集合,可以存放多个字符。
相同内容的字符数组和字符串都是字符的集合,但是字符数组比字符串数组少了一个转义字符'0'。

2.9.3 C++字符串和C字符串的转换

C ++提供的由C++字符串得到对应C_string的方法使用的是data()、c_str()和copy()。其中,data()以字符数组的形式返回字符串内容,但并不添加'0',c_str()返回一个以'0'结尾的字符数组,而copy()则把字符串的内容复制或写到既有的c_string或字符数组。C++字符串并不以'0'结尾。笔者建议在程序中尽量使用C++字符串,一般情况下不选用c_string。

2.9.4 C++字符串和字符串结束标志

为了测定字符串的实际长度,C++规定了一个“字符串结束标志”,以字符′0′代表。在上面的数组中,第11个字符为′0′,表明字符串的有效字符为其前面的10个字符。也就是说,遇到字符′0′就表示字符串到此结束,由它前面的字符组成字符串。

对一个字符串常量,系统会自动在所有字符的后面加一个'0'作为结束符。例如,字符串“I am happy”共有10个字符,但是在内存中共占11个字节,最后一个字节'0'是由系统自动加上的。

在程序中往往依靠检测'0'的位置来判定字符串是否结束,而不是根据数组的长度来决定字符串的长度。当然,在定义字符数组时应估计实际字符串的长度,应保证数组长度始终大于字符串的实际长度。如果在一个字符数组中先后存放多个不同长度的字符串,则应使数组长度大于最长的字符串的长度。

2.9.5 C++中的面向对象、C中的面向过程的含义

面向对象指的是把属性和方法封装成类,实例化对象后,要完成某个操作时,直接调用类里面相应的方法。面向过程则不进行封装,要完成什么功能需要详细地把算法写出来。举个例子来说,要完成买东西这个任务,面向对象的实现方法就是,先对手下的人办个培训,教他们怎么去买(相当于定义类的属性和方法),以后要让他们买东西,只要喊“张三(或者李四,相当于实例化对象),你用上次我教你的方法去买个东西。”这样就可以了;而面向过程的方法则不进行培训,每次要去买东西,都找张三过来,再教他怎么去买,但是下次再叫他去买,又要重新教一次。

2.9.6 面向对象和面向过程的区别

C语言是一门面向过程的语言,C++是一门面向对象的语言。究竟面向对象和面向过程有什么区别呢?面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了。面向对象是把构成问题的事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描述某个事物在整个解决问题步骤中的行为。

例如,要开发一个五子棋游戏,使用面向过程的设计思路的步骤如下。

(1)开始游戏,(2)黑子先走,(3)绘制画面,(4)判断输赢,(5)轮到白子,(6)绘制画面,(7)判断输赢,(8)返回步骤(2),(9)输出最后的结果。

把上面每个步骤分别用函数来实现,问题就解决了。而面向对象的设计则是从另外的思路来解决问题的,开发整个五子棋游戏的基本过程如下。

(1)设计黑白双方,这两方的行为是一模一样的。

(2)设计棋盘系统,负责绘制画面。

(3)开发规则系统,负责判定,如犯规、输赢等。

上述3个过程分别代表3个对象,其中第一类对象(玩家对象)负责接收用户输入,并告知第二类对象(棋盘对象)棋子布局的变化,棋盘对象接收到棋子的变化就要负责在屏幕上显示出这种变化,同时利用第三类对象(规则系统)来对棋局进行判定。

由此可以明显地看出,面向对象是以功能来划分问题的,而不是步骤。同样是绘制棋局,这样的行为在面向过程的设计中分散在多个步骤中,很可能出现不同的绘制版本,因为通常设计人员会考虑到实际情况进行各种各样的简化。而面向对象的设计中,绘图只可能在棋盘对象中出现,从而保证了绘图的统一。

功能上的统一保证了面向对象设计的可扩展性,比如要加入“悔棋”这一功能,如果要改动面向过程的设计,那么从输入到判断到显示这一连串的步骤都要改动,甚至步骤之间的顺序都要进行大规模调整。如果是面向对象的话,只用改动棋盘对象就行了,棋盘系统保存了黑白双方的棋谱,简单回溯就可以了,而显示和规则判断则不用顾及,同时整个对象功能的调用顺序都没有变化,改动只是局部的。

再如,要把这个五子棋游戏改为围棋游戏,如果使用的是面向过程设计,那么五子棋的规则就分布在程序的每一个角落,要改动还不如重写。但是如果一开始就使用了面向对象的设计,那么只用改动规则对象就可以了,五子棋和围棋的区别主要就是规则,而下棋的大致步骤从面向对象的角度来看没有任何变化。

当然,要达到改动只是局部的效果需要设计人员有足够的经验,使用对象不能保证程序就是面向对象的,初学者或者蹩脚的程序员很可能以面向对象之虚而行面向过程之实,这样设计出来的所谓面向对象的程序很难有良好的可移植性和可扩展性。

2.9.7 C++中常量的命名

因为常量属于标识符,所以也需要遵循C++标识符的命名规范,也和变量的命名规范类似。另外,C++常量还要遵循如下3点规范。

用#define定义的常量最好大写且以下划线开始,如_PI和_MAX。
如果用#define定义的常量用于代替一个常数,则常量名和其常数符号要对应,如圆周率就用PI表示。
用const声明的常量完全遵循C++变量的命名规范。

2.9.8 在C++程序中如何定义常量

在C++程序中,既可以用const定义常量,也可以用#define定义常量,前者比后者有如下4个优势。

(1)const常量有数据类型,而宏常量没有数据类型。编译器可以对const进行类型安全检查,而对后者只进行字符替换,没有类型安全检查,并且在字符替换中可能会产生意料不到的错误(边际效应)。

(2)有些集成化的调试工具可以对const常量进行调试,但是不能对宏常量进行调试。在C++程序中只使用const常量而不适用宏常量,即const常量完全取代宏常量。

(3)编译器处理方式不同。define宏是在预处理阶段展开;const常量在编译运行阶段使用。

(4)存储方式不同。define宏仅仅是展开,有多少地方使用,就展开多少次,不会分配内存;const常量会在内存中分配(可以是堆中也可以是栈中)。

2.9.9 使用关键字const注意事项

在C++程序中,const是一个很重要的关键字,能够对常量施加一种约束。有约束其实不是件坏事情,无穷的权利意味着无穷的灾难。应用了const之后,就不可以改变变量的数值了,要是一不小心改变了编译器就会报错,你就容易找到错误的地方。不要害怕编译器报错,正如不要害怕朋友指出你的缺点一样,编译器是程序员的朋友,编译时期找到的错误越多,隐藏着的错误就会越少。所以,只要你觉得有不变的地方,就用const修饰,用得越多越好。比如想求圆的周长,需要用到PI,PI不会变的,就加const,const double PI=3.1415926;再如,需要在函数中传引用,只读,不会变的,前面加const;比如函数有个返回值,返回值是个引用,只读,不会变的,前面加const;比如类中有个private数据,外界要以函数方式读取,不会变的,加const;这个时候就是加在函数定义末尾,加在末尾只不过是个语法问题。其实语法问题不用太过注重,语法只不过是末节,记不住了,翻翻书就可以了,接触多了,自然记得,主要是一些概念难以理解。想一下,const加在前面修饰函数返回值,这时候const不放在末尾就没有什么地方放了。

2.9.10 关于全局变量的初始化,C语言和C++是否有区别

在C语言中,只能用常数对全局变量进行初始化,否则编译器会报错。在C++中,如果在一个文件中定义了:

int a = 5;
要在另一个文件中定义下面的b:

int b = a;
前面必须对a进行声明:
`
extern int a;`
否则编译不通过。即使是这样,int b = a;这句话也是分两步进行的:在编译阶段,编译器把b当成未初始化数据而将它初始化为0;在执行阶段,在main被执行前有一个全局对象的构造过程,int b = a;被当成int型对象b的副本初始化构造来执行。  

其实在C++中,全局对象、变量的初始化是独立的,如果不是像:
`
int a = 5;`
这样的已初始化数据,那么就是像b这样的未初始化数据。而C++中全局对象、变量的构造函数调用顺序是跟声明有一定关系的,即在同一个文件中先声明的先调用。对于不同文件中的全局对象、变量,它们的构造函数调用顺序是未定义的,取决于具体的编译器。

2.9.11 C/C++变量在内存中的分布

变量在内存地址的分布格式为:
`
堆-栈-代码区-全局静态-常量数据`
同一区域的各变量按声明的顺序在内存中依次由低到高分配空间,只有未赋值的全局变量是个例外。全局变量和静态变量如果不赋值,默认为0。栈中的变量如果不赋值,则是一个随机的数据。编译器会认为全局变量和静态变量是等同的,已初始化的全局变量和静态变量分配在一起,未初始化的全局变量和静态变量分配在另一起。

2.9.12 静态变量的初始化顺序

静态变量进行初始化顺序是基类的静态变量先初始化,然后是它的派生类。直到所有的静态变量都被初始化。这里需要注意全局变量和静态变量的初始化是不分次序的。这也不难理解,其实静态变量和全局变量都被放在公共内存区。可以把静态变量理解为带有“作用域”的全局变量。在一切初始化工作结束后,main函数会被调用,如果某个类的构造函数被执行,那么会先初始化基类的成员变量。要注意的是,成员变量的初始化次序只与定义成员变量的顺序有关,与构造函数中初始化列表的顺序无关。因为成员变量的初始化次序是根据变量在内存中次序有关,而内存中的排列顺序早在编译期就根据变量的定义次序决定了。

本文仅用于学习和交流目的,不代表异步社区观点。非商业转载请注明作译者、出处,并保留本文的原始链接。

时间: 2024-08-01 14:49:12

《Visual C++ 开发从入门到精通》——2.9 技术解惑的相关文章

《Visual C++ 开发从入门到精通》——导读

前言 Visual C++ 开发从入门到精通 从你开始学习编程的那一刻起,就注定了以后要走的路:从编程学习开始,依次经历实习生.程序员.软件工程师.架构师.CTO等职位的磨砺:当你站在职位顶峰的位置蓦然回首,会发现自己的成功并不是偶然,在程序员的成长之路上会有不断修改代码,寻找并解决Bug.不停测试程序和修改项目的经历:不可否认的是,只要你在自己的开发生涯中稳扎稳打,并且善于总结和学习,最终将会得到可喜的收获. 第1章 第1章 Visual C++ 6.0的最初印象 1.1 Visual C++

《Visual C++ 开发从入门到精通》——第2章 C++的基本语法2.1 面向对象

第2章 C++的基本语法 Visual C++ 开发从入门到精通 学习Visual C++ 6.0开发知识,需要具备C++语言的基本知识,特别是语法知识.C++是继C语言之后的又一门受程序员欢迎的编程语言,它不但是C的加强版,而且吸取了传统汇编语言的优点,开创了全新的面向对象语言世界.从此,软件领域彻底进入面向对象时代.由此可以看出,C++的最重要特征是:面向对象.语法是任何一门编程语言的基础,一个程序员只有在掌握了语法知识后,才能根据语法规则编写出项目需要的代码.本章将详细介绍C++语言的基本

《Visual C++ 开发从入门到精通》——1.4 技术解惑

1.4 技术解惑 Visual C++ 6.0开发技术博大精深,能够用于多个领域,因此,一直深受广大程序员的喜爱.作为一名初学者,肯定会在学习过程中遇到很多疑问和困惑.为此,在本节的内容中,作者将自己的心得体会传授给大家,帮助读者解决困惑. 1.4.1 学习C++是否有用 下面就介绍一下C++的优势,以增强大家学习的信心. (1)C++是一门全能的语言 首先我们先要知道C++是一门什么语言,简单来说,C++是一门接近于全能的语言.为什么说是接近呢?因为C++有一门语言是无法取代的,那就是汇编.再

《Visual C++ 开发从入门到精通》——1.2 Visual C++ 6.0开发环境

1.2 Visual C++ 6.0开发环境 知识点讲解:光盘\视频\PPT讲解(知识点)\第1章\Visual C++ 6.0开发环境介绍.mp4 学习任何一门程序语言,都需要遵循图1-12所示的过程.本节将介绍Visual C++ 6.0集成开发环境的基本知识. 图1-12 学习一门语言的过程 1.2.1 熟悉集成开发环境 在打开Visual C++ 6.0后,需要熟悉Visual C++ 6.0这个集成开发环境.首先从Windows操作系统中选择"开始"→"程序&quo

《Visual C++ 开发从入门到精通》——2.2 分析C++的程序结构

2.2 分析C++的程序结构 知识点讲解:光盘视频PPT讲解(知识点)第2章分析C++的程序结构.mp4 程序结构即程序的组织结构,它包括语句结构.语法规则和表达式,其内容包含代码组织结构和文件组织结构.在C++开发中,我们必须严格遵循这些规则,才能编写出高效.易懂的程序. 2.2.1 从一段代码看C++程序结构 先看如下代码. //这是一个演示程序,它从命令行读入一个整数,然后加1再输出 #include <stdafx.h> #include <iostream.h> int

《Visual C++ 开发从入门到精通》——第1章 Visual C++ 6.0的最初印象1.1 Visual C++ 6.0概述

1.1 Visual C++ 6.0概述 知识点讲解:光盘视频PPT讲解(知识点)第1章Visual C++ 6.0介绍.mp4 Visual C++ 6.0是一个强大的可视化软件开发环境,通过它可以快速编写出各种C/C++程序.从数据库应用程序到网络应用程序,从图形.图像绘制到多媒体编程,从基本的对话框.单文档.多文档应用程序到动态链接库,再到ActiveX控件.总之,通过Visual C++ 6.0这一工具,可以实现上述各类程序. 1.1.1 Visual C++ 6.0的特点Visual

《Visual C++ 开发从入门到精通》——2.3 必须遵循的编码规范

2.3 必须遵循的编码规范 知识点讲解:光盘\视频\PPT讲解(知识点)\第2章\必须遵循的编码规范.mp4 编码规范即我们在编写代码时需要遵守的一些规则.好的编码规范可以大大提高代码的可读性和可维护性,甚至提高程序的可靠性和可修改性,保证了代码的质量.特别是在团队开发大型项目时,编码规范就成为了项目高效运作的重要要素.本节将简要介绍在编写C++程序时必须遵循的编码规范. 2.3.1 养成良好的习惯 程序快缩进,要使用Tab键缩进,不能和空格键混合使用. 函数不要太长,如果太长,建议拆分处理.

《Visual C++ 开发从入门到精通》——2.8 常量

2.8 常量 知识点讲解:光盘\视频\PPT讲解(知识点)\第2章\常量.mp4 所谓常量是指内容固定不变的量,无论程序怎样变化执行,它的值永远不会变.在编程中,常量常用于保存像圆周率之类的常数.在本节的内容中,将详细介绍C++中常量的基本知识,为读者步入本书后面知识的学习打下基础. 2.8.1 什么是常量 常量是指在程序执行中不变的量,它分为字面常量和符号常量(又称标识符常量)两种表示方法.如25.-3.26.'a'."constant"等都是字面常量,即字面本身就是它的值.符号常量

《Visual C++ 开发从入门到精通》——1.3 利用Visual C++ 6.0编写C++程序

1.3 利用Visual C++ 6.0编写C++程序 知识点讲解:光盘视频PPT讲解(知识点)第1章利用Visual C++ 6.0编写C++程序.mp4 实例003 编写.调试和运行一个标准的C++程序源码路径 光盘daimapart 01 视频路径 光盘视频实例第1章003 本实例的功能是,使用Visual C++6.0编写.调试并运行一个标准的C++程序.本实例的具体实现流程如下. (1)选择File→New命令,在New对话框中选择Win32 Console Application项,