C++数组

C++数组

C++支持数组数据结构,它可以存储一个固定大小的相同类型元素的顺序集合。数组是用来存储一系列数据,但它往往被认为是一系列相同类型的变量。
数组的声明并不是声明一个个单独的变量,比如number0、number1、…、number99,而是声明一个数组变量、比如numbers,然后使用numbers[0],number[1]、…、number[99]来代表一个个单独的变量。数组中的特定元素可以通过索引访问。
所有的数组都是有连续的内存位置组成。最低的位置对应第一个元素,最高的位置对应最后一个元素。

声明数组

在C++中要声明一个数组,需要指定元素的类型和元素的数量,如下所示:

type arrayName[arraySize];

这叫做一维数组。arraySize必须是一个大于零的整数常量,type可以是任意有效的C++数据类型,例如,要声明一个类型为double的包含10个元素的数组balance,声明如下:

double balance[10];

现在balance是一个可用的数组,可以容纳10个类型为double的数字。

初始化数组

在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};

你将创建一个数组,它与前一个实例中创建的数组是完全相同的。下面是一个为数组中某一个元素赋值的实例:

balance[4] = 50.0;

上述的语句把数组中第五个元素的值赋为50.0。所有的数组都是以0作为他们第一个元素的索引,也称为基索引,数组的最后一个索引是数组的总大小减去1,以下是上面所讨论的数组的图形表示:
在这里插入图片描述

访问数组元素

数组元素可以通过数组名称加索引进行访问。元素的索引是放在方括号内,跟在数组名称的后边。例如:

double salary=balance[9];

上面的语句将把数组中第10个元素的值赋给salary变量。下面的实例使用了上述的三个概念,即,声明数组,数组赋值,访问数组:

#include 
using namespace std;
 
#include 
using std::setw;
 
int main ()
{
   int n[ 10 ]; // n 是一个包含 10 个整数的数组
 
   // 初始化数组元素          
   for ( int i = 0; i < 10; i++ )
   {
      n[ i ] = i + 100; // 设置元素 i 为 i + 100
   }
   cout << "Element" << setw( 13 ) << "Value" << endl;
 
   // 输出数组中每个元素的值                     
   for ( int j = 0; j < 10; j++ )
   {
      cout << setw( 7 )<< j << setw( 13 ) << n[ j ] << endl;
   }
 
   return 0;
}

上面的程序使用了setw() 函数来格式化输出。当上面的代码被编译和执行时,会产生下列结果:

Element        Value
      0          100
      1          101
      2          102
      3          103
      4          104
      5          105
      6          106
      7          107
      8          108
      9          109

C++中数组详解

在C++中,数组是非常重要的,下面列出了我们必须清楚的一些与数组相关的重要概念:

概念 描述
多维数组 C++支持多维数组。多维数组最简单的形式就是二维数组。
指向数组的指针 可以通过不带索引的数组名称来生成一个指向数组中第一个元素的指针。
传递数组给函数 可以通过指定不带索引的数组名称来给函数传递一个指向数组的指针。
从函数返回数组 C++允许从函数返回数组

多维数组

C++支持多维数组。多维数组声明的一般形式如下:

type name[size1][size2]...[sizeN];

例如,下面的声明创建了一个三维5,10,4整型数组:

int threedim[5][10][4];

二维数组

多维数组最简单的形式就是二维数组。一个二维数组,在本质上,是一个一位数组的列表。声明一个x行y列的二维整型数组,形式如下:

type arrayName [ x ][ y ];

其中,type可以是任意有效的C++数据类型,arrayName是一个有效的C++表示符。
一个二维数组可以被认为是一个带有x行和y列的表格。下面是一个二维数组,包含3行和4列:
C++数组_第1张图片
因此,数组中的每一个元素是使用形式为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];

上面的语句将获取第3行第4个元素。可以通过上面的示意图来进行验证。下面的程序就是使用了嵌套循环来处理二维数组:

#include 
using namespace std;
 
int main ()
{
   // 一个带有 5 行 2 列的数组
   int a[5][2] = { {0,0}, {1,2}, {2,4}, {3,6},{4,8}};
 
   // 输出数组中每个元素的值                      
   for ( int i = 0; i < 5; i++ )
      for ( int j = 0; j < 2; j++ )
      {
         cout << "a[" << i << "][" << j << "]: ";
         cout << a[i][j]<< endl;
      }
 
   return 0;
}

上面的代码被编译和执行时,会产生下列结果:

a[0][0]: 0
a[0][1]: 0
a[1][0]: 1
a[1][1]: 2
a[2][0]: 2
a[2][1]: 4
a[3][0]: 3
a[3][1]: 6
a[4][0]: 4
a[4][1]: 8

如上所述,可以创建任意维度的数组,但是一般情况下,我们只采用一维数组和二维数组。
如果想从键盘中获取值来构建二维数组,可以使用如下写法构建:

#include  
#include 
#include 
using namespace std;
int main()
{
    vector< vector<int> > arry; //写成arry(5) 可理解为设定大小5行 
    vector<int> d;        //定义一个一维的数组; 
    int i, j, k, n;
    int number;
    
    scanf("%d", &n );
    /*可以这样实现对vector二维的初始化,得到的是n行n列的矩阵*/ 
    for( i=0; i<n; i++ ){ 
        for( j=0; j<n; j++ ){
            scanf("%d", &number );
            d.push_back( number ); 
        }
        sort( d.begin(), d.end() ); //pai xu xuyao头文件algorithm 
        arry.push_back( d );
        //d.clear();        //清空一维的数组 
        d.resize(0);
    }
    /*遍历输出*/ 
    if( arry.empty() )
        printf("0\n");
    else{
        for( i=0; i<arry.size(); i++ ) {
            for( j=0; j<arry[0].size(); j++ ){
                printf("%d ", arry[i][j] );
            }
            printf("\n");
        }
    } 
    
    return 0;
}

指向数组的指针

数组名是一个指向数组中第一个元素的常量指针。
因此,在下面的声明中:

double balance[50];

balance是一个指向&balance[0]的指针,即数组balance的第一个元素的地址。因此,下面的程序片段把p赋值为balance的第一个元素的地址:

double *p;
double balance[10];
p=balance;

使用数组名作为常量指针是合法的,反之亦然。因此, * (balance+4) 是一种访问balance[4]数据的合法方式。
当把某一个元素的地址存储到p中,就可以使用 { * p 、 * (p+1)、 *(p+2) }等来访问数组元素。下面的实例演示了上面讨论的这些概念:

#include 
using namespace std;
 
int main ()
{
   // 带有 5 个元素的双精度浮点型数组
   double balance[5] = {1000.0, 2.0, 3.4, 17.0, 50.0};
   double *p;
 
   p = balance;
 
   // 输出数组中每个元素的值
   cout << "使用指针的数组值 " << endl; 
   for ( int i = 0; i < 5; i++ )
   {
       cout << "*(p + " << i << ") : ";
       cout << *(p + i) << endl;
   }
 
   cout << "使用 balance 作为地址的数组值 " << endl;
   for ( int i = 0; i < 5; i++ )
   {
       cout << "*(balance + " << i << ") : ";
       cout << *(balance + i) << endl;
   }
 
   return 0;
}

当上面的代码被编译和执行时,会产生下列结果:

使用指针的数组值
*(p + 0) : 1000
*(p + 1) : 2
*(p + 2) : 3.4
*(p + 3) : 17
*(p + 4) : 50
使用 balance 作为地址的数组值
*(balance + 0) : 1000
*(balance + 1) : 2
*(balance + 2) : 3.4
*(balance + 3) : 17
*(balance + 4) : 50

在上面的实例中,p是一个指向double型的指针,这意味着它可以存储一个double类型的变量。一旦有了p的地址, * p将给出存储在p中相应地址的值,正如上面实例中所演示的。

C++中,将 char * 或char[]传递给cout进行输出,结果会是整个字符串,如果想要获得字符串的地址(第一个字符的内存地址),可使用以下方法:
强制转换为其他指针(非char * )。可以是void * ,int * ,float * ,double * 等。使用&s[0]不能输出s[0](首字符)的地址。因为&s[0] 将返回 char*,对于 char *(char 指针),cout 会将其作为字符串来处理,向下查找字符并输出直到字符结束。

#include 
 
using namespace std;
const int MAX = 3;
 
int main ()
{
   char  var[MAX] = {'a', 'b', 'c'};
   char  *ptr;
 
   // 指针中的数组地址
   ptr = var;
            
   for (int i = 0; i < MAX; i++)
   {

      cout << "Address of var[" << i << "] = ";
      cout << (int *)ptr << endl;
 
      cout << "Value of var[" << i << "] = ";
      cout << *ptr << endl;
 
      // 移动到下一个位置
      ptr++;
   }
   return 0;
}

输出结果:

Address of var[0] = 0x7fffd63b79f9
Value of var[0] = a
Address of var[1] = 0x7fffd63b79fa
Value of var[1] = b
Address of var[2] = 0x7fffd63b79fb
Value of var[2] = c

从函数返回数组

C++不允许返回一个完整的数组作为函数的参数。但是,可以通过指定不带索引的数组名来返回一个指向数组的指针。
如果要从函数返回一个一维数组,必须声明一个返回指针的函数,如下1:

int * myFunction()
{
.
.
.
}

另外,C++不支持在函数外返回局部变量的地址,除非定义局部变量为static 变量。
下面的代码,会生成10个随机数,并使用数组来返回它们,具体如下:

#include 
#include 
#include 
 
using namespace std;
 
// 要生成和返回随机数的函数
int * getRandom( )
{
  static int  r[10];
 
  // 设置种子
  srand( (unsigned)time( NULL ) );
  for (int i = 0; i < 10; ++i)
  {
    r[i] = rand();
    cout << r[i] << endl;
  }
 
  return r;
}
 
// 要调用上面定义函数的主函数
int main ()
{
   // 一个指向整数的指针
   int *p;
 
   p = getRandom();
   for ( int i = 0; i < 10; i++ )
   {
       cout << "*(p + " << i << ") : ";
       cout << *(p + i) << endl;
   }
 
   return 0;
}

当上面代码被执行时,会产生下列结果:

624723190
1468735695
807113585
976495677
613357504
1377296355
1530315259
1778906708
1820354158
667126415
*(p + 0) : 624723190
*(p + 1) : 1468735695
*(p + 2) : 807113585
*(p + 3) : 976495677
*(p + 4) : 613357504
*(p + 5) : 1377296355
*(p + 6) : 1530315259
*(p + 7) : 1778906708
*(p + 8) : 1820354158
*(p + 9) : 667126415

C++中函数是不能直接返回一个数组的,但是数组其实就是指针,所以可以让函数返回指针来实现:
例如下面代码:

 #include 
 
 using namespace std;
 
 void MultMatrix(float M[4], float A[4], float B[4])
 {
     M[0] = A[0]*B[0] + A[1]*B[2];
     M[1] = A[0]*B[1] + A[1]*B[3];
     M[2] = A[2]*B[0] + A[3]*B[2];
     M[3] = A[2]*B[1] + A[3]*B[3];
 
     cout << M[0] << " " << M[1] << endl;
     cout << M[2] << " " << M[3] << endl;
 }
 
 int main()
 {
     float A[4] = { 1.75, 0.66, 0, 1.75 };
     float B[4] = {1, 1, 0, 0};
 
     float *M = new float[4];
     MultMatrix(M, A, B);
 
     cout << M[0] << " " << M[1] << endl;
     cout << M[2] << " " << M[3] << endl;
     delete[] M;
 
     return 0;
 }
补充

『返回指针的函数』和『指向函数的指针』非常相似,使用时特别注意区分。
返回指针的函数定义:char * upper(char * str)
指向函数的指针:char ( * fun)(int int)
返回指针的函数:

char * upper(char *str)
{
    char *dest = str;
    while(*str != NULL)
    {
        if(*str >= 'a' && *str <= 'z')
        {
            *str -= 'a' - 'A';
        }
        str++;
    }
    return dest;
}

指向函数的指针:

int add(int a,int b)
{
    return a+b;
}

int min()
{
    int (*fun)() = add;
    int result = (*fun)(1,2);
    char hello[] = "Hello";
    char *dest = upper(heLLo);
}

int result = ( * fun)(1,2); 是指向 add 函数的函数,执行结果 result=3。
char *dest = upper(heLLo); 将 hello 字符串中的小写字母全部转换为大写字母。

Array 是固定大小的,不能额外增加元素.当我们想定义不固定大小的字符时,可以使用 vector(向量) 标准库。
用法:
1.文件包含:
首先在程序开头处加上 #include < vector > 以包含所需要的类文件 vector。
还有一定要加上 using namespace std;
2.变量声明:
2.1 例: 声明一个 int 向量以替代一维的数组: vector a; (等于声明了一个 int 数组 a[],大小没有指定,可以动态的向里面添加删除)。
2.2 例: 用 vector 代替二维数组.其实只要声明一个一维数组向量即可,而一个数组的名字其实代表的是它的首地址,所以只要声明一个地址的向量即可,即: vector a 。同理,想用向量代替三维数组也是一样,vector 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);

例如:

#include 
#include 
using namespace std;
 
int main() {
   // 创建向量用于存储整型数据
   vector<int> vec; 
   int i;

   // 显示 vec 初始大小
   cout << "vector size = " << vec.size() << endl;

   // 向向量 vec 追加 5 个整数值
   for(i = 0; i < 5; i++){
      vec.push_back(i);
   }

   // 显示追加后 vec 的大小
   cout << "extended vector size = " << vec.size() << endl;

   return 0;
}

vec 的大小随着 for 循环的输入而增大。
执行以上代码,输出结果:

vector size = 0
extended vector size = 5

你可能感兴趣的:(个人笔记,学习笔记,C++,C++,数组,学习笔记)