在做这类题时有几个点需要注意
1. sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小
2.&数组名,这里的数组名表示整个数组,取出的是整个数组的地址
3. 除此之外的所有数组名都表示首元素的地址
4. 推荐先自己看一看做一做再来核对一下
5. 头文件的引用在各个代码块省略,放在最后的完整代码
目录:
一维数组
二维数组
完整代码
一.一维数组
1.整型数组int main()
{
int a[] = { 1,2,3,4 };
printf("%d\n", sizeof(a)); //16
printf("%d\n", sizeof(a + 0)); //4/8 - a+0是第一个元素的地址
printf("%d\n", sizeof(*a)); //4 - *a是数组的第一个元素,sizeof(*a)计算的是第一个元素的大小
printf("%d\n", sizeof(a + 1)); //4/8 - a+1计算的是第二个元素的地址,sizoef计算的是第二个元素地址的大小
printf("%d\n", sizeof(a[1])); //4 - 计算的是第二个元素的大小
printf("%d\n", sizeof(&a)); //4/8 - &a是数组本身的地址,故sizeof计算的是地址
printf("%d\n", sizeof(*&a)); //16 - 将地址解引用即为数组本身
printf("%d\n", sizeof(&a + 1)); //4/8 - 数组地址+1.跳过一个数组,即指向4后面
printf("%d\n", sizeof(&a[0])); //4/8 - 第一个元素地址
printf("%d\n", sizeof(&a[0] + 1));//4/8 - 第二个元素地址
return 0;
}
地址的大小为4/8,在32位系统时是4,在64位系统是8
2.字符数组
例一
int main()
{
char arr[] = { 'a','b','c','d','e','f' };
printf("%d\n", sizeof(arr));//6 数组的大小
printf("%d\n", sizeof(arr + 0));//4/8 a的地址+0 == a的地址
printf("%d\n", sizeof(*arr));//1 arr此时表示a的地址,解引用后为1
printf("%d\n", sizeof(arr[1]));//1 计算b的大小
printf("%d\n", sizeof(&arr));//4/8 数组的地址
printf("%d\n", sizeof(&arr + 1));//4/8 &arr为数组地址,加一后跳过一个数组
printf("%d\n", sizeof(&arr[0] + 1));//4/8 计算b的地址
return 0;
}
注意该数组内并没有‘\0’
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));//随机值-6
printf("%d\n", strlen(&arr[0] + 1));//随机值-1
return 0;
}
>strlen函数当读取到‘\0’时结束,而数组内部没有’\0’,会向下读取从而产生随机值
>strlen函数接收的参数类型为const char* str, *arr即为a本身,传给strlen以ASCII码表示,即97,产生错误,arr[1]为b,同理产生不了正确的值
>&arr+1即跳过了一个数组的地址,最后长度等于&arr - 6,即 随机值 - 6,&arr[0]+1是b的地址
//注意在运行的时候产生错误的结果记得注释掉
例二
int main()
{
char arr[] = "abcdef";
printf("%d\n", sizeof(arr));//7 数组最后一位是'\0'
printf("%d\n", sizeof(arr + 0));//4/8 首元素地址
printf("%d\n", sizeof(*arr));//1 a
printf("%d\n", sizeof(arr[1]));//1 b
printf("%d\n", sizeof(&arr));//4/8 arr地址
printf("%d\n", sizeof(&arr + 1));//4/8 跳过一个数组的地址
printf("%d\n", sizeof(&arr[0] + 1));//4/8 b地址
return 0;
}
此数组最后一位为‘\0’
int main()
{
char arr[] = "abcdef";
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
return 0;
}
根据例一的strlen的题可以较轻松的得出结果
另外&arr+1因为跳过了数组,只能向后随机找到’\0’,故产生随机值
例三
字符指针
int main()
{
char* p = "abcdef";
printf("%d\n", sizeof(p));//4/8 首元素地址
printf("%d\n", sizeof(p + 1));//4/8 b的地址
printf("%d\n", sizeof(*p));//1 a
printf("%d\n", sizeof(p[0]));//1 a
printf("%d\n", sizeof(&p));//4/8 p的地址
printf("%d\n", sizeof(&p + 1));//4/8 跳过p后的地址
printf("%d\n", sizeof(&p[0] + 1));//4/8 b的地址
return 0;
}
此时p指向a前面的地址
对于此类字符指针,p[0]等价于*(p+0)
下面一个简单的图示便于理解
int main()
{
char* p = "abcdef";
printf("%d\n", strlen(p));//6 a地址
printf("%d\n", strlen(p + 1));//5 b地址
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 b地址
return 0;
}
这一题相信经过前面的吸收已经没有什么大问题了,唯一需要注意的是&p和&p+1产生的随机值并没有不变的明确关系,由上图可知指针p所占用的4个字节不能确定是否含有‘\0’,唯一可以确定的是前者值一定大于后者。
二.二维数组
二维数组需要注意的点
1.二维数组的首元素就是第一行
>若a为数组,a[0]就是第一行数组名,可以看作是一个一维数组(以a[0][0]为首元素)
int main()
{
int a[3][4] = { 0 };
printf("%d\n", sizeof(a));//48 3*4*sizeof(int)
printf("%d\n", sizeof(a[0][0]));//4 第一行第一个元素
printf("%d\n", sizeof(a[0]));//16 第一行的大小
printf("%d\n", sizeof(a[0] + 1));//4/8 第一行第二个元素的大小
//解释:a[0]并不属于sizeof(数组)和&数组的情况,此时可以看过是第一行的一维数组,此时一维数组名即首元素的地址,+1成为第一行第二个元素的地址
printf("%d\n", sizeof(*(a[0] + 1)));//4 对第一行第二个元素的解引用
printf("%d\n", sizeof(a + 1));//4/8 第二行的地址
//解释:a并不属于sizeof(数组)和&数组的情况,作为第一行的地址,+1为第二行的地址
printf("%d\n", sizeof(*(a + 1)));//16 第二行的大小
//解释:a+1为第二行地址,解引用为第二行的大小/也可以将*(a+1)等价于a[1]
printf("%d\n", sizeof(&a[0] + 1));//4/8 第二行的地址
//解释:a[0]是第一行数组名,&a[0]为第一行地址,+1后为第二行地址,等价于sizeof(a+1)
printf("%d\n", sizeof(*(&a[0] + 1)));//16 第二行大小
//解释:将上一行的地址解引用
printf("%d\n", sizeof(*a));//16 第一行的大小
//a并不属于sizeof(数组)和&数组的情况,相当于首元素地址,解引用计算为第一行大小
printf("%d\n", sizeof(a[3]));//16 第四行的数组大小(假设存在)
//解释:sizeof()并不会计算其中的表达式,a[3]相当于一个int [4]类型,可以看作一维数组
return 0;
}
解释注释在对应的代码下面
三.完整代码
#define _CRT_SECURE_NO_DEPRECATE 1
#pragma warning(disable:4996)
#include <stdio.h>
#include <string.h>
//一维数组
//1.整型数组
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;
}
//2.字符数组
//例一
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));
}
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;
}
//例二
int main()
{
char arr[] = "abcdef";
printf("%d\n", siezof(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;
}
int main()
{
char arr[] = "abcdef";
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;
}
//例三 - 字符指针
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));
return 0;
}
int main()
{
char* p = "abcdef";
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;
}
//二维数组
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;
}
在运行的时候不要忘了将会产生错误的代码注释掉哦