sizeof和strlen的区别
sizeof(): 是求字节大小的,但是是在编译期间看表达式的结果将来会是什么类型
数组名只有处于以下两种情况时才代表整个数组:
①数组名单独在sizeof内时。② &数组名(如&a)
strlen是函数,只能以char*(字符串)做参数。而且,要想得到的结果正确必须包含 ‘\0’(通过strlen的实现得知)。
而strlen是在运行的时候才开始计算结果,这是计算的结果不再是类型所占内存的大小,数组名就退化为指针了。
一维数组
//一维数组
int a[] = { 1, 2, 3, 4 };
printf("%d\n", sizeof(a)); //16
//sizeof(a)中,a代表整个数组
printf("%d\n", sizeof(a+0));//4
//a+0已经发生运算,代表a[0]的地址
printf("%d\n", sizeof(*a)); //4
//*a数组名代表数组首元素的地址,解引用代表元素1的字节大小
printf("%d\n", sizeof(a + 1));//4
//代表数据2的地址
printf("%d\n", sizeof(a[1])); //4
//a[1]代表数据2的地址
printf("%d\n", sizeof(&a));//4
//&a代表整个数组的地址
printf("%d\n", sizeof(*&a));//16
// &a代表整个数组的地址,解引用后代表整个数组的字节大小
printf("%d\n", sizeof(&a + 1));//4
//跳过整个数组的元素的地址
printf("%d\n", sizeof(&a[0]));//4
//数组首元素的地址
printf("%d\n", sizeof(&a[0] + 1));//4
//数据2的地址,指针加减数字也是指针,占4个字节
字符数组
//字符数组
char arr[] = {'a','b','c','d','e','f'};
printf("%d\n", sizeof(arr));//6
//整个数组的大小
printf("%d\n", sizeof(arr+0));//4
//字符'a'的地址
printf("%d\n", sizeof(*arr));//1
//指针解引用,得到字符'a'
printf("%d\n", sizeof(arr[1]));//1
//字符'b'的大小
printf("%d\n", sizeof(&arr));//4
//取地址,数组arr的地址
printf("%d\n", sizeof(&arr+1));//4
//指针加减指针还是指针
printf("%d\n", sizeof(&arr[0]+1));//4
//指针加减指针还是指针
printf("%d\n", strlen(arr));//随机值
//arr代表数组名,代表数组首元素地址。
//strlen是函数,只能以char*(字符串)做参数。而且要想得到的结果正确必须包 //含‘\0’,所以它就会一直找\0,直到随缘出现为止,
printf("%d\n", strlen(arr + 0));//随机值
printf("%d\n", strlen(*arr));//语法错误 char*
printf("%d\n", strlen(arr[1]));// 语法错误
printf("%d\n", strlen(&arr)); //语法错误 数组指针
printf("%d\n", strlen(&arr + 1));//语法错误 数组指针
printf("%d\n", strlen(&arr[0] + 1));//随机值-1
//指针+1,会从b开始算,但找不到\0,所以取随机值-1,否则就是数组长度-1
char arr[] = "abcdef";
printf("%d\n", sizeof(arr));//7
//sizeof计算的是分配空间的实际字节数。字符串默认有\0
printf("%d\n", sizeof(arr + 0));//4
//字符'a'的地址,存地址的指针变量大小是4
printf("%d\n", sizeof(*arr));//1
//*arr代表字符'a'
printf("%d\n", sizeof(arr[1])); //1
//代表字符'b'
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)); //语法错误
//printf("%d\n", strlen(arr[1]));//语法错误
//printf("%d\n", strlen(&arr));// 语法错误
//printf("%d\n", strlen(&arr + 1)); //语法错误
printf("%d\n", strlen(&arr[0] + 1));//5
char* p = "abcdef";
//p存的地址是数组首元素的地址,即&a
printf("%d\n", sizeof(p)); //4
//p是指针类型的变量
printf("%d\n", sizeof(p+1)); //4
//指针相加减还是指针
printf("%d\n", sizeof(*p)); //1
//解引用得到a,a占一个字节
printf("%d\n", sizeof(p[0])); //1
//p[0]即取值为a,数组第0个元素
printf("%d\n", sizeof(&p)); //4
//二级指针本质上也是一级指针,占4个字节
printf("%d\n", sizeof(&p+1)); //4
printf("%d\n", sizeof(&p[0]+1));//4
printf("%d\n", strlen(p)); //6
//strlen以'\0'结尾,但并不将它计数
printf("%d\n", strlen(p+1)); //5
//指针+1也就是从b开始计数,有5个数
//printf("%d\n", strlen(*p)); //
//printf("%d\n", strlen(p[0])); //
//不能对一个字符使用strlen函数
printf("%d\n", strlen(&p)); //随机值
printf("%d\n", strlen(&p+1)); //随机值
//上面两个都是取随机值,第一个是个二级指针,指向的不是这个字符数组
//第二个是二级指针+1指向的不是这个字符数组
printf("%d\n", strlen(&p[0]+1));//5
//取p[0]的地址,+1得到&p[1],从这开始算字符串长度为5
return 0;
}
二维数组
int a[3][4] = {0};
printf("%d\n",sizeof(a)); //48
//sizeof(数组名)代表整个数组
printf("%d\n",sizeof(a[0][0]));//4
//a[0][0]代表第一行第一列的元素
printf("%d\n",sizeof(a[0])); //16
//a[0]代表第一行的数组名
printf("%d\n",sizeof(a[0]+1)); //4
//(a[0]+1)代表a[0][1]的地址
printf("%d\n",sizeof(*(a[0]+1))); //4
//(*(a[0]+1))代表 a[0][1]的内容
printf("%d\n",sizeof(a+1)); //4
//a+1代表的是第二行的地址
printf("%d\n",sizeof(*(a+1))); //16
//*(a+1)代表第二行的内容
printf("%d\n",sizeof(&a[0]+1)); //4
//&a[0]+1代表第二行首元素的地址
printf("%d\n",sizeof(*(&a[0]+1))); //16
//*(&a[0]+1)代表第二行的内容
printf("%d\n",sizeof(*a)); //16
//*a,解引用,代表第一行的内容
printf("%d\n",sizeof(a[3]));//16
//*(a+3) a+3的类型是数组指针
总结: 数组名的意义:
- sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小。
- &数组名,这里的数组名表示整个数组,取出的是整个数组的地址。
- 除此之外所有的数组名都表示首元素的地址。