1.一维数组
2.字符数组
sizeof
strlen这个参数部分它要的是地址 如果你传一个元素 元素的ASCII码值被strlen读取
那么这是非法的
3.
4.
5.
abcdef是一个常量字符串
p是一个指针 因此它只可以存放4个字节的大小
因此在p中只能存放常量字符串首元素a的地址 地址一般为4个或8个字节 32位为4个字节 64位为8个字节
如图所示 内存布局
重点在第五 六 七 这三个
第五个 分析 p指向abcdef这个常量字符串 &p指向p 那么&p存放p的地址
它仍然是一个地址 那么sizeof(地址)==4或8字节
第六个 &p+1跳过整个p 但它仍然是一个地址
6.
7.二维数组
重点*
a[0]相当于第一行的数组名 数组名单独放在sizeof中 表示的是整个数组的大小
那么sizeof(arr[0])相当于是求第一行所有元素的大小 即是4*4=16个字节
当sizeof(arr[0]+1)时 arr[0]不是表示第一行的地址了 因为它没有单独存在到sizeof()中
这个arr[0]代表的是第一行的首元素地址
sizeof(a[3]) 分析
对于一个二维数组 给定一个a[3]表示第四行的地址
sizeof()这里计算的是一个类型 它并不关心你是否真实存在第四行 因为sizeof并不参与真实的计算的 所以这里a[3]会被当做a[0]即是二维数组第一行去计算大小 即是4*4=16个字节
8.
1.把地址强转成结构体指针类型 然后每次加一跳过结构体变量 20个字节的大小
0x00100000+0x1=0x00100000+20=0x00100014 十六进制
2.强制转化成长整型long的形式 每次加一 真的就是加一
0x00100000+0x1=0x00100001
3.同1 强制转化为整形指针类型 加0x1 跳过一个int类型的大小
结果为0x00100004
9.
本题的切入点在于 a的被强制类型转化为int整形 之后再加一 表示加一个字节
由于一个元素占据四个字节的空间大小 并且是小端存储
从左到右地址依次升高
如图 那么ptr2解引用 由于强制转化为int* 那么一次访问4个字节的大小 即是0x02000000
ptr[-1]=*(ptr-1) 同理被强制类型转化为整形指针类型 那么一次访问四个字节 即是0x00000004
10.
a[0]没有单独放在sizeof内部 也没有&
所以它代表第一行第一个元素的地址
逗号表达式 从左往右计算 并且结果是右边的那个数
那么相当于存储了1 3 5 其余位置默认为0
p[0]=*(p+0)=*(a[0])=1
11.
%p打印地址 默认-4的补码为1111111111111111111111111100 转化为16进制为0xfffffffc
%d打印结果为-4
两个地址相减结果就是两个地址之间的元素个数
a为一个二维数组 那么a表示第一行的地址
p=a相当于p一开始指向第一行的地址 即是指向首元素
p是一个数组指针类型 每一次加一 都相当于跳过4个元素大小的区域
p[4][2]=*(*(p+4)+2)
12.
aa为二维数组名
&aa时 取出的是整个二维数组的地址 那么&aa+1跳过整个二维数组 再把它赋给ptr2
由于强制类型转化为int*类型 那么减一跳过一个int类型的区域大小
aa 与&aa[0] 意义相同都是代表二维数组第一行的地址
那么*(aa+1)==aa[1] 由于这里的aa[1]前面没有& 也不是放在sizeof()里面
所以这里的aa[1]代表的是第二行首元素的地址
之后的步骤同前面差不多了 就这样吧
13.
p[1][2]==*(*(p+1)+2)==*(p[1]+2)
14.重点题型
首先我们得知 char**pa=a;
众所周知 *pa代表着它是一个指针 指向a char*代表着被指向对象a的类型
char*a[ ]是一个指针数组 数组元素类型是char*
我们可知 work at 等这三个字符串都是常量字符串
那么我们可知 这个指针数组中的char*类型的三个元素分别保存着这三个字符串首字符的地址
那么分别指向这三个字符
14.最后一题 硬核压轴
先写第一部分的解析吧
如何画出这个图 char***cpp *cpp代表cpp它是一个指针 指向cp 被指向的cp的类型是什么呢?是前面红色标记处 char** cp是一个二级指针数组它的元素都是二级指针类型 那么理所应当的指向一级指针数组c cp数组元素指向另外一个数组指针 这个数组指针 各个元素的内容即是相对应的常量字符串首元素的地址
1.cpp一开始指向c+3 先++指向c+2 c+2指向c中第三个元素的地址 第三个类型为char* 它包含着常量字符串POINT 首字符的地址 %s打印 打印结果是POINT
2.cpp是变化的 ++cpp 相当于cpp=cpp+1
cpp指向向下一个指向c+1 解引用得到c+1的内容
c+1的内容是第二个char*的地址
由于是得到了c+1的内容 是内容不是地址
然后-- 直接在内容上改 而不是直接改变它的指向
那么c+1-1=c 如图所示即可 所以这时候它指向第一个char*的地址
再解引用得到第一个char*的内容
这个内容是 常量字符串ENTER的首字符的地址
3.先转化一下 即等价于 *(*(cpp-2))+3
这里的-2 跟++ -- 这些不一样 它不会改变cpp的值 即是不改变cpp的指向位置 但确实改变了结果的值 即是cpp的指向不发生改变
所以原来指向c+1 减二之后指向c+3
但是cpp的指向是一直指向c+1的 因为cpp-2 不是一个表达式 而是一个结果变化而已
只有当cpp=cpp-2时 cpp的指向才会发生变化
4.同理 可转化成*(*(cpp-1)-1)+1