这章感觉好难啊,放个别人的总结.
// 多维数组和指针
#include <stdio.h>
int main(void)
{
int zippo[4][2] = {
{
2, 4}, {
6, 8}, {
1, 3}, {
5, 7}};
/*
zippo[0]是一个整数大小对象的地址,而zippo是两个整数大小对象的地址。
因为(一个)整数和两个整数组成的数组开始于同一个地址,因此zippo和zippo[0]具有相同的数值。
验证:
输出也显示出二维数组zippo的地址和一维数组zippo[0]的地址是相同的,均为相应的数组
首元素的地址,它的值是和&zippo[0][0]相同的;
而且,*zippo也是一个指针,它与一维数组zippo[0](也是一个指针)的地址相同,证明了我的猜想!
*/
printf("===========首先验证第一条结论===========\n");
printf("zippo: \t\t%p\n&zippo[0]: \t%p\n", zippo, &zippo[0]);
printf("zippo[0]: \t%p\n&zippo[0][0]: \t%p\n",zippo[0],&zippo[0][0]);
printf("*zippo: \t%p\n&*zippo: \t%p\n", *zippo, &*zippo);
printf("\n");
/*
zippo所指向对象的大小是两个int,而zippo[0]所指向对象的大小是一个int
验证:
zippo[0]指向4字节长的数据对象。对zippo[0]加1导致它的值增加4。数组名zippo是包含
两个int数的数组的地址,因此它指向8字节长的数据对象。所以,对zippo加1导致它的值增加8。
*/
printf("===========然后验证第二条结论===========\n");
printf("zippo: \t\t%p\nzippo+1: \t%p\n", zippo, zippo+1);
printf("zippo[0]: \t%p\nzippo[0]+1: \t%p\n", zippo[0], zippo[0]+1);
printf("\n");
/*
*zippo也是一个指针,它与一维数组zippo[0](也是一个指针)的地址相同,它们指向同一个int变量
即zippo[0][0]
*zippo[0] = zippo[0][0]
**zippo = *zippo[0] = zippo[0][0](得证)
------------------------------------------------
分析*(*(zippo+2)+1)
zippo------------------第1个大小为2个int的元素的地址
zippo+2----------------第3个大小为2个int的元素的地址
*(zippo+2)-------------第3个元素,即包含2个int值的数组,因此也是其第1个元素的(int值)的地址
*(zippo+2)+1-----------包含2个int值的数组的第2个元素(int值)的地址
*(*(zippo+2)+1)--------数组第3行第2列int(zippo[2][1])的值
总结:更一般地,要表示单个元素,可以使用数组符号或指针符号;并且在这两种表示中即可以使用
数组名,也可以使用指针:
zippo[m][n] == *(*(zippo+m)+n)
*/
printf("===========最后验证第三条结论===========\n");
printf("*zippo: \t%p\nzippo[0]: \t%p\n", zippo, zippo[0]);
printf("*(zippo+1): \t%p\nzippo[1]: \t%p\n", *(zippo+1), zippo[1]);
printf("**zippo: \t%d\nzippo[0][0]: \t%d\n", **zippo, zippo[0][0]);
printf("*(*(zippo+2)+1)\t%d\nzippo[2][1]: \t%d\n", *(*(zippo+2)+1), zippo[2][1]);
return 0;
}
===========首先验证第一条结论===========
zippo: 0x7fff1c31a900
&zippo[0]: 0x7fff1c31a900
zippo[0]: 0x7fff1c31a900
&zippo[0][0]: 0x7fff1c31a900
*zippo: 0x7fff1c31a900
&*zippo: 0x7fff1c31a900
===========最后验证第三条结论===========
*zippo: 0x7fff1c31a900
zippo[0]: 0x7fff1c31a900
*(zippo+1): 0x7fff1c31a908
zippo[1]: 0x7fff1c31a908
**zippo: 2
zippo[0][0]: 2
*(*(zippo+2)+1) 3
zippo[2][1]: 3
// 指针的兼容性
#include <stdio.h>
int main(void)
{
/*
指针之间的赋值规则比数值类型的赋值更严格
举例说明:
*/
int n = 5;
double x;
int * pi = &n;
double * pd = &x;
x = n; // 不需要进行类型转换就直接把一个int数值赋给一个double类型的变量(隐藏的类型转换)
pd = pi // 编译时错误,原因:pd指向一个double类型的数值,pi指向一个int类型的数值
int * pt;
int (* pa) [3];
int ar1[2][3];
int ar2[3][2];
int **p2; // (指向int指针)的指针
pt = &ar1[0][0]; // pt为指向一个int数值的指针,ar1[0][0]是一个int数值的变量
pt = ar1[0]; // pt为指向一个int数值的指针,ar1[0]也为指向一个int数值的指针
pt = ar1; // pt为指向一个int数值的指针,ar1指向由3个int值构成的指针(非法)
pa = ar1; // pa指向由3个int值构成的数组,ar1也指向由3个int值构成的数组
pa = ar2; // pa指向由3个int</