首页 > 编程语言 > 详细

C语言指针进阶阶段知识总结

时间:2021-05-30 20:17:49      阅读:19      评论:0      收藏:0      [点我收藏+]
C语言进阶阶段学习总结

内容

1->字符指针 //char* p;

2->指针数组 //int* arr[10];

3->数组指针 //int (*p)[10] = &arr;

4->数组传参和指针传参 //

5->函数指针 //int (*pAdd)(int, int) = Add;

6->函数指针数组 //int (*pArr[])(int, int);

7->指向函数指针数组的指针? //int(* (*ppArr[]))(int, int) = &pArr;

8->回调函数

9->指针和数组面试题的解析


1->字符指针

//1.字符指针
int?main()
{
	char?arr[]?=?"abcdef";
	char*?pc?=?arr;
	printf("%s\n",?arr);
	printf("%s\n",?pc);
	return?0;
}
int?main()
{
	const?char*?p?=?"abcdef";//"abcdef"是一个常量字符串
	//指向元素a
	//*p?=?‘w‘;
	//printf("&c\n",*p);
	//printf("%s\n",?p);
	return?0;
}


2->指针数组

//2.指针数组?
//		是数组,用来存放指针的数组

int?main()
{
	int?arr[10]?=?{?0?};//整形数组
	char?ch[5]?=?{?0?};//字符数组
	int*?parr[4];//存放整形指针的数组?-?指针数组
	char?pch[5];//存放字符指针的数组?-?指针数组
	return?0;
}
int?main()
{
	int?arr1[]?=?{?1,2,3,4,5?};
	int?arr2[]?=?{?2,3,4,5,6?};
	int?arr3[]?=?{?3,4,5,6,7?};
	int*?parr[]?=?{?arr1,arr2,arr3?};//存首元素地址
	int?i?=?0;
	for?(i?=?0;?i?<?3;?i++)
	{
		int?j?=?0;
		for?(j?=?0;?j?<?5;?j++)
		{
			printf("%d?",?*(parr[i]?+?j));
		}
		printf("\n");
	}
	return?0;
}


3->数组指针

//3.数组指针
//		是指针

int?main()
{
	int*?p?=?NULL;?//p是整形指针?-?指向整形的指针?-?可以存放整形的地址
	char*?pc?=?NULL;?//pc是字符指针?=?指向字符的指针?-?可以存放字符的地址
	//数组指针?-?指向数组的指针?-?存放数组的地址
	int?arr[10]?=?{?0?};
	//arr?-?首元素地址
	//&arr[0]?-?首元素地址
	//&arr?-?数组地址

	int?arr[10]?=?{?1,2,3,4,5,6,7,8,9,10?};
	int(*p)[10]?=?&arr;?//方块优先级高
	//上面的p就是数组指针
	return?0;
}
int?main()
{
	int?arr[10]?=?{?1,2,3,4,5,6,7,8,9,10?};
	int(*pa)[10]?=?&arr;
	int?i?=?0;
	for?(i?=?0;?i?<?10;?i++)
	{
		printf("%d?",?(*pa)[i]);?//*pa?==?arr
	}
	return?0;
}
int?main()
{
	int?arr[3][5]?=?{?{1,2,3,4,5},{2,3,4,5,6?},{3,4,5,6,7}?};
	print1(arr,?3,?5);//arr?-?数组名就是首元素地址
	//把arr想象成一维数组
	//所以数组arr有三个元素,首元素地址就是第一行地址

	print2(arr,?3,?5);
	return?0;
}
int?arr[5];??????????//???
int*?parr1[10];??????//parr1是一个数组,数组有10个元素,每个元素都是一个int型指针,?int*?parr1[10]是指针数组
int?(*parr2)[10];	???//parr2是一个指针,该指针指向的了一个数组,数组有10个元素,每个元素是int型,int?(*parr2)[10]是数组指针	
int?((*parr3)[10])[5];?
//parr3是一个数组,该数组有10个元素,每个元素是一个数组指针,该数组指针指向的数组有五个元素,每个元素是int


4->数组参数、指针参数

//4.数组参数、指针参数

//一维数组传参
void?test(int?arr[])//ok
{}
void?test(int?arr[10])//ok
{}
void?test(int?*arr)//ok
{}
void?test2(int?*arr[20])//ok
{}
void?test2(int?**arr)//ok?
{}
int?main()
{
	int?arr[10]?=?{?0?};
	int?*arr2[20]?=?{?0?};
	test(arr);
	test2(arr2);
	return?0;
}
//二维数组传参
void?test(int?arr[3][5])
{}
void?test2(int?arr[][5])
{}
void?test3(int?arr[3][])?//err,不能省略列
{}
void?test4(int*?arr)?//err,传过来的是一行数组?不能用int*
{}
void?test5(int?**arr)//err,二级指针也不能接收?一个数组地址
{}
void?test6(int?(*arr)[5])
{}

int?main()
{

	int?arr[3][5]?=?{?0?};
	test(arr);//二维数组传参
	test2(arr);
	test3(arr);

	test4(arr);
	test5(arr);
	test6(arr);
	return?0;
}

//总结:二维数组传参,函数形参的设计只能省略第一个[]的数字。
//因为对一个二维数组,可以不知道有多少行,但是必须知道一行多少元素
//这样才方便运算

//二级指针传参
void?test(int**??ptr)
{
	printf("num?=?%d\n",?**ptr);
}
int?main()
{
	int?n?=?10;
	int*?p?=?&n;
	int**?pp?=?&p;
	test(pp);
	test(&p);
	return?0;
}


5->函数指针

//5.函数指针?-?是指向函数的指针?-?存放函数地址的一个指针

int?Add(int?x,?int?y)
{
	int?z?=?0;
	z?=?x?+?y;
	return?z;
}
int?main()
{
	int?a?=?10;
	int?b?=?20;
	int?arr[10]?=?{?0?};
	int?(*p)[10]?=?&arr;
	//printf("%d\n",?Add(a,?b));
	//&函数名?和?函数名?都是函数的地址?
	/*
	printf("%p\n",?&Add);
	printf("%p\n",?Add);
	*/
	int??(*pa)(int,?int)?=?Add;?//函数指针
	printf("%d\n?",?(*pa)(2,?3));
	return?0;
}

void?Print(char*str)
{
	printf("%s\n",?str);
}

int?main()
{
	void?(*p)(char*)?=?Print;?
	(*p)("hello?bit");
	return?0;
}
//分析代码1
(*(void?(*)())0)();

void(*)()?-?函数指针类型
把0强制类型转换成:void(*)()?-?0就是一个函数的地址
调用0地址处的该函数

//代码2
void?(*signal(int,?void(*)(int)))(int);

void(*??)(int);
signal(int,?void(*)(int))?
signal是一个函数声明?-?参数有两个,一个是int,第二个是函数指针,该函数指针指向的函数的参数是int,返回类型是void
signal函数的返回类型也是个函数指针:?该函数指针指向的函数的参数是int,返回类型是void
int?Add(int?x,?int?y)
{
	int?z?=?0;
	z?=?x?+?y;
	return?z;
}
int?main()
{
	int?a?=?10;
	int?b?=?20;

	int??(*pa)(int,?int)?=?Add;?//函数指针
	//以下三种都正确
	printf("%d\n?",?(*pa)(2,?3));
	printf("%d\n?",?pa(2,?3));
	printf("%d\n?",?Add(2,?3));
	
	return?0;
}


6->函数指针数组

//6.函数指针数组?-?存放函数的地址的数组
?
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?Div(int?x,?int?y)
{
	return?x?/?y;
}

int?main()
{
	//指针数组
	int*?arr[5];
	//需要一个数组,这个数组可以存放4个函数的地址?-?函数指针的数组
	int?(*pa)(int,?int)?=?Add;?//Sub/Mul/Div
	int?(*parr[4])(int,?int)?=?{Add,Sub,?Mul,Div};//函数指针的数组
	int?i?=?0;
	for?(i?=?0;?i?<?4;?i++)
	{
		printf("%d\n",parr[i](2,?3));
	}
	return?0;
}
//测试题
char*?my_strcpy(char*?dest,?const?char*?src);

//1.写一个函数指针?pf,能够指向my_strcpy
char*?(*pf)(char*,?const?char*);
//2.写一个函数指针数组pfArr,?能够存放4个my_strcpy函数的地址
char*?(*pfArr[4])(char*,?const?char*);
//函数指针案例
//计算器
void?menu()
{
	printf("1.add\n2.sub\n3.Mul\n4.div\n");
}
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?Div(int?x,?int?y)
{
	return?x?/?y;
}
int?Div(int?x,?int?y)
{
	return?x?^?y;
}
int?main()
{
	int?input?=?0;
	int?x?=?0;
	int?y?=?0;
	do
	{
		menu();
		printf("请选择:>");
		scanf("%d",&input);
		switch(input)
		{
		case?1:
			printf("请输入两个操作数:>");
			scanf("%d%d",?&x,?&y);
			printf("%d\n",?Add(x,?y));
			break;
		case?2:
			printf("请输入两个操作数:>");
			scanf("%d%d",?&x,&y);
			printf("%d\n",?Sub(x,?y));
			break;
		case?3:
			printf("请输入两个操作数:>");
			scanf("%d%d",?&x,?&y);
			printf("%d\n",?Mul(x,?y));
			break;
		case?4:
			printf("请输入两个操作数:>");
			scanf("%d%d",?&x,?&y);
			printf("%d\n",?Div(x,?y));
			break;
		case?0:
			printf("退出\n");
			break;
		default:
			printf("选择错误\n");
			break;
		}
	}?while?(input);
}

//方法2.利用函数指针数组
void?menu()
{
	printf("1.add\n2.sub\n3.Mul\n4.div\n5.Xor");
}
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?Div(int?x,?int?y)
{
	return?x?/?y;
}
int?Xor(int?x,?int?y)
{
	return?x?^?y;
}

int?main()
{
	int?input?=?0;
	int?x?=?0;
	int?y?=?0;
	//pfArr?是一个函数指针数组?-?用途:转移表
	int?(*pfArr[])(int,?int)?=?{?0,Add,Sub,Mul,Div,Xor};
	do
	{
		menu();
		printf("请选择:>");
		scanf_s("%d",?&input);
		if?(input?>=?1?&&?input?<=?5)
		{
			printf("请输入操作数:>");
			scanf_s("%d%d",?&x,?&y);
			int?ret?=?pfArr[input](x,?y);
			printf("%d\n",?ret);
		}
		else?if?(input?==?0)
		{
			printf("退出\n");
		}
		else
		{
			printf("选择错误!\n");
		}
		
	}?while?(input);
}


7->指向函数指针数组的指针

//7.指向函数指针数组的指针
int?Add(int?x,?int?y)
{
	return?x?+?y;
}

int?main()
{
	int?arr[10]?=?{?0?};
	int?(*p)[10]?=?&arr;?//取出数组的地址

	int?(*pfArr[4])(int,?int);//pfArr?-?是一个数组?-函数指针的数组
	//ppfArr是一个指向?函数指针数组?的指针
	int(*(*ppfArr)[4])(int,?int)?=?&pfArr;?
	//
	//ppfArr?是一个数组指针,指针指向的数组有4个元素
	//指向的数组的每个元素的类型是一个函数指针?int(*)(int,?int)
	//
	return?0;
}


8->回调函数

//8.回调函数?-?通过函数指针调用的函数

void?print(const?char?*str)
{
	printf("hehe:%s",?str);
}
void?test(void?(*p)(char*))
{
	printf("test\n");
	p("bit");
}
int?main()
{
	test(print);
	return?0;
}
//void类型的指针
int?main()
{
	int?a?=?10;
	//int*?pa?=?&a;
	//char*?pc?=?&a;
	//char?ch?=?‘w‘;
	void*?p?=?&a;?//无类型指针?-?可以接收任意类型的地址?-?不能进行解引用操作?-?不能进行加减整数的操作
	p?=?&ch;
	return?0;
}
//qsort?-?库函数?-?排序?-?可以排序任意类型的数据?
//quick?sort

//void?qsort(
//	void*?base,??//目标数组首元素地址
//	size_t?num,	?//待排序数组元素个数
//	size_t?width,?//每个元素的大小-单位是字节
//	int?(*cmp)(const?void*?e1,?const?void*?e2)?//函数指针,比较两个元素的所用函数的地址?-?这个函数使用者自己实现?-?函数指针的两个参数是:待比较的两个元素的地址
//);	

//对arr进行排序,排成升序
//冒泡排序函数只能排序整形数组
//bubble_sort(arr,?sz);//冒泡排序函数?
//void?bubble_sort(int?arr[],?int?sz)

{
	//确定冒泡排序的趟数
	int?i?=?0;
	for?(i?=?0;?i?<?sz?-?1;?i++)
	{
		int?flag?=?1;//假设这一趟要排序的数据已经有序?
		//每一趟冒泡排序
		int?j?=?0;
		for?(j?=?0;?j?<?sz?-?1?-?i;?j++)
		{
			if?(arr[j]?>?arr[j?+?1])
			{
				int?tmp?=?arr[j];
				arr[j]?=?arr[j?+?1];
				arr[j?+?1]?=?tmp;
				flag?=?0;
			}
		}
		if?(flag?==?1)
		{
			break;
		}
	}
}

struct?stu
{
	char?name[20];
	int?age;
};

int?cmp_int(const?void*?e1,?const?void*?e2)?//void*?-?可以接收任意类型的地址
{
	//比较两个整形值的
	return?*(int*)e1?-?*(int*)e2;
}
int?cmp_float(const?void*?e1,?const?void*?e2)
{
	//比较两个浮点型
	return?((int)(*(float*)e1?-?*(float*)e2));
}
int?cmp_stu_by_age(const?void*?e1,?const?void*?e2)
{
	//比较两个年龄
	return?((struct?stu*)e1)->age?-?((struct?stu*)e2)->age;
}
int?cmp_stu_by_name(const?void*?e1,?const?void*?e2)
{
	//比较名字就是比较字符串
	//字符串比较不能直接用><=来比较,应该用strcmp函数
	return?strcmp(((struct?Stu*)e1)->name?,((struct?Stu*)e2)->name);
}

void?test1()
{
	int?arr[10]?=?{?9,8,7,6,5,4,3,2,1,0?};
	int?sz?=?sizeof(arr)?/?sizeof(arr[0]);
	qsort(arr,?sz,?sizeof(arr[0]),?cmp_int);
	int?i?=?0;
	for?(i?=?0;?i?<?sz;?i++)
	{
		printf("%d?",?arr[i]);
	}
}

void?test2()
{
	float?f[]?=?{?9.0,?8.0,?7.0,?6.0,?5.0,?4.0?};
	int?sz?=?sizeof(f)?/?sizeof(f[0]);	
	qsort(f,?sz,?sizeof(f[0]),?cmp_float);
	int?i?=?0;
	for?(i?=?0;?i?<?sz;?i++)
	{
		printf("%f?",?f[i]);
	}
}
void?test3()
{
	struct?stu?s[3]?=?{?{"zhangsan",20},{"lisi",30},{"wangwu",10}?};
	int?sz?=?sizeof(s)?/?sizeof(s[0]);	
	qsort(s,?sz,?sizeof(s[0]),?cmp_stu_by_age);
	int?i?=?0;
	for?(i?=?0;?i?<?sz;?i++)
	{
		printf("%d?",?s[i]);
	}
}
void?test4()
{
	struct?stu?s[3]?=?{?{"zhangsan",20},{"lisi",30},{"wangwu",10}?};
	int?sz?=?sizeof(s)?/?sizeof(s[0]);
	qsort(s,?sz,?sizeof(s[0]),?cmp_stu_by_name);
	int?i?=?0;
	for?(i?=?0;?i?<?sz;?i++)
	{
		printf("%s?",?s[i]);
	}
}



//实现bubble_sort函数的程序员,他是否知道未来排序的数据类型-不知道
//那程序员也不知道,待比较的两个元素的类型

void?Swap(char*?buf1,?char*?buf2,?int?width)
{
	int?i?=?0;
	for?(i?=?0;?i?<?width;?i++)
	{
		char?tmp?=?*buf1;
		*buf1?=?*buf2;
		*buf2?=?tmp;
		buf1++;
		buf2++;
	}
}
void??bubble_sort(void*?base,?int?sz,?int?width,?int?(*cmp)(const?void*?e1,?const?void*?e2))
{
	int?i?=?0;
	for?(i?=?0;?i?<?sz?-?1;?i++)
	{
		//每一趟冒泡排序
		int?j?=?0;
		for?(j?=?0;?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?cmp_stu_by_age(const?void*?e1,?const?void*?e2)
{
	//比较两个年龄
	return?((struct?stu*)e1)->age?-?((struct?stu*)e2)->age;
}
void?test5()
{
	struct?stu?s[3]?=?{?{"zhangsan",20},{"lisi",30},{"wangwu",10}?};
	int?sz?=?sizeof(s)?/?sizeof(s[0]);
	//使用bubble_sort的程序员一定知道自己排序的是什么数据
	//就应该知道如何比较待排序数组中的元素
	bubble_sort(s,?sz,?sizeof(s[0]),cmp_stu_by_age);
}

int?main()
{
??
	//通过qsort排序
	test1();?//排序整型数组
	test2();?//排序浮点型数组
	test3();?//排序-?通过结构体数组的年龄
	test4();?//排序-?通过结构体数组的名字
	test5();?//仿照qsort来修改冒泡函数实现能够排序任意类型
	return?0;
}


9->指针和数组面试题的解析

//9.指针和数组面试题的解析

int?main()
{
	//数组名是首元素地址
	//例外
	//1.sizeof(数组名)?-?数组名表示整个数组
	//2.&数组名?-?数组名表示整个数组
??//
	//一维数组
	int?a[]?=?{?1,2,3,4?};
	printf("%d\n",?sizeof(a));????//sizeof(数组名)?-?计算的是数组总大小?-?单位是字节?-16
	printf("%d\n",?sizeof(a?+?0));//?4/8?-?数组名这里表示首元素的值,a+0还是首元素地址,地址的大小就是4/8个字节
	printf("%d\n",?sizeof(*a));???//4?-?数组名表示首元素地址,*a就是首元素
	printf("%d\n",?sizeof(a?+?1));//?4/8?-?第二个元素的地址,地址的大小就是4/8个字节
	printf("%d\n",?sizeof(a[1]));?//4?-?第2个元素的大小
	printf("%d\n",?sizeof(&a));???//?4/8?-?&a取出的是数组的地址,但是数组地址那也是地址,地址的大小就是4/8个字节
	printf("%d\n",?sizeof(*&a));??//16
	printf("%d\n",?sizeof(&a?+?1));?//?4/8
	printf("%d\n",?sizeof(&a[0]));	//?4/8
	printf("%d\n",?sizeof(&a[0]?+?1));//?4/8
	return?0;
}
//字符数组
int?main()
{
	char?arr[]?=?{?‘a‘,‘b‘,‘c‘,‘d‘,‘e‘,‘f‘?};
	printf("%d\n",?sizeof(arr));;	//6
	printf("%d\n",?sizeof(arr?+?0));//?4/8
	printf("%d\n",?sizeof(*arr));???//?1
	printf("%d\n",?sizeof(arr[1]));?//1
	printf("%d\n",?sizeof(&arr));	//4/8
	printf("%d\n",?sizeof(&arr?+?1));?//?4/8
	printf("%d\n",?sizeof(&arr[0]?+?1));?//?4/8
	
	printf("%d\n",?strlen(arr));	//?随机值
	printf("%d\n",?strlen(arr?+?0));//?随机值
	//printf("%d\n",?strlen(*arr));???//?err
	//printf("%d\n",?strlen(arr[1]));?//?err

	printf("%d\n",?strlen(&arr));	//?随机值
	printf("%d\n",?strlen(&arr?+?1));?//随机值-6
	printf("%d\n",?strlen(&arr[0]?+?1));?//随机值-1
	return?0;

}

int?main()
{
	char?arr[]?=?"abcdef";

	printf("%d\n",?sizeof(arr));	//?7??
	printf("%d\n",?sizeof(arr?+?0));//?4/8
	printf("%d\n",?sizeof(*arr));	//1
	printf("%d\n",?sizeof(arr[1]));?//1
	printf("%d\n",?sizeof(&arr));???//?4/8
	printf("%d\n",?sizeof(&arr?+?1));//?4/8
	printf("%d\n",?sizeof(&arr[0]?+?1));//?4/8

	printf("%d\n",?strlen(arr));	//?6
	printf("%d\n",?strlen(arr?+?0));//?6
	//printf("%d\n",?strlen(*arr));	//err
	//printf("%d\n",?strlen(arr[1]));?//err
	printf("%d\n",?strlen(&arr));???//?6
	printf("%d\n",?strlen(&arr?+?1));//随机值
	printf("%d\n",?strlen(&arr[0]?+?1));//?5

	return?0;
}

int?main()
{
	const?char*?p?=?"abcdef";
	printf("%d\n",?sizeof(p));		//?4/8
	printf("%d\n",?sizeof(p?+?1));	//?4/8
	printf("%d\n",?sizeof(*p));		//?1
	printf("%d\n",?sizeof(p[0]));	//?1	p[0]?==?*(p?+?0)?==?‘a‘
	printf("%d\n",?sizeof(&p));		//?4/8
	printf("%d\n",?sizeof(&p?+?1));	//?4/8
	printf("%d\n",?sizeof(&p[0]?+?1));//?4/8

	printf("%d\n",?strlen(p));		//?6
	printf("%d\n",?strlen(p?+?1));	//?5
	//printf("%d\n",?strlen(*p));	//?err
	//printf("%d\n",?strlen(p[0]));	//?err	p[0]?==?*(p?+?0)?==?‘a‘
	printf("%d\n",?strlen(&p));		//?随机值
	printf("%d\n",?strlen(&p?+?1));	//?随机值
	printf("%d\n",?strlen(&p[0]?+?1));//?5
	return?0;
}
//二维数组
int?main()
{
	int?a[3][4]?=?{?0?};
	printf("%d\n",?sizeof(a));?//?48
	printf("%d\n",?sizeof(a[0][0]));//4
	printf("%d\n",?sizeof(a[0]));???//16??a[0]相当于第一行做为一维数组的数组名?==?sizeof(数组名)
?	printf("%d\n",?sizeof(a[0]?+?1));//?4/8?a[0]是第一行首元素地址?a[0]+1,第一行第二个元素的地址
	printf("%d\n",?sizeof(*(a[0]?+?1)));//4
	printf("%d\n",?sizeof(a?+?1));???//4/8??a是二维数组的首元素地址,而二维数组的首元素是第一行,及把二位数组看作了一维数组,a+1就是第二行的地址
	printf("%d\n",?sizeof(*(a?+?1)));//16
	printf("%d\n",?sizeof(&a[0]?+?1));//4/8?第二行地址
	printf("%d\n",?sizeof(*(&a[0]?+?1)));//16
	printf("%d\n",?sizeof(*a));?//16?*a?=?第一行地址解引用
	printf("%d\n",?sizeof(a[3]));?//16?表示第四行,sizeof不参与真实计算
	return?0;
}
//指针笔试题
int?main()
{
	int?a[5]?=?{?1,2,3,4,5?};
	int*?ptr?=?(int*)(&a?+?1);?//&a?+?1?为5后面的地址
	printf("%d,?%d\n",?*(a?+?1),?*(ptr?-?1));?//2?5??
	return?0;
}

struct?Test
{
	int?Num;
	char*?pcName;
	short?sDate;
	char?cha[2];
	short?sBa[4];
}*p;?//结构体指针?p

//假设p?的值为ox100000,如下表表达式的值分别为多少?
//已知,?结构体Test类型的变量大小是20个字节

int?main()
{
	p?=?(struct?Test*)0x100000;
	printf("%p\n",?p?+?0x1);??//0x00100014?
	printf("%p\n",?(unsigned?long)p?+?0x1);?//0x00100001
	printf("%p\n",?(unsigned?int*)p?+?0x1);?//0x00100004
	return?0;
}
?
int?main()
{
	int?a[4]?=?{?1,2,3,4?};
	int*?ptr1?=?(int*)(&a?+?1);
	int*?ptr2?=?(int*)((int)a?+?1);
	printf("%x,%x",?ptr1[-1],?*ptr2);//?4?0x02000000
	return?0;
}

int?main()
{
	int?a[3][2]?=?{?(0,1),(2,3),(4,5)?};//逗号表达式?1,3,5
	int*?p;
	p?=?a[0];?//第一行?1,?3
	printf("%d",?p[0]);?//1?
	return?0;
}

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

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));?//*(aa?+?1)?==?aa[1]
	printf("%d,%d\n",?*(ptr1?-?1),?*(ptr2?-?1));?//?10?5
	return?0;
}

int?main()
{
	char*?a[]?=?{?"work","at","alinbaba"?};
	char**?pa?=?a;

	pa++;
	printf("%s\n",?*pa);//at
	return?0;
}


C语言指针进阶阶段知识总结

原文:https://blog.51cto.com/u_15157811/2833720

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!