MyMSDN

MyMSDN记录开发新知道

C++ notes (1)

1、标识符命名规则!

标识符不能包含两个连续的下划线,也不能以下划线开头后面紧跟一个大写字母。有些标识符(在函数外定义的标识符)不能以下划线开头。

但是在G++编译器和VC编译器下,二者均可正确编译!

Eclipse&G++Visual studio 2008

2、跨平台编译程序!

这里不是要讲解如何跨平台编译程序,也不是告诉你如何更好地编写通用平台的程序规则,那可能涉及到很多的宏定义以及硬件相关特性。这里仅为使用示例代码提供一种精简的方式。

用Eclipse+MinGW的方式默认会很精简,所以把它当作一种目标!

用Visual Studio 2008创建的程序会让你引入预编译头stdafx.h(这通常发生在使用Visual Studio创建Win32控制台应用程序,并直接点击“完成”后),这将导致你无法将在Eclipse上编写的程序直接运行在Visual Studio上。这时你应该通过修改项目属性来获得这种精简的方式:(选择项目,右键属性,选择配置属性->C/C++->预编译头->创建/使用预编译头,选择“不使用预编译头”->“确定”后再次编译即可!)

properties

3、变量命名习题

//测试变量命名!
//error C2632: “int”后面的“double”非法
//int double = 3.14159;
//-------------------------------------------------
char _='a';
std::cout<<_<<std::endl;
//-------------------------------------------------
//warning C4091: “”: 没有声明变量时忽略“bool”的左侧
//error C2059: 语法错误: “-”
//bool catch-22;
//-------------------------------------------------
//error C2059: 语法错误: “数字上的错误后缀”
//char 1_or_2 = '1';
//-------------------------------------------------
float Float=3.14f;
std::cout<<Float<<std::endl;

4、在C++中,“初始化不是赋值”

初始化指创建变量并给它赋初始值,而赋值则是擦除对象的当前值并用新值代替。

int ival(1024); //直接初始化
int ival = 1024; //复制初始化

直接初始化语法更灵活,效率更高!

对内置类型来说,复制初始化和直接初始化几乎没有差别。

对类类型来说,有些初始化仅能用直接初始化完成。要想理解其中缘由,需要初步了解类是如何控制初始化的。

例如:

也可以通过一个计数器和一个字符初始化string对象。这样创建的对象包含重复多次的指定字符,重复次数由计数器指定:

std::string all_nines(10, ‘9’); //all_nines = “9999999999”;

本例中,初始化all_nines的唯一方法是直接初始化。有多个初始化式时不能使用复制初始化。(V注:这里的初始化式即为构造函数的多个重载;这里所谓的“不能使用”应该是“功能有所不及”的意思!)

5、变量初始化规则

使用未初始化的变量经常导致错误,而且十分隐蔽。问题出在未初始化的变量事实上都有一个值。编译器把该变量放到内存中的某个位置,而把这个位置的无论哪种位模式都当成是变量初始的状态。当被解释成整型值时,任何位模式都是合法的值——虽然这个值不可能是程序员想要的。因为这个值合法,所以使用它也不可能导致程序崩溃。可能的结果是导致程序错误执行和/或错误计算。

//在Eclipse中运行没有出现错误!
//在Visual Studio中运行出现运行时错误!
int ival;    //没有初始化!
std::cout<<ival<<std::endl;

6、声明和定义

为了能让多个文件访问相同的变量,C++区分了声明和定义。简单地说就是可以用extern关键字来声明,任何有分配内存行为的声明都是定义。定义也是声明。声明:标明变量的类型和名字;定义:为变量分配存储空间,还可以为变量指定初始值。

举例说明:

extern double pi; //声明
double pi; //定义,声明了pi同时定义了pi
extern double pi = 3.14159; //定义,因为它为pi分配了初值。只有当该extern语句
     位于函数外部的时候才允许使用初始化式,否则将导致编译错误。

7、变量的隐藏:

std::string s1 = "I am a std::string!";
std::cout<<s1<<std::endl;
for(int s1=3; s1!=0; --s1)
std::cout<<"I am a number(int):"<<s1<<std::endl;

提示:在Visual Studio 2008中使用std::string定义一个变量,再通过std::cout将其输出,将会得到“error C2679: 二进制“<<”: 没有找到接受“std::string”类型的右操作数的运算符(或没有可接受的转换)”错误信息,这时要检查头文件中是否包含#include <string>。而在Eclipse中则不用如此设置(具体看编译器版本)。这与标准库实现的具体细节有关,在MSVC中,它在文件Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\string中被实现,在GNU中,它在base_string.h中被实现。在使用std::string时,总是包含#include <string>是一个好习惯!

8、const对象默认为文件的局部变量

一般声明变量后可以在其它文件中通过extern关键字声明并使用该变量:

//文件1:
int counter;
//文件2:
extern int counter;
++counter;

但是如果是const则无法访问。可以通过显式指定extern关键字使其成为全局可访问对象:

//文件1:
extern const int bufSize = getBufSize();
//文件2:
extern count int bufSize;
//……使用bufSize

注解:非const变量默认为extern。要使const变量能够在其他的文件中访问,必须显式地指定它为extern。

9、引用

int ival = 1024;
int &refVal = ival;

当引用初始化后,只要该引用存在,就保持绑定到初始化时指向的对象。不可能将引用绑定到另一个对象。

也正因为如此,所以引用比指针的优势就在于:引用不可以在方法中篡改,这使得方法变量变得安全了。

10、const引用

const int ival = 1024;
const int &refVal = ival;

这里我们要求左侧的类型是一致的,包括const!

非const引用只能绑定到与该引用同类型的对象。
const引用则可以绑定到不同但相关的类型的对象或绑定到右值。(具体示例详见C++Primer v4 P52)

例如:

//错误代码
double dval = 3.14;
const int &ri = dval;

编译器会将这些代码转换成如以下形式的编码:

int temp = dval;
const int &ri = temp;
如果ri不是const,那么可以给ri赋一新值。这样做不会修改dval,而是修改了temp。期望对ri的赋值会修改dval的程序员会发现dval并没有被修改。仅允许const引用绑定到需要临时使用的值完全避免了这个问题,因为const引用是只读的。
 

但是如下代码可以执行:

int ival = 1024;
const int &refVal = ival;
++ival;
//++refVal;    //error C3892: “refVal” 不能给常量赋值
std::cout<<"ival="<<ival<<"\trefVal="<<refVal<<std::endl;

输出:ival=1025    refVal=1025

const double dval = 3.14;
const int &ri = (int)dval;
std::cout<<ri<<std::endl;
输出:3

posted on 2008-12-19 17:52 volnet 阅读(2877) 评论(6)  编辑 收藏 引用 所属分类: C++ Primer 学习笔记

评论

# re: C++ notes (1) 2008-12-20 13:54 9278

看完第一句就知道copy的哪本书了 噢也!  回复  更多评论   

# re: C++ notes (1) 2008-12-20 13:56 volnet

@9278
从所属分类也可以判断~恭喜楼上!   回复  更多评论   

# re: C++ notes (1) 2008-12-21 16:11 永恒白天

不让你使用 下划线 的原因是标准规定说这些都是预留给编译器用的  回复  更多评论   

# re: C++ notes (1) 2008-12-21 16:41 volnet

@永恒白天
所以那句话翻译或者表达不好,怎么能说“不能”二字!呵呵  回复  更多评论   

# re: C++ notes (1) 2009-03-13 19:08 sinor51

不说:“不能”,您认为应该翻译成什么呢?  回复  更多评论   

# re: C++ notes (1) 2009-03-13 19:15 volnet

@sinor51
可以说“不应该”,不能一般是指编译会出错吧  回复  更多评论   


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


特殊功能