数组在内存中是连续存储的。由低地址到高地址。
为了很好的管理内存,我们对内存进行了一个详细的编址。
结论:1.内存中的每一个内存单元(字节)对应一个地址。
2.在32位平台上指针的大小是4个字节,64位平台上是8个字节。
指针可以理解为一个变量,是一个专门用来存放地址的一个变量。
1.数组的数组名其实是数组首元素的地址。
2.数组名+整数的运算,其实可以获取到数组每个元素的地址。例如:arr+2;
3.二维数组在内存总的存储:二维数组在内存中也是连续存储的。
&arr[0][1] = arr[0]+1; &arr[1][1] = arr[1]+1;
&arr[0]+1 = &arr[1][0]; &arr[1]+1 = &arr[2][0];
&arr[0] = &arr[0][0]; &arr[1] = &arr[1][0];
数组的内存分配形式
char arr[] = "abc"; //‘a’'b' 'c' '\0'
char arr2[3] = {'a','b','c'}; //‘a’'b' 'c'
char* p = "abcdef"; //p中存放a的地址。
有关数组的运算:
**总结:sizeof(数组名),这里的数组名表示整个数组。
&数组名,这里的数组名表示整个数组。**
**(1)sizeof():返回值为unsigned int,该类型能保证能容纳实现所建立的最大对象的字节大小。其值在编译时就已计算好,参数可以是数组,指针,对象,函数等。由于在编译时计算,不能返回动态分配的内存空间大小。函数时返回类型所占空间的大小,返回类型不能是void。此操作符返回这个指针占的空间,一般是4个字节,而对于数组,返回这个数组所有元素占的总空间。
(2)strlen():运行时才计算,参数必须是字符型指针(char*),当数组名作为参数传入时,实际上数组就退化成指针了。strlen()函数的返回值类型为size_t (无符号整形),所以不能以他的返回值比较运算。不区分是指针还是数组,读到\0为止就返回,而且strlen不把\0计算在内**。
一维数组
int a[] = {1,2,3,4};
printf("%p\n",&a); //数组首地址
printf("%p\n",&a+1); //跳过整个数组的大小
printf("%p\n",&a[0]); //第一个元素的地址
printf("%p\n",&a[0]+1);//第二个元素的地址
printf("%p\n",a+1); //第二个元素的地址
printf("%d\n",sizeof(a)); //16
printf("%d\n",sizeof(a+0));//4 首元素地址。
printf("%d\n",sizeof(*a));//4
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+1));//4 数组地址加一跳过整个数组
printf("%d\n",sizeof(&a[0]));//4
printf("%d\n",sizeof(&a[0]+1));//4
字符数组
char arr[] = {'a','b','c','d','e','f'};
printf("%d\n", sizeof(arr));//6 sizeof(数组名)表示整个数组的大小
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第二个元素的地址
printf("%d\n", strlen(arr));//x19 随机数
printf("%d\n", strlen(arr+0));//x19 随机数
printf("%d\n", strlen(*arr));//error 不可以传一个值,必须是一个指针
printf("%d\n", strlen(arr[1]));//error
printf("%d\n", strlen(&arr));//x19
printf("%d\n", strlen(&arr+1));//x-6 13
printf("%d\n", strlen(&arr[0]+1));//x-1 18
字符数组
char arr[] = "abcdef";
printf("%d\n", sizeof(arr));//7 char*与char[]是不一样在sizeof中
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
printf("%d\n", strlen(arr));//6
printf("%d\n", strlen(arr+0));//6
printf("%d\n", strlen(*arr));//error
printf("%d\n", strlen(arr[1]));//error
printf("%d\n", strlen(&arr));// 6
printf("%d\n", strlen(&arr+1));//x 12 跳过整个数组,以\0计算结束
printf("%d\n", strlen(&arr[0]+1));//5 从第二个字符开始计算
char* p = "abcdef";
printf("%d\n", sizeof(p));//4 sizeof里传指针,是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
printf("%d\n", strlen(p));//6
printf("%d\n", strlen(p+1));//5
printf("%d\n", strlen(*p));//error
printf("%d\n", strlen(p[0]));//error
printf("%d\n", strlen(&p));//x 从指针的地址寻找, 随机地址查找
printf("%d\n", strlen(&p+1));//x*2
printf("%d\n", strlen(&p[0]+1));//5
二维数组
int a[3][4] = {0};
printf("%p\n",a);
printf("%p\n",a[0][0]);
printf("%p\n",a[0]);//第一行的首地址
printf("%p\n",a[0]+1); //第一行第二个元素地址
printf("%p\n",a+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 *&a =48, 数组首元素地址,也就是一维数组的第一个地址
printf("%d\n",sizeof(a[3]));//16 //编译器就以确定,不做运算。