sizeof和strlen在数组中的计算

数组在内存中是连续存储的。由低地址到高地址。

为了很好的管理内存,我们对内存进行了一个详细的编址。
结论: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  //编译器就以确定,不做运算。

猜你喜欢

转载自blog.csdn.net/niukeming/article/details/79598912