C++基础(4) - 数组

 

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

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值