深入理解C语言指针

什么是指针

指针:存储变量的地址。

指针变量

专门用于存储指针的变量。

指针的定义

类型* 变量名;

char *p  *p 取出一个字节的内容

short *p *p取出两个字节的内容

int *p  *p取出四个字节的内容

指针的长度

在32位系统下,指针的长度为32位,即4个字节。

指针的运算

指针+整数:右移n个元素

指针-整数:左移n个元素

指针- 指针:地址差/元素的长度

指针与一维数组的关系

int buf = {0,1,2,3,4,5,6,7,8,9};

int *pbuf = buf;

下标法:

buf[i];第i个元素的值.

指针法:

*(pa+i):第i个元素的值

指针与二维数组的关系

int buf[2][3] = {{1,2,3},{4,5,6}}

物理结构:在内存中地址是连续地

逻辑结构:二维结构

buf为首地址 为第一行的首地址

buf[n] 为第n+1行第1列的首地址

指针变量与二维数组的关系

二维数组指针变量:类型 (*p)[列长度]

此时p为行指针 *p为列指针

指针数组

存放多个指针的数组

类型 *p[长度]

该数组专门用于存储地址

函数指针变量:

返回类型 (*p)(参数)

用于存储函数的入口地址

使用函数指针变量的好处:直接调用函数在编译时就确定,而使用函数指针变量来调用函数是在运行时确定。属于静态联编与动态联编的区别。

有了这些概念之后,我们来看几个小的例子

	char* pa=(void*)0;

	short* pb=(void*)0;

	int * pc=(void*)0;


	printf("%d %d %d %d\n",pa,pa+1,pa+2,pa+3);

	printf("%d %d %d %d\n",pb,pb+1,pb+2,pb+3);

	printf("%d %d %d %d\n",pc,pc+1,pc+2,pc+3);

其运算结果为

0  1  2  3
0  2  4  6
0  4  8  12

该知识点主要为指针指向的类型以及指针的加减一个整数:通过结果我们可以看出指针的加减为 指针+-n = p+-sizeof(去掉一个*)之后的值。大家可以通过上面的例子,可以试试

下面的题目。

	int a=67305985;

	char* p1=(char*)&a;

	short* p2=(short*)&a;

	int* p3=(int*)&a;


	printf("%d %d %d %d\n",a,*p1,*p2,*p3);

	printf("%d %d %d %d %d\n",a,*p1,*(p1+0),*(p1+1),*p1+2);

	printf("%d %d %d %d\n",a,*p2,*(p2+0),*(p2+1));

指针数组

#include<stdio.h>

void main()
{
	//字符数组: 数组名是首地址
	char name1[10]="lifei";
	char name2[10]="zhangsan";
	char name3[10]="wangwu";
	//数组:用于存储多个指针
	char* buf[4]={name1,name2,name3};
	//引用
	printf("%c %c\n",*(buf[0]+0),buf[0][0]);
	printf("%s %s\n",*(buf+0),buf[1]);

	//打印第1列
	printf("%c %c %c\n",buf[0][0],*(buf[1]+0),buf[2][0]);

	//打印所有内容
	char**  pbuf=buf;
	do
	{
		printf("%s\n",*pbuf);
	}while(NULL!=*(++pbuf));
}
数组指针

#include<stdio.h>

void main()
{
	//二维数组:
	int score[4][5]={{1,2,3,4,5},{6,7,8,9,10},{11,12,13,14,15},{16,17,18,19,20}};
	//引用:下标法,指针法
	printf("%d\n",score[2][1]);
	//行与列指针:
	printf("%x %x %x %x\n",&score[0][0],&score[1][0],&score[2][0],&score[3][0]);
	//行+n   指向第n行
	printf("%x %x  %x  %x\n",score+0,score+1,score+2,score+3);
	//列:  列+1指向下一列
	printf("%x %x %x %x\n",*(score+0)+0,score[0]+1,score[0]+2,*(score+0)+3);
	//打印元素:确定此元素的地址
	printf("%d %d %d\n",score[2][2],(*(score+2))[2],*(*(score+2)+2));	
	//指针变量:
	int* pscore=score;
	printf("%d",*(pscore+1));
	//说明:pscore+1指向下个元素
	//二维数组指针:
	int (*mp)[5]=score;
	printf("%x %x %x %x\n",mp,mp+1,mp+2,mp+3);
	//指针
	printf("%x %x %x %x\n",*(mp)+0,mp[0]+1,*mp+2,mp[0]+3);
	//列指针
	//第3行  通过mp指针
	int i=0;
	for(i=0;i<5;i++)
		printf("%d %d\n",mp[2][i],*(*(mp+2)+i));

	for(i=0;i<4;i++)
		printf("%d %d\n",mp[i][1],*(*(mp+i)+1));
	for(i=0;i<20;i++)
	{
	//	printf("%d ",mp[i/5][i%5]);
		printf("%d %d\n",*(pscore+i),pscore[i]);
	}
}

函数指针

#include<stdio.h>


int show()
{
	int i=0;
	for(i=1;i<10;i++)
	{
		printf("%d ",i);
	}
	return 0;
}
int*   display(int* pbuf)
{
	int i=0;
	for(i=0;i<10;i++)
		printf("%d ",pbuf[i]);
	return NULL;
}

void main()
{
//调用函数:
	show();
//调用函数:
	int buf[10]={1,2,3,4,5,7,8,9,0,10};
	//display(buf);
//定义函数指针变量:
	int*  (*pfun)(int*)=NULL;
	printf("%d\n",sizeof(pfun));
	//调用函数
	display(buf);//静态调用:在编译时就已经确定调用某函数
	pfun(buf);//动态调用:在编译时无法确定调用某函数,只能在运行才能确定。
}









  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值