sizeof针对不同输入的区别

转载于:https://blog.****.net/prokgtfy9n18/article/details/68962512

在数组运算前,先了解一下数组的解引用到底是怎么回事。

  1. #include <windows.h>
  2. #include <stdio.h>
  3. int main()
  4. {
  5. int arr[] = {1,2,3,4,5,6,7,8,9,0};
  6. printf("%d\n", *arr);
  7. system("pause");
  8. return 0;
  9. }


这段代码输出来的是什么呢?


sizeof针对不同输入的区别


由此可见,数组的数组名其实是数组首元素的地址。

那么,如果要访问一个数组中其他元素呢?

  1. #include <stdio.h>
  2. int main()
  3. {
  4. int arr[10] = {0};
  5. int i = 0;
  6. for(i=0; i<sizeof(arr)/sizeof(arr[0]); ++i)
  7. {
  8. printf("&arr[%d] = %p\n", i, &arr[i]);
  9. printf("%p\n", arr+i);
  10. }
  11. return 0;
  12. }

这里输出的是&arr[i]的地址,那么从arr[0]到arr[9]的地址能不能通过arr+i的方式打印出来呢?我们来看


                    sizeof针对不同输入的区别


观察结果我们发现,通过对数组名+整数的运算,其实可以获取到数组每个人元素的地址。这样我们就可以用指针访问我们的数组了。


看完一维数组的表示方式,下列关于数组的一些运算我们必须掌握。


//一维数组


int a[] = {1,2,3,4};


printf("%d\n",sizeof(a));  //16    数组的大小(4个元素,一个占4个字节)


printf("%d\n",sizeof(a+0));  //4   第一个元素的大小


printf("%d\n",sizeof(*a));  //4    数组的解引用,数组首元素的大小(int型)


printf("%d\n",sizeof(a+1));  //4   第二个元素的大小


printf("%d\n",sizeof(a[1]));  //4  第二个元素的大小


printf("%d\n",sizeof(&a));  //4    数组的地址大小都是4


printf("%d\n",sizeof(&a+1)); //4   这个数组的下一个数组的地址


printf("%d\n",sizeof(&a[0])); //4  首元素的地址


printf("%d\n",sizeof(&a[0]+1)); //4  第二个元素的地址


sizeof针对不同输入的区别



//字符数组


char arr[] = {'a','b','c','d','e','f'};

printf("%d\n", sizeof(arr));  //6      数组的大小(6个元素,一个占1个字节)


printf("%d\n", sizeof(arr+0));//4      首元素的地址


printf("%d\n", sizeof(*arr)); //1   数组的解引用,首元素的大(char型)


printf("%d\n", sizeof(arr[1]));//1   第二个元素的大小


printf("%d\n", sizeof(&arr)); //4   数组的地址是4


printf("%d\n", sizeof(&arr+1));//4   下个数组的首地址


printf("%d\n", sizeof(&arr[0]+1));//4  第二个元素的地址

sizeof针对不同输入的区别



printf("%d\n", strlen(arr)); //随机


printf("%d\n", strlen(arr+0));//随机
/*
printf("%d\n", strlen(*arr));//error
*/
/*printf("%d\n", strlen(arr[1]));*/ //error


printf("%d\n", strlen(&arr));//随机


printf("%d\n", strlen(&arr+1));//随机


printf("%d\n", strlen(&arr[0]+1));//随机


sizeof针对不同输入的区别


为什么在运算strlen 时会出现这么多随机数呢?不妨先来看看strlen的用法


它从内存的某个位置(可以是字符串开头,中间某个位置,甚至是某个不确定的内存区域)开始扫描,直到碰到第一个字符串结束符'\0'为止


sizeof针对不同输入的区别

而对于strlen(*arr),在对arr解引用求长度时,会自动将首元素的地址先用ASCII码值表示出了,然后向后查找,系统会一直查找下去(a的ASCII为97)


sizeof针对不同输入的区别


strlen(&arr)是对arr的地址求长度,而arr的地址里没'\n',所以他会一直找到'\n'才能停下了,会产生一个随机值


sizeof针对不同输入的区别

          

char *p = "abcdef";

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     指针的地址为4


printf("%d\n", sizeof(&p+1));//4 下个指针的地址


printf("%d\n", sizeof(&p[0]+1));//4 第二个元素的地址


sizeof针对不同输入的区别


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 从首元素地址开始找'\n',随机值

printf("%d\n", strlen(&p+1));//x 同上

printf("%d\n", strlen(&p[0]+1));//5第二个元素开始的长度


sizeof针对不同输入的区别

 

这里产生的错误和上面的strlen 一样会从首元素对应的ASCII值出查找,所以一样会出错。


//二维数组

int a[3][4] = {0};


printf("%d\n",sizeof(a));//48 整个数组的大小


printf("%d\n",sizeof(a[0][0]));// 4 第一个元素的大小


printf("%d\n",sizeof(a[0]));//16 第一行元素的大小(int型)


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 数组首元素(相当于第一行的大小)


printf("%d\n",sizeof(a[3]));//16 下个数组的首个元素(第一行)大小


sizeof针对不同输入的区别


接下来总结一下sizeof和strlen的区别:

sizeof:

1、sizeof的单位是字节

2、sizeof(数组名)表示整个数组的大小(和类型有关)

3、sizeof(&数组名)表示整个数组的地址(和类型无关)

4、sizeof(*数组名)表示数组首元素的大小

strlen:

1、strlen(数组名)表示数组的长度(如果是非字符串则会产生一个随机值)

2、strlen(*数组名)表示从首元素对应的ASCII开始找'\n',会出错

3、strlen(&数组名)表示从首元素的地址开始找'\n',直到找到'\n',会产生一个随机值

   结果和你想的一样吗?