C++ 数组相关知识小结

疫情所迫,希望用这种方法督促自己坚持学习。同时记录在找工作过程中的艰辛不易。博客内容持续增减修改,都为摘录和个人理解。欢迎各位批评指正其中错误,相互勉励,共同进步。

一、数组初始化与注意事项

数组相较于前面学习的string和vector数据类型,其更加固定。不能随意的往数组中增添元素。虽然一定程度上程序的运行性能会有所提升,但是缺乏灵活性。以下是几种数组常用的初始化方式:

int arr[5];                              //含有5个int类型的数组
int *ptr[10];                            //含有10个整型指针的数组
string arr1[10];                         //含有10个string类型的数组
int arr = {5,8,9,6,4};                   //显式初始化整型数组
string arr1[] = {"hello","world!"};      //显式初始化字符串数组
int arr[5] = {1,2,3};                    //将数组的前三个元素赋值,剩余为0
int arr[3] = {1,2,3,4,5};                //编译出错,超过数组维度

重点需要注意的几个问题:

  • 不能用变量动态规定数组大小,如下所示,编译错误;
    int i; cin >> i ;
    int arr[i];   //编译报错,不能用变量分配数组大小
    const j = 5;
    int arr1[j];  //编译通过,可以用const常数量规定数组大小
    
  • 数组使用前必须定义和定义其空间大小(不同于string和vector);
  • 不能用一个数组给另外一个数组初始化,也不能数组直接赋值给另一个;
    int arr1[5] = {0,1,2,3,4};
    int arr2[] = arr1;           //编译报错
    arr2 = arr1;                 //编译报错
    
  • 定义数组末尾是否有字符“\0”,对比以下几种定义方式:
    char a1[] = "shi";                 //sizeof(a1)=4 末尾会自动添加'\0'
    char a2[] = {'s','h','i','\0'};    //与上一行定义方式等价
    char a3[] = {'s','h','i'};         //sizeof(a3)=3
    char a4[3] = "shi";                //编译出错,大小空间定义应该大于等于4
    

示例代码一:
对比vector和数组赋值方式与拷贝方式区别

int a[10], a1[10];
vector<int> b, b1;
for (int i = 0; i < 10; i++) {
	a[i] = i;
	b.push_back(i);
}
for (int j = 0; j < 10; j++)
	a1[j] = a[j];
b1 = b;

二、几种复杂的数组申明(一定要完全弄清楚)

示例代码展示了三种复杂的数组申明。

  • 定义一,iter1保存了5个整型数的指针。从右往左看,先是iter1[5]表示定义数组大小为5,再加上*表示为指针元素 ;
  • 定义二,iter2指向一个大小为5的整型数组。由内往外看,先是*iter2表示为指针变量,再加上[5]表示指向大小为5的整型数组;
  • 定义三,iter3为引用一个大小为5的整型数组。由内往外看,先是&iter3表示一个引用,再加上[5]表示引用一个大小为5的整型数组;
int a[5] = { 0,1,2,3,4 };
int *iter1[5] = { &a[0],&a[1],&a[2],&a[3],&a[4] }; //定义一
int(*iter2)[5] = &a;                               //定义二
int(&iter3)[5] = a;                                //定义三
cout << a << endl;               //00000033F875F8E8
cout << iter1[0] << endl;        //00000033F875F8E8
cout << iter2 << endl;           //00000033F875F8E8
cout << iter3 << endl;           //00000033F875F8E8

三、数组和指针

实际在使用数组时,编译器会把其变为指针。现有如下代码:所述两种定义方法中的指针p和p1都是指向a[0]。

string a[] = {'wdn','cer','vbtr'};
string *p = &a[0];
string *p1 = a;
auto p3(a);              //p3是一个string指针,指向a;

指针迭代器
代码功能:利用指针遍历输出字符数组

char a[6] = { 'a','b','c','d','e','f' };
char *e = &a[6];
for (char *b = a; b<e; b++)
	cout << *b << endl;

标准库函数的begin和end
数组不是类类型,因此begin和end不是其成员函数。其使用方法如下:

int a[6];
int *b = begin(a);   //指向数组的首元素
int *e = end(a);     //指向尾元素的后一位

指针运算

int a[10] = {0,1,2,3,4,5,6,7,8,9};
int *p = a;
int *p1 = p + 4; //指向数组中第五个元素
auto n = end(a) - begin(a); //输出该数组有多少元素
auto n1 = size(a);
//解引用
int b = *(a+4);   //a[4]的值为3
int b = *a + 4;   //等价于a[0]+4

需要注意,如果两个指针指向不同的类型,则比较没有意义。

四、字符串数组操作

对于字符串数组,有如下几种常用操作方式:(图片来源于Primer c++ P109)
在这里插入图片描述
字符串的长度
上诉操作中需要注意,对于字符数组要以‘\0‘结尾。如下代码所示:strlen只有当遇到‘\0’才会停止,并且不会将‘\0’作为一个字符计入;

扫描二维码关注公众号,回复: 9559494 查看本文章
char a[3] = {'C','+','+'};
int n = strlen(a);         //输出一个不为3且大于3的数
/*****************/
char b[4] = {'C','+','+','\0'};
int n = strlen(b);         //输出为3

字符串的比较
我们需要区别字符串数组和string比较方法

//对于string类型可以直接用比较运算符实现对两个字符串的比较
string s1 = "cnjsklcncnsil";
string s2 = "hxcskugcbkjsc";
if(s1<s2)
//对于数组字符串,直接比较相当于比较两个指针,虽然不会报错,但是没有任何意义
char c1[] = "cbjaskbc";
char c2[] = "casbhkjcb";
if(c1<c2)
//因此对于字符串数组,需要用strcmp进行比较
if(strcmp(c1,c2)>0)

字符串拼接与复制
同样的对于数组字符串我们与string类型字符串进行对比记忆

string s1 = "csbcbkavch";
string s2 = "xhasjcbsjkan";
char c1[100] = "chsacjasbjck";
char c2[] = "ahduskgcbcsjsag";
//对于字符串复制
string s3 = s1;
strcpy(c1,c2);    //将c2拷贝到c1,如果c1内存小于c2则只复制c2部分
//对于字符串拼接
string s4 = s1 + s2;
strcat(c1,c2);   //将c2附加到c1

对于字符串数组的拼接,要确保c1的内存大于等于c1+c2,否则会报错。因此,对于大小不确定的字符串,最好使用string类型变量。

发布了27 篇原创文章 · 获赞 4 · 访问量 4519

猜你喜欢

转载自blog.csdn.net/SGL_LGS/article/details/104619653