C++ Primer学习笔记——$5 数组
来源:互联网 发布:java手机qq 编辑:程序博客网 时间:2024/06/15 21:06
题记:本系列学习笔记(C++ Primer学习笔记)主要目的是讨论一些容易被大家忽略或者容易形成错误认识的内容。只适合于有了一定的C++基础的读者(至少学完一本C++教程)。
作者: tyc611, 2007-01-18
本文主要讨论C++中数组。
如果文中有错误或遗漏之处,敬请指出,谢谢!
数组
数组的定义和初始化
数组的维数必须用值大于等于1的常量表达式定义。
如果指定了数组维数,那么初始化列表提供的元素个数不能超过维数值。如果维数值大于列表中的元素个数,则只初始化前面的数组元素;对于剩下的元素,若是内置类型则初始化为0,若是类类型则调用其默认构造函数进行初始化。
动态创建数组
动态创建数组时,不能进行初始化,但却可以用值初始化()要求编译器把内置类型初始化为0。另外,C++允许动态分配长度为0的数组。动态数组的释放一定要记得用delete []。例如:
string* psa = new string[10]; // ok: array of 10 empty strings
int* pia1 = new int[10]; // ok: array of 10 uninitialized ints
int* pia2 = new int[10](); // ok: array of 10 initialized ints with value 0
int* pia3 = new int[10](3); // error: ISO forbids initializer
int* pia4 = new int[0]; // ok
delete [] psa;
delete [] pia1;
delete [] pia2;
指针
指针的初始化和赋值
对指针进行初始化或赋值时,只能使用以下四种类型的值:
1)0常量表达式;
2)类型匹配的对象的地址;
3)另一对象末的下一个地址;
4)同一类型的另一个有效指针。
注意:把int型变量赋给指针是非法的,尽管此int型变量的值可能为0;C++允许计算数组或对象的超出末端的地址,但不允许对此地址进行解引用操作。而计算数组超出末端位置之后或数组之前的地址都是不合法的。
另外,还可以使用以C语言中继承而来的预处理变量NULL。该变量在<cstdlib>头文件中定义,其值为0。个人倾向于使用NULL,这样更能直观地反映出是在对一个指针变量进行初始化或者赋值。注意:NULL是预处理变量,并不在std空间内。
指针的运算
两个指针相减的结果类型是ptrdiff_t类型,该类型在cstddef头文件中定义,并且是signed整型。
这里需要举一个例子:
typedef string* pstring;
const pstring cstr;
请问 cstr是什么类型?
typedef string* pstring;
const pstring cstr;
请问 cstr是什么类型?
这是一个很容易答错的问题。实质上cstr是一个string* 类型的const变量,即上面的定义相当于
string* const cstr;
因为声明const pstring cstr;时,const修饰的是pstring的类型,而不是修饰string类型。
数组与指针
在表达式中使用数组名时,该名字会自动转换成为指向数组第一个元素的指针。
建议:
尽量避免使用指针和数组:指针的错误使用(比如未初始化就使用)和数组越界是程序Bug的重要来源。相反,在C++程序里可以用vector类型和迭代器类型取代一般的数组和指针,采用string类型代替字符数组和C风格字符串。如果要使用指针,尽量在定义时初始化它。如果暂时不能初始化它,可以用0(NULL)作为它的初始值。一般的编译器都可以检查出值为0的指针的解引用。
尽量避免使用指针和数组:指针的错误使用(比如未初始化就使用)和数组越界是程序Bug的重要来源。相反,在C++程序里可以用vector类型和迭代器类型取代一般的数组和指针,采用string类型代替字符数组和C风格字符串。如果要使用指针,尽量在定义时初始化它。如果暂时不能初始化它,可以用0(NULL)作为它的初始值。一般的编译器都可以检查出值为0的指针的解引用。
多维数组
多维数组的初始化,其规则类似数组,因为多维数组实质上是数组的数组。这里只举个例子就能说明问题了,例如:
int ia[3][3] = {{1}, {2, 3}}; <===> int ia[2][3] = {{1, 0, 0}, {2, 3, 0}, {0, 0, 0}};
int ia[3][3] = {1, 2, 3}; <===> int ia[2][3] = {{1, 2, 3}, {0, 0, 0}, {0, 0, 0}};
int ia[3][3] = {{1}, {2, 3}}; <===> int ia[2][3] = {{1, 0, 0}, {2, 3, 0}, {0, 0, 0}};
int ia[3][3] = {1, 2, 3}; <===> int ia[2][3] = {{1, 2, 3}, {0, 0, 0}, {0, 0, 0}};
同样因为多维数组是数组的数组,所以由多维数组转换而成的指针类型应是指向第一个内层数组的指针。因而,多维数组名将自动转换为指向该数组第一元素(也是数组)的指针。
当需要使用多维数组的指针时,可以使用typedef来简化定义这类指针,也使定义更加清晰直观。
最后,补充一下基本知识:
1)C风格字符串(C-style character string):以null('/0')结束的字符数组。
2)缓冲区溢出(buffer overflow):当程序中出现数组越界时,就会导致这类错误。
如果文中有错误或遗漏之处,敬请指出,谢谢!
参考文献:
[1] Thinking in C++(Volume Two, Edition 2)
[2] C++ Primer(Edition 4)
[3] International Standard:ISO/IEC 14882:1998
参考文献:
[1] Thinking in C++(Volume Two, Edition 2)
[2] C++ Primer(Edition 4)
[3] International Standard:ISO/IEC 14882:1998
- C++ Primer 学习笔记——数组
- C++ Primer学习笔记——$5 数组
- c++primer学习笔记(4.1)数组
- c++primer学习笔记-----3.5数组
- C++primer学习笔记-----3.6多维数组
- C++Primer笔记--数组
- C++Primer学习笔记《5》
- 【C++】《C++ Primer Plus》笔记(3)——数组
- C++Primer(5th)学习-数组篇
- C++PRIMER学习笔记
- c++primer学习笔记
- c++primer学习笔记
- C++primer学习笔记
- c++primer 学习笔记
- C++Primer 学习笔记
- c++primer学习笔记
- C++Primer学习笔记
- C++PRIMER 学习笔记
- 另一种MTK特效制作的方法,层复制
- 设计模式介绍 高内聚,低耦合
- 《华清远见学习手记》 之3G智能机器人——移植RT2571(73)WIFI无线网卡驱动到FS2410
- Asp.NET 中两个listbox实现值相互传递
- tomcat域名配置
- C++ Primer学习笔记——$5 数组
- CEGUI:layout
- 对比敏捷开发和IPD的核心思想
- C++ Primer学习笔记——$6 表达式
- 网站迁移过程中遇到的问题
- ASP.NET 中listbox实现上移下移置顶置底,(支持多选)
- C++ Primer学习笔记——$7 语句和函数
- 2011年第1期技术分享:SUM函数实战交流
- win7关闭同步中心