1.题目一
#include "stdio.h" #include "string.h" int main() { char arr[] = "abcdef"; 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)); printf("%d\n", strlen(arr)); printf("%d\n", strlen(arr+0)); 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)); return 0; }
1.1 sizeof( arr )
单独的arr放在sizeof中代表的是整个数组大小,数组arr有abcdef六个元素,后面还有1个隐藏的\0,所以结果应该是7字节。
1.2 sizeof( arr + 0 )
而这里的并不是单独的arr放在sizeof里面,所以这里的arr代表首元素地址,arr+0依旧是首元素地址,既然是地址,就4/8字节。
1.3 sizeof( *arr )
*arr是对arr的解引用,arr是首元素地址,解引用后是首元素,也就是arr[0],数据类型是char,结果就是1个字节。
1.4 sizeof( arr[ 1 ] )
同理arr[1]是数组的第二个元素,数据类型是char,结果就是1字节。
1.5 sizeof( &arr )
&arr是取整个数组的地址,既然是地址,就是4/8字节。
1.6 sizeof( &arr + 1 )
&arr+1是取整个数组的地址,之后➕1,整个数组的地址就是首元素地址,这里的加一,是向后移动整个数组字节大小,但是&arr+1还是地址,所以4/8字节。
1.7 sizeof( &arr[ 0 ] + 1 )
&arr[0]+1,取出数组第一个元素地址加一,指向了第二个元素的地址,也就是&arr[1],既然是地址,就是4/8字节。
1.8 strlen( arr )
我们要记住strlen的实参必须是指针,而且只能是字符类型的,否则就会出现错误。
arr代表首元素地址,那么就是在首元素这里向后寻找\0,数组元素为abcdef,\0 在f后面,所以长度就是6个。
1.9 strlen(arr + 0 )
arr+0依旧是首元素地址,所以起始位置还是首元素地址,往后找\0,长度是6个。
1.10 strlen( *arr )
*arr是首元素,相当于arr[0],不是指针变量(地址),所以这个是错的。
1.11 strlen( arr[ 1 ] )
同理,这个也不是指针,也是错的。
1.12 strlen( &arr )
&arr 取出整个数组的地址,而整个数组的地址 == 数组首元素地址,所以起始位置还是首元素地址,那长度是6个。
1.13 strlen( &arr + 1 )
&arr+1 取出整个数组的地址 +1 就已经跳过了整个数组了,我们也因此跳过了\0,不知道下一个\0 的位置,所以结果是随机值。
1.14 strlen( &arr[0] + 1 )
&arr[0] + 1 取出数组第一个元素的地址➕1,也就是我们strlen函数从第二个元素的地址往后找\0,长度就是5
2.题目二
#include "stdio.h" #include "string.h" int main() { char *p = "abcdef"; printf("%d\n", sizeof(p)); printf("%d\n", sizeof(p+1)); printf("%d\n", sizeof(*p)); printf("%d\n", sizeof(p[0])); printf("%d\n", sizeof(&p)); printf("%d\n", sizeof(&p+1)); printf("%d\n", sizeof(&p[0]+1)); printf("%d\n", strlen(p)); printf("%d\n", strlen(p+1)); 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)); return 0; }
2.1 sizeof( p )
这里的p是一个指针变量,它代表的是这个字符串的首元素地址,所以是4/8字节。
2.1 sizeof( p + 1 )
p+1 ,就是该字符串第二个元素地址,结果是4/8字节。
2.1 sizeof( *p )
p是字符串首元素地址,解引用后是字符‘a’,是char类型,结果是1字节。
2.1 sizeof( p[0] )
p代表首元素地址,相当于数组名,所以p[0]就相当于第一个元素'a',是char类型,结果是1字节。
2.1 sizeof( &p )
取首元素地址的地址,是二级指针,依旧是地址,结果是4/8字节。
2.1 sizeof( &p + 1 )
取首元素地址的地址,加1,还是地址,结果是4/8字节,但是跳过的是1个字节,因为p的类型是char*。
2.1 sizeof( &p[0] + 1 )
其实咱们只要判断它的数据类型就行,这个依旧是指针,所以就是4/8字节。
2.8 strlen( p )
p是首元素地址,我们strlen的起始位置就是首元素地址,往后找\0,结果就是6。
2.8 strlen( p + 1 )
这个起始位置就是首元素地址往后一位,也就是字符‘b’的地址,往后找\0,结果就是5。
2.8 strlen( *p )
对p解引用,得到的就是字符'a',是char类型,而我们strlen函数需要的是字符指针,所以错误。
2.8 strlen( p[0] )
同理,p是首元素地址,相当于数组名,p[0]代表的是首元素--字符'a',所以传入的数据类型不匹配,是错误的。
2.8 strlen( &p )
这里的&p可就不是&arr一样的了,&p就是取出p的地址,而&arr是取整个数组地址。所以strlen的起始位置是p的地址,我们不知道p的地址是什么,所以结果应该是随机值。
2.8 strlen( &p + 1 )
同上只不过是加了1,加了一个指针变量大小的字节,也就是要跳过4/8字节,起始位置是&p往后加4/8字节。但是依旧不知道起始位置,所以还是随机值。
2.8 strlen( &p[0] + 1 )
这个就很容易看出来了,取的是首元素地址,加上一,往后跳一个字节,到了第二个元素地址,往后找\0,结果就是5。