字符串与数组

2020-05-07  本文已影响0人  李伟13

如何定义一个数组

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个整数的数组

定义和初始化string对象

拷贝初始化
string str = "abc";
直接初始化
string str("abc");
字符数组的初始化
列表初始化,不会自动添加空字符
char c1[] = {'C', '+', '+' };
char c2[] = {'C', '+', '+', '\0' };
char c3[] = "C++";    自动添加表示字符串结束的空字符'\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]即为数组值

https://blog.csdn.net/lizi_stdio/article/details/74502986
0

上一篇下一篇

猜你喜欢

热点阅读