0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

C语言指针

嵌入式技术 来源:嵌入式技术 作者:嵌入式技术 2022-08-18 17:36 次阅读

C语言指针

1、指针定义

  指针是一个变量, 它保存的是另一个变量的地址, 即内存位置的直接地址。

int ptr; //整型变量,ptr+1 表示变量值+1;
const int ptr;//只读变量,和int const ptr效果一致;
int *ptr1; //定义一个整型指针, ptr+1 表示地址偏移 int 类型字节;
int ptr[3];//3 个成员的整型数组, ptr+1 表示指向 ptr[1]的地址;
int *ptr[3];//指针数组,ptr[3]是数组,int*再与 ptr[3]结合成指针数组, 表明数组中保存着 int 类型的指针, ptr+1 表示指向 ptr[1][]的地址, 即二维数组 ptr[1][0]的地址;
int (*ptr)[3];//数组指针,()优先级高,(*ptr)是指针, 再与[3]结合, 说明指针所指向的内容是数组, 最后和 int 结合, 表示数组元素类型是 int 类型。ptr+1 表示指向 ptr[1][]的地址, 即 ptr[1][]的地址;
int **ptr;//二维指针变量, 保存一维指针变量的地址;
int const *ptr;//常量指针,ptr指向的内容不可以修改,但可以改变指向;
int *const ptr;//指针常量,ptr的指向不可以修改,但可以修改指向的内容;

2、*p++、 *(p++)、 *++p、 ++*p、 *p+1、 *(p+1)

#include 
int main()
{
	int buff[]={10,20,30};
	int *p=buff;
	/*1 buff[0]的地址:&buff[0]*/
	printf("print1 buff addr:%#x\n",buff);
	/*2 buff[0]的地址:&buff[0]*/
	printf("print2 p addr:%#x\n",p);
	/*3 偏移 sizeof(int)字节*/
	printf("print3 p+1 addr:%#x\n",p+1);
	/*4 取 buff[0]的值*/
	printf("print4 *p=%d\n",*p);
	/*5 取 buff[0]的值+1*/
	printf("print5 *p+1=%d\n",*p+1);
	/*6 地址偏移 sizeof(int)再取值, 即 buff[1]*/
	printf("print6 *(p+1)=%d\n",*(p+1));
	/*7 先取*p 的值,再 p+1*/
	printf("print7 *p++=%d\n",*p++);
	/*8 先取*p 的值, 再(*p)+1*/
	printf("print8 ++*p=%d\n",++*p);
	/*9 先 p+1,再取*(p+1)*/
	printf("print9 *++p=%d\n",*++p);
}
  • 运行结果:
[xsw@xsw cc]$ ./a.out
print1 buff addr:0xbf98f2a0
print2 p addr:0xbf98f2a0
print3 p+1 addr:0xbf98f2a4
print4 *p=10
print5 *p+1=11
print6 *(p+1)=20
print7 *p++=10
print8 ++*p=21
print9 *++p=30

3.NULL指针和void*指针

  NULL 是标准宏定义, 用来表示空指针常量, 在声明指针变量时若没有确切地址赋值, 可以给指针变量赋NULL。

#include 
int main()
{
	char *ptr=NULL;
	printf("ptr addr:%d\n",ptr);
	return 0;
}
  • 执行结果
[xsw@xsw cc]$ ./a.out
ptr addr:0

 在大多数操作系统中程序不允许访问地址为 0 的内存, 因为该内存是操作系统保留的。 指针指向地址为 0 的内存表示该指针指向的地址不可访问。 按照惯例 NULL 指针假定为不指向任何东西。

  void 表示”无类型”, void*指针表示”无类型指针”, 即可指向任何数据类型。


#include 
int main()
{
	void *p;
	int a=100;
	char buff[]={0,10,20,30};
	p=&a;//保存 int 型变量地址
	//void*指针访取值时要保证和所指向的变量类型一致
	printf("*p=%d\n",*((int *)p));//强制转换成 int*
	p=buff;//指向字符数组首地址
	//强制转换成 char*
	printf("*p=%d\n",*(char *)p);//buff[0]
	printf("*(p+1)=%d\n",*(char *)(p+1));//地址往后偏移 char 字节: buff[1]
	printf("*p+1=%d\n",*(char *)p+1);//取出的值+1: buff[0]+1
	return 0;
}
  • 执行结果
*p=100
*p=0
*(p+1)=10
*p+1=1

  注:void 几乎只能用于指针的声明和函数返回值以及函数形参, 不能用于变量的定义。

4、二维指针

  二维指针:指向指针的指针。 保存一维指针的地址。
  指针声明:int **ptr;

#include 
int main()
{
	int a=0x12;
	int *ptr=&a;//一维指针保存变量地址
	int **pptr=&ptr;//二维指针保存一维指针本身地址
	//1 ptr==&a
	printf("line1:a addr:%#x\n",ptr);
	//2 *(&ptr)==&a
	printf("line2:*(&ptr)=%#x\n",*(&ptr));
	//3 pptr==&ptr
	printf("line3:pptr :%#x\n",pptr);
	//4 *ptr==*(&a)==a
	printf("line4:*ptr=%#x\n",*ptr);
	//5 *(&ptr)==ptr==&a
	printf("line5:*pptr=%#x\n",*pptr);
	//6 **pptr==**(&ptr)==*ptr=*(&a)
	printf("line6:**pptr=%#x\n",**pptr);
	//7 ***(&pptr)==**(&ptr)==*ptr==*(&num)=0x12
	printf("line7:**pptr=%#x\n",***(&pptr));
}
  • 执行结果:
[xsw@xsw cc]$ ./a.out
line1:a addr:0xbf90384c
line2:*(&ptr)=0xbf90384c
line3:pptr :0xbf903848
line4:*ptr=0x12
line5:*pptr=0xbf90384c
line6:**pptr=0x12
line7:**pptr=0x12

5、数组指针

指针定义:int (p)[n];指向数组整体的指针。 数组指针类型:int ()[n];

()优先级高, 所以 p 是一个指针, 指向一个整型的一维数组, 一维数组的成员个数位 n, 也就是说 p 的步长为 n。 即 p+1 偏移的地址为 n 个 int 型长度。 因此数组指针也称为行指针。

优先级: () > [] > *

示例一:数组指针指向一维数组示例

#include 
int main()
{
	int buff[]={11,22,33,44,55,66};
	int (*ptr)[6];//数组指针,指向数组整体
	ptr=&buff;
	int i;
	//数组指针 ptr+1 偏移指向的数组整体大小,即偏移 6*sizeof(int)=24 字节
	printf("ptr addr:%#x\n",ptr);
	printf("(ptr+1) addr:%#x\n",ptr+1);
	/*数组指针遍历 buff*/
	for(i=0;i<6;i++)
	{
		printf("%d ",*(*ptr+i));//或*(ptr[0]+i)或 ptr[0][i]
	}
	printf("\n");
	return 0;
}
  • 执行结果:
[root@xsw cc]# ./a.out
ptr addr:0xbfbc8ce0
(ptr+1) addr:0xbfbc8cf8
11 22 33 44 55 66

示例二:数组指针指向二维数组示例:

#include 
int main()
{
	int buff[][3]={1,10,3,4,5,6};//每行有 3 个元素
	int (*p)[3]=buff;
	printf("*p[0]=%d\n",*p[0]);//等价于 buff[0][0]
	printf("*(p[0]+1)=%d\n",*(p[0]+1));//等价于 buff[0][1]
	printf("*p[1]=%d\n",*p[1]);//等价于 buff[1][0]
}

6、指针数组

  定义:int p[n];数组中保存 int指针。指针数组类型:int *[n], p的类型是 int **,p+1 偏移的地址为:sizeof(int *)。
  示例一:将一维数组赋值给指针数组:

#include 
int main()
{
	int buff[]={11,22,33,44,55,66};
	/*
	//初始化直接赋值
	int *ptr[10]={&buff[0],&buff[1],&buff[2],&buff[3],&buff[4],&buff[4]}
	*/
	int *ptr[10];//指针数组,数组中保存 int 型指针
	/*数组指针赋值*/
	int i;
	for(i=0;i<6;i++)
	{
		*(ptr+i)=&buff[i];//或:buff+i
	}
	for(i=0;i<6;i++)
	{
		printf("%d ",*(*ptr+i));
	}
	printf("\n");
	return 0;
}
  • 运行结果:
[root@xsw cc]# ./a.out
11 22 33 44 55 66

  示例二:将二维数组赋值给指针数组示例

#include 
void tow_array(int (*buff)[3],int line);
int main()
{
	int buff[][3]={1,10,3,4,5,6};//每行有 3 个元素
	int *p[3];
	*p=buff[0];
	p[0]=buff[0];
	*(p+1)=buff[1];
	printf("%d\n",(*p)[0]);//等价于:p[0][0]
	printf("%d\n",(*p)[1]);//等价于 p[0][1]
	printf("%d\n",*(p[0]+1));//等价于 p[0][1]printf("%d\n",*(p+1)[0]);//等价于 p[1][0], *(p+1)指向 buff[1][0]地址
	printf("%d\n",*(*(p+1)+1));//等价于 p[1][1]
}
printf("%d\n",*(p+1)[0]);//等价于 p[1][0], *(p+1)指向 buff[1][0]地址
printf("%d\n",*(*(p+1)+1));//等价于 p[1][1]

  注:二维数组赋值给指针数组时 p=buff 是错误的。

7、函数指针

  函数指针:指向函数的指针变量。 本质是指针变量。

#include 
int func(int a,int b);
int main()
{
	//pfunc 表示函数指针变量
	int (*pfunc)(int ,int );//定义函数指针,可以在定义时初始化
	pfunc=func;//初始化函数指针,也可写成 pfunc=&func
	int data=pfunc(10,20);
	printf("%d\n",data);
}
int func(int a,int b)
{
	return a+b;
}

8、回调函数

#include 
int func_1(int a,int b);
int func_2(int a,int b);
int func_3(int a,int b);
void func_Callback(int a,int b,int (*pfunc[])(int,int),int num);
int main()
{
	int data;
	int i=0;
	//定义函数指针数组
	int (*pfunc[3])(int ,int)={func_1,func_2,func_3};
	func_Callback(30,20,pfunc,sizeof(pfunc)/sizeof(int *));
}
int func_1(int a,int b)
{
	printf("\t[%s] %s line:%d %d+%d=%d\n",__FILE__,
										__FUNCTION__,
										__LINE__,
										a,b,a+b
										);
	return a+b;
}
int func_2(int a,int b)
{
	printf("\t[%s] %s line:%d %d*%d=%d\n",__FILE__,
											__FUNCTION__,
											__LINE__,
											a,b,a*b
											);
	return a*b;
}
int func_3(int a,int b)
{
	printf("\t[%s] %s line:%d %d%%%d=%d\n",__FILE__,
											__FUNCTION__,
											__LINE__,
											a,b,a%b
											);
	return a%b;
}
/***************************回调函数******************
**
**
**形参:int a,int b ---函数指针所需要动形参
** int (*pfunc[])(int,int) --- 函数指针数组
** int num ---函数指针数组成员个数
**
*********************************************************/
void func_Callback(int a,int b,int (*pfunc[])(int,int),int num)
{
	int i;
	int data;
	for(i=0;i
  • 运行结果:

[xsw@xsw cc]$ ./a.out
[func.c] func_1 line:17 30+20=50
data=50
[func.c] func_2 line:22 30*20=600
data=600
[func.c] func_3 line:27 30%20=10
data=10

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • C语言
    +关注

    关注

    180

    文章

    7604

    浏览量

    136816
  • 指针
    +关注

    关注

    1

    文章

    480

    浏览量

    70562
收藏 人收藏

    评论

    相关推荐

    不错的C语言指针教程.pdf

    不错的C语言指针教程.pdf
    发表于 08-11 00:28

    C语言指针的高级用法

    C语言指针搞不好说实话实在是太麻烦的一个东西,而且C语言指针还是绕不过的一个坎,所以我觉得还是苦
    发表于 11-06 16:50

    什么是C语言指针变量

    C语言指针变量
    发表于 12-15 07:22

    C语言指针在32位单片机上有哪些应用呢

    C语言指针有哪些应用呢?C语言指针在32位单片机上有哪些应用呢?
    发表于 02-25 07:37

    C语言指针电子教程

    本资料是一份不错的关于C语言指针的电子教程,希望对大家有所帮助... 指针简介 指针C
    发表于 07-30 16:00 77次下载

    C语言_指针总结_经典讲解

    C语言_指针总结_经典讲解。
    发表于 01-06 13:47 10次下载

    C语言指针函数和函数指针详细介绍

    C语言指针函数和函数指针详细介绍。。。。。。。
    发表于 03-04 15:27 5次下载

    彻底搞定C语言指针详解完整版

    彻底搞定C语言指针详解完整版。
    发表于 05-10 17:04 0次下载

    C语言指针跨函数访问

    C语言指针跨函数访问
    发表于 12-16 17:23 1次下载

    嵌入式开发之C语言指针

    学习 C 语言指针既简单又有趣。通过指针,可以简化一些 C 编程任务的执行。
    的头像 发表于 11-06 17:09 3223次阅读
    嵌入式开发之<b class='flag-5'>C</b><b class='flag-5'>语言</b>的<b class='flag-5'>指针</b>

    C语言指针的表达式实例程序说明

    本文档的主要内容详细介绍的是C语言指针的表达式实例程序说明。
    发表于 11-05 17:07 4次下载
    <b class='flag-5'>C</b><b class='flag-5'>语言</b><b class='flag-5'>指针</b>的表达式实例程序说明

    C语言指针指针变量的简介和运算实例程序免费下载

    本文档的主要内容详细介绍的是C语言指针指针变量的简介和运算实例程序免费下载
    发表于 11-05 17:38 14次下载

    C语言指针的理解使用

    C语言指针的理解使用指针变量的声明给普通变量的赋值对比给指针变量的赋值代*的指针的使用说明
    发表于 01-13 13:42 3次下载
    <b class='flag-5'>C</b><b class='flag-5'>语言</b><b class='flag-5'>指针</b>的理解使用

    C语言进阶】C语言指针的高阶用法

    C语言进阶】C语言指针的高阶用法
    的头像 发表于 08-31 13:24 2336次阅读

    C语言指针学习笔记

    本文从底层内存分析,彻底让读者明白C语言指针的本质。
    的头像 发表于 11-05 17:40 236次阅读
    <b class='flag-5'>C</b><b class='flag-5'>语言</b><b class='flag-5'>指针</b>学习笔记