C语言:指针练习(2)

练习5:

int main()
{
	int a[5][5];
	int(*p)[4];
	p = a;
	printf("a_ptr=%#p,a_ptr=%#p\n", &a[4][2], &p[4][2]);
	printf("%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);
	return 0;
}

输出结果:ff ff ff fc;-4

分析:

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

输出结果:10 ; 5

分析:&aa,取的是二维数组的地址,加1,跳过整个数组,指向了10的后面,赋给ptr1,相当于ptr1指向了10的后面,ptr1-1再解引用,整形指针减1,向前挪动4个字节,解引用后拿出10;数组名是首元素地址,但是aa是二维数组,所以首元素地址就是第一行的地址,加1向后跳过了一行,也就是指向了第二行的地址,第二行的地址解引用,就是aa[1],也是第二行的数组名,它又相当于第二行首元素的地址,也就是让ptr2指向了6,ptr2-1,向前挪动一个整形,解引用,访问的就是5.

 

练习7:

(*(void(*)())0)();

怎么理解这句代码?

分析:我们希望0是某个函数的地址,所以把它强制类型转换为函数的指针类型,这个时候它就是个函数地址了,在前面加个*,表示解引用操作,找到这个函数,后面去调用它,调用的时候,因为函数无参,所以不用传参数。这是分析过程,那么具体如何描述呢?

答:调用0地址处的函数,调用的函数的参数是无参,返回类型为void,还要解释的话,可以这样说:把0强制类型转换为函数的指针类型,解引用,去找到这个函数,并调用该函数,调的函数没有参数,返回类型为void。

void(*signal(int, void(*)(int)))(int);

怎么理解这句代码呢?

分析:分析这种复杂的代码,首先,我们得找到一个名字或者一个符号开始,这个代码呢,就从signal开始,这是函数,而且是函数声明,不是函数调用,为什么这样说呢?调用函数有传参,但是这里面没传参,有的人可能会说传的是int,但是传int时,也只能传1,2,3,或者其他整形数字,不可能会传int过去,所以这绝对不是一个函数的调用,而是一个函数的声明,它的参数为int和函数指针,返回类型为函数指针。

 void (*signal(int,void(*)(int)))(int);

signal(int,void(*)(int))就是函数名和函数参数,去掉signal(int,void(*)(int))之后,剩下的就是函数的返回类型void (*)(int),所以它返回的是一个函数指针,该指针指向函数的参数是int,返回类型为void。

不过,我们理解的的写法应该是:

void(*)(int) signal(int,void(*)(int));

但是实际上并不这样写。这个代码太复杂,我们写的代码应该是让别人读得懂的,所以可以使用 typedef 把它简化一下:

typedef void(*ptr_t)(int);
ptr_t signal(int,ptr_t);

分析了这么多,这段代码具体应该这样解释:

signal是一个函数声明,函数的参数为int和一个函数指针,该函数指针指向的函数参数为int,返回类型为void;signal函数的返回类型也为函数指针,该函数指针指向的函数参数为int,返回类型为void。
 

练习8:

#include <stdio.h>
int main()
{
	char *a[] = { "work", "at", "alibba" };
	char** pa = a;
	pa++;
	printf("%s\n", *pa);
	return 0;
}

输出结果:"at"

分析:

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值