刷题的基础
一.数组名是数组首元素的地址
但是有2个例外:
1. sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小,单位是字节
2. &数组名,这里的数组名表示整个数组,取出的是整个数组的地址
二.strlen
strlen是库函数,strlen函数参数的部分需要传一个地址。统计的是在字符串之前的字符个数,如果没有'\0'就会一直往后找。
题目的解析省略了单位字节。
1.一维数组
#include<stdio.h>
int main()
{
int a[] = { 1,2,3,4 };
printf("%d\n", sizeof(a));//
printf("%d\n", sizeof(a + 0));
printf("%d\n", sizeof(*a));
printf("%d\n", sizeof(a + 1));
printf("%d\n", sizeof(a[1]));
printf("%d\n", sizeof(&a));
printf("%d\n", sizeof(*&a));
printf("%d\n", sizeof(&a + 1));
printf("%d\n", sizeof(&a[0]));
printf("%d\n", sizeof(&a[0] + 1));
return 0;
}
解析:
(1)sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小,4*4=16
(2)不是sizeof(数组名),a是数组首元素的地址,a+0还是数组首元素的地址,地址的大小是4/8。
(3)a是数组首元素的地址,*a是首元素,int类型大小是4。
(4)a是数组首元素的地址,a+1是第二个元素的地址,地址的大小是4/8。
(5)a[1]是首元素,int类型大小是4。
(6)sizeof(*&a)==sizeof(a),16。
(7)&a表示整个数组,取出的是整个数组的地址,&a+1是跳过整个数组后的地址,地址的大小是4/8。
(8)&a[0]是数组首元素的地址,&a[0]+1是第二个元素的地址,地址的大小是4/8.
2.字符数组
1.
#include<stdio.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;
}
解析:
(1)数组名单独放在sizeof内部,这里的arr表示整个数组,计算的是整个数组的大小,单位是字节,总共6个字节。
(2)arr表示数组首元素的地址,arr+0还是数组首元素的地址,是地址就是4/8个字节。
(3)arr表示数组首元素的地址,*arr就是首元素,大小1个字节。
(4)/arr[1]就是第二个元素,大小是1个字节。
(5)&arr是数组的地址,但是数组的地址也是地址,是地址就是4/8。
(6)&arr + 1是跳过整个数组后的地址,是地址就是4/8个字节
(7)第二个元素的地址,是4/8个字节。
2.
#include<stdio.h>
#include<string.h>
int main()
{
char arr[] = { 'a','b','c','d','e','f' };
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)因为字符数组arr中没有\0,所以在求字符串长度的时候,会一直往后找,产生的结构就是随机值
(2)arr + 0是首元素的地址,和第一个一样,也是随机值
(3)err, arr是数组首元素的地址,*arr就是数组首元素'a'。strlen函数参数的部分需要传一个地址,当我们传递的是'a'时,'a'的ASCII码值是97,那就是将97作为地址传参.strlen就会从97这个地址开始统计字符串长度,这就非法访问内存了。
(4)与(3)同理,err。
(5)&arr是数组的地址,数组的地址和数组首元素的地址,值是一样的,那么传递给strlen函数后,依然是从数组的第一个元素的位置开始往后统计,也是随机值。
(6)也是随机值。
(7)&arr[0] + 1是第二个元素的地址。结果也是随机值
3.
int main()
{
char arr[] = "abcdef";//[a b c d e f \0]
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)6
(2)6
(3)err
(4)err
(5)6
(6)随机值
(7)5
因为和上题大同小异,不做过多解释。
4.
#include <string.h>
#include<stdio.h>
int main()
{
char arr[] = "abcdef";//[a b c d e f \0]
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;
}
解析:
(1)7
(2)arr + 0是首元素的地址,地址的大小是4/8。
(3)*arr其实就是首元素,1个字节 。(*arr--> *(arr+0) -- arr[0])
(4)arr[1]是第二个元素,1个字节。
(5)&arr是数组的地址,是地址就是4/8个字节。
(6)&arr + 1是跳过一个数组的地址,4/8。
(7)&arr[0] + 1是第二个元素的地址 4/8。
5.
#include<stdio.h>
#include<string.h>
int main()
{
char* p = "abcdef";
//[a b c d e f \0]
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;
}
解析:
(1)6
(2)5
(3)err
(4)err
(5)随机值
(6)随机值
(7)5
因为和以上例题大同小异,不做过多解释。
6.
#include<stdio.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));
//&p -- char**
printf("%d\n", sizeof(&p + 1));
printf("%d\n", sizeof(&p[0] + 1));
return 0;
}
解析:
(1)p是一个指针变量,大小就是4/8
(2)p+1是'b'的地址,是地址大小就是4/8个字节
(3)*p 就是'a',就是1个字节
(4)p[0]--> *(p+0) --> *p 1个字节
(5)4/8
(6)4/8
(7)4/8 , &p[0] + 1得到是'b'的地址
3.二维数组
#include<stdio.h>
int main()
{
int a[3][4] = { 0 };
printf("%d\n", sizeof(a));
printf("%d\n", sizeof(a[0][0]));
printf("%d\n", sizeof(a[0]));
printf("%d\n", sizeof(a[0] + 1));
printf("%d\n", sizeof(*(a[0] + 1)));
printf("%d\n", sizeof(a + 1));
printf("%d\n", sizeof(*(a + 1)));
printf("%d\n", sizeof(&a[0] + 1));
printf("%d\n", sizeof(*(&a[0] + 1)));
printf("%d\n", sizeof(*a));
printf("%d\n", sizeof(a[3]));
return 0;
}
解析:
(1)sizeof(数组名),这里的数组名表示整个数组,3*4*4 = 48。
(2)4
(3)a[0]是第一行这个一维数组的数组名。,数组名算是单独放在sizeof内部了,计算的是整个数组的大小,大小是16个字节。
(4)a[0]+1是第一行第二个元素的地址,是地址就是4/8个字节。
(5)计算的是就是第一行第2个元素的大小,是4个字节。
(6)a是数组首元素的地址,是第一行的地址 ,a+1 就是第二行的地址,是地址就是4/8个字节。
(7)*(a+1) --> a[1] , sizeof(*(a+1))->sizeof(a[1]) 计算的是第二行的大小,a+1 --> 是第二行的地址,*(a+1) 访问的第二行的数组,大小是16个字节。
(8)&a[0]是第一行的地址 ,&a[0]+1 是第二行的地址,是地址就是4/8个字节。
(9)访问的第二行的数组,大小是16个字节。
(10)*a --> *(a+0) --> a[0],一维数组的数组名,计算的是整个数组的大小,大小是16个字节。
(11)sizeof本质看的是()里的类型属性,a[3]--> int [4]类型,4*4=16。
以上为我个人的小分享,如有问题,欢迎讨论!!!