C语言指针-- 进阶学习(二)

指针进阶(一)

指针的运算

1、指针的运算
指针+整数 = 指针
指针-整数 = 指针 和加法的规则一样。
结论:实际增加\减少 = 整数 +- 指针所指向类型所占内存大小

	int a = 10,b = 20,c = 30;
	printf("a=%d,b=%d,c=%d\n",a,b,c);
	int *pa = &a,*pb = &b,*pc = &c;
	printf("pa=%d,pb=%d,pc=%d\n",pa,pb,pc);
	
	int *pd = pa +10;
	printf("pd = %d\n",pd); 
	
	double d = 45.6;
	double *pdouble = &d;
	printf("pdouble = %d\n",pdouble); 
	printf("pdouble + 5 = %d\n",pdouble + 5); 

	char ch = 'A';
	char *pch = &ch;
	printf("pd = %d\n",pch); 
	printf("pd = %d\n",pch + 5); 

C语言指针-- 进阶学习(二)_第1张图片
指针-指针 = 单位长度

printf("%d\n",pa - pb );

指针的运算
在一段连续的内存空间,数组,动态开辟的内存中使用

	int arr[10] = {1,2,3,4,5,6,7,8,9,10};
	printf("arr = %d\n",arr);
	printf("arr = %d\n",&arr[0]);
	printf("arr = %d\n",&arr[1]);
	//arr 是常量
	//arr 的类型 指向int型的指针 
int* parr = arr;
	printf("arr = %d\n",arr+1);
	printf("arr = %d\n",arr+2);
	printf("arr = %d\n",arr+10);//能打印 但是越界了 

指针和一维数组的关系:

	//推导
	
	arr + 0 = &arr[0]
	arr + 1 = &arr[1]
	arr + 2 = &arr[2]
	...
	arr + 3 = &arr[3]	
	
	//继续推导
	
	*(arr + 0) =  arr[0]
	*(arr + 1) =  arr[1]
	*(arr + 2) =  arr[2]
	...
	*(arr + 3) =  arr[3]
	

注意:

,<这两个判断指针的大小,需要在一段连续的内存空间比较才有意义。
== != 这两个可以随意比较。

指针进阶(二)

指针和二维数组的关系:
1、arr表示 什么? 首地址型是什么? 不是指向int型的指针,是一个指向一维数组的指针
2、可以把二维数组看做成一维数组,只不过这个一维数组中每个元素有5个元素

	int i = 0;
	int j = 0; 
	int arr[4][5]=
	{
	    {1,2,3,4,5},
		{6,7,8,9,10},
		{11,12,13,14,15},
		{16,17,18,19,20}
	}; 
	for(i = 0;i<4;i++)
	{
	    for(j = 0;j<5;j++)
	    {
    	printf("a[%d][%d] = %d ",i,j,arr[i][j]);
  //另一种访问方式:
		printf("a[%d][%d] = %d ",i,j,*(*(arr+i) + j));
	    }
//	    	printf("\n");
	}

指针数组:是一个数组,数组里面存储的都是指针。
int * arr[4] = {&a,&b,&c,null };

数组指针:是一个指针

typedef  int(*PARR)[5];//是一种新的类型 ,数组指针类型 
arr; //数组指针 指向一个数组 
int (*parr)[5] = arr;//现在就定义了数组指针 
PARR parr2 = arr; 

地址偏移了多少?

	printf("%d\n",arr + 0);//偏移的字节数 = 类型*大小 
	printf("%d\n",arr + 1);
	printf("%d\n",arr + 2);
	printf("%d\n",arr + 3);
	printf("\n");

间接访问

	printf("%d\n",*(arr + 0));//得到整个数组,数组名=》arr2[0] 
	printf("%d\n",*(arr + 1));
	printf("%d\n",*(arr + 2));
	printf("%d\n",*(arr + 3));

推导:

  *(arr + 0) = 》arr[0] 
	*(arr + 1) = 》arr[1]
	*(arr + 2) = 》arr[2]
	*(arr + 3) = 》arr[3]

arr + 0; //类型是指向整个一维数组的指针
arr[0]; //类型是指向整型的指针

*(*(arr+0) + 0) =》 arr[0] + 0;
*(arr+0) + 2    =&arr[0][2]=》 arr[0] + 2; 
*(*(arr+0) + 2) =3//得到数字3
printf("%d\n",*(*(arr+1) + 2));

推导

  *(*(arr+0)+0) => arr[0][0] 
	*(*(arr+0)+1) => arr[0][1] 
	*(*(arr+0)+2) => arr[0][2] 
	*(*(arr+0)+3) => arr[0][3] 

三维数组:

	int arr[2][3][4]  = {0,1,2,3};
	int (*parr)[3][4] = arr;

指针和字符串的关系,这个指针的类型是 : char *型

  //字符串的首地址,指针
	printf("%d\n","hello,world"); 
	char *str = "hello world"; 
	printf("%s\n",str); 
*"hello,world";
printf("hello,world = %c\n",*"hello,world"); //得到的是h
	printf("hello,world = %c\n",*("hello,world"+1)); //打印出e

数组下标访问和数组的间接访问

printf("hello,world [0]= %c\n","hello,world"[0]); 

数组指针:是一个指针,指向数组的指针
区别 占用空间不一样。

	char str[4][10] = {"hello world","china","123456","yellow"};
	char *strarr[4] = {"hello world","china","123456","yellow"};
	for(i = 0;i<4;i++)
	{
		printf("%s\n",strarr[i]);
	}

指针进阶(三)

交换两个变量的数值
传值和传址不同,传值都是传递的一种拷贝,不管传值还是传地址 都是传递的是一种拷贝。

void swap(int *pa,int *pb)
{
	int temp = *pa;
	*pa = *pb;
	*pb = temp;
} 
void display(char* str)
{
	printf("%s\n",str);
}

传递一个数组
数组作为函数参数传递的时候,传递的是首地址,而不是整个数组了,已经变成了地址而不是数组了。

//方式1
void printArr(int arr[],int length);
//方式2
void printArr(int *arr,int length)
{
	for(int i; i<length;i++)
	{
		//printf("%d, ",arr[i]);
		printf("%d, ",*(arr+i));
	}
	printf("\n");
} 
//主函数
printArr(arr,sizeof(arr)/sizeof(arr[0]));

二维数组作为函数参数传递。

void printArr2(int (*arr)[5],int x,int y)
{
	for(int i = 0; i<x;i++){
		for(int j = 0; j<y;j++)
		{
			
			printf("%d, ",arr[i][j]);
		}
		printf("\n");
	}
}
//二维数组作为函数参数进行传递
	int arr2[4][5] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
	printArr2(arr2,4,5);
void showdouble(double *d)
{
printf("浮点数 :%f\n",*d);
}
	double d = 456.678;
	showdouble(&d);

指针作为函数的返回值
注意:返回的地址必须是可用的,就是没有释放的。

int* test()
{
	int a= 10,b=20,c=10;
	c = a + b;
	return &c; 
}
	int *p = test();
	*p = 45; //后续不可以使用 
	printf("p=%d\n",*p);
//没问题的
int* test1(int *c)
{
	*c = 1000;
	return c;	
}
	int *pa = test1(&a); 
	printf("a= %d\n",a);

数组不能作为函数参数返回。

函数指针:
类型是什么?
类型是指向函数的指针。

void show()
{
	printf("你好"); 
}
printf("show = %d\n",show); //打印函数名,函数指针
void(*pShow)() = show;//pShow是一个函数指针
(*pShow)();
//另一种写法 
pShow(); 

指向函数的指针

	typedef void (*PSWAP)(int *,int *) ;//定义一种新类型
	void (*pswap)(int *pa,int *pb) = swap;//指向函数的指针
	pswap(&a,&b);
	PSWAP pswap = swap; //起别名 
	printf("a=%d,b=%d,c=%d\n",a,b,c);

你可能感兴趣的:(#,C语言指针,c语言)