c语言总结 2.指针(重点)

主要内容为:

  • 字符指针
  • 数组指针
  • 指针数组
  • 函数指针
  • 指针函数
  • 复杂指针
  • 函数指针数组
  • 回调函数
1.字符指针(char*)

一般使用方法为:

    char ch = 'w';
	char *pc = &ch;
	printf("%c", *pc);

结果为‘w’
另一种使用方式为:

   char *pstr = "hello world";
   printf("%s\n", *pstr);

结果为hello world,但是并不是把字符串放进了字符指针中,而是把字符串首元素的地址放在了字符指针中。

    char str1[] = "hello world";
	char str2[] = "hello world";
	char *str3 = "hello world";
	char *str4 = "hello world";
	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");

结果为str1 and str2 are not same!,str3 and str4 are same!,因为str3和str4指向同一个常量字符串,c会把常量字符串存储到单独的一个内存环境,当几个指针指向同一个字符串时,它们实际指向同一块内存。

2.数组指针

即为指向数组的指针,实际上是指针,例如 int (*p2)[10]为数组指针,因为[]的优先级高于 *,因此带上括号,表示p先与 * 结合,说明p是一个指针变量,指向一个大小为10个整形的数组。

3.指针数组

即为元素为指针的数组,实际上为数组,例如 int *p2[10]为指针数组。

4.函数指针

即为指向函数的指针,实际上为指针,例如 int (*pfun)(int,int),表示指向有两个整形参数的函数的指针

5.指针函数

即为函数的类型为指针,实际上是函数,例如 int *pfun(int,int).

6.几个复杂指针解读
  • int (*func)(int *,int( * )(int *));
    解读:func是一个指向函数的指针,函数的返回值为int,函数有两个参数,一个参数为整形指针,另一个参数为指向函数的指针,这个指针指向的函数的参数为整形指针。
  • int(* func[5])(int *);
    解读:func为具有5个元素的数组,元素为函数类型的指针,函数参数为整形指针,返回值为int。
  • int(* (* func)[5])(int *);
    解读:func为指针,指向一个数组,数组元素为指向函数的指针,函数的参数为int *,返回值为int。
  • int(* (* func)(int *))[5]
    解读:func为函数指针,函数的参数为int *,返回值为指向数组的指针,数组的元素为5个整形元素。
  • int*(* func(int *))[5]
    解读:func是函数,函数的参数为整形指针,返回值为指向数组的指针,数组的元素为5个整形指针。
  • (* (void( * )())0)()
    解读:是一个函数指针,函数没有参数,返回类型为空,0表示强行转换为函数,是一个地址,放一个函数,最外层的 * 表示解引用。
  • void (* signal(int,void( * )(int)))(int)
    解读:signal为函数,函数有两个参数,一个参数为int,另一个参数为函数指针,函数的返回类型为函数指针,函数的第二个参数是函数指针,函数参数为int,返回类型为void。
7.函数指针数组

用途:转移表,模拟一个计算器

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 ret = 0;
	int(*p[5])(int x, int y) = { 0, Add, Sub, Mul, Div };//转移表
	while (input)
	{
		printf("************************\n");
		printf("**1.Add         2.Sub **\n");
		printf("**3.Mul         4.Div **\n");
		printf("************************\n");
		printf("请选择:>");
		scanf("%d", &input);
		if ((input <= 4 && input >= 1))
		{
			printf("请输入操作数:>");
			scanf("%d %d", &x, &y);
			ret = (*p[input])(x, y);
		}
		else
			printf("输入有误!\n");
		printf("ret=%d\n", ret);
	}
	system("pause");
	return 0;
}
8.回调函数

1.演示qsort的使用,实现整形数组元素的排序

int int_cmp(const void* p1, const void* p2)
{
	return (*(int*)p1 - *(int*)p2);//比较两个整形指针元素
}
int main()
{
	int arr[] = { 1, 3, 4, 6, 2, 7, 9, 0 };
	int i = 0;
	qsort(arr, sizeof(arr) / sizeof(arr[0]), sizeof(int), int_cmp);//实现排序
	for (; i < sizeof(arr) / sizeof(arr[0]); i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");
	return 0;
}

其中,qsort的参数为要排序的空间的起始地址,元素个数,元素大小,比较函数,此程序实现数组元素从小到大排列。
2.使用结构体,通过结构体成员排序

//实现一个比较函数
void qsort(void *base, size_t num, size_t width,
	int (*cmp)(const void *e1, const void *e2));//函数指针
struct S
{
	char name[20];
	int age;
};
int cmp_S_by_name(const void *e1, const void *e2)//按照名字排序
{
	return strcmp(((struct S*)e1)->name,((struct S*)e2)->name);
}
int cmp_S_by_age(const void *e1, const void * e2)
{
	return (((struct S*)e1)->age - ((struct S*)e2)->age);
}
void test1()
{
	int i = 0;
	struct S arr[3] = { { "x", 20 }, { "l", 10 }, { "w", 30 } };
	qsort(arr, 3, sizeof(struct S), cmp_S_by_name);
	for (; i < 3; i++)
	{
		printf("%s ", arr[i].name);
	}
	printf("\n");
}
void test2()
{
	int i = 0;
	struct S arr[3] = { { "x", 20 }, { "a", 10 }, { "w", 30 } };
	qsort(arr, 3, sizeof(struct S), cmp_S_by_age);
	for (; i < 3; i++)
	{
		printf("%d ", arr[i].age);
	}
	printf("\n");
}
int main()
{
	test1();
	test2();
	return 0;
}

此程序实现一个结构体,通过回调函数分别按照名字和年龄排序。
3.通过回调函数实现冒泡排序

void swap(char *buf1, char *buf2, size_t width)
{
	size_t i = 0;
	for (; i < width; i++)
	{
		char tmp = *buf1;
		*buf1 = *buf2;
		*buf2 = tmp;
		buf1++;
		buf2++;
	}
}
int cmp_int(const void *e1, const void *e2)//e1,e2要比较的两个元素
{
	return *(int*)e1 - *(int*)e2;
}
void bubble_sort(void *base, size_t sz, size_t width,
	int(*cmp)(const void *e1, const void *e2))//函数指针
{
	size_t i = 0;
	for (; i < sz - 1; i++)
	{
		size_t j = 0;
		for (; j < sz - 1 - i; j++)
		{
			if (cmp((char*)base + j*width, (char*)base + (j + 1)*width)>0)
			{
				swap((char*)base + j*width, (char*)base + (j + 1)*width, width);
			}
		}
	}
}
int main()
{
	int arr[]={1,3,2,4,15,6,7,10,8};
	bubble_sort(arr,sizeof(arr)/sizeof(arr[0]),sizeof(int),cmp_int);
	size_t i=0;
	for(;i<sizeof(arr)/sizeof(arr[0]);++i)
	{
		printf("%d ",arr[i]);
	}
	printf("\n");
	return 0;
}

在比较时,应该将其转换为字符类型指针类型。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值