一、字符指针

字符指针的定义方式为char*。

案例1:

#include <stdio.h>
int main()
{
	char ch = 'w';
	char *p = &ch;
	*p = 'a';
	printf("*p=%c\n", *p);
	printf("ch=%c\n", ch);
	return 0;
}

执行程序:

C语言指针的进阶学习_指针数组

案例2:

#include <stdio.h>
int main()
{
	// 把字符串首字符的地址放到了p
	char *p = "hello bit";
	printf("*p=%c\n", *p);
	printf("%s\n", p);
	return 0;
}

执行程序:

C语言指针的进阶学习_数组指针_02

二、指针数组

指针数组是一个存放指针的数组。

#include <stdio.h>
int main()
{
	// 整形指针数组
	int a = 3, b = 4;
	int *arr[2] = { &a,&b };
	for (int i = 0; i < 2; i++)
	{
		printf("*arr[%d]=%d\n", i, *arr[i]);
	}
	return 0;
}

执行程序:

C语言指针的进阶学习_指针数组_03

三、数组指针

数组指针是指针,是能够指向数组的指针。

#include <stdio.h>
int main()
{
	int arr1[] = { 1,2,3,4,5 };
	// 数组指针
	int (*arr)[] = &arr1;

	for (int i = 0; i < 5; i++)
	{
    // 因为(*arr)就代表数组名,同时也代表着首元素的地址
		printf("%d\n", (*arr)[i]);
	}
	return 0;
}

输出:

C语言指针的进阶学习_指针数组_04

&数组名VS数组名

#include <stdio.h>
int main()
{
	int arr1[] = { 1,2,3,4,5 };
	printf("%p\n", arr1);
	printf("%p\n", &arr1);
	return 0;
}

输出:

C语言指针的进阶学习_数组指针_05

可见数组名和&数组名打印的地址是一样的。但是这两个代表的含义却不一样。

#include <stdio.h>
int main()
{
	int arr[10] = { 0 };
	printf("%p\n", arr);
	printf("%p\n", &arr);
	printf("%p\n", arr + 1);
	printf("%p\n", &arr + 1);
	return 0;
}

输出:

C语言指针的进阶学习_指针数组_06

根据上面的代码我们发现,其实&arr和arr,虽然值是一样的,但是意义应该不一样的。

实际上: &arr 表示的是数组的地址,而不是数组首元素的地址。arr代表是数组首元素的地址。

本例中 &arr 的类型是: int(*)[10] ,是一种数组指针类型 数组的地址+1,跳过整个数组的大小,所以 &arr+1 相对于 &arr 的差值是40。

四、指针参数

1.一级指针传参


#include <stdio.h>
void show(int *p, int sz)
{
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d\n", *(p + i));
	}
}
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,0 };
	int *p = arr;
	int sz = sizeof(arr) / sizeof(arr[0]);
  // 一维指针作为参数
	show(p,sz);

	return 0;
}

2.二级指针传参

#include <stdio.h>
void show(int **p)
{
	**p = 5;
}
int main()
{
	int a = 10;
	int *p = &a;
	int *pp = &p;

	show(&p);
	printf("a=%d\n", a);

	return 0;
}

输出:

C语言指针的进阶学习_指针参数_07

五、函数指针

#include <stdio.h>
void show()
{
	printf("hehe\n");
}
int main()
{
	printf("%p\n", show);
	printf("%p\n", &show);

	return 0;
}

输出:

C语言指针的进阶学习_指针数组_08

函数名和&函数名代表着相同的含义,表示的都是函数的地址,其数值表现形式也都是函数的地址,两者没有任何的区别,在使用上也没有任何的区别!

六、函数指针数组

把函数的地址存放到一个数组中,那么这个数组就叫函数指针数组。

格式:

数据类型 (*parr1[])();
#include <stdio.h>
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;
}
int main()
{
	int x, y;
	int input = 1;
	int result = 0;
	// 函数指针数组
	int(*p[5])(int x, int y) = { 0,add,sub,mul,div };
	while (input)
	{
		printf("请选择->1:add 2:sub 3:mul 4:div\n");
		scanf("%d", &input);
		if (input >= 1 && input <= 4)
		{
			printf("请输入操作数:");
			scanf("%d %d", &x, &y);
			result = (*p[input])(x, y);
			printf("结果为:%d\n", result);
		}
		else {
			printf("输入有误!\n");
			break;
		}
	}
	return 0;
}

输出:

C语言指针的进阶学习_数组指针_09