C++ Primer学习第四天
2008-05-27 21:45
253 查看
第四章 数组和指针
C++语言提供了两种类似于vector和迭代器类型的低级复合类型——数组和指针。与vector类型相似,数组也可以保存某种类型的一组对象;而它们的区别在于,数组的长度是固定的。数组一经创建,就不允许添加新的元素。指针则可以像迭代器一样用于遍历和检查数组中的元素。 现代C++程序应尽量使用vector和迭代器类型,避免使用数组和指针。设计良好的程序只有在强调速度时才在类实现的内部使用数组和指针。
与vector类型相比,数组的显著缺陷在于:数组的长度是固定的,而且程序也无法知道一个给定数组的长度。数组没有获取其容量大小的size操作,也不提供pust_back操作在其中自动添加元素。如果需要更改数组的长度,程序员只能创建一个更大的新数组,然后把原数组的所有元素复制到新数组空间中去。
1、数组的定义和初始化:
Type name[const]
Type是数组的类型,规定了存放在数组中的数据的类型,可以是任意的内置类型或类,也可以是除引用之外的任意一种复合类型;name是数组的名字;const是数组的维数,表明数组中存放的数据元素个数,必须是值大于等于1的常量表达式。
例如:int array[10]定义了可以存放10个int型数据的数组,名字是array
在定义数组时可以为其元素提供一组用逗号分隔的初值,这些初值用花括号括起来。
比如:int array[] = {1,2,3,4,5};
如果定义时没有提供初值,则数组元素的初始化规则是:
a、在函数外定义的内置数组,其元素都初始化为0
b、在函数体内定义的内置数组,其元素不初始化
c、如果数组元素是类类型,则使用默认的构造函数初始化,不论数组是在哪里定义的。不允许数组之间直接复制和赋值。
2、指针指针用于指向对象。
指针保存的是另一个对象的地址。指针指向单个对象,迭代器只能访问容器内的元素。
指针的定义和初始化:
Type *name;
Type是指针所指向的对象的类型,name是指针名字。
例:int *p;声明了一个指向int对象的指针p
对指针的赋值和初始化只能使用下面四种类型的值:
a、0值常量表达式
b、类型匹配的对象的地址
c、另一个对象之后的下一个地址
d、同类型的另一个有效指针
指针操作:
解引用操作返回指向对象的左值,利用这个功能可修改指针所指对象的值:
string s = "badboy";
string *sp = &s;//sp指向s
*sp = "goodboy";//把s的值修改为goodboy
指针和引用的区别:
引用一经定义就指向一个固定的对象,并且永远不能修改;可以修改指针,使其指向另一个对象。
指针和const限定符:
const int a = 1;
const int *p = &a;//定义了一个指向int型常量a的指针,不能通过该指针修a的值,但是可以修改p使其指向另一个对象。
int b = 2;
int *const p = &b;//定义了一个常指针,指向非常量b,可以通过该指针修改b的值,但是不可以修改p使其指向另一个对象。
3、我的意外收获
a、数组名可以作为指针使用,但是不能进行算术操作:
例:
int a[] = {1,2,3};
cout<<*a<<endl;//ok
cout<<*a++<<endl;//error,数组名不能进行算术操作
但是,当数组作为函数的参数时,在此函数的内部,数组名就是一个真正的指针,可以进行算术操作。
b、大家先看下面的程序:
#include <iostream>
#include <vector>
#include <cstring>
#include <string>
using namespace std;
int main()
{
int p[] = {1,2,3};
cout < <p < <endl;
return 0;
}
结果是:0012FF54
这很正常,因为p是一个指针,p的值应该是一个地址,所以这个结果是正常的。
大家再看下一个程序:
#include <iostream>
#include <vector>
#include <cstring>
#include <string>
using namespace std;
int main()
{
char p[] = {'1','2','3','/0'};
cout < <p < <endl;
return 0;
}
结果是:123
这里为什么直接输出了指针p所指向的内容,而不是指针p自身的地址值呢?
这个与cout对操作符<<的重载有关系。就是说cout<<对不同的类型会进行不同的操作。如果cout<<后面接int类型的指针的话,就会输出指针的内容,也就是一个地址。如果cout<<后面接char类型的指针的话,就会输出指针所指向的对象的内容,上例中就是123。
C++语言提供了两种类似于vector和迭代器类型的低级复合类型——数组和指针。与vector类型相似,数组也可以保存某种类型的一组对象;而它们的区别在于,数组的长度是固定的。数组一经创建,就不允许添加新的元素。指针则可以像迭代器一样用于遍历和检查数组中的元素。 现代C++程序应尽量使用vector和迭代器类型,避免使用数组和指针。设计良好的程序只有在强调速度时才在类实现的内部使用数组和指针。
与vector类型相比,数组的显著缺陷在于:数组的长度是固定的,而且程序也无法知道一个给定数组的长度。数组没有获取其容量大小的size操作,也不提供pust_back操作在其中自动添加元素。如果需要更改数组的长度,程序员只能创建一个更大的新数组,然后把原数组的所有元素复制到新数组空间中去。
1、数组的定义和初始化:
Type name[const]
Type是数组的类型,规定了存放在数组中的数据的类型,可以是任意的内置类型或类,也可以是除引用之外的任意一种复合类型;name是数组的名字;const是数组的维数,表明数组中存放的数据元素个数,必须是值大于等于1的常量表达式。
例如:int array[10]定义了可以存放10个int型数据的数组,名字是array
在定义数组时可以为其元素提供一组用逗号分隔的初值,这些初值用花括号括起来。
比如:int array[] = {1,2,3,4,5};
如果定义时没有提供初值,则数组元素的初始化规则是:
a、在函数外定义的内置数组,其元素都初始化为0
b、在函数体内定义的内置数组,其元素不初始化
c、如果数组元素是类类型,则使用默认的构造函数初始化,不论数组是在哪里定义的。不允许数组之间直接复制和赋值。
2、指针指针用于指向对象。
指针保存的是另一个对象的地址。指针指向单个对象,迭代器只能访问容器内的元素。
指针的定义和初始化:
Type *name;
Type是指针所指向的对象的类型,name是指针名字。
例:int *p;声明了一个指向int对象的指针p
对指针的赋值和初始化只能使用下面四种类型的值:
a、0值常量表达式
b、类型匹配的对象的地址
c、另一个对象之后的下一个地址
d、同类型的另一个有效指针
指针操作:
解引用操作返回指向对象的左值,利用这个功能可修改指针所指对象的值:
string s = "badboy";
string *sp = &s;//sp指向s
*sp = "goodboy";//把s的值修改为goodboy
指针和引用的区别:
引用一经定义就指向一个固定的对象,并且永远不能修改;可以修改指针,使其指向另一个对象。
指针和const限定符:
const int a = 1;
const int *p = &a;//定义了一个指向int型常量a的指针,不能通过该指针修a的值,但是可以修改p使其指向另一个对象。
int b = 2;
int *const p = &b;//定义了一个常指针,指向非常量b,可以通过该指针修改b的值,但是不可以修改p使其指向另一个对象。
3、我的意外收获
a、数组名可以作为指针使用,但是不能进行算术操作:
例:
int a[] = {1,2,3};
cout<<*a<<endl;//ok
cout<<*a++<<endl;//error,数组名不能进行算术操作
但是,当数组作为函数的参数时,在此函数的内部,数组名就是一个真正的指针,可以进行算术操作。
b、大家先看下面的程序:
#include <iostream>
#include <vector>
#include <cstring>
#include <string>
using namespace std;
int main()
{
int p[] = {1,2,3};
cout < <p < <endl;
return 0;
}
结果是:0012FF54
这很正常,因为p是一个指针,p的值应该是一个地址,所以这个结果是正常的。
大家再看下一个程序:
#include <iostream>
#include <vector>
#include <cstring>
#include <string>
using namespace std;
int main()
{
char p[] = {'1','2','3','/0'};
cout < <p < <endl;
return 0;
}
结果是:123
这里为什么直接输出了指针p所指向的内容,而不是指针p自身的地址值呢?
这个与cout对操作符<<的重载有关系。就是说cout<<对不同的类型会进行不同的操作。如果cout<<后面接int类型的指针的话,就会输出指针的内容,也就是一个地址。如果cout<<后面接char类型的指针的话,就会输出指针所指向的对象的内容,上例中就是123。
相关文章推荐
- 我的iOS学习历程 - OC第四天
- Linux学习之Shell--第四天:Shell流程控制-循环语句for
- 《c++ primer》 第13章 拷贝控制 学习笔记
- C++ Primer 学习笔记(二)
- (学习)C++ Primer(1)
- 学习Linux第四天
- 学习MySql第四天
- C#学习第四天
- springmvc学习第四天
- 如何更好的利用《C++ Primer》学习C++?
- C++ Primer 学习笔记_35_STL实践与分析(9)--map种类(在)
- C++ Primer 学习笔记_43_STL实践与分析(17)--再谈迭代器【中】
- C++ Primer 学习笔记_50_类与数据抽象 --类作用域
- C++ Primer 学习笔记_57_类与数据抽象 -治理指针成员
- jQuery框架学习第四天:使用jQuery操作元素的属性与样式
- C++ Primer 学习笔记_44_STL实践与分析(18)--再谈迭代器【下】
- c++ primer 第五版学习笔记-第二章-类型转换
- JS基础学习第四天:条件控制语句、循环语句、函数模块、事件等通用代码块2
- C++ Primer 中文版(第四版)学习笔记
- Vue.js第四天学习笔记(组件)