一定要慢慢看!!!!否则你会疯掉
首先先简单介绍下sizeof和strlen,然后再通过数组的相关运算来对这两个运算有相应的认识。在刚开始看得时候肯定会感觉很绕,需要静下心来一点点理解才可以慢慢掌握。
①sizeof:计算对象所占的字节数。
②strlen:从内存的某个位置,开始数字符串的长度直到遇到第一个\0结束。
一:一维数组
#include<stdio.h>
#include<Windows.h>
int main()
{
int a[] = { 1,2,3,4 };
printf("%d\n", sizeof(a));
//16 数组名单独放在sizeof内部,输出数组长度,因为数组为int型,共四个元素,总大小即为4*4 =16
printf("%d\n", sizeof(a + 0));
//4 此时a是首元素地址,+i表示向后偏移指针指向元素类型的大小*i个字节
printf("%d\n", sizeof(*a));
//4 解引用首元素地址就是首元素,sizeof判断首元素的大小(整型)
printf("%d\n", sizeof(a + 1));
//4 首地址+1*4 即表示第二个元素,元素为int型,所以为4
printf("%d\n", sizeof(a[1]));
//4 第二个元素的类型大小
printf("%d\n", sizeof(&a));
//4 a为数组首地址,&a表示数组的地址
printf("%d\n", sizeof(*&a));
//16 &a表示数组的地址,再解引用就是整个数组,整个数组大小为4*4 = 16
printf("%d\n", sizeof(&a + 1));
//4 数组的地址+1 跳出数组仍然是个地址,一个地址四个字节
printf("%d\n", sizeof(&a[0]));
//4 第一个元素的地址的类型大小
printf("%d\n", sizeof(&a[0] + 1));
//4 第二个元素的地址类型大小
system("pause");
return 0;
}
运行结果:
二:字符数组
#include<stdio.h>
#include<Windows.h>
int main()
{
char arr[] = { 'a','b','c','d','e','f' };
//*************sizeof************
printf("%d\n", sizeof(arr));
//6 整个数组大小,六个char类型元素
printf("%d\n", sizeof(arr + 0));
//4 首元素地址,一个指针大小为4
printf("%d\n", sizeof(*arr));
//1 arr为首元素地址 *arr也就是第一个元素,类型为一个字节的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 b的地址
//*******************strlen*****************
printf("%d\n", strlen(arr));
//随机值 strlen判断字符串长度直到遇到\0才停止计数
printf("%d\n", strlen(arr + 0));
//随机值 和上一个值相同
//printf("%d\n", strlen(*arr));
//报错 *arr解引用找到首元素'a', =strlen(97)
//printf("%d\n", strlen(arr[1]));
//错误
printf("%d\n", strlen(&arr));
//随机值
printf("%d\n", strlen(&arr + 1));
//随机值
printf("%d\n", strlen(&arr[0] + 1));
//随机值
system("pause");
return 0;
}
运行结果
其中有两条语句由于运行后会报错所以注释掉,单独拿出来解释
printf("%d\n", strlen(*arr));
arr代表的是数组首地址,解引用后则表示数组第一个元素也就是 'a' ,'a'在ASCII中所对应的是97,括号内就等于变成了97,我们将一个错误的地址给了strlen,所以编译器就会报错当然也不能继续运行下去。
printf("%d\n", strlen(arr[1]));
这句话和上句也同样是错误的,arr[1]代表的是字符b,对应的是ASCII中的98,编译器默认98是一个地址,然而这是一个错误的地址,也同样会报错不能运行下去。三:二维数组
首先先简单介绍一下二维数组。比如 a[3][4] 在我们看来是一个三行四列的数组,但是在内存中则是连续的一段存储空间,下面用图解释和将二维数组每个元素内存地址打印出来,更方便观察:
接下来言归正传,来讨论二维数组的情况下sizeof和strlen的运算
#include<stdio.h>
#include<windows.h>
int main()
{
int a[3][4] = { 0 };
printf("%d\n", sizeof(a)); //48 整个数组大小,3*4*4=48
printf("%d\n", sizeof(a[0][0])); //4 第一个元素类型的大小
printf("%d\n", sizeof(a[0])); //16 a[0]可以看为第一行的大小,4*4
printf("%d\n", sizeof(a[0] + 1)); //4 第一行第二个元素 a[0][0] +1
printf("%d\n", sizeof(a + 1)); //4 第一行的地址+1 = 第二行
printf("%d\n", sizeof(&a[0] + 1)); //4 &a[0]取出的是第一行的地址,加一指向第二行第一个
printf("%d\n", sizeof(*a)); //16 第一行的大小
printf("%d\n", sizeof(a[3])); //16 只是求取大小并不访问空间
system("pause");
return 0;
}
由于二维数组我们可以看做是多个一维的组成,而每个一维数组中又是一个一维数组。sizeof括号中若只放数组名,则表示整个数组的大小;否则降级表示首元素的地址。例如sizeof (a + 1)我们可以这样理解:由于a不是单独放在括号内,所以表示首元素地址,而二维数组的首元素代表的是第一行的首地址,再加1则变为第二行;如果在数组名前再加上&,表示这个数组的地址。
如果看得一头雾水,那么就静下心再来几遍,并在电脑上进行调试,就会发现规律了