征服指针——指针练习
Posted 小倪同学 -_-
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了征服指针——指针练习相关的知识,希望对你有一定的参考价值。
练习1
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表示取出整个数组的地址,&a+1表示该数组后的地址。
a+1表示数组第二位元素的地址,*(a+1)对其解应用得第二位元素
ptr - 1表示数组末尾的地址,* (ptr - 1)表示数组最后一个元素
如下图
运行结果如下
练习2
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);
printf("%p\\n", (unsigned long)p + 0x1);
printf("%p\\n", (unsigned int*)p + 0x1);
return 0;
}
解析:
printf("%p\\n", p + 0x1);
p+0x1 表示跳过一个结构体的地址(20个字节),20转化为16进制为14,
所以结果为00100014
printf("%p\\n", (unsigned long)p + 0x1);
(unsigned long)p + 0x1 表示把p强制转化为无符号整型再+1,这里就变为整数+1
结果为00100001
printf("%p\\n", (unsigned int*)p + 0x1);
(unsigned int*)p + 0x1 表示把p强制转化为无符号整型指针再+1,+1表示跳过一个int类型的地址(4个字节),结果是00100004
运行结果:
练习3
int main()
{
int a[4] = { 1, 2, 3, 4 };
int* ptr1 = (int*)(&a + 1);
int* ptr2 = (int*)((int)a + 1);
printf("%x,%x", ptr1[-1], *ptr2);
return 0;
}
解析:
int* ptr1 = (int*)(&a + 1);
取出该数组之后一位地址,将其强制转化成整型指针并存放到ptr1中
int* ptr2 = (int*)((int)a + 1);
将元素首地址强制转化成int型,再+1,再对其解应用。这里相当于将元素首地址+1.
ptr1[-1]相当于ptr-1
输出结果为
练习4
#include <stdio.h>
int main()
{
int a[3][2] = { (0, 1), (2, 3), (4, 5) };
int* p;
p = a[0];
printf("%d", p[0]);
return 0;
}
解析:
这里我们要注意如何对二维数赋初值,
1.直接写入数据,这样不足位会按0补齐,如下图
int a[3][2] = { 1, 2, 3, 4 };
2.每行用{ }隔开(注意是大括号),不足位会按0补齐
int a[3][2] = { { 1, 0 }, { 2, 0 } };
上述题目对二维数组赋初值是用的是( ),( )表还逗号表达式,结果为最后一个表达式的结果,int a[3][2] = { (0, 1), (2, 3), (4, 5) }相当与int a[3][2]={1,3,5}。a[0]表示第一行第一个元素的地址,所以结果是1。
运行结果
练习5
int main()
{
int a[5][5];
int(*p)[4];
p = a;
printf("%p,%d\\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);
return 0;
}
解析:
指针相减得两指针间元素个数,从上图可看出指针之间相差4个元素,又因为盘p<a,所以
&p[4][2] - &a[4][2]=-4。
因为-4在计算机中储存的是补码
11111111111111111111111111111100
所以以地址形式打印为FFFFFFFC
运行结果
练习6
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* ptr1 = (int*)(&aa + 1);
ptr1是跳过整个二维数组的后一位地址
int* ptr2 = (int*)(*(aa + 1));
ptr2是跳过二维数组第一行,第二行首元素的地址
运行结果
练习7
int main()
{
char* a[] = { "work","at","alibaba" };
char** pa = a;
pa++;
printf("%s\\n", *pa);
return 0;
}
解析:
看到这道题目,你可能已经意识到了,没错这就是阿里的一道面试题。下面来看看这题的解法。
pa通过pa++,指向a[1]的地址,a[1]存放"at"常量字符串的首地址,*pa对a[1]解应用得到“at”
运行结果
练习8
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;
}
解析:
运行结果
以上是关于征服指针——指针练习的主要内容,如果未能解决你的问题,请参考以下文章