一、前言
我们已经知道数组名只有在两种特定的情况下才是表示的是整个数组
第一个情况就是:sizeof(数组名)-这里计算的是
第一个情况就是:&数组名
二、一维数组
printf("%d\n",sizeof(a));
printf("%d\n",sizeof(a+0));
我们sizeof(数组名)不等于sizeof(数组名+0),这时候数组名就是仅仅表示首元素的地址。
三、字符数组
1.关于strlen函数的几点注意
对于strlen函数:strlen()函数中的参数只能是地址,所以我们strlen(*arr)是非法访问。
这个非法访问是怎么样进行的呢?
对于代码:char arr[]={'a','b','c','d','e','f'}; strlen(*arr); *arr是对应的字符‘a’,字符无法直接存入计算机,存入的其实是字符的对应的ascii码值,字符a对于的ascii值为97
通过我们的代码运行,我们可以知道我们的猜想是正确的。
2.strlen函数出现的警告
strlen在头文件里面是strlen(const char* str)
char arr[]="abcdef";
printf("%d\n",strlen(&arr));
这个代码出现这个警告,首先我们知道strlen在头文件里面是strlen (const char* str)而我们&arr出来的是整个数组的地址,存放在数组指针里面int(*p)[7],它的类型是int(*)[7];两个内容是不兼容的
3.数组中‘*’的等效使用
int arr[10]; arr[0]==*(arr+0);
p[0]==*(p+0);
4.指针直接赋值字符串
指针直接赋值字符串,此个字符串为常量字符串,常量字符串我们是不能改变的,里面存储的是字符串首个字符的地址,*得出来的字符
四、二维数组
1.strlen函数的注意
记住strlen(地址),函数的参数只能是地址,从这个地址开始计算长度,遇到’\0’停止计算
2.二维数组的数组名
例如
int a[3][4]={0};
printf("%d\n",sizeof(a+1));
a是二维数组的数组名,没有sizeof(数组名),也没有&(数组名),所以a表示的是首元素的地址,而把二维数组看成一维数组时,二维数组的首元素就是它的第一行,a就是第一行(首元素)的地址
3.sizeof计算大小的方法
int a[3][4]={0};
printf("%d\n",sizeof(a[3]));
这个代码是并没有第四行的,但是我们仍然能够得到结果
如何理解呢?
sizeof是不会真实访问数组的,而是根据它的类型计算大小的
五、做类似题目的方法
1.分析这类题
这类题我们有指针,有不同类型的变量,因此我们分析代码题,在纸上把变量的内存存储情况画出来
2.用一个例题概括这种方法
#include<stdio.h>
int main()
{
char* c[] = { "ENTER","NEW","POINT","FIRST" };
char** cp[] = { c + 3,c + 2,c + 1,c };
char*** cpp[] = cp;
printf("%s\n", **++cpp);
printf("%s\n", *-- * ++cpp + 3);
printf("%s\n", *cpp[-2]+3);
printf("%s\n", cpp[-1][-1]+1);
return 0;
}
根据我们的理解思路画出图形:
1.创建c,cp,cpp三个变量
2.创建一个三维指针指向的是cp的首元素的地址
3.创建一个指针数组,指针数组中第一个指针指向c的最后一个元素的地址,第二个指针指向c的倒数第二个元素的地址,第三个指针指向c的第二个元素的地址,第四个指针指向c中首元素的地址。
特别注意:我们就进行了自增操作,这里的++cpp与cpp+1不同,++cpp可是会造成永久性的改变,所以cpp已经指向了第二个元素。再进行前置++操作,cpp指向第三个元素,此代码参考凉夏y的博客