C语言指针进阶学完指针必看练习题详解-创新互联
该篇与上篇衔接
创新互联"三网合一"的企业建站思路。企业可建设拥有电脑版、微信版、手机版的企业网站。实现跨屏营销,产品发布一步更新,电脑网络+移动网络一网打尽,满足企业的营销需求!创新互联具备承接各种类型的成都网站设计、成都做网站项目的能力。经过10年的努力的开拓,为不同行业的企事业单位提供了优质的服务,并获得了客户的一致好评。二维数组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
//a[0]就可以理解为 第一行数组名
//sizeof(a[0])数组名a【0】单独放在sizeof内部 a【0】表示整个第一行
//sizeof(a[0])计算的就是第一行的大小
printf("%d\n", sizeof(a[0]+1));//4/8 符合sizeof规则第三条 所以他叔第一行第一个元素的地址
printf("%d\n", sizeof( * (a[0] + 1)));//4 第一行第二个解引用 , 的到元素
printf("%d\n", sizeof(a+1));//4/8 对于二维数组来说 首元素就是第一行
printf("%d\n", sizeof(*(a+1)));//16 *(a+1)->a[1]
printf("%d\n", sizeof(&a[0]+1));// 4/8
printf("%d\n", sizeof(*(&a[0] + 1)));// 16
printf("%d\n", sizeof(*a));// 16 a是代表整个数组 *a 代表的是对第一行解应用 得到的是第一行的数组
printf("%d\n", sizeof(a[3]));//16 既然a[3]存在它的类型就是int()[4] 假象他是一个第四行
return 0;
}
int main()
{short s = 5;
int a = 4;
printf("%d", sizeof(s = a + 6));//2 最后的结果由short而定 short2个字节。sizeof内部表达式不参与运算
printf("%d", s);//5
return 0;
}
第三个解析
int main()
{int a[5] = {1, 2, 3, 4, 5 };
int *ptr = (int *)(&a + 1);
printf( "%d,%d", *(a + 1), *(ptr - 1));
return 0; //第一个打印:a的地址没变 指向一 加一指向2的地址
}
//程序的结果是什么?
//2 5
解析
//由于我还没介绍过结构体,这里告知结构体的大小是20个字节
struct Test
{int Num;
char* pcName;
short sDate;
char cha[2];
short sBa[4];
}*p;
//假设p 的值为0x100000。 如下表表达式的值分别为多少?
//已知,结构体Test类型的变量大小是20个字节
int main()
{ printf("%p\n", p + 0x1);//相当于p+1 加1跳过一个类型 结构体类型20个字节直接跳过所以是加20 0x100000+20=0x100014 4成16的0次方。。。
printf("%p\n", (unsigned long)p + 0x1);//0x100001 正数加1就是1 不跟指针一样
printf("%p\n", (unsigned int*)p + 0x1);//0x100004 +4 一个整形字节
return 0;
}
int main()
{int a[4] = {1, 2, 3, 4 };
int* ptr1 = (int*)(&a + 1);
int* ptr2 = (int*)((int)a + 1);// a转化为整形 一个整形4个字节 加1是加一个字节
printf("%x,%x", ptr1[-1], *ptr2);
return 0;
}
%x打印打印16进制 只打印有效数组所以结果为4 2000000
#includeint main()
{int a[3][2] = {(0, 1), (2, 3), (4, 5) };
int* p;
p = a[0];
printf("%d", p[0]);
return 0;
}
解析
#includeint main()
{int a[3][2] = {(0, 1), (2, 3), (4, 5) };//用了小括号表示是逗号表达式 相当于就放了{1,3,5}第一行放了1 3 第二行5 0 第三行00
int* p;
p = a[0];//没有& 也没放在sizeof内部 所以他代表首元素地址 1 放到了整形指针
printf("%d", p[0]);//结果1 *(p+0)
return 0;
}//a[0]表示第一行,然后没有&,也没有sizeof,所以是首元素,加起来就是a[0]这一行的首元素
int main()
{int a[5][5];
int(*p)[4];
p = a;//int (*)[5]
printf("%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);
//?
return 0;
}
int main()
{int a[5][5];
int(*p)[4];
p = a;//int (*)[5]
printf("%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);
//&p[4][2] 可以理解为 (*(p+4)+2) 解引用相当于从当前位置访问一个数组 刚好int四个 然后加2
return 0;
}
**结果FFFFFFFC,4 **
C是12
//&p[4][2] 可以理解为 (*(p+4)+2) 解引用相当于从当前位置访问一个数组p[4] 刚好int四个 然后加2
指针-指针 得到指针见的元素个数
因为地址由低到高变化小地址减去大地址所以是-4
-4以%d打印就是-4 认为内存里放的有符号整数 以%p打印认为内存里是个地址 所以将地址补码直接拿出来 因为%p所以以16进制书写 4个1是一个f如下
- 4 写到内存就是
10000000000000000000000000000000100
111111111111111111111111111111111111011
111111111111111111111111111111111111100
int main()
{int aa[2][5] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int* ptr1 = (int*)(&aa + 1);
int* ptr2 = (int*)(*(aa + 1));
printf("%d,%d", *(ptr1 - 1), *(ptr2 - 1));
return 0;
}
int main()
{int aa[2][5] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int* ptr1 = (int*)(&aa + 1);//10 赋给ptr1的时候他就是个整形了 下面的-1是减去一个整形 所以打印10
int* ptr2 = (int*)(*(aa + 1));//5 对第二行解引用拿到第二行 拿到第二行相当于拿到数组名。可以写成aa[1] 他就是6的地址 本身是个整形在解引用整形无意义
printf("%d,%d", *(ptr1 - 1), *(ptr2 - 1));
return 0;
}
#includeint main()
{char* a[] = {"work","at","alibaba" };
char** pa = a;
pa++;
printf("%s\n", *pa);
return 0;
}
int main()
{char* a[] = {"work","at","alibaba" };//数组名表示首元素地址 首元素地址表示char*
char** pa = a;//相当于pa指向第一个的char*
pa++;//指向“at”的char* pa指向数组,+1指向下一个元素
printf("%s\n", *pa);//解引用at 从这里向后打印字符串
return 0;
}//at
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;
}
第一次解引用拿到c+2 第二次拿到了 char*内容 所以打印 POINT
printf("%s\n", *-- * ++cpp + 3);//++优先级高 --就是对c+1 减去1 后变成c 如果是c 指向位置也会发生改变 再解引用拿到 ENTER 加3 指向T。从E向后打印打印结果ER
*cpp[-2]可以写成 **(cpp-2) +3指向R打印ST
printf("%s\n", cpp[-1][-1] + 1);//cpp[-1][-1] 可以写成 (*(*(cpp-1)-1)+1 结果EW
总体打印结果POINT ER ST EW
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
分享题目:C语言指针进阶学完指针必看练习题详解-创新互联
文章链接:http://ybzwz.com/article/ihijh.html