C++primer(六) 数组和指针
2015-03-24 15:02
176 查看
经过前面的学习,我们知道了vector类是可以保存某一类相同对象的工具。现在我们进入数组和指针的学习
相比于前面,数组也是可以保存相同对象的集合,但是数组不可变,一旦初始化了,就不允许添加新的元素。指针则是和迭代器一样可以用于遍历和检查元素。
进入正题:
数组的基本知识点在这里我就不做叙述了,因为实在是太简单了。
模仿effective c++来写这部分的学习笔记:
条款1:不允许数组直接赋值和复制
例如:int a[]={0,1,2}; int b[]=a[]; //错误
条款2:变量名,函数都不能作为定义数组的维度;字符数组有个特殊的地方,字符串字面值默认包含一个额外的空字符(null)用于结束字符串。
条款3:数组长度是固定,且不提供获取其长度的size函数的操作。因此若要改变数组长度,则必须重新创建新的数组,然后覆盖原数组。
条款4:如何实现数组的输入
C语言:for(........) scanf("%d",&a[i])
C++:for(......) cin>>a[i]
比较两个数组是否相等:逐项比较 for(......) {
if(a[i]==b[i])
cout<<"the array is equal "<<endl;
}
指针保存的是另一个的对象的地址
条款5:尽量避免使用指针和数组
许多程序采用vector类型和迭代器取代一般的数组,采用string类取代C风格字符串
每个指针都有与之关联的数据类型,定义指针的时候,同时也就定义了指针的类型。例如,一个字符型指针只能指向字符型对象。
vector<int> *pvec;
int *p1,*p2;
string *pstring;
double *dp;
如何去记忆指针的含义呢?在见识了许多网络帖子的说法,我觉得primer上的说法更具有记忆性:从右向左读即可。pstring是一个指向string类型数据的string指针。
条款6:指针的初始化,因为C++是无法检测出未被初始化的错误。
对象初始化的四种方式:
(1)0值常量表达式
(2)类型匹配的对象的地址
(3)另一对象之后的下一个地址
(4)同一类型的另一个有效地址
例如:int i; double *dp=&i; //非法触犯了第二条
使用引用和指针都可间接访问另 一个值,但它们之间存在两个重要区别: (1) 引用总是指向某个确定的对象(事实 上,引用就是该对象的别名),定义引用时没有进行初始化会出现编译错误;(2) 赋值行为上存在差异:给引用赋值修改的是该所关联对象,而 不是使该引用与另一个对 象关联。引用经初始化,就终指向同特定一个对 象关联。引用经初始化,就终指向同特定对象。给指针赋值修改的是指针对象本身,也就使该向另一改的是指针对象本身,也就使该向另一改的是指针对象本身,也就使该向另一在不同时刻可指向不同的对象(只要保证类型匹配)。
条款7:const限定符限定指针的情况;
const char *cp; //说明指向的内容是常量
char * const cp; //指针值是常量
下面进入到C风格字符串的学习
1.C风格字符串的标准库函数(这里的s1,s2全是对象的指针变量)
strlen(s); //返回s的长度,但不包含字符串结束符
strcmp(s1,s2); //比较s1,s2是否相同;相等返回0;s1>s2返回1;s1<s2返回-1
strcat(s1,s2); //将s2连接到s1后面,返回s1
strcpy(s1,s2); //将s2复制给s1,并返回s1
strncat(s1,s2,n); //将s2的前n个字符连接到s1后面,并返回s1
strncpy(s1,s2,n)
2.动态数组的创建
例如:int *pa=new int[10]; string *psa=new string[10]
/**********动态创建一个与该vector对象大小一致的数组,并把对象所有元素数组复制给新数组
#include<iostream>
#include<string>
#include<vector>
#include<cctype>
using namespace std;
int main()
{
int a;
vector <int> T;
while(cin>>a)
{
T.push_back(a);
}
if(T.size()==0)
{
cout<<"No input!"<<endl;
return -1;
}
int *pa=new int[T.size()];
//复制到数组
int *t=pa; //指针的指针为对象的内容
for(vector <int>::iterator iter=T.begin();iter!=T.end();++iter,++t) //想想为什么要用迭代器而不是下标
{
*t=*iter;
delete[] pa;
return 0;
}
for(int j=0;j<T.size();j++)
cout<<t[j]<<"\t";
system("pause");
return 0;
}
************************************************/
习题4.30
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
char c[]="hello";
char d[]="world";
for(int i=0;i<strlen(c);++i)
cout<<c[i];
cout<<endl;
strcat(c,d);
for(int i=0;i<strlen(c);++i)
cout<<c[i];
cout<<endl;
system("pause");
return 0;
}
下面进入多维数组的学习
1.多维数组的初始化
int a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};
2.多维数组的下标引用
for循环来初始化一个二维数组
const size_t row=3;
const size_t col=4;
int a[row][col];
for(size_t i=0;i<row;i++)
{
for(size_t j=0;j<col;j++)
a[i][j]=i*j;
cout<<a[i][j]<<endl;
}
多维数组的指针问题留待以后讨论
相比于前面,数组也是可以保存相同对象的集合,但是数组不可变,一旦初始化了,就不允许添加新的元素。指针则是和迭代器一样可以用于遍历和检查元素。
进入正题:
数组的基本知识点在这里我就不做叙述了,因为实在是太简单了。
模仿effective c++来写这部分的学习笔记:
条款1:不允许数组直接赋值和复制
例如:int a[]={0,1,2}; int b[]=a[]; //错误
条款2:变量名,函数都不能作为定义数组的维度;字符数组有个特殊的地方,字符串字面值默认包含一个额外的空字符(null)用于结束字符串。
条款3:数组长度是固定,且不提供获取其长度的size函数的操作。因此若要改变数组长度,则必须重新创建新的数组,然后覆盖原数组。
条款4:如何实现数组的输入
C语言:for(........) scanf("%d",&a[i])
C++:for(......) cin>>a[i]
比较两个数组是否相等:逐项比较 for(......) {
if(a[i]==b[i])
cout<<"the array is equal "<<endl;
}
指针保存的是另一个的对象的地址
条款5:尽量避免使用指针和数组
许多程序采用vector类型和迭代器取代一般的数组,采用string类取代C风格字符串
每个指针都有与之关联的数据类型,定义指针的时候,同时也就定义了指针的类型。例如,一个字符型指针只能指向字符型对象。
vector<int> *pvec;
int *p1,*p2;
string *pstring;
double *dp;
如何去记忆指针的含义呢?在见识了许多网络帖子的说法,我觉得primer上的说法更具有记忆性:从右向左读即可。pstring是一个指向string类型数据的string指针。
条款6:指针的初始化,因为C++是无法检测出未被初始化的错误。
对象初始化的四种方式:
(1)0值常量表达式
(2)类型匹配的对象的地址
(3)另一对象之后的下一个地址
(4)同一类型的另一个有效地址
例如:int i; double *dp=&i; //非法触犯了第二条
使用引用和指针都可间接访问另 一个值,但它们之间存在两个重要区别: (1) 引用总是指向某个确定的对象(事实 上,引用就是该对象的别名),定义引用时没有进行初始化会出现编译错误;(2) 赋值行为上存在差异:给引用赋值修改的是该所关联对象,而 不是使该引用与另一个对 象关联。引用经初始化,就终指向同特定一个对 象关联。引用经初始化,就终指向同特定对象。给指针赋值修改的是指针对象本身,也就使该向另一改的是指针对象本身,也就使该向另一改的是指针对象本身,也就使该向另一在不同时刻可指向不同的对象(只要保证类型匹配)。
条款7:const限定符限定指针的情况;
const char *cp; //说明指向的内容是常量
char * const cp; //指针值是常量
下面进入到C风格字符串的学习
1.C风格字符串的标准库函数(这里的s1,s2全是对象的指针变量)
strlen(s); //返回s的长度,但不包含字符串结束符
strcmp(s1,s2); //比较s1,s2是否相同;相等返回0;s1>s2返回1;s1<s2返回-1
strcat(s1,s2); //将s2连接到s1后面,返回s1
strcpy(s1,s2); //将s2复制给s1,并返回s1
strncat(s1,s2,n); //将s2的前n个字符连接到s1后面,并返回s1
strncpy(s1,s2,n)
2.动态数组的创建
例如:int *pa=new int[10]; string *psa=new string[10]
/**********动态创建一个与该vector对象大小一致的数组,并把对象所有元素数组复制给新数组
#include<iostream>
#include<string>
#include<vector>
#include<cctype>
using namespace std;
int main()
{
int a;
vector <int> T;
while(cin>>a)
{
T.push_back(a);
}
if(T.size()==0)
{
cout<<"No input!"<<endl;
return -1;
}
int *pa=new int[T.size()];
//复制到数组
int *t=pa; //指针的指针为对象的内容
for(vector <int>::iterator iter=T.begin();iter!=T.end();++iter,++t) //想想为什么要用迭代器而不是下标
{
*t=*iter;
delete[] pa;
return 0;
}
for(int j=0;j<T.size();j++)
cout<<t[j]<<"\t";
system("pause");
return 0;
}
************************************************/
习题4.30
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
char c[]="hello";
char d[]="world";
for(int i=0;i<strlen(c);++i)
cout<<c[i];
cout<<endl;
strcat(c,d);
for(int i=0;i<strlen(c);++i)
cout<<c[i];
cout<<endl;
system("pause");
return 0;
}
下面进入多维数组的学习
1.多维数组的初始化
int a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};
2.多维数组的下标引用
for循环来初始化一个二维数组
const size_t row=3;
const size_t col=4;
int a[row][col];
for(size_t i=0;i<row;i++)
{
for(size_t j=0;j<col;j++)
a[i][j]=i*j;
cout<<a[i][j]<<endl;
}
多维数组的指针问题留待以后讨论
相关文章推荐
- 第二遍C++primer->数组指针和指针数组
- c++Primer,四,数组和指针
- C++primer第四章(二):数组和指针——指针
- C++Primer (第四版) 第四章 数组和指针
- C++Primer--数组、指针
- c++primer学习笔记3 - 数组和指针
- c++primer阅读笔记之数组与指针
- 《C++primer》读书笔记---数组和指针
- C++Primer学习笔记4 数组和指针
- C++primer 4.4 多维数组、指针数组、数组指针(未完)
- C++primer第四章(一):数组和指针——数组
- 《C++Primer》 第四章 数组和指针
- c++primer 6.3.3节练习(返回数组指针的4个方法)
- C++Primer 数组和指针
- 《C++primer》标准库类型 数组和指针
- 指针和数组(c++primer)
- 第二遍C++primer->关于数组名的输出,数组名和指针
- C++primer第四版第四章数组与指针
- 【C++Primer学习笔记】第4章 数组和指针
- 【转】字符数组与字符指针