征服指针——指针练习

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;
}

解析:
在这里插入图片描述
在这里插入图片描述
运行结果
在这里插入图片描述

以上是关于征服指针——指针练习的主要内容,如果未能解决你的问题,请参考以下文章

指针练习:输出Hello

详解C语言指针我真的让C指针给我唱征服了~乌拉

《征服 C 指针》摘录6:解读 C 的声明

指针练习:指向指针的指针

C语言进阶学习笔记二指针的进阶(重点必看+代码演示+练习)

更新:C++ 指针片段