指针的深入理解(2)

一.字符指针变量

基本使用的话就是和普通的int*类型是一样的,但是我们这里直接是看一下特殊的情况:

int main()
{
	char* p = "hello";
	printf("%s\n", p);
	return 0;
}

这里也是将hello打印出来了,可是这里需要特别注意的是,这里并不是把字符串放入了指针p里面而只是将字符串首字符的地址给入了p中。

下面给大家看一个笔试题就知道了。

int main()
{
 char str1[] = "hello bit.";
 char str2[] = "hello bit.";
 const char *str3 = "hello bit.";
 const char *str4 = "hello bit.";
 if(str1 ==str2)
 printf("str1 and str2 are same\n");
 else
 printf("str1 and str2 are not same\n");
 
 if(str3 ==str4)
 printf("str3 and str4 are same\n");
 else
 printf("str3 and str4 are not same\n");
 
 return 0;
}

打印出来这个结果是因为,同一个字符串来初始化数组是开辟了不同的空间,本质是不一样的,而用指针指向同一个字符串指向的都是同一个内存空间,所以二者是相同的。

二.数组指针

1.数组指针表示

数组指针指的是一个指针,而不是数组。写法是int (*p)[];

2.数组指针的初始化

int arr[10] = {0};
&arr;//得到的就是数组的地址
 int(*p)[10] = &arr;

这就是所谓的数组指针的初始化。

三.二维数组传参的本质

二维数组的每一个元素就是一维数组。那么将这个类型提取出来就是,int [i]这就是一维数组的类型,那么一维数组的地址就是int (*)[i]也就是数组指针,简单的说那个[i]就代表着一维数组中元素的个数。那就意味着⼆维数组传参本质上也是传递了地址,传递的是第一行这个⼀维数组的地址。

void test(int(*p)[3], int r, int c)
{
	for (int i = 0; i < r; i++)
	{
		for (int j = 0; j < c; j++)
		{
			printf("%d ", p[i][j]);
		}
		printf("\n");
	}
}

int main()
{
	int arr[2][3] = { {1,2,3},{4,5,6} };
	test(arr,2,3);
	return 0;
}

四.函数指针

通过前面指针的学习我们也应该明白了函数指针就是存放函数地址的指针了吧.

void test()
{
 printf("hehe\n");
}
int main()
{
 printf("test: %p\n", test);
 printf("&test: %p\n", &test);
 return 0;
}

和数组名差不多的是,函数名就是函数的地址。如果需要将函数的地址存储起来那么就需要使用到函数指针来存储

先说一下函数指针的类型

使用函数指针

int add(int x, int y)
{
	return x + y;
}

int main()
{
	int(*padd)(int, int) = add;
	printf("%d\n", (*padd)(2, 3));
	printf("%d\n", padd(2, 3));
	return 0;
}

五.typedef关键字

typedef 是⽤来类型重命名的,可以将复杂的类型,简单化。⽐如,你觉得 unsigned int 写起来不⽅便,如果能写成 uint 就⽅便多了,那么我们可以使⽤:typedef unsigned int uint;其他的也是如此。

其中数组指针和函数指针是有点区别的。typedef int(*parr_t)[5];这样才可以重命名而不是写在最右边。typedef void(*pfun_t)(int);这个也和数组指针一样的。

六.有趣的代码

(*(void (*)())0)();
void (*signal(int , void(*)(int)))(int);
//简化上面的两个代码

(*(void (*)())0)();
//void (*)()是一个函数指针  (void (*)())就是强制类型转换
*就是对0这个函数指针类型的解引用
因为void (*)()的参数是空所以解引用的参数也是空
void (*signal(int , void(*)(int)))(int);
这个我们是需要对他进行使用typedef的
typedef void(*pf)(int)
pf signal(int,pf)
这就是使用typedef重命名之后的代码

七.函数指针数组

他的本质还是数组,只不过元素类型是函数指针而已。int (*parr1[3])()这就是函数指针数组的写法

我们直接使用它的用途写个代码:

int add(int a, int b)
{
	return a + b;
}
int sub(int a, int b)
{
	return a - b;
}
int mul(int a, int b)
{
	return a * b;
}
int div(int a, int b)
{
	return a / b;
}

void menu()
{
	printf("*************************\n");
	printf("       1:add 2:sub   \n");
	printf("       3:mul 4:div   \n");
	printf("          0:exit     \n");
	printf("*************************\n");
}

int main()
{
	int (*parr[5])(int, int) = { 0,add,sub,mul,div };
	int input = 0;
	do
	{
		menu();
		printf("请输入你的选择:");
		scanf("%d", &input);
		int x = 0; int y = 0;
		int ret = 0;
		if ((input <= 4 && input >= 1))
		{
			printf("输入操作数:");
			scanf("%d %d", &x, &y);
			ret = (*parr[input])(x, y);
			printf("ret = %d\n", ret);
		}
		else if (input == 0)
		{
			printf("退出计算器\n");
		}
		else
		{
			printf("输⼊有误\n");
		}

	}while(input);
	return 0;
}

这就是用函数指针数组写的一个简易计算器。

总结

以上就是深入指针2的简单介绍咯,还是老话有问题要给小编指出,谢谢大家的观看哦!

  • 7
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值