- 如何定义一个数组
- 数组如何在函数间传递
- 需要使用变量定义数组怎么办
- 二维数组与指针
如何定义一个数组
- 只做声明时而不初始化时,数组内元素乱七八糟
int数组定义
int a[5];
有趣的问题,做以下定义而未初始化时.我在Vscode上定义时查看地址内的值,一排false中出现了int值,如下图所示
bool a[10]
{ }内元素数目不能大于[ ]内,如下既定义又初始化,未初始化的会默认初始化
int a[5] = {0, 1};
此时a[4]为0
int a[5];
a[2] = 1;
此时a[4]可能是4199705(不确定的值)
int a[2] = {1, 2};
int b[] = a; 不允许使用一个数组初始化另一个数组
b = a; 不能把数组直接赋值给另一个数组
int *ptrs[10]; ptrs是含有10个整型指针的数组
int &refs[10] = /* ?*/; 错误:不存在引用的数组
int (*Parray) [10] = &arr; Parray指向一个含有10个整数的数组
int (&arrRef) [10] = arr; arrRef引用一个含有10个整数的数组
-
为什么不存在引用的数组?
引用可以理解为一个别名,它的地址就是原变量的地址.引用本身不占空间,如何放在有内存分配的数组里呢? -
复杂数组声明如何理解?
从右往左,高优先级到低优先级,然后再倒序.
int *(&array) [10] = ptrs;
引用 数组 指针
即指针的数组的引用,是ptrs这个存放十个指向整形的指针的数组的引用
定义和初始化string对象
拷贝初始化
string str = "abc";
直接初始化
string str("abc");
字符数组的初始化
列表初始化,不会自动添加空字符
char c1[] = {'C', '+', '+' };
char c2[] = {'C', '+', '+', '\0' };
char c3[] = "C++"; 自动添加表示字符串结束的空字符'\0'
- '\0'与""(双引号)等价.''(单引号)不合法
有趣的问题
接上所述
char c[] = {'a', 'b', 'c'} 不会自动添加空字符'\0'
char c[] = "C++"; 自动添加表示字符串结束的空字符'\0'
char c[] = "C++\0\0" 自动添加表示字符串借书的空字符'\0'
char c[] = "C++ "; 此时空格表示的为空格字符,ASCII码为32,而非空字符
'0' - ' ' 值为16,ASCII相减
"0" - " " 值为2
const char c0[2] = {'0', '\0'};
const char c1[2] = {' ', '\0'};
值是地址相减
指针与数组
string nums[] = {"one", "two", "three"}; 数组元素是string对象
以下两条表达式等价
string *p = &num[0];
string *p2 = nums;
int ia = {0, 2, 4, 6, 8};
int i = ia[2]; ia转换成指向数组首元素的指针,ia[2] 得到(ia + 2)所指的元素
对数组执行下标运算其实是对指向数组元素的指针执行下标运算
int *p = ia;
i = *(p + 2);
只要指针指向的是数组的元素(或者数组中微元素的下一位置),都可以执行下标运算,如下.
int *p = &ia[2];
int j = p[1]; ia[3]
int k = p[-2]; ia[0]
多维数组
建议将其看成数组的数组
定义
int ia[3][4];
初始化
int arr[10][20][30] = {0}; 将所有元素初始化为0
其实我觉得这一句话有一定的误导性,这是因为初始化默认为0,将第一个初始化为0后其余都为0,但是若是{1}这样,就只有第一个是1,其他都是0,而非将所有元素初始化为1.
初始化
int ia[3][4] = { // 三个元素,每个元素都是大小为4的数组
{0,1, 2, 3},//第1行的初始值
{4, 5,6,7},//第2行的初始值
{8,9,10,11}//第3行的初始值
};
//没有标识每行的花括号,与之前的初始化语句是等价的
int ia[3] [4] = {0,1,2,3, 4,5,6, 7,8, 9,10,11} ;
//显式地初始化每行的首元素
int ia[3][4] = {{ 0},{ 4},{ 8}};
//显式地初始化第1行,其他元素执行值初始化
int ia[3][4] = {0, 3,6,9};
int ia[3][4] ; 大小为3的数组,每个元素是含有4个整数的数组
int (*p)[4] = ia; p指向含有4个整数的数组
p = &ia[2] ; p指向ia的尾元素,即第2行(基0),
int (*p)[4] = ia
p = &ia[2]
其中ia是int (*)[4] 的行指针,指向(或者说值为)数组行首元素的地址,以行为单位步进
所以以下赋值错误
int *p = ia;
int iv[2][2][2] = {1,2,3,4,5,6,7,8};
以下赋值错误,iv类型是int (*)[2][2]
int (*p)[2] = iv;
int (*p)[4] = ia;
p = &ia[2] ; &(*(ia + 2)) ia + 2 表示第三行的首元素地址
ia[2] *(ia + 2) (*ia[2] == [8,9,10,11])伪
需要使用变量定义的数组
动态数组
使用new 与 delete
对于内置数据类型元素的数组,必须使用()来显示指定程序执行初始化操作,否则程序不执行初始化操作:
int *pia = new int[10]; 每个元素都没有初始化
int *pia2 = new int[10] (); 每个元素初始化为0
类类型元素的数组,则无论是否使用(),都会自动调用其默认构造函数来初始化:
string *psa = new string[10]; 每个元素调用默认构造函数初始化
string *psa = new string[10](); 每个元素调用默认构造函数初始化
通过{ }来初始化
int *pb= new int[2 * 1]{1, 2, 3}; 编译时报错
int row = 1, col = 1;
bool *flag = new bool[row*col]{false, false}; 运行时报错
bool (*flag)[col] = new bool[row][col]{false}; 不能运行,(*flag)[col]中col必须为常量值
bool *flag = new bool[len]{false}; √
delete[] flag;动态数组删除要加[]
对于二维数组a,
其a[0]数组由a指向,a[1]数组则由a+1指向,a[2]数组由a+2指向,以此类推。
*a与a[0]等价、*(a+1)与a[1]等价、*(a+2)与a[2]等价,┅,
即对于a[i]数组,由*(a+i)指向。
对于数组元素a[i][j],用数组名a的表示形式为:
*(*(a+i)+j)
指向该元素的指针为:*(a+i)+j
数组在函数间的传递
int A(int a[]) {
}
int A(int a[9]) {
}
这样不能传递数组长度,实际还是传递了一个数组的指针.,需要还是*p 与n的形式比较好
二维数组传 T (*a)[n].a[i][j]即为数组值
网友评论