C++学习——数组

所有的数组都是由连续的内存位置组成。最低的地址对应第一个元素,最高的地址对应最后一个元素。

1.声明数组

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

这叫做一维数组。arraySize 必须是一个大于零的整数常量,type 可以是任意有效的 C++ 数据类型。
例如:double balance[10];

2.初始化数组

初始化总共分为一下几种方式:

2.1 定义数目,{}初始化

double balance[5] = {1000.0, 2.0, 3.4, 7.0, 50.0};
大括号 { } 之间的值的数目不能大于我们在数组声明时在方括号 [ ] 中指定的元素数目。

2.2 不定义数目,{}初始化

数组的大小则为初始化时元素的个数,省略掉了数组的大小。
double balance[] = {1000.0, 2.0, 3.4, 7.0, 50.0};

2.3 为数组中某个元素赋值

balance[4] = 50.0;
仅为第5个元素赋值,其他元素不变。

  • 注意:所有数组都是以0作为他们的第一个元素的索引。

3.访问数组

数组元素可以通过数组名称加索引进行访问。元素的索引是放在方括号内,跟在数组名称的后边。
double salary = balance[9];

4.多维数组

C++ 支持多维数组。多维数组声明的一般形式如下。
type name[size1][size2]...[sizeN];
示例:创建一个三维数组
int threedim[5][10][4];

4.1 二维数组

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

type arrayName [ x ][ y ];

一个二维数组可以被认为是一个带有 x 行和 y 列的表格。下面是一个二维数组,包含 3 行和 4 列:

4.2 初始化二维数组

  • 方法一:多维数组可以通过在括号内为每行指定值来进行初始化

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

5.C++指向数组的指针

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

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

double *p;
double runoobAarray[10];

p = runoobAarray;
  • 使用数组名作为常量指针是合法的,反之亦然。因此,*(runoobAarray + 4) 是一种访问 runoobAarray[4] 数据的合法方式。

  • 一旦您把第一个元素的地址存储在 p 中,您就可以使用 p、(p+1)、*(p+2) 等来访问数组元素。下面的实例演示了上面讨论到的这些概念:

C/C++ 对 char 型数组做了特殊规定,直接输出首地址时,会输出数组内容。如果想得到地址,可采用 & 。
示例1

 char name[] = {"Zara Ali"};
 cout << name << endl; // 输出 Zara Ali
 cout << &name << endl; // 输出 0x7ffe08e50977 

示例2

char name[] = "Zara Ali";
cout << name << endl; // char[],输出整个字符数组的描述(就是字符串)
cout << &name << endl; // char[],输出数组的地址(就是首字符的地址)
cout << (void *)&name[1] << endl;//由于&name[1]的类型是char*,直接输出会是字符串,所以需要强转成其他类型才能输出地址
printf("name:%s  name:%p  &name:%p &name[1]:%p\n",name,name,&name,&name[1]);//print可以指定输出样式,所以没有上面cout的问题

int bbb[] = {1,2,3,4};
cout << bbb << endl;//int[],输出整个数组的描述(数组变量的地址代表整个变量的描述)
cout << &bbb << endl;//int[],输出数组的地址(就是首元素的地址)
cout << &bbb[1]<< endl;//&bbb[1] 输出下标为1的元素的地址(就是输出一个int *的指针变量的值)

6.传递数组给函数

C++ 中您可以通过指定不带索引的数组名来传递一个指向数组的指针。

C++ 传数组给一个函数,数组类型自动转换为指针类型,因而传的实际是地址。

如果您想要在函数中传递一个一维数组作为参数,您必须以下面三种方式来声明函数形式参数,这三种声明方式的结果是一样的,因为每种方式都会告诉编译器将要接收一个整型指针。同样地,您也可以传递一个多维数组作为形式参数。

  • 方式 1
    形式参数是一个指针:

     void myFunction(int *param)
    {
    .
    .
     .
    }
    
  • 方式 2
    形式参数是一个已定义大小的数组:

    void myFunction(int param[10])
    {
    .
    .
    .
    }
    
  • 方式 3
    形式参数是一个未定义大小的数组:

    void myFunction(int param[])
    {
    .
    .
    .
    }
    

#include <iostream>
 using namespace std;

double getAverage(int *arr, int size); //形式参数是一个指针:
double getAverage(int arr[5]); // 重载函数,形式参数是一个已定义大小的数组:
double getAverage2(int arr[]); // 不可重载,形式参数是一个未定义大小的数组:

int main(int argc, char const *argv[])
{
    // 带有 5 个元素的整型数组
    int balance[5] = {1000, 2, 3, 17, 50};
int *pt1 = balance;
// 分别计算数组元素个数,以及整型指针的字节数
size_t balance_size = sizeof(balance) / sizeof(int);
size_t pt1_size = sizeof(pt1);

double avg, avg2, avg3;

cout << "array size : " << balance_size << endl;
cout << "pt1_size : " << pt1_size << endl;

avg = getAverage(balance, 5);
avg2 = getAverage(balance);
avg3 = getAverage2(balance);

// 输出返回值
cout << "方法1平均值是:" << avg << endl;
cout << "方法2平均值是:" << avg << endl;
cout << "方法3平均值是:" << avg << endl;
return 0;
}

double getAverage(int *arr, int size)
{
int i, sum = 0;
double avg;
// 打印第一个形参的字节数
cout << "Inside getAverage sizeof(arr) = " << sizeof(arr) << endl;
for (int i = 0; i < size; ++i)
{
    sum += arr[i];
}

avg = double(sum) / size;
return avg;
}

double getAverage(int arr[5])
{
int i, sum = 0, size = 5;
double avg;
// 打印第一个形参的字节数
cout << "Inside getAverage sizeof(arr) = " << sizeof(arr) << endl;
for (int i = 0; i < size; ++i)
{
    sum += arr[i];
}

avg = double(sum) / size;
return avg;
}

double getAverage2(int arr[])
{
int i, sum = 0, size = 5;
double avg;
// 打印第一个形参的字节数
cout << "Inside getAverage sizeof(arr) = " << sizeof(arr) << endl;
for (int i = 0; i < size; ++i)
{
    sum += arr[i];
}

avg = double(sum) / size;
return avg;
}

arr 是一个指针,即为地址,指针占几个字节跟语言无关,而是跟系统的寻址能力有关。

例如:以前是 16 位地址,指针即为 2 个字节,现在一般是 32 位系统,所以是 4 个字节,以后 64 位,则就占 8 个字节。

7.从函数返回数组

C++ 不允许返回一个完整的数组作为函数的参数。但是,您可以通过指定不带索引的数组名来返回一个指向数组的指针。

如果您想要从函数返回一个一维数组,您必须声明一个返回指针的函数,如下:

int * myFunction()
{
.
.
.
}

另外,C++ 不支持在函数外返回局部变量的地址,除非定义局部变量为 static 变量。

#include <iostream>
#include <cstdlib>
#include <ctime>

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;
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,907评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,987评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,298评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,586评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,633评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,488评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,275评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,176评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,619评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,819评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,932评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,655评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,265评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,871评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,994评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,095评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,884评论 2 354

推荐阅读更多精彩内容