sizeof是一个关键字,求字符串所占的字节数。
- sizeof在计算变量所占空间大小时,括号可以省略,但是绝对不能sizeof int,这是错误的,可以在int前加unsigned,const等关键字,但是不能加sizeof,以下三种都是正确的;
- sizeof在编译的时候计算出来。
printf("%d\n", sizeof(int));
printf("%d\n", sizeof(a));
printf("%d\n", sizeof a);
strlen是一个函数,求字符串的长度,结束符\0之前的字符个数。
- 它的值在函数运行完后才求出来的
看一下下面几组练习:
**一维数组**
int a[] = { 1, 2, 3, 4 };
printf("%d\n", sizeof(a)); //16 sizeof(数组名)表示整个数组大小
printf("%d\n", sizeof(a + 0)); //4 首元素地址
printf("%d\n", sizeof(*a)); //4 首元素地址解引用拿到第一个元素1,int型
printf("%d\n", sizeof(a + 1));//4 首元素地址+1指向第二个元素地址
printf("%d\n", sizeof(a[1])); //4 第二个元素
printf("%d\n", sizeof(&a)); //4 取整个数组的地址,4个字节
printf("%d\n", sizeof(*&a)); //16 数组地址解引用访问整个数组
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 首元素地址解引用拿到第一个元素1,char型
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", sizeof(*&arr));//6 数组地址解引用访问整个数组
printf("%d\n", strlen(arr)); //随机值x
printf("%d\n", strlen(arr + 0)); //随机值x
printf("%d\n", strlen(*arr)); //错误,*arr取的是a的ASCII码值97,在去访问地址为97的这块空间,不允许访问
printf("%d\n", strlen(arr[1])); //错误,理由同上
printf("%d\n", strlen(&arr)); //随机值x
printf("%d\n", strlen(&arr + 1)); //随机值x-6
printf("%d\n", strlen(&arr[0] + 1));//随机值x-1
char arr[] = "abcdef";
printf("%d\n", sizeof(arr)); //7 表示整个数组大小 abcdef\0
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", sizeof(*&arr));//7 数组地址解引用访问整个数组
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)); //6 取首地址
printf("%d\n", strlen(&arr + 1)); //随机值
printf("%d\n", strlen(&arr[0] + 1));//5 从第二个元素数直到\0
char *p = "abcdef";
printf("%d\n", sizeof(p)); //4 p是一个指针
printf("%d\n", sizeof(p + 1));//4 第二个元素b的地址
printf("%d\n", sizeof(*p)); //1 p中存放了a的地址,解引用找到a,a是char类型的
printf("%d\n", sizeof(p[0])); //1 第二个元素大小,相当于*(p+0)
printf("%d\n", sizeof(&p)); //4 取指针变量p的地址
printf("%d\n", sizeof(&p + 1));//4
printf("%d\n", sizeof(&p[0] + 1));//4 取第二个元素的地址,即b的地址
printf("%d\n", strlen(p));//6 遇到\0停止
printf("%d\n", strlen(p + 1)); //5 p+1指向b这个元素,从b开始往后走遇到\0就停下
printf("%d\n", strlen(*p)); //错误
printf("%d\n", strlen(p[0])); //错误
printf("%d\n", strlen(&p));//随机值
printf("%d\n", strlen(&p + 1));//随机值
printf("%d\n", strlen(&p[0] + 1));//5 第一个元素地址+1指向第二个元素地址,从b开始往后走遇到\0就停下,跟strlen(p + 1)同理
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 a[0]第一行数组的大小
printf("%d\n", sizeof(a[0] + 1)); //4 第一行数组第二个元素的地址
printf("%d\n", sizeof(a + 1)); //4 降级为首元素地址(第一行地址)跳过16个字节到第二行的地址
printf("%d\n", sizeof(&a[0] + 1)); //4 第二行地址
printf("%d\n", sizeof(*a)); //16 降级为首元素地址(第一行地址)解引用
printf("%d\n", sizeof(a[3]));//16 sizeof()内部表达式不计算,数组名单独放在sizeof内部跟第一行数组大小一样还是16个字节
以下三点要好好记住并理解含义:
1.sizeof(数组名)————数组名表示整个数组,求整个数组大小,单位:字节
2.&数组名————取整个数组的地址
3.除此之外,所有遇到的数组名都是首元素地址
strlen(arr),参数是地址,从这个地址往后找遇到\0停止。