C语言指针入门详解

一、指针简介

  • 指针(Pointer)是C语言的一个重要知识点,其使用灵活、功能强大,是C语言的灵魂
  • 指针与底层硬件联系紧密,使用指针可操作数据的地址,实现数据的间接访问
  • 指针就是地址,通过访问此地址来获取该地址存储的数据

二、计算机存储机制

每个字节(Byte)(8位Bits)对应有自己的地址;

1、 int a = 0x123456;(一个整型是4个字节,即32位),下图中是以小端字节序跨字节存储,有关字节序内容请参考Linux系统编程-网络通信_linux系统网络通信_单行梦想家的博客-CSDN博客

2、short b = 0x5A6B;

3、char c[ ] = {0x33,0x34,0x35};  char型是一个字节;数组在内存中必须分配一个连续的线性空间;

如果要把short  d[ ] = {0x5A6B,0X5B6A}存储,表示为图二,数组元素按顺序存储(0->1...),每个short按小端字节序存储

图一
图二

 

 

 

 

 

三、定义指针

  • 指针即指针变量,用于存放其他数据单元(变量/数组/结构体/函数等)的首地址
  • 若指针存放了某个数据单元的首地址,则这个指针指向了这个数据单元
  • 若指针存放的值是0,则这个指针为空指针
  • 定义一个指针变量: 

16位系统:x=2,32位系统:x=4,64位系统:x=8  (与系统位宽相等) 

demo1:查看数据类型的长度(即存储大小)

#include <stdio.h>

int main()
{
	int a;
	int *p1;
	
	char b;
	char *p2;
	
	printf("a:%d\n",sizeof(a));
	printf("p1:%d\n",sizeof(p1));
	printf("b:%d\n",sizeof(b));
	printf("p2:%d\n",sizeof(p2));
	
	return 0;
	
}

>>>运行结果:
a:4
p1:8
b:1
p2:8

四、指针操作

若已定义:     

int a;        //定义一个int型的数据     

int *p;        //定义一个指向int型数据的指针

则对指针p有如下操作方式:

 

demo2:打印char型变量a的地址

#include <stdio.h>

int main()
{
	char a = 0x66;
	char *p = &a;
	
	printf("a:%x\n",a);
	printf("p:%x\n",p);
    printf("取内容p:%x\n",*p);
	
	return 0;
	
}

>>>运行结果:
a:66
p:61fe17
取内容p:66

 指针++的操作:偏移的是1个数据宽度,int*就是4个字节,char*就是1个字节,short*2个字节

demo3:指针++操作

#include <stdio.h>

int main()
{
	char a;
	char *p1 = &a;
	
	int b;
	int *p2 = &b;
	printf("p1:%x\n",p1);
	printf("p2:%x\n",p2);
	
	p1++;
	p2++;
	printf("p1++:%x\n",p1);
	printf("p2++:%x\n",p2);
	
	return 0;
	
}

>>>运算结果:
p1:61fe0f
p2:61fe08
p1++:61fe10
p2++:61fe0c

五、数组与指针

  • 数组是一些相同数据类型的变量组成的集合,其数组名即为指向该数据类型的指针。
  • 数组的定义等效于申请内存、定义指针和初始化

例如:   

char c[ ] = {0x33, 0x34, 0x35};

等效于:    申请内存         

                  定义 char *c = 0x4000;  

                  初始化数组数据 

利用下标引用数组数据也等效于指针取内容

例如:    c[0];    等效于:    *c;         

               c[1];    等效于:    *(c+1);         

               c[2];    等效于:    *(c+2); 

demo4:数组与指针

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

int main()
{
	//char a[] = {0x33,0x34,0x35};//等效于以下步骤
	char *a;
	a=malloc(3*1);
	*a=0x33;
	*(a+1)=0x34;
	*(a+2)=0x35;
	
	printf("a[0]=%x\n",a[0]);
	printf("a[1]=%x\n",a[1]);
	printf("a[2]=%x\n",a[2]);
	
	printf("a[0]=%x\n",*a);
	printf("a[1]=%x\n",*(a+1));
	printf("a[2]=%x\n",*(a+2));
	
	return 0;
	
}

>>>运算结果:
a[0]=33
a[1]=34
a[2]=35
a[0]=33
a[1]=34
a[2]=35

 六、注意事项

  • 在对指针取内容之前,一定要确保指针指在了合法的位置,否则将会导致程序出现不可预知的错误
  • 同级指针之间才能相互赋值,跨级赋值将会导致编译器报错或警告

 七、指针应用

传递参数

  • 使用指针传递大容量的参数,主函数和子函数使用的是同一套数据,避免了参数传递过程中的数据复制,提高了运行效率,减少了内存占用
  • 使用指针传递输出参数,利用主函数和子函数使用同一套数据的特性,实现数据的返回,可实现多返回值函数的设计

传递返回值

  • 将模块内的公有部分返回,让主函数持有模块的“句柄”,便于程序对指定对象的操作

直接访问物理地址下的数据

  • 访问硬件指定内存下的数据,如设备ID号等
  • 将复杂格式的数据转换为字节,方便通信与存储
demo5:函数返回多个返回值,求数组中最大值以及该值出现的次数

#include <stdio.h>

void FindMaxAndCount(int *max,int *count,const int *array,int length)
{
	int i;
	*max=array[0];
	*count=1;
	
	for(i=1;i<length;i++)
	{
		if(array[i]>*max)
		{
			*max=array[i];
			*count=1;
		}
		else if(array[i]==*max)
		{
			(*count)++;
		}
	}
} 

int main()
{
	int a[]={1,2,4,6,4,6,3};
	int Max;
	int Count;
	
	FindMaxAndCount(&Max,&Count,a,7);
	
	printf("Max=%d\n",Max);
	printf("Count=%d\n",Count);
	
	return 0;
	
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值