1.数组
1.1 一维数组
- 数组定义
int a[10] = {1,2,3,4};
缺省时后面的元素自动赋值0
int a[ ] = {1,2,3,4};
对全部元素赋值,长度可以不给出 - 初始化为0
int nums[10] = {0};
char str[10] = {0};
float scores[10] = {0.0};
1.2 二维数组
- 数组定义
按行分段赋值:
int a[3][3]= {{1,2,3}, {4,5,6}, {7,8,9}};
按行连续赋值:
int a[3][3] = {1,2,3,4,5,6,7,8,9};
缺省赋值:
int a[3][3]= {{1}, {4}, {7}};
未赋值元素为0
对全部元素赋值,行数可以不给出:
`int a[][3] = {1,2,3,4,5,6,7,8,9}; - 初始化为0
char a[3][3]={0};
char a[3][3]; memset(a,0,sizeof(a));
1.3 字符串数组
字符串数组其实就是char类型的数组
- 定义及初始化
一维字符串数组
char str[10] = {0};
char str[10] = "abcd";
char str[] = "abcd";
char str[] = {"abcd"};
char str[10] = {'a','b','c','d'};
二维字符串数组
char a[][10]={"liming","xiaowang","haoge","yangguang"};
char *a[]={"liming","xiaowang","haoge","yangguang"};
以上两种定义不限制字符串个数,只限制长度,建议使用 - 注意点
1)定义完初始化
char str[10];
str = “abcd”;//这是错误的
只有定义时才能一次性赋值,定义完只能单个元素赋值
2)忽略字符串结束标志
字符串总是以’\0’作为结尾,是字符串结束符
“ ”
赋值时字符串会自动在末尾添加’\0’,但是逐个元素赋值时不会自动添加’\0’
'\0’占用一个字节的内存空间,定义时请预留1byte - scanf与gets区别
scanf()读取字符串以空格为分隔,遇到空格就认为字符串结束
gets()认为空格也是字符串一部分,只有遇到换行符才结束
2.数组指针
类型:int (*p)[n]
()优先级高,首先说明p是一个指针,指向一个长度为n的整型一维数组,也称为行指针
int a[3][4]={0};
int (*p)[4]; //定义一个数组指针,指向含4个元素的一维数组
p = a; //将二维数组首地址赋给p,也就是a[0]
p++; //该语句执行后,p跨过行a[0][]指向了a[1][]
错误示范:
char a[5] = {'a','b','c','d'};
char (*p1)[5] = a;
错在哪?这样理解,赋值语句左右两边类型一致,就会发现一边是数组,一边是数组指针
数组名代表数组首元素的地址,虽然和指向整个数组的地址值一致,但是含义不同。有以下两种改法:
char (*p1)[5] = &a;
取数组地址
char (*p1)[5] =char (*)[5] a;
强转成数组指针类型
3.指针数组
类型:int *p[n]
[]优先级高,首先说明它是一个数组,再由int *说明这是整型指针数组,它有n个指针类型的元素
int *p[3];
int a[3][4]={0};
for (i = 0; i < 3; i++)
{
p[i] = a[i]; //每一个指针指向了一个一维数组
}
错误赋值:p = a;
p是一个不可知的表示,只存在p[0] p[1] p[2] …
p++指向下一个数组元素,但是赋值需*p = a
数组中第i行j列的几种表示
*(p[i]+j)
*(*(p+i)+j)
(*(p+i))[j]
p[i][j]