再谈指针(字符指针,数组指针和指针数组,函数指针,数组传参和指针传参,函数 指针数组,指向函数指针数组的指针,回调函数,)

再谈指针

1、字符指针

字符指针的一般使用:

#include 
#include 

//一般使用
int main()
{
	char ch = 'a';
	char *pch = &ch;
	*pch = 'b';
	system("pause");
	return 0;
}

int main()
{
	//把一个常量字符的首字符H存放在指针变量pstr中
	char *pstr = "Hello,World!";
	printf("%s\n", pstr);
	system("pause");
	return 0;
}

字符指针是将字符串的首地址放在字符指针中
即就是把常量字符的首字符的地址 存放到字符指针中

2、指针数组

指针数组是指存放指针的数组

#include 
#include 

int main()
{
	//指针数组是一个存放指针的数组
	int *arr1[10];//整型指针数组
	char *arr2[4];//一级字符型指针数组
	char **arr3[5];//二级字符型指针数组
	system("pause");
	return 0;
}

3、数组指针

3.1区分数组指针和指针数组

#include 
#include 

//区分数组指针和指针数组
int main()
{
	int *p1[10];//指针数组
	int(*p2)[10];//数组指针
	system("pause");
	return 0;
}

3.2&数组名和数组名

#include 
#include 

//&数组名和数组名的区别
int main()
{
	int arr[10] = { 0 };
	printf("%p\n", arr);
	printf("%p\n", &arr);
	system("pause");
	return 0;
}
//&数组名表示的数组的地址
//数组名表示的数组首元素的地址

int main()
{
	int arr[10] = { 0 };
	printf("%p\n", arr);
	printf("%p\n", &arr);

	printf("%p\n", arr + 1);
	printf("%p\n", &arr + 1);
	system("pause");
	return 0;
}

&数组名表示 数组的地址
数组名表示 数组首元素的地址

3.3数组指针的使用

#include 
#include 

//不常用的数组指针使用方法
int main()
{
	int arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
	int(*p)[10] = &arr;//把数组的地址赋值给指针变量p
	system("pause");
	return 0;
}
#include 
#include 

void Print_arr1(int arr[3][5], int row, int col)
{
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			printf("%d ", arr[i][j]);
		}
		printf("\n");
	}
}

void Print_arr2(int(*arr)[5], int row, int col)
{
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			printf("%d ", arr[i][j]);
		}
		printf("\n");
	}
}

int main41()
{
	int arr[3][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
	Print_arr1(arr, 3, 5);
	Print_arr2(arr, 3, 5);
	system("pause");
	return 0;
}

4、函数指针

函数指针是用来表示函数存放的地址

#include 
#include 

void test()
{
	printf("Hello,World!\n");
}

int main()
{
	printf("%p\n", test);
	printf("%p\n", &test);
	system("pause");
	return 0;
}

5、数组传参和指针传参

一维数组传参

#include 
#include 


//void test1(int arr[])
//{
//	printf("%d ", arr[0]);
//}
//
//void test1(int arr[10])
//{
//	printf("%d ", arr[0]);
//}
//
//void test1(int *arr)
//{
//	printf("%d ", arr[0]);
//}
//
//void test2(int *arr[20])
//{
//	printf("%d ", arr[0]);
//}
//
//void test2(int **arr)
//{
//	printf("%d ", arr[0]);
//}

int main()
{
	int arr1[10] = { 0 };
	int *arr2[20] = { 0 };

	test1(arr1);
	test2(arr2);
	system("pause");
	return 0;
}

二维数组传参

#include 
#include 

void test1(int arr[3][5])
{

}

void test2(int arr[][5])
{

}

//void test3(int arr[][])
//{
//
//}

void test4(int *arr)
{

}

void test5(int **arr)
{

}

void test6(int *arr[5])
{

}

void test7(int (*arr)[5])
{

}

int main6()
{
	int arr[3][5] = { 0 };
	test1(arr);
	test2(arr);
	//test3(arr);
	test4(arr);
	test5(arr);
	test6(arr);
	test7(arr);
	system("pause");
	return 0;
}

一级指针传参

#include 
#include 

void Print(int *parr, int size)
{
	for (int i = 0; i < size; i++)
	{
		printf("%d ", *(parr + i));
	}
}

int main()
{
	int arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
	int *parr = arr;
	int size = sizeof(arr) / sizeof(arr[0]);
	//一级指针parr,传给函数
	Print(parr, size);
	system("pause");
	return 0;
}

二级指针传参

#include 
#include 

void test11(int  **ptr)
{
	printf("num = %d\n", **ptr);
}

void test22(char **p)
{
	printf("%c\n", **p);
}

int main()
{
	int n = 10;
	int *p = &n;
	int **pp = &p;
	test11(pp);
	test11(&p);

	char c = 'b';
	char *pc = &c;
	char **ppc = &pc;
	char *arr[10];
	test22(&pc);
	test22(ppc);
	test22(arr);//错误
	system("pause");
	return 0;
}

6、函数指针数组

用来做转移表

举例:

#define _CRT_SECURE_NO_WARNINGS
#include 
#include 

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

int sub(int x, int y)
{
	return x - y;
}

int mul(int x, int y)
{
	return x * y;
}

int div1(int x, int y)
{
	return x / y;
}

int main()
{
	int x, y;
	int res;
	int input = 1;
	while (input)
	{
		printf("#####################\n");
		printf("#######1、 add#######\n");
		printf("#######2、 sub#######\n");
		printf("#######3、 mul#######\n");
		printf("#######4、 div#######\n");
		printf("#####################\n");
		printf("请输入:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			printf("请输入两个数字:");
			scanf("%d %d", &x, &y);
			res = add(x, y);
			break;
		case 2:
			printf("请输入两个数字:");
			scanf("%d %d", &x, &y);
			res = sub(x, y);
			break;
		case 3:
			printf("请输入两个数字:");
			scanf("%d %d", &x, &y);
			res = mul(x, y);
			break;
		case 4:
			printf("请输入两个数字:");
			scanf("%d %d", &x, &y);
			res = div1(x, y);
			break;
		default:
			printf("选择错误,请重新选择!\n");
			break;
		}
		printf("res = %d\n", res);
	}
	system("pause");
	return 0;
}
#endif

#if 0

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

int sub(int x, int y)
{
	return x - y;
}

int mul(int x, int y)
{
	return x * y;
}

int div1(int x, int y)
{
	return x / y;
}

int main()
{
	int x, y;
	int input = 1;
	int res = 0;
	int(*p[5])(int x, int y) = { 0, add, sub, mul, div1 };//转移表
	while (input)
	{
		printf("#####################\n");
		printf("#######1、 add#######\n");
		printf("#######2、 sub#######\n");
		printf("#######3、 mul#######\n");
		printf("#######4、 div#######\n");
		printf("#####################\n");
		printf("请输入:");
		scanf("%d", &input);
		if (input >= 1 && input <= 4)
		{
			printf("请输入操作数:");
			scanf("%d %d", &x, &y);
			res = ((*p[input])(x, y));
		}
		else
		{
			printf("选择错误,请重新选择!");
		}
		printf("res = %d\n", res);
	}
	system("pause");
	return 0;
}

#endif

7、指向函数指针数组的指针

指向函数指针数组的指针表示的是一个指针。这个指针指向一个数组,数组的元素都是函数指针

8、回调函数

回调函数就是一个通过函数在调用的函数。
如果函数的指针作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,称之为回调函数
回调函数不是由该函数的实现方直接使用,而是在特定的事件或者条件发生时由另外的一方调用的,用于该时间或条件进行响应。

#include 
#include 

#if 0
void test111(const char *str)
{
	printf("%s\n", str);
}

int main()
{
	//函数指针pfun
	void(*pfunArr[5])(const char *str);
	pfunArr[0] = test111;
	//指向函数指针数组pfunArr的指针ppfunArr
	void(*(ppfunArr)[10])(const char *str) = &pfunArr;
	system("pause");
	return 0;
}
#endif

#if 0

int int_cmp(const void *p1, const void *p2)
{
	return (*(int*)p1 > *(int*)p2);
}

int main()
{
	int arr[] = { 3, 1, 2, 7, 5, 6, 4, 8, 9, 0 };
	qsort(arr, sizeof(arr) / sizeof(arr[0]), sizeof(int), int_cmp);
	for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");
	system("pause");
	return 0;
}

#endif

#if 1

//使用回调函数模拟实现qsort,使用冒泡排序
int int_cmp(const void *p1, const void *p2)
{
	return (*(int*)p1 > *(int*)p2);
}

void _swap(void *p1, void *p2, int size)
{
	for (int i = 0; i < size; i++)
	{
		char tmp = *((char*)p1 + i);
		*((char*)p1 + i) = *((char*)p2 + i);
		*((char*)p2 + i) = tmp;
	}
}

void bubble_sort(void *base, int count, int size, int(*cmp)(void*, void*))
{
	for (int i = 0; i < count - 1; i++)
	{
		for (int j = 0; j < count - i - 1; j++)
		{
			if (cmp((char*)base + j*size, (char*)base + (j + 1)*size)>0)
			{
				_swap((char*)base + j*size, (char*)base + (j + 1)*size, size);
			}
		}
	}
}

int main()
{
	//int arr[] = { 3, 1, 2, 7, 5, 6, 4, 8, 9, 0 };
	char *arr[] = { "aaaa", "dddd", "cccc", "bbbb" };
	bubble_sort(arr, sizeof(arr) / sizeof(arr[0]), sizeof(int), int_cmp);
	for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
	{
		printf("%s ", arr[i]);
	}
	system("pause");
	return 0;
}

#endif

9、指针和数组指针练习

1.c

#include 
#include 
#include 

//sizeof(数组名) 表示整个数组
//&数组名 表示整个数组,取出的是整个数组的地址
//其余的数组名表示首元素地址

#if 0
int main()
{
	//一维数组
	int a[] = { 1, 2, 3, 4 };
	printf("%d\n", sizeof(a));//16
	printf("%d\n", sizeof(a + 0));//4
	printf("%d\n", sizeof(*a));//4
	printf("%d\n", sizeof(a + 1));//4
	printf("%d\n", sizeof(a[1]));//4
	printf("%d\n", sizeof(&a));//4
	printf("%d\n", sizeof(*&a));//16
	printf("%d\n", sizeof(&a + 1));//4
	printf("%d\n", sizeof(&a[0]));//4
	printf("%d\n", sizeof(&a[0] + 1));//4

	//字符数组
	char arr[] = { 'a', 'b', 'c', 'd', 'e', 'f' };
	printf("%d\n", sizeof(arr));//6
	printf("%d\n", sizeof(arr + 0));//4
	printf("%d\n", sizeof(*arr));//1
	printf("%d\n", sizeof(arr[1]));//1
	printf("%d\n", sizeof(&arr));//4
	printf("%d\n", sizeof(&arr + 1));//4
	printf("%d\n", sizeof(&arr[0] + 1));//4
	printf("%d\n", strlen(arr));
	printf("%d\n", strlen(arr + 0));
	printf("%d\n", strlen(*arr));
	printf("%d\n", strlen(arr[1]));
	printf("%d\n", strlen(&arr));
	printf("%d\n", strlen(&arr + 1));
	printf("%d\n", strlen(&arr[0] + 1));

	char arr[] = "abcdef";
	printf("%d\n", sizeof(arr));//7
	printf("%d\n", sizeof(arr + 0));//4
	printf("%d\n", sizeof(*arr));//1
	printf("%d\n", sizeof(arr[1]));//1
	printf("%d\n", sizeof(&arr));//4
	printf("%d\n", sizeof(&arr + 1));//4
	printf("%d\n", sizeof(&arr[0] + 1));//4
	printf("%d\n", strlen(arr));
	printf("%d\n", strlen(arr + 0));
	printf("%d\n", strlen(*arr));
	printf("%d\n", strlen(arr[1]));
	printf("%d\n", strlen(&arr));
	printf("%d\n", strlen(&arr + 1));
	printf("%d\n", strlen(&arr[0] + 1));

	char *p = "abcdef";
	printf("%d\n", sizeof(p));//4
	printf("%d\n", sizeof(p + 1));//4
	printf("%d\n", sizeof(*p));//4
	printf("%d\n", sizeof(p[0]));//1
	printf("%d\n", sizeof(&p));//4
	printf("%d\n", sizeof(&p + 1));//4
	printf("%d\n", sizeof(&p[0] + 1));//4
	printf("%d\n", strlen(p));
	printf("%d\n", strlen(p + 1));
	printf("%d\n", strlen(*p));
	printf("%d\n", strlen(p[0]));
	printf("%d\n", strlen(&p));
	printf("%d\n", strlen(&p + 1));
	printf("%d\n", strlen(&p[0] + 1));

	//二维数组
	int a[3][4] = { 0 };
	printf("%d\n", sizeof(a));//48
	//printf("%d\n", sizeof(a[0][0]));
	printf("%d\n", sizeof(a[0]));//16
	printf("%d\n", sizeof(a[0] + 1));//4
	//printf("%d\n", sizeof(*(a[0] + 1)));
	printf("%d\n", sizeof(a + 1));//4
	printf("%d\n", sizeof(*(a + 1)));//16
	printf("%d\n", sizeof(&a[0] + 1));//4
	printf("%d\n", sizeof(*(&a[0] + 1)));//16
	printf("%d\n", sizeof(*a));//16
	printf("%d\n", sizeof(a[3]));//16
	system("pause");
	return 0;
}
#endif

2.c

#include 
#include 

int main()
{
	int a[5] = { 1, 2, 3, 4, 5 };
	int *ptr = (int*)(&a + 1);
	printf("%d, %d", *(a + 1), *(ptr - 1));
	system("pause");
	return 0;
}

3.c

#include 
#include 
#include 

struct Test
{
	int num;
	char *pcName;
	short sDate;
	char ch[2];
	short sDa[4];
}*p;

int main()
{
	printf("%p\n", p + 0x1);
	printf("%p\n", (unsigned long)p + 0x1);
	printf("%p\n", (unsigned int*)p + 0x1);
	system("pause");
	return 0;
}

4.c

#include 
#include 

int main()
{
	int a[4] = { 1, 2, 3, 4 };
	int *ptr1 = (int *)(&a + 1);
	int *ptr2 = (int *)((int)a + 1);
	printf("%x, %x\n", ptr1[-1], *ptr2);
	system("pause");
	return 0;
}

5.c

#include 
#include 

int main()
{
	int a[3][2] = { { 0, 1 }, { 2, 3 }, { 4, 5 } };
	int *p;
	p = a[0];
	printf("%d\n", p[0]);
	system("pause");
	return 0;
}

6.c

#include 
#include 

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]);
	system("pause");
	return 0;
}

7.c

#include 
#include 

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\n", *(ptr1 - 1), *(ptr2 - 1));
	system("pause");
	return 0;
}

8.c

#include 
#include 

int main()
{
	char *a[] = { "work", "at", "alibaba" };
	char **pa = a;
	pa++;
	printf("%s\n", *pa);
	system("pause");
	return 0;
}

9.c

#include 
#include 

int main()
{
	char *c[] = { "ENTER", "NEW", "POINT", "FRIST" };
	char **pc[] = { c + 3, c + 2, c + 2 };
	char ***ppc = pc;
	printf("%s\n", **++ppc);//POINT
	printf("%s\n", *--*++ppc + 3);//
	printf("%s\n", *ppc[-2] + 3);//ST
	printf("%s\n", ppc[-1][-1] + 1);//EW
	system("pause");
	return 0;
}

你可能感兴趣的:(再谈指针(字符指针,数组指针和指针数组,函数指针,数组传参和指针传参,函数 指针数组,指向函数指针数组的指针,回调函数,))