初学指针汇总

指针

变量访问常用的方式有两种,一种是直接通过变量名访问,另一种则是通过访问变量的存放位置访问,指针变量,即存有变量存放地址的变量
例如,你打出租车去中国计量大学,你可以和司机说学校名中国计量大学去,也可以和司机说杭州钱塘区下沙学源街258号的地址去。
示例代码

#include<stdio.h>
int main()
{
	int a=10;
	int *pa=&a;
	printf("a is %d\n",a);                  //变量名访问
	printf("the number pa save is %d\n",*pa);//地址访问(指针)
	return 0;
}

请添加图片描述

指针定义

//数据类型 *变量名;
int *p;
double *p;

//&用于获取变量地址
int *pa=&a;//将a的地址赋给pa指针变量

//*用于获取地址中所保存的内容
int a=*pa;//将pa所指向地址存储的值赋给a

指针类型

既然指针存储的是变量的地址为什么还要区分类型呢?
指针的类型会影响两个因素:1.决定指向空间的大小 2.决定增量

#include<stdio.h>
int main()
{
	int a = 0x1234;
	int *p = &a;
	char *c = &a;
	
	printf("the address of p = %p\n",p);
	printf("the address of c = %p\n\n",c);
	
	printf("the content of p = %p\n",*p);
	printf("the content of c = %p\n\n",*c); //访问时会根据指针类型访问不同空间大小,虽然指针指向地址相同,但是空间大小并不一致
	
	printf("the next address of p = %p\n",++p);
	printf("the next address of c = %p\n\n",++c); //同时自增的大小也不同
	
}

在这里插入图片描述
因此,在定义指针变量时要注意指针类型一致。

指针应用场景

函数封装

#include<stdio.h>
void exchange_1(int a,int b)
{
	int tmp = a;
	a = b;
	b = tmp;
}

void exchange_2(int *pa,int *pb)
{
	int tmp = *pa;
	*pa = *pb;
	*pb = tmp;
}


int main()
{
	int a=10;
	int b=20;
	exchange_1(a,b);
	printf("after exchange1 a is %d,b is %d\n",a,b);
	exchange_2(&a,&b);
	printf("after exchange2 a is %d,b is %d\n",a,b);
	
}

在这里插入图片描述
从结果中可以看出经过exchange_1函数交换,原来的a,b值并未发生交换,这是因为函数并不是对a,b原有的地址进行操作,而经过exchange_2后,a,b 发生了交换

需要你指向特定的存储区域
1.单片机
2.armbootloarder

指针与数组

通过指针引用数组

定义指针指向数组,并通过指针偏移遍历数组

#include<stdio.h>
int main()
{
	int arr[3]={1,2,3};
	int *p;
	
	p=arr;//定义指针指向数组,数组名就是数组的首地址
	printf("首元素是:%d\n",*p);
	
	int length=sizeof(arr)/sizeof(arr[0]);
	
	printf("arr中的元素为:");
	for(int i=0;i<length;i++)
	{
		printf("%d ",*p);
		p++;
	}
	
	return 0;
}

见怪不怪
1.指针当作数组名

#include<stdio.h>
int main()
{
	int arr[6]={0,1,2,3,4,5};
	int *p=arr;
	for(int i=0;i<6;i++)
	{
		printf("%d ",p[i]);
	}
	return 0;
}

在这里插入图片描述

2.数组名拿来加

#include<stdio.h>
int main()
{
	int arr[6]={0,1,2,3,4,5};
	int *p=arr;
	for(int i=0;i<6;i++)
	{
		printf("%d ",*(arr+i));
	}
	return 0;
}

在这里插入图片描述

指针二维数组

在这里插入图片描述
二维数组本质上还是数组,不同点是其数组元素还是一个数组(子数组),因此我们就可以知道a表示的是父数组的地址;
a[0],*a表示的子数组的地址

#include<stdio.h>
int main()
{
	int arr[4][4]={{11,12,13,14},
					{21,22,23,24},
					{31,32,33,34},
					{41,42,43,44}};
	printf("父数组地址是0x%p\t偏移一位后为0x%p\n",arr,arr+1);
	printf("子数组地址是0x%p\t偏移一位后为0x%p\n",*arr,*(arr)+1);
	printf("子数组地址是0x%p\t偏移一位后为0x%p\n",arr[0],arr[0]+1);
}

在这里插入图片描述
小总结
在这里插入图片描述

二级(多级)指针

二级指针可以理解为指针的指针,即该指针变量保存的是指针变量的地址

#include<stdio.h>
int main()
{
	int data=100;
	int *p=&data;
	printf("data的地址是:0x%p\n",&data);
	printf("p保存的是data的地址:0x%p,内容是%d\n",p,*p);
	
	
	int **p2=&p;
	printf("p的地址是:0x%p\n",&p);
	printf("p2保存的是.p的地址:0x%p,内容是0x%p\n",p2,*p2);
	
	
	int ***p3=&p2;
	printf("p2的地址是:0x%p\n",&p2);
	printf("p3保存的是p2的地址:0x%p,内容是0x%p\n",p3,*p3);
}

在这里插入图片描述

数组指针与指针数组

数组指针

定义:指向一个数组的指针 int (*p)[4]

#include<stdio.h>
int main()
{
	int arr[4][4]={{11,12,13,14},
					{21,22,23,24},
					{31,32,33,34},
					{41,42,43,44}};
	int(*p)[4]=arr;//定义一个数组指针指向int[4]的数组
	//数组指针才真正等价于一个二维数组名
	for(int i=0;i<4;i++)
	{
		for(int j=0;j<4;j++){
			printf("%d\t",*(*(p+i)+j));//通过该指针遍历数组
		}
		printf("\n");
	}
}

在这里插入图片描述

二级指针不可直接指向二维数组

#include<stdio.h>
int main()
{
	int arr[4][4]={{11,12,13,14},
					{21,22,23,24},
					{31,32,33,34},
					{41,42,43,44}};
	int **p;
	p=arr;//会出问题;一般认为*p是野指针
	printf("The address of arr:0x%p\n",arr);
	printf("p=0x%p\n",p);
	printf("*p=0x%p\n",*p);
	printf("*arr=0x%p\n",*arr);
	
}

在这里插入图片描述
在编译时产生了报错。

#include<stdio.h>
int main()
{
	int arr[4][4]={{11,12,13,14},
					{21,22,23,24},
					{31,32,33,34},
					{41,42,43,44}};
	int(*p1)[4]=arr;//先定义一个数组指针
	
	int **p=&p1;//定义二级指针指向该数组指针
	
	**p=100;//通过二级指针修改数组
	printf("%d",arr[0][0]);

}

在这里插入图片描述

指针数组

指针数组是一个保存指针变量的数组,其数组中的每个元素都为指针变量

#include<stdio.h>
#include<stdlib.h>

int main()
{
	int a=10;
	int b=20;
	int c=30;
	int d=40;
	
	int* p[4]={&a,&b,&c,&d};
	for(int i=0;i<4;i++)
	{
		printf("%d ",*p[i]);
	}
	
}

在这里插入图片描述

函数指针与指针函数

函数指针

如果在程序中定义了一个函数,在编译时,编译系统为函数代码分配一段存储空间,这段存储空间的起始地址(又称入口地址)成为这个函数的的指针。
函数指针是指向函数的指针变量。
函数指针可以像一般函数一样,用于调用函数、传递参数。

#include<stdio.h>

void printWelcome()
{
	puts("welcome to use");
}
int Increase(int data)
{
	return ++data;
}
int main()
{
	void (*p)(); //define functionPointer
	p=printWelcome;//point to function
	(*p)(); //use function
	int (*pa)(int);
	pa=Increase;
	int a=10;
	int b=(*pa)(a);
	printf("%d\n",b);
	printWelcome();
	return 0;
} 

在这里插入图片描述

指针函数

指针函数只指针作为函数的形参或者返回值。

指针和字符串

字符串可以粗略理解为字符变量的数组,其应用同数组与指针。

一些面试题常见

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值