1. Cpp中的数组
C++支持数组数据结构,它可以存储一个固定大小的相同类型的元素的顺序集合。数组是用来存储一系列数据,但它往往被认为是一系列相同类型的变量。
数组的声明并不是声明一个个单独的变量,如a0,a1,a2,a3,a4...,a99,而是声明一个数组变量,比如as,然后使用as[0],as[1],as[2],...,as[99]来
代表一个个单独的变量,数组的特定元素可以通过索引来访问。所数组都是由连续的内存位置组成,最低的地址对应第一个元素,最高的地址对应最后一个元素。
2. 声明数组
在C++在声明一个数组,需要指定元素的类型和元素的数量,如下所示:
数据类型 数组名[元素数量];
上面声明的格式是一维数组的声明,其中元素个数必须是一个大于0的整型常量,数据类型可以是任意有效的C++数据类型。如声明一个类型为double的包含10
个元素的数组balance,声明语句是:
double balance[10];
3. 初始化数组
在C++中,可以逐个初始化数组,也可以使用一个初始化语句,如下所示:
double balance[5] = {1000.0, 2.0, 3.4, 7.0, 50.0};
大括号{ }之间的值的数目不能大于在数组声明时在方括号[ ]中指定的元素数目。
如果省略掉了数组的大小,数组的大小则为初始化时元素的个数。因此,如果是下面的格式,将创建一个数组,它与前一个实例中所创建的数组是完全相同的
double balance[] = {1000.0, 2.0, 3.4, 7.0, 50.0};
为数组中某个元素赋值的实例,下面的语句把数组中第五个元素的值赋为666.6。所有的数组都是以0作为它们第一个元素的索引,也被称为基索引,
数组的最后一个索引是数组的总大小减去1。
balance[4] = 666.6;
4. 访问数组元素
数组元素可以通过数组名称加索引进行访问。元素的索引是放在方括号内,跟在数组名称的后边。例如:
double salary = balance[3];
声明数组、初始化数组、访问数组元素实例如下:
#include "iostream"
#include "iomanip"
using namespace std;
using std::setw; // setw() 函数来格式化输出
int main(){
int a[10]; // 声明一个包含10个元素的整型数组
// 初始化数组
for (int i = 0; i < 10; i++)
a[i] = i + 100;
cout << "元素索引" << setw(13) << "元素值" << endl;
// 输出数组中的每个元素
for (int j = 0; j < 10; j++)
cout << setw(7) << j << setw(13) << a[j] << endl;
return 0;
}
5. 与数组有关的概念
5.1 多维数组
C++支持多维数组。多维数组声明的一般形式如下:
数据类型名 数组名[size1][size2]...[sizeN];
例如,下面的声明创建了一个三维整型数组:
int tridim[5][10][4];
二维数组
多维数组最简单的形式是二维数组。一个二维数组,在本质上,是一个一维数组的列表。声明一个x行y列的二维整型数组,形式如下:
数据类型 数组名[x][y];
一个二维数组可以被认为是一个带有x行和y列的表格。下面是一个二维数组,包含3行和4列:
因此,数组中的每个元素是使用形式为a[i][j]的元素名称来标识的,其中a是数组名称,i和j 是唯一标识a中每个元素的下标。
初始化二维数组
多维数组可以通过在括号内为每行指定值来进行初始化,下面是一个带有3行4列的数组。
int a[3][4] = {
{0, 1, 2, 3}, /* 初始化索引号为 0 的行 */
{4, 5, 6, 7}, /* 初始化索引号为 1 的行 */
{8, 9, 10, 11}, /* 初始化索引号为 2 的行 */
};
内部嵌套的括号是可选的,下面的初始化与上面是等同的:
int a[3][4] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
访问二维数组元素
二维数组中的元素是通过使用下标(即数组的行索引和列索引)来访问的。例如:
int val = a[2][3];
二维数组如下:
//1.二维数组
int aa[5][2] = {{0, 0}, {1, 2}, {2, 4}, {5, 7}, {9, 10}};
for (int i = 0; i < 5; i++){
for (int j = 0; j < 2; j++) {
cout << "aa[" << i << "][" << j << "] = " << aa[i][j] << endl; }
}
5.2 指向数组的指针----数组指针
数组名是一个指向数组中第一元素的常量指针(int const *p;),因此,double a[40];a是一个指向&a[0]的指针,即数组a的第一个元素的地址。因此,
下面的程序片段p赋值给a的第一个元素的地址:
double *p;
double a[10];
p = a;
使用数组名作为常量指针是合法的,因此*(a+4)是一种访问a[4]数据的合法方式。一旦把第一个元素的地址存储在p中,就可以使用*p,*(p+1),*(p+2)等
来访问数组的元素。
// 2.指向数组的指针:数组指针
double b[5] = {12.4, 3.1, 5.6, 0.8, 5.4};
double *p; // 一个指向double型的指针,可以存储一个double类型变量的地址
p=b;
cout << "使用指针的数组值 "<<endl;
for(inti=0;i<5;i++)
cout << "*(p + " << i << ") = " << *(p + i) << endl;
cout << "使用b作为地址的数组值 " << endl;
for(inti=0;i<5;i++)
cout << "*(b + " << i << ") = " << *(b + i) << endl;
C++中,将char*或char[]传给cout进行输出,结果会是整个字符串,如果想要获得字符串的地址(第一个字符的地址),可以使用方法:
强制转化为其他指针(非char),可以是void*, float*,int*,double*等。使用&s[0]不能输出s[0]的地址,因为&s[0]将返回char*,
对于char*,cout会将其作为字符串来处理,向下查找字符并输出直到字符结束*。
// C++中,将char*或char[]传递给cout进行输出,结果会是整个字符串。如果想要获得字符串的地址,强制转化为其他指针(非char*)
char var[MAX] = {'a', 'b', 'c'};
char*ptr;
ptr=var;
for (int i = 0; i < 3; i++){
cout << "var[" << i << "]的地址是 = " << (int *)ptr << endl;
cout << "var[" << i << "] = " << *ptr << endl;
ptr++; // 移动到下一个位置
}
5.3 C++中传递数组给函数
C++中可以通过指定不带索引的数组名来传递一个指向数组的指针
C++传数组给一个函数,数组类型自动转换为指针类型,因此传的实际是地址
如果想在函数中传递一个一维数组作为参数,必须用下面三种方式来声明函数形式参数,这三种声明方式的结果是一样的,因为每种方式都会告诉编译器将要接收一个整型指针。同样的,也可以传递一个多维数组作为形式参数。
方式1(形式参数是一个指针))
void func1(int *param){
…
}
方式2(形式参数是一个已定义大小的数组))
void func1(int params[10]){
…
}
方式3(形式参数是一个未定义大小的数组)
void func1(int params[]){
…
}
实例如下:
// 3.C++中把数组传递给函数(方法1)
int bb[5] = {1000, 2, 3, 17, 50};
double avg, avg1;
// 传递一个指向数组的指针作为参数
avg = getAverage(bb, 5);
cout << "平均值: " << avg << endl;
/*-----------------------方法2-----------------------*/
int bbb[5] = {1000, 2, 3, 17, 50};
int *ptr1 = bbb;
// 分别计算数组元素个数,以及整型指针的字节数
size_t bbb_size = sizeof(bbb) / sizeof(int);
size_t ptr1_size = sizeof(ptr1);
cout << "bbb size = " << bbb_size << endl;
cout << "ptr1 size = " << ptr1_size << endl;
avg1 = getAverage1(bbb, 5);
cout << "平均值: " << avg1 << endl;
// 方法1(下面的例子中把数组作为参数,同时还传递了另一个参数)
double getAverage(int arr[], int size){
int i, sum = 0;
double avg;
cout << "sizeof(arr) = " << sizeof(arr) << endl;
for (i = 0; i < size; i++)
sum += arr[i];
avg = double(sum) / size;
return avg;
}
// 方法2
double getAverage1(int *arr, int size){
int i, sum = 0;
double avg;
cout << "sizeof(arr) = " << sizeof(arr) << endl;
for (i = 0; i < size; i++)
sum += arr[i];
avg = double(sum) / size;
return avg;
}
5.4 从函数返回数组
C++不允许返回一个完整的数组作为函数的参数。但是,可以通过指定不带索引的数组名来返回一个指向数组的指针。C++不支持在函数外返回局部变量的地址,除非定义局部变量为static变量。如果想要从函数返回一个一维数组,必须声明一个返回指针的函数(指针函数),如下:
int * func(){
...
}
实例如下:
// 要生成和返回随机数的函数
int * getRandom()
{
static int r[10]; // C++不支持在函数外返回局部变量的地址,除非定义局部变量为static变量
// 设置随机数种子
srand((unsigned)time(NULL));
for (int i = 0; i < 10; i++){
r[i] = rand();
cout << "r[" << i << "] = " << r[i] << endl;
}
return r;
}
// 4.从函数返回数组----指针函数
int *p1;
p1 = getRandom();
for (int i = 0; i < 10; i++)
cout << "*( p1 + " << i << ") = " << *(p1 + i) << endl;
6.数组中的细节知识
直接初始化字符数组char是特殊的,这种初始化需要一个null作为结尾的。如下:
char a1[] = {'p', 'y', 't', 'h', 'o', 'n'}; // 初始化,没有 null
char a2[] = {'p', 'y', 't', 'h', 'o', 'n', '\0'}; // 初始化,明确有 null
char a3[] = "python"; // null 终止符自动添加
const char a4[6] = "python"; // 报错,没有 null 的位置
数组的大小是固定的,不能额外增加元素,当想定义不固定大小的字符时,使用vector!
vector<int> vec; // 创建向量用于存储整型数据
int m;
// 显示vec初始大小
cout << "vector size = " << vec.size() << endl;
// 向向量vec追加5个整数值
for(int m = 0; m < 5; m++)
vec.push_back(m);
// 显示追加后vec的大小
cout << "追加后的vector size = " << vec.size() << endl;
在C++中,setw(int n)用来控制输出间隔,(n-1个空格),setw()默认填充的内容是空格,可以使用setfill()配合使用设置其他字符填充。
cout << setfill('*') << setw(5) << 'a' << endl;
静态与动态数组:
静态 int array[100]; 定义了数组 array,并未对数组进行初始化
int array[100] = {1, 2}; 定义并初始化了数组 array
动态 int * array = new int[100]; 分配了长度为 100 的数组 array
delete [] array;
动态 int * array = new int[100]{1, 2}; 为长度为100的数组array初始化前两个元素
delete [] array;
数组初始化时可以用聚合方法,但是赋值时候不可以用聚合方法。举例如下:
int array[] = {5,10,20,40}; // 合法
int array[];
int main()
{
array[] = {5,10,20,40}; // 不合法
return 0;
}
数组在使用时可以是一个含有变量的表达式,但是,在数组声明时必须用常量表达式。例如:
// 合法
const int a=19;
long b[a];
// 合法
const int a=19;
long b[a+5];
// 不合法
int a=19;
long b[a+5];
声明一个任意长度的数组,可以用显式的类型转换,例如:
int a=19;
int b[(const int)a];
也可以定义一个常量来声明,例如:
int a=19;
const int a1=a;
int b[a1];
Vector(向量): C++中的一种数据结构,确切的说是一个类。它相当于一个动态的数组,当程序员无法知道自己需要的数组的规模多大时,用其来解决问题可以达到最大节约空间的目的。
用法:
1.文件包含:
首先在程序开头处加上 #include<vector> 以包含所需要的类文件vector;还有一定要加上
using namespace std;
2.变量声明:
2.1例: 声明一个 int 向量以替代一维的数组: vector <int> a; (等于声明了一个 int 数组 a[],大小没有指定,
可以动态的向里面添加删除)。
2.2例: 用vector代替二维数组.其实只要声明一个一维数组向量即可,而一个数组的名字其实代表的是它的首地址,
所以只要声明一个地址的向量即可,即: vector <int *> a。同理想用向量代替三维数组也是一样,vector <int**>a;
3.具体的用法以及函数调用:
3.1 得到向量中的元素和数组一样,例如:
vector <int *> a
int b = 5;
a.push_back(b);//该函数下面有详解
cout << a[0]; //输出结果为5
使用数组给向量赋值:
vector<int> v( a, a+sizeof(a)/sizeof(a[0]) );
或者:
int a[]={1,2,3,4,5,6,7,8,9};
typedef vector<int> vec_int;
vec_int vecArray(a,a+9);
原文:https://www.jianshu.com/p/0d3ffd335e24