有关数组
一维数组:
1.数组的定义(一维数组): (类型名 数组名[数组元素个数] = {} )
定义一个数组需要给定数组的类型,以及数组所包含元素的个数,如: int ar[10] = {};在定义数组时若不对数组进行初始化,里面为随机值,且在后面对数组进行赋值不能整体的进行
如: ar[10] = {1,2,3,4,5,6,7,8,9,10}(error) , 这种写法是错误的,只能通过访问数组内的每一个元素对其进行赋值:如通过循环:对数组进行赋值.
int ar[] = {1,2,3,4,5,6}; //定义一个已初始化且包含六个整型元素的数组ar.
//int ar[] = {};error
int br[10];//定义一个未初始化的包含十个整型元素的数组br.
for (int i = 0 ; i < 10; i++) //利用循环对br进行赋值 { br[i] = i+1; }
!!注意:定义数组若未给定元素个数,则需要在{}内填入数据,否则将报错:如:int ar[] ;(error),正确写法应为 int ar[] = {1,2,3};
2.数组的元素的个数:
数组元素的个数可以通过(sizeof(ar)/sizeof(ar[0]))计算得到.其中sizeof(ar)为整个数组的大小,sizeof(ar[0])指的是数组元素类型的大小.
例:
int main() { int ar[] = { 1,2,2,2,2,2,2,23,2,3,2,1, }; int size = 0; printf("ar size = %d", sizeof(ar) / sizeof(ar[0])); return 0; }
运行结果:
3.数组的访问:
3.1 下标访问: ar[i] (下标访问时中括号外面的变量有可能是数组名,也有可能为指针 => i[ar])
3.2基地址访问: *(ar + i), i[ar]=>*(i+ar)
!!注意:1. 其中下标访问在编译链接过程会转化为指针访问 即基地址访问.
2. 在访问数组元素时 i 可以是变量,也可以是常量,但是必须是整型类型
例:
int main() { int ar[10] = { 1,2,3,4,5,6,7,8,9,10 };//定义一个包含十个整型元素的数组ar. printf("%d \n", ar[3]);//打印数组ar中下标为3的元素 => 4. printf("%d \n", *(ar + 3));//打印相对于数组ar首元素地址3个整型距离的元素 => 4. for (int i = 0; i < 10; i++)//定义一个变量依次打印ar中的每一个元素 { printf("%d ", ar[i]); } printf("\n"); return 0; }
运行结果:
4.数组名:
1. 除了在sizeof(ar) 以及 定义一个指向数组的指针int (*p)[2] = &ar 代表整个数组,在其他情况下,数组名会退化成指向数组首元素的地址的指针.此时无法对数组名进行加一以及赋值操作.
即此时数组名ar 作为数组首元素地址时是一个指针常量无法进行ar++或ar = ar+1等操作!,
例:代码如下:
int main() { Array ar = {1,2,3,4,5,6,7,8,9,10}; for (int i = 0; i < 10; i++) { printf("%d %d %d \n", ar[i], *(ar + i), i[ar]);//i[ar] 以及 ar[i] 在程序的编译过程会转化为 *(ar + i). } return 0; }
运行结果:
2. 在一个函数中,若是将数组传递给函数的形参,函数名会退化成一个指针.
代码:
#include<typeinfo> #include<stdio.h> using namespace std; typedef int Array[10]; void Fun(Array ar) { printf("%s \n", typeid(ar).name());//打印类型名 printf("%d \n", sizeof(ar));//打印字节大小 } int main() { Array ar = {}; Fun(ar); return 0; }
运行结果:
由此可见,数组名在向形参的传递过程会退化为指针.
二维数组:(二维数组本质上是由多个一维数组组成的)
1.数组的定义(二维数组): (类型名 数组名[行表达式][列表达式] = {} ) (在定义二维数组时,行表达式以及列表达式都必须是常量表达式)
例如:
int main() { char ch[3][4]; int ar[3][3]; double dr[3][4]; return 0; }
2.数组的初始化:对二维数组的初始化,第一维的长度是可以确省,第二维不可确省.
例如:
int main() { int ar[3][3]= {1,2,3,4,5,6,7,8,9}; int ar[][3]= {1,2,3,4,5,6,7,8,9}; //true int ar[3][]= {1,2,3,4,5,6,7,8,9}; //error return 0; }
3.二维数组元素的访问:
二维数组中的元素是通过下标(即行索引和列索引)来进行访问
例:
int main() { const int row = 3; const int col = 3; int ar[row][col] = {}; int k = 1; for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { ar[i][j] = k++; } } for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { printf("ar[%d][%d] = %d \n", i, j, ar[i][j]); } } return 0; }
运行结果:
4:二维数组在内存中的存储形式:是以行优先的方式存储的:
如:
int main() { int ar[3][3]= {1,2,3,4,5,6,7,8,9}; return 0; }
由下图可以看出 ar[0],ar[1],ar[2]分别为一个包含三个整型元素的一维数组:
同时可以看出一个二维数组是存储在一块连续的地址空间上.