/int main()
{
int a[] = { 1,2,3,4 };
printf("%d\n", sizeof(a));//16
此时a为数组名,当数组名直接放在sizeof内部时,sizeof(数组名)表示的时数组的大小
printf("%d\n", sizeof(a + 0));//4/8 个字节
a虽然为数组名,但a+0放在sizeof中,并不相当于sizeof(数组名),此时a表示&a[0],a+0表示&a[0]为一个指向数组首元素的指针,大小为4或8字节
printf("%d\n", sizeof(*a));//4
a是数组首元素的地址 - &a[0]
*a -> *&a[0] -> a[0],大小为4个字节
printf("%d\n", sizeof(a + 1));//4/8
a为数组首元素的地址&a[0] a+1即为&a[1],为指向数组第二个元素的指针,大小为4或8个字节
printf("%d\n", sizeof(a[1]));//4
printf("%d\n", sizeof(&a));//4/8
&a取出的是a这个数组的地址,也就是一个数组指针,无论什么指针,指针的大小总为4或8个字节
int(*p)[4]=&a;
printf("%d\n", sizeof(*&a));//16
*与&相互抵消,结果即为sizeof(a),即sizeof(数组名),大小为16
printf("%d\n", sizeof(&a + 1));//4/8
&a取出的是数组的地址,+1指向下一个数组,是数组指针,只要是指针,大小即为4或8个字节
printf("%d\n", sizeof(&a[0]));// 4/8
取出首元素的地址,即为一个指针大小为4或8
printf("%d\n", sizeof(&a[0] + 1));//第二个元素的地址
&a[0]+1即为&a[1],即指向第二个元素的指针,大小为4或8
return 0;
}
int main()
{
//字符数组
char arr[] = { 'a','b','c','d','e','f' };
注意,这种情况时数组就只有abcdef这六个字符,没有其它字符,并没有\0
printf("%d\n", sizeof(arr));//6
①.sizeof计算的是占用内存的大小,单位是字节,并不关注内存中到底存放的是什么
②.sizeof不是函数,是操作符
③.strlen是针对字符串的,求的是字符串的长度,本质上统计的是'\0'之前出现的字符个数
这里arr这个字符数组直接放入sizeof中,求得就是它的大小为6个字节
printf("%d\n", sizeof(arr + 0));//arr+0是数组首元素的地址 4/8
arr+0等同于&arr[0]+0即为&arr[0]即为一个指针指向字符数组的首元素,只要是指针大小就为4或8个字节
printf("%d\n", sizeof(*arr));//1
arr是&arr[0] *arr[0]就是arr[0],sizeof(arr[0])求的就是字符数组首元素的大小,为1个字节
printf("%d\n", sizeof(arr[1]));//1
字符数组第二个元素的大小,就是一个字节
printf("%d\n", sizeof(&arr));//4或8
&arr是一个指针,存放的是数组的地址
char(*p)[6]=&arr;
只要是指针无论大小均为4或8个字节
printf("%d\n", sizeof(&arr + 1));
&arr + 1跳过一个数组后的地址,4/8
printf("%d\n", sizeof(&arr[0] + 1));//4/8
&arr[0]+1即为&arr[1]
printf("%d\n", strlen(arr));//随机值
strlen传入的参数是一个地址,该函数的作用是统计这个地址之后到'\0'的字符个数
在sizeof(数组名)中,计算的是整个数组的大小,而在strlen(数组名)中,数组名则代表着首元素的地址传入strlen
由于以这种方式定义字符数组的结尾并非\0,因为不知道\0的位置,故不知道从数组首元素到'\0'有几个字符,所以结果为随机值
printf("%d\n", strlen(arr + 0));//随机值
与上题相同,arr+0还是&arr[0],所以结果仍为随机值
printf("%d\n", strlen(*arr));//非法访问
strlen的参数要是一个地址,但*arr的结果是*&arr[0]即为arr[0],也就是把'a'当做地址传入了,其的ASCII码值为97,故为非法访问
printf("%d\n", strlen(arr[1]));//非法访问
arr[1]的结果是字符'b',ASCII码值即为98,所以会把这个98当做地址来传入了,会造成非法访问
printf("%d\n", strlen(&arr));//随机值
其实传入&arr[0],传入&arr传入的都是同一个地址,故效果是一样的,都是随机值
printf("%d\n", strlen(&arr + 1));//随机值-6
&arr+1跳过的是6个字符,即跳过6个字节,所以会比传入&arr造成的随机值少6个字节
printf("%d\n", strlen(&arr[0] + 1));//随机值-1
&arr[0]+1跳过的是1个字节,所以会比传入&arr的随机值少1个字节
return 0;
}
3.char arr[] = "abcdef";
与char arr1[] = { 'a','b','c','d','e','f' }不同,其最后有'\0',相当于char arr1[] = { 'a','b','c','d','e','f','\0' };
printf("%d\n", strlen(arr));//6
在strlen(数组名)中,数组名就代表数组首元素的地址
printf("%d\n", strlen(arr + 0));//6
arr+0实际上就是&arr[0],与上一题相同
printf("%d\n", strlen(*arr));//err
在strlen中,arr可一视同仁为数组首元素地址&arr[0],故*arr即为*&arr[0]即为arr[0],把arr[0]即'a'的ASCII码值当做地址传入会造成非法访问
printf("%d\n", strlen(arr[1]));//err
与上一题相同,把ASCII码值当做地址非法传入
printf("%d\n", strlen(&arr));
&arr即为数组地址,而数组地址与数组首元素地址是相同的
printf("%d\n", strlen(&arr + 1));
&arr是一个数组指针 char(*)[],指向的是一个数组,其+1跳过的是一个数组的大小,因不知道下一个\0在哪,故结果为随机值
printf("%d\n", strlen(&arr[0] + 1));
&arr[0]+1即为&arr[1],所以从&arr[1]到'\0'共·5个元素
printf("%d\n", sizeof(arr));//7
因为数组内加上'0'有七个元素,故大小为7(sizeof只关心数组的大小)
printf("%d\n", sizeof(arr + 0));//4/8
arr+0即为&arr[0]是一个指针大小为4或8个字节
printf("%d\n", sizeof(*arr));// 1
*arr即为*&arr[0],*arr就是数组首元素
arr[0] *(arr+0)
int sz = sizeof(arr)/sizeof(*arr);
int sz = sizeof(arr)/sizeof(arr[0]);
printf("%d\n", sizeof(arr[1]));//1
printf("%d\n", sizeof(&arr));//数组的地址,是地址就是4 / 8
printf("%d\n", sizeof(&arr + 1));//4 / 8
printf("%d\n", sizeof(&arr[0] + 1));//4 / 8
return 0;
```4.
```c
char* p = "abcdef";
printf("%d\n", strlen(p));//6
因为p存放的是字符串变量首元素的地址,从字符串首元素的地址到'\0'共6个字符
printf("%d\n", strlen(p + 1));/ 5
p+1跳过一个char类型,故p+1存放的是'b'的地址
printf("%d\n", strlen(*p));//err
*p的结果是'a',将'a'的ASCII码值传入,即把97当做地址传入,形成非法访问
printf("%d\n", strlen(p[0]));//err
p[0]即 *(p+0) 即传入字符'a'与上一题相同,形成非法访问
printf("%d\n", strlen(&p));//随机值
![在这里插入图片描述](https://img-blog.csdnimg.cn/cd76ecee84004fbeace942153178c3f9.png)
printf("%d\n", strlen(&p + 1));//随机值
这个随机值与上一题的随机值并无关系,因为从&p到&p+1中可能存在'\0',结果不可预知
printf("%d\n", strlen(&p[0] + 1));//5
&p[0]+1即为&p[1],结果为5
printf("%d\n", sizeof(p));//4 / 8
p就是一个指针变量,它指向一个字符串常量,将字符串变量首元素的地址放入p中,故p的类型为字符指针
printf("%d\n", sizeof(p + 1));//'b'的地址,4/8
p是一个字符指针,对其+1跳过一个字符的大小,不过p+1还是指针,大小为4或8
printf("%d\n", sizeof(*p));//1
*p即对p解引用,得到的是'a'的大小即为1个字节
printf("%d\n", sizeof(p[0]));//*(p+0)--'a' 1
p[0]即为 *(p+0)即为'a'
printf("%d\n", sizeof(&p));//4或8
&p即为p的地址,大小为4或8,不过要注意p的地址跟这个字符串常量已经没关系了
因为p是一个指针,所以&p是个二级指针 char**a=&p;
printf("%d\n", sizeof(&p + 1));
&p跳过一个char*的大小,不过其还是指针,故大小还是4或8个字节
printf("%d\n", sizeof(&p[0] + 1));
&p[0]+1即为&p[1]即为&*(p+1)即为p+1是一个指向字符'b'的指针,还是一个指针,故大小为4或8
4. int a[3][4] = { 1,2,3,4,5,6,7,8,9,10,11,12 };
printf("%d\n", sizeof(a));//48
a这个二维数组的数组名单独放在sizeof内部,计算整个数组的大小
printf("%d\n", sizeof(a[0][0]));//4
第一行第一个元素,大小为4个字节
printf("%d\n", sizeof(a[0]));//16
**a[0] 第一行的数组名**,这时数组名单独放在sizeof内部了
计算的是数组的大小,单位是字节,16
printf("%d\n", sizeof(a[0] + 1));//4或8
a[0]虽然是数组名,但不是直接放在sizeof中的,a[0]+1等于&a[0][0]+1即为&a[0][1];
&a[0][1]是个指针指向第一行第二个元素
printf("%d\n", sizeof(*(a[0] + 1)));//4
结果为a[0][1]
printf("%d\n", sizeof(a + 1));//4或8
a作为二维数组的数组名并非单独放在sizeof内部,所以表示首元素的地址
二维数组的首元素是第一行,这里的a就是第一行的地址--- int (*)[4]
a+1即为 &a[0]+1即为 &a[1],即为第一行的地址,它其实是数组指针
printf("%d\n", sizeof(*(a + 1)));//16
*(a+1)-->a[1]
sizeof(a[1])a[1]是二维数组中的一维数组数组名,求得的是a[1]的大小
printf("%d\n", sizeof(&a[0] + 1));//4或8
&a[0]+1 即为&a[1]
printf("%d\n", sizeof(*(&a[0] + 1)));//16 a[1]
&a[0]+1即为&a[1]*&a[1]即为a[1]
printf("%d\n", sizeof(*a));//16 *a - 就是第一行
*a即为*&a[0]即为a[0]
printf("%d\n", sizeof(a[3]));//16
int a = 5;
short s = 11;
printf("%d\n", sizeof(s = a + 2));//2
printf("%d\n", s);//11
test.c-编译-链接-test.exe
sizeof中的表达式根本不会运算,故sizeof(s=a+2)根本不会运算,后面打印的s不会是a+2
由于s的类型就是short类型,故sizeof(short)就是2了,不会计算里面的值