sizeof,strlen的指针与数组使用,详细讲解!

  • Post author:
  • Post category:其他


文章目录



  • 一、



    sizeof与strlen的区别

  • 二、学前须知

  • 三、具体实例



    • 1


      .

      一维数组


    • 2.



      字符数组

    • 3.二维数组


  • 总结




一、strlen与sizeof的区别

  • sizeof为运算符 可以计算变量,类型,数组的大小,单位是字节。
  • strlen为函数,需要引头函数<string.h>,作用是获取字符串的长度,所以只可对字符串使用。

    size_t


    strlen(


    const


    char


    *


    string


    ),由此可见strlen的结果类型为char*。
  • sizeof在计算字符串大小时候会将’\0’计入大小,而strlen会自动去除’\0′
  • #include<stdio.h>
    #include<string.h>
    int main()
    {
    	char a[] = "abcdef";
    	printf("%d\n", sizeof(a));
    	printf("%d\n", strlen(a));
    	return 0;
    }

    由此可见sizeof未去除’\0’,strlen自动去除了’\0’。



二、学前须知

  1. sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小。
  2. &数组名,这里的数组名表示整个数组,得出的是整个数组的地址。
  3. 除此之外所有的数组名表示首元素的地址。
  4. sizeof(),括号内部的表达式不会进行计算

结果为

由此可见,s在sizeof内部并没有进行计算。


三、具体实例



1.一维数组

代码如下(示例):

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

结果为

  • 注意1与2的区别 sizeof(a)计算的是整个数组的大小,这其中的a表示的是整个数组

    而sizeof(a+0)计算的是a[1]的地址大小,这其中的a表示的首元素地址

    总的来说,数组只有单独出现的sizeof()中才表示为整个元素

  • 其中2 4 6 8 9 10计算的是指针的大小,根据不同位数的平台的大小不同,在32位平台中大小为4,在64位平台中大小为8

  • 其中第八组较为特殊,&a+1,&a表示整个数组的地址,以int a[5] ; &a+1;为例&a+1这个+1是在整个数组的维度上,所以&a+1是往后走了20个字节。而a+1则是往后走了一个字节。但是它终究只是个地址,所以sizeof结果仍然为4


2、字符数组


{‘a’,’b’,’c’,’d’,’e’,’f’}类型


sizeof

#include<stdio.h>
#include<string.h>
int main()
{
	char arr[] = { 'a', 'b', 'c', 'd', 'e', 'f' };
	printf("%d\n", sizeof(arr));
	printf("%d\n", sizeof(arr + 0));
	printf("%d\n", sizeof(*arr));
	printf("%d\n", sizeof(arr[1]));
	printf("%d\n", sizeof(&arr));
	printf("%d\n", sizeof(&arr + 1));
	printf("%d\n", sizeof(&arr[0] + 1));
	return 0;
}

结果为

因为char类型只占一个字节所以3 4答案为1


strlen

#include<stdio.h>
#include<string.h>
int main()
{
	char arr[] = { 'a', 'b', 'c', 'd', 'e', 'f' };
    //1.
	printf("%d\n", strlen(arr));
	//2.
    printf("%d\n", strlen(arr + 0));
	//3.
    printf("%d\n", strlen(*arr));
	//4.
    printf("%d\n", strlen(arr[1]));
	//5.
    printf("%d\n", strlen(&arr));
	//6.
    printf("%d\n", strlen(&arr + 1));
	//7.
    printf("%d\n", strlen(&arr[0] + 1));
	return 0;
}


重点来了,首先要搞清楚{‘a’,’b’,’c’,’d’,’e’,’f’}与”abcdef”的区别


{‘a’,’b’,’c’,’d’,’e’,’f’}数组在末尾结束时候不会自动添加’\0’收尾


相反”abcdef”在结尾时会自动添加’\0’收尾。

根据我们所学的知识可知strlen计算的大小的原理是指针碰到’\0’的地址时自动停止,由此有两种问题

  • strlen()内未传入指针,strlen要接受char*类型的参数,会产生错误
  • strlen()计算的字符串末尾未添加’\0’,这会导致strlen计算的值会为一个随机值。

所以我们在运行这段代码时要将第3、4组屏蔽掉。

其他所有组的结果都为随机值,因为没有在结尾添加’\0’。

第1,2,3组的结果相同,都为一个随机值。

其中第6组为随机值-6。因为&a+1在a数组的基础上向后移动了6个字节

第7组为随机值随机值-1


“abcdef”类型


sizeof

int main()
{
	char arr[] = "abcdef";
	//1
	printf("%d\n", sizeof(arr));
	//2
	printf("%d\n", sizeof(arr + 0));
	//3
	printf("%d\n", sizeof(*arr));
	//4
	printf("%d\n", sizeof(arr[1]));
	//5
	printf("%d\n", sizeof(&arr));
	//6
	printf("%d\n", sizeof(&arr + 1));
	//7
	printf("%d\n", sizeof(&arr[0] + 1));
	return 0;
}

具体参考上面的sizeof,唯一要注意的是”abcdef”类型在结尾添加了’\0’,因为sizeof不会自动去除”\0″所以第1组的结果是7而不是6

结果如下


strlen

int main()
{
	char arr[] = "abcdef";
	//1
	printf("%d\n", strlen(arr));
	//2
	printf("%d\n", strlen(arr + 0));
	//3
	printf("%d\n", strlen(*arr));
	//4
	printf("%d\n", strlen(arr[1]));
	//5
	printf("%d\n", strlen(&arr));
	//6
	printf("%d\n", strlen(&arr + 1));
	//7
	printf("%d\n", strlen(&arr[0] + 1));
	return 0;
}
  • 同样的第3、4组因为传的不是char*会报错
  • 第6组在数组a的基础上+1向后移动了6个字节,在这个过程中会将strlen自动补冲的’\0’略过,所以结果仍为随机值。
  • 第7组传的是a[1]的地址所以字符串长度会少一个a[0],结果为5

结果如下

3、二维数组

#include<stdio.h>
#include<string.h>
int main()
{
	int a[3][4] = { 0 };
	//1
	printf("%d\n", sizeof(a));//48
	//2
	printf("%d\n", sizeof(a[0][0]));//4
	//3
	printf("%d\n", sizeof(a[0]));//16
	//4
	printf("%d\n", sizeof(a[0] + 1));//4
	//5
	printf("%d\n", sizeof(*(a[0] + 1)));//4
	//6
	printf("%d\n", sizeof(a + 1));//4
	//7
	printf("%d\n", sizeof(*(a + 1)));//16
	//8
	printf("%d\n", sizeof(&a[0] + 1));//4
	//9
	printf("%d\n", sizeof(*(&a[0] + 1)));//16
	//10
	printf("%d\n", sizeof(*a));//16
	//11
	printf("%d\n", sizeof(a[3]));//16
	return 0;
}
  • 第1组,a表示整个数组,结果为4*整个数组元素个数,结果为48
  • 第2组,表示a[0][0]的地址,结果为4/8
  • 第3组,a[0]表示第一行数组的地址,结果为4*第一行元素个数,结果为16
  • 第4组,a[0]+1表示a[0][1]的地址,也就是第一行第二个元素的地址,结果为4/8
  • 第5组,同四组,解引用,结果为4
  • 第6组,a+1,a表示二维数组首元素的地址,即第一行的地址,a+1表示第二行的地址,结果为4
  • 第7组,同第6组,解引用,结果为16
  • 第8组,&a[0]为第一行数组的地址,&a[0]+1为第二行数组的地址,结果为4
  • 第9组,同第8组,解引用,结果为16
  • 第10组,因为a没有单独出现在sizeof中

    (伴随了一个*)

    ,所以此地方的a表示第一行的地址,*a解引用,结果为16.
  • 第11组,第11组看起来好像是错误的,但其实sizeof(),括号内的表达式是不进行计算的,不会进行访问的,所以最终结果仍然是16

    (其实就算a[]里面随便填个数,结果都是16)



结果为

结尾

小白新手之作,希望您看了这篇之后有所收获,本文还存在着瑕疵不足,有问题请您指出。谢谢观看!



版权声明:本文为qq_49923458原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。