对于数组的学习要掌握这些基本的内容:
一.学会数组的定义和初始化的方式,包括一维数组,二维数组,三维四维等等。
1.char arr1[] = "abc";//4
2.char arr2[] = {'a', 'b', 'c'};//3
这两种初始化方式中第一个数组arr1中有4个元素,而arr2中只有3个元素,
因为使用字符串"abc"给arr1初始化会自动加上一个'\0',因此有四个元素。
二.数组中的下标操作符的活用,理解下标操作符的用法。
下面从下列代码中解析下标操作符的活用
//int main()
//{
// int arr[] = {1,2,3,4,5,6,7,8,9};
// int i = 0;
// //int *p = &arr[0];//和int *p = arr;的作用是一样的
// int *p = arr;//
// for(i=0; i<sizeof(arr)/sizeof(arr[0]); i++)//补充一个知识点,sizeof(arr)返回的是arr这个整个数组所占内存的大小
// sizeof(arr[0])代表数组中第一个元素的占内存大小,sizeof(arr)/sizeof(arr[0])
// 得到的就是元素的个数
// {
// printf("%d ", arr[i]);//因为数组arr[0]是第一个元素,所以arr[i]代表数组中第i+1个元素的值
// printf("%d ", i[arr]);//比较不常见的用法,与arr[i]一个意思
// printf("%d ", *(arr+i));//一维数组中的数组名是首元素的地址,因此arr也是一个指针类型,*(arr+i)代表第i+1个元素中的值
// printf("%d ", *(p+i));//代表第i+1个元素中的值
// printf("%d ", *(i+p));//代表第i+1个元素中的值
// printf("%d ", i[p]);//代表第i+1个元素中的值
// printf("%d ", p[i]);//代表第i+1个元素中的值
//
// }
总结:arr[i]等于*(arr+i),[]和*的功能都是把地址中的值拿出来,同时i[arr]等于arr[i],这个性质要记住。
三.数组名与数组的关系。
如果定义一个一维数组:
int a[2];
a的值等于&a[0]的值,a代表的是首元素的地址
&a的地址虽然与a和&a[0]相同,但是它代表的
整个数组的地址。
如果定义一个二维数组:
int a[2][2];
&a等于a和a[0]和&a[0][0]的值
但是&a的地址代表整个二维数组的地址
a代表第一排数组的地址,&a[0]与a是一个意思
a+1代表第二排地址的数组
a[0]代表第一排数组的首个元素的地址
a[0][0]代表第一排数组首个元素的值
四.数组中内存的储存方式。
如果定义一个二维数组
1.int a[2][2]={1,2,3,4};
是否可以按2中这样理解,把1中的数组看成2中的形式,aa0看成1中二维数组的第一排的元素,aa1看成1中二维数组的第二排元素。2.
int *a[2];
int aa0[2]={1,2};
int aa1[2]={3 , 4};
a[0]=aa0;//把第一排的数组中的首地址给指针类型数组a[0]
a[1]=aa1;//把第二排的数组中的首地址给指针类型数组a[1]
如果初始化值相同的话
在 2中的 *a代表 a[0], *a[0]又代表数组 aa0中的 首个元素 , 那么 *(*a)也代表 aar0首个元素的值
类比1中 *(*a)也代表第一排首个元素,好像二维数组可以如2中转化为一维数组来理解,但是实际上是不可以这样理解的,
因为定义一个二维数组后,实际内存中储存关系是连续的,而2中这样定义数组不一定是
连续的,因此不能这样去理解。五.函数中怎么调用数组。
int a[10];
void arraysUser(int *p)
{
...
}
要在arraysUser函数中使用数组a
arraysUser(a);//这样写即可,意思为把数组的首地址传给指针p,这样即把数组带入到函数中使用,在函数中
//可以改变数组的值,或者使用数组的值
六.strlen()和sizeof()对二维数组的用法的不同之处。
1. 数组名单独放在sizeof()内部,数组名表示整个数组sizeof(数组名)计算的是整个数组的大小,单位是字节
2. &数组名,数组名表示整个数组&数组名,取出的是整个数组的地址
3. 除此之外所有的数组名都表示首元素的地址
重点了解下面两个的输出结果:
//char arr[] = {'a','b','c','d','e','f'};
//printf("%d\n", strlen(&arr));//随机值
//printf("%d\n", strlen(&arr+1));//随机值
因为&arr的地址是整个数组的地址,那么&arr+1代表的是整个数组
的下一个储存单位的地址,也就是说&arr+1实际上是跳过了这个数组
4.补充一个知识点,如果
short s;
int a=1;
int b=1;
printf("%d\n",sizeof(s=a+b));
上述输出的结果为 2
为什么呢?
因为编译器在执行程序时 先编译->链接->产生执行文件
表达式在执行文件.exe文件中才会执行,而sizeof()在编译的时候
就已经执行,也就是说sizeof()执行时只提取了s的类型short来进行
运算,这也就是为什么sizeof(int)这总写法也是合法的了。
例题:下列输出的结果是什么,如果下面的你都能算对,说明对数组的掌握还不错
1.
//char arr[] = {'a','b','c','d','e','f'};
//printf("%d\n", strlen(arr));//随机值
//printf("%d\n", strlen(arr+0));//随机值
printf("%d\n", strlen(*arr)); //err
printf("%d\n", strlen(arr[1]));//err
//printf("%d\n", strlen(&arr));//随机值
//printf("%d\n", strlen(&arr+1));//随机值
//printf("%d\n", strlen(&arr[0]+1));//随机值
// printf("%d\n", sizeof(arr));//7
// printf("%d\n", sizeof(arr+0));//4
// printf("%d\n", sizeof(*arr));//1
// printf("%d\n", sizeof(arr[1]));//1
// printf("%d\n", sizeof(&arr));//4
// printf("%d\n", sizeof(&arr+1));//4
// printf("%d\n", sizeof(&arr[0]+1));
2.
// printf("%d\n",sizeof(a));//16
// printf("%d\n",sizeof(a+0));//4
// printf("%d\n",sizeof(*a));//4
// //*a == *(a+0) == a[0];
// //arr[i] ==> *(arr+i)
// printf("%d\n",sizeof(a+1));//4
// printf("%d\n",sizeof(a[1]));//4
// printf("%d\n",sizeof(&a)); //4
// printf("%d\n",sizeof(*&a)); //16
// printf("%d\n",sizeof(&a+1)); //4
// printf("%d\n",sizeof(&a[0]));//4
// printf("%d\n",sizeof(&a[0]+1));//4
3.
//printf("%d\n", strlen(arr));//随机值
//printf("%d\n", strlen(arr+0));//随机值
printf("%d\n", strlen(*arr)); //err
printf("%d\n", strlen(arr[1]));//err
//printf("%d\n", strlen(&arr));//随机值
//printf("%d\n", strlen(&arr+1));//随机值
//printf("%d\n", strlen(&arr[0]+1));//随机值
// printf("%d\n", sizeof(arr));//6
// printf("%d\n", sizeof(arr+0));//4
// printf("%d\n", sizeof(*arr)); //1
// printf("%d\n", sizeof(arr[1]));//1
// printf("%d\n", sizeof(&arr));//4
// printf("%d\n", sizeof(&arr+1));//4
// printf("%d\n", sizeof(&arr[0]+1));//4
4.
//char *p = "abcdef";
//printf("%d\n", strlen(p));//6
//printf("%d\n", strlen(p+1));//5
printf("%d\n", strlen(*p));//err
printf("%d\n", strlen(p[0]));//err
//printf("%d\n", strlen(&p));//随机值
//printf("%d\n", strlen(&p+1));//随机值
//printf("%d\n", strlen(&p[0]+1));//5
//int arr[3][4];
//*(*(arr+1)+0)
//*(*(arr)) = *(*(arr+0)+0)
// *arr = *(arr+0)
//printf("%d\n", sizeof(p));//4
//printf("%d\n", sizeof(p+1));//4
//printf("%d\n", sizeof(*p));//1
//printf("%d\n", sizeof(p[0]));//1
//printf("%d\n", sizeof(&p));//4
//printf("%d\n", sizeof(&p+1));//4
//printf("%d\n", sizeof(&p[0]+1));//4
5.
int a[3][4] = {0};
//
//int *p = a+1;
short s = 1;
int n = 10;
printf("%d\n", sizeof(s=n+1));//2
printf("%d\n", s);//
printf("%d\n", sizeof(int));
printf("%p\n", &a[0][0]);
printf("%p\n", &a[0]+1);
printf("%d\n",sizeof(a));//48
printf("%d\n",sizeof(a[0][0]));//4
printf("%d\n",sizeof(a[0]));//16
printf("%d\n",sizeof(a[0]+1));//4
printf("%d\n",sizeof(a+1));//4
printf("%d\n",sizeof(&a[0]+1));//4
printf("%d\n",sizeof(*a));//16//sizeof(*(a+0))
printf("%d\n",sizeof(a[3]));//
6.
//int arr[3][4] = {0};
//int *p = &arr[0][0];
//int *p = &arr;
//int(*p)[4];//
//sizeof()
//&arr
//char arr[] = {'a','b','c','d','e','f'};
//printf("%d\n", strlen(arr));//随机值
//printf("%d\n", strlen(arr+0));//随机值
printf("%d\n", strlen(*arr)); //err
printf("%d\n", strlen(arr[1]));//err
//printf("%d\n", strlen(&arr));//随机值
//printf("%d\n", strlen(&arr+1));//随机值
//printf("%d\n", strlen(&arr[0]+1));//随机值
// printf("%d\n", sizeof(arr));//6
// printf("%d\n", sizeof(arr+0));//4
// printf("%d\n", sizeof(*arr)); //1
// printf("%d\n", sizeof(arr[1]));//1
// printf("%d\n", sizeof(&arr));//4
// printf("%d\n", sizeof(&arr+1));//4
// printf("%d\n", sizeof(&arr[0]+1));//4
7.
//int a[] = {1,2,3,4};
//printf("%p\n", &a[0]);
//printf("%p\n", &a[0]+1);
//printf("%p\n", a);
//printf("%p\n", a+1);
//printf("%p\n", &a);
//printf("%p\n", &a+1);
总结 二维数组 int a[3][4]={0};
在sizeof()中 a单独出现代表整个二维数组
&a代表整个二维数组的地址
a+0 代表二维数组的第一排的地址
而 *(a+0)代表二维数组的第一排 ,a+0与*(a+0)的关系与 a与&a的关系类似
同时 *(a+0)等同于 a[0]
一维数组 int a[4]={0}中
在sizeof()里 a单独出现代表整个一维数组
a+0实际上代表一维数组中第一个元素的地址
*(a+0)代表第一个元素