5分钟深刻理解sizeof和strlen

一、sizeof和strlen是什么?

sizeof是运算符关键字不是函数,功能是返回一个变量或者类型的大小。
而strlen是库函数,函数求的是字符串的长度。

二、案例分析

在看下面的案例前先要理解下面几句话,才好进行下面案例的环节:
1.数组名单独放在sizeof()内部,数组名表示整个数组,计算的是整个数组的大小,单位是字节
2.&数组名,数组名表示整个数组,取出的是整个数组的地址
除上面2种情况之外,所有的数组名都是数组首元素的地址

Part 1

Part 1.1 sizeof在一维数组中的运用

	//1.一维数组
	int a[] = {
    
     1,2,3,4 };
	printf("%d\n", sizeof(a));         // sizeof(a)==16---数组名单独放在sizeof内部,计算的是数组总大小
	printf("%d\n", sizeof(a + 0));     // sizeof(a + 0)==4/8---a+0是第一个元素的地址
	printf("%d\n", sizeof(*a));        // sizeof(*a)==4---*a就是数组a的首元素
	printf("%d\n", sizeof(a + 1));     // sizeof(a + 1)==4/8---a+1是数组第二个元素的地址
	printf("%d\n", sizeof(a[1]));      // sizeof(a[1])==4---a[1]就是数组的第二个元素
	printf("%d\n", sizeof(&a));        // sizeof(&a)==4/8---&a是数组的地址,但是只要是地址就是4/8个字节
	printf("%d\n", sizeof(*&a));       // sizeof(*&a)==16---sizeof(*&a)==sizeof(a),计算的是数组总大小
	printf("%d\n", sizeof(&a+1));      // sizeof(&a + 1)==4/8---是一个地址,指向的是数组之后的空间
	printf("%d\n", sizeof(&a[0]));     // sizeof(&a[0])==4/8---是首元素地址
	printf("%d\n", sizeof(&a[0]+1));   // sizeof(&a[0] + 1)==sizeof(a[1])==4/8---是数组第二个元素的地址

Part 1.2 sizeof在二维数组

	//3.二维数组
	int a[3][4] = {
    
     0 };
	//printf("%p\n", &a[0][0]);
	//printf("%p\n", a[0]+1);
	//对于二维数组,数组名单独放在sizeof内部,数组名表示整个数组,计算的是整个数组的大小
	printf("%d\n", sizeof(a));            // sizeof(a)==48
	printf("%d\n", sizeof(a[0][0]));	  // sizeof(a[0][0])==4
	printf("%d\n", sizeof(a[0]));         // sizeof(a[0])==16---a[0]是第一行的数组名,第一行的数组名单独放在sizeof内部
	                                      // 计算的是第一行这个数组的总大小

	printf("%d\n", sizeof(a[0] + 1));     // sizeof(a[0] + 1)==4/8---arr[0]作为第一行的数组名,并没有单独放在sizeof内部
	                                      // 所以数组名相当于数组首元素的地址,就是第一行第一个元素的地址
	                                      // a[0]+1---是第一行第二个元素的地址
	
	printf("%d\n", sizeof(*(a[0] + 1)));  // sizeof(*(a[0] + 1))==4---第一行第二个元素的大小
	printf("%d\n", sizeof(a + 1));        // sizeof(a + 1)==4/8---a作为二维数组的数组名,并没有&,也没有单独放在sizeof内部
	                                      // 那么数组名a就是首元素(第1行)的地址
	                                      // 所以a+1,也就是第2行的地址

	printf("%d\n", sizeof(*(a + 1)));     // sizeof(*(a + 1))==16---第二行的大小 *(a+1)==a[1]
	printf("%d\n", sizeof(&a[0] + 1));    // sizeof(&a[0] + 1)==4/8---&arr[0]是第一行的地址,+1就是第二行的地址
	printf("%d\n", sizeof(*(&a[0] + 1))); // sizeof(*(&a[0] + 1))==16---计算的是第二行的大小
	printf("%d\n", sizeof(*a));           // sizeof(*a)==16---*a==*(a+0)==a[0]
	                                      // a是二维数组得到数组名,没有&,也没有单独放在sizeof内部
	                                      // 所以a是二维数组首元素的地址,就是第一行的地址
	                                      // *a就是第一行的大小

	printf("%d\n", sizeof(a[3]));         // sizeof(a[3])==16
	                                      // a[3] - 明确了类型就可以计算大小
	return 0;
}

Part 2

Part 2.1 sizeof与strlen在字符数组

	//2.1字符数组
	char arr[] = {
    
     'a','b','c','d','e','f' };
	printf("%d\n", sizeof(arr));         // sizeof(arr)==6---数组名arr,单独放在sizeof内部,计算的是数组总大小
	printf("%d\n", sizeof(arr + 0));     // sizeof(arr + 0)==4/8---arr是数组首元素的地址,地址就是4/8
	printf("%d\n", sizeof(*arr));        // sizeof(*arr)==1---*arr是数组首元素,计算的是首元素大小
	printf("%d\n", sizeof(arr[1]));      // sizeof(arr[1])==1---arr[1]数组的第二个元素
	printf("%d\n", sizeof(&arr));        // sizeof(&arr)==4/8---&arr虽然是数组的地址,但是只要是地址就是4/8个字节
	printf("%d\n", sizeof(&arr + 1));    // sizeof(&arr + 1)==4/8---&arr+1跳过了整个数组,指向了数组之后,但还是地址
	printf("%d\n", sizeof(&arr[0] + 1)); // sizeof(&arr[0] + 1)==4/8---&arr[0] + 1是第二个元素的地址


	printf("%d\n", strlen(arr));         // strlen(arr)==随机值---因为arr数组中原本没有'\0',就会在数组arr后继续找'\0'
	printf("%d\n", strlen(arr+0));       // strlen(arr + 0)==随机值
	//printf("%d\n", strlen(*arr));      // error,应该传递地址进去,而不是传字符进去
	//printf("%d\n", strlen(arr[1]));    // error,应该传递地址进去,而不是传字符进去
	printf("%d\n", strlen(&arr));        // strlen(&arr)==随机值
	printf("%d\n", strlen(&arr+1));      // strlen(&arr + 1)==随机值
	printf("%d\n", strlen(&arr[0]+1));   // strlen(&arr[0] + 1)==随机值

Part 2.2 sizeof与strlen在字符串

	//2.2字符串
	char arr[] = "abcdef";
	printf("%d\n", sizeof(arr));           // sizeof(arr)==7---计算的是arr数组的总大小
	printf("%d\n", sizeof(arr + 0));       // sizeof(arr + 0)==4/8---arr+0是数组arr的首元素地址
	printf("%d\n", sizeof(*arr));          // sizeof(*arr)==1---首元素大小
	printf("%d\n", sizeof(arr[1]));        // sizeof(arr[1])==1---arr第二个元素的大小
	printf("%d\n", sizeof(&arr));          // sizeof(&arr)==4/8---&arr是数组的地址
	printf("%d\n", sizeof(&arr + 1));      // sizeof(&arr + 1)==4/8---&arr+1跳过了整个数组,指向了数组之后,但还是地址
	printf("%d\n", sizeof(&arr[0] + 1));   // sizeof(&arr[0] + 1)==4/8---第二个元素地址

	//传给strlen()必须是地址,不是地址都是error
	printf("%d\n", strlen(arr));           // strlen(arr)==6
	printf("%d\n", strlen(arr + 0));       // strlen(arr + 0)==6
	//printf("%d\n", strlen(*arr));        // error
	//printf("%d\n", strlen(arr[1]));      // error
	printf("%d\n", strlen(&arr));          // strlen(&arr)==6
	printf("%d\n", strlen(&arr + 1));      // strlen(&arr + 1)==随机值	
	printf("%d\n", strlen(&arr[0] + 1));   // strlen(&arr[0] + 1)==5


	//2.3字符串
	char* p = "abcdef";
	printf("%d\n", sizeof(p));         // sizeof(p)==4/8---p就是个指针变量
	printf("%d\n", sizeof(p + 1));     // sizeof(p + 1)==4/8---p + 1是的地址
	printf("%d\n", sizeof(*p));        // sizeof(*p)==1---p是字符指针,*p访问一个字节
	printf("%d\n", sizeof(p[0]));      // sizeof(p[0])==sizeof(*p)==sizeof(*(p+0))==1
	printf("%d\n", sizeof(&p));        // sizeof(&p)==4/8---&p是地址
	printf("%d\n", sizeof(&p + 1));    // sizeof(&p + 1)==4/8---&p+1是指向p后边空间的地址
	printf("%d\n", sizeof(&p[0] + 1)); // sizeof(&p[0] + 1)==4/8---&p[0]+1就是第二个元素的地址

	printf("%d\n", strlen(p));         // strlen(p)==6
	printf("%d\n", strlen(p + 1));     // strlen(p + 1)==5
	//printf("%d\n", strlen(*p));      // error
	//printf("%d\n", strlen(p[0]));    // error
	printf("%d\n", strlen(&p));        // strlen(&p)==随机值
	printf("%d\n", strlen(&p + 1));    // strlen(&p + 1)==随机值
	printf("%d\n", strlen(&p[0] + 1)); // strlen(&p[0] + 1)==5

总结

  1. 数组名单独放在sizeof()内部,数组名表示整个数组,计算的是整个数组的大小,单位是字节
    2.1 &数组名,数组名表示整个数组,取出的是整个数组的地址除上面2种情况之外,所有的数组名都是数组首元素的地址
    2.2 sizeof操作符是计算操作数所占空间的大小,计算大小时,不在乎内存中放的值
    2.3 strlen()库函数—求【字符串】长度只使用于:字符串,字符数组,求长度的时候,只关注’\0’

猜你喜欢

转载自blog.csdn.net/weixin_47812603/article/details/113771351