您的位置:首页 > 编程语言 > C语言/C++

深入理解C语言指针

2017-07-24 21:54 190 查看

什么是指针指针:存储变量的地址。

指针变量

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

指针的定义

类型* 变量名;
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+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);//动态调用:在编译时无法确定调用某函数,只能在运行才能确定。
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: