指针

指针

指针的重要性:
 表示一些复杂的数据结构
 快速地传递数据,减少内存的耗用【重点】
 使函数返回一个以上的值【重点】
 能够直接访问硬件
 能够方便的处理字符串
 是立即面向对象语言中引用的基础

总结:指针是c语言的灵魂

指针的定义:
 地址:
  内存单元的编号
  从零开始的非负整数
范围:4G【0到4G-1】

指针:
 1、指针就是地址,地址就是指针
  例如:int *p = a[5];
 p是指针,&a[0]地址,地址等价于指针
 所以可以这样说:
 p等价于a等价于&a[0]
 p+i等价于a+i等价于&a[i]
 
2、指针变量就是存放内存单元编号(说白了就是地址)的变 量,或者说指针变量就是存放地址的变量。

3、指针(*p)和指针变量§是两个不同的概念但是要注意的是:我们通常叙述时会把指针变量简称为指 针,实际上它们的含义并不一样。

4、指针的本质就是一个操作受限的非负整数。

指针的分类
1、基本类型指针【重点】

int *p; //p是变量的名字,int *表示p变量存放的是int*类型变量的地址。
 //int *p;不表示定义了一个名字叫做*p的变量
 //int *p;应该这样理解:p是变量名,p变量的	数据类型是int *类型,所谓int *类型 				  实际就是存放int变量地址的类型。
  int i = 3;
  int j;
  p = &i;

1、p保存了i的地址,因此p指向i;
  2、p不是i,i也不是p,更准确的说:修改p的值不影响i的值,修改i的值也不会影响p的值
  3、如果一个指针变量只想某个普通变量,则*指针变量 就完全等价于 普通变量*p 就完全等价于 a[0]。
  
例子:
如果p是某个指针变量,并且 p 存放了普通变量 i 的地址(即上面的int * p; int i; p = &i;)
则p 指向普通变量 i
*p 就完全等同于 i
后者说:在所有出现*p的地方都可以替换成i
在所有出现i的地方都可以替换成*p

*p最准确的解释是:*p表示的是以p的 内容为地址的变量。

j = *p;	//	等价于 j = i;
printf(“i = %d, j = %d\n”, i, j);

附录:
*的三种含义
 1、乘法符号
 2、定义指针变量
int *p;
//定义了一个名叫p的变量,int * 表示p只能存放int类型变量的地址
3、指针运算符
(1)该运算符放在已经定义好的指针变量的前面。
(2)如果p是一个已经定义好的指针变量则*p表示以 p的内容为地址的变量。

如何通过被调函数修改主调函数变量的值:
 1、实参必须为该普通变量的地址。
 2、形参必须为指针变量。
 3、在被调含糊中通过。
*形参名 = …
的方式就可以修改主调函数相关变量的值。

指针和数组

指针和一维数组
 一维数组名(比如a[4]的a就是数组名)
 一维数组名是一个指针常量(int *p;int a[10];a等价于p;*(p+i)等价于a[i]也等价于p[i];)
 它存放的是一维数组第一个元素的地址。

下标和指针的关系
 如果p是一个指针变量,则
 p[i]永远等价于*(p+i)
确定一个一维数组需要几个参数【如果一个函数要处理一个一维数组,则需要接收该数组的那些信息】
需要两个参数:
(1)数组的第一个元素的地址a。
(2)数组的长度。

指针变量的运算:
 指针变量不能相加、乘、除
 如果两个指针变量指向的是同一块连续空间的不同储存单元,则这两个指针变量才可以相减。
例如:

int a[5] = {1,2,3,4,5};
int * p;
int * q;
p = &a[1];
q = &a[4];
printf(%d\n”, q-p);

输出值为3. //p和q所指向的单元相隔q-p个单元
p+i等价于p+i*(p指向的变量所占的字节数)

一个指针变量到底占几个字节【非重点】
预备知识:
 sizeof(数据类型)
 功能:返回值就是该数据类型所占的字节数
 例子:sizeof(int) = 4 sizeof(char) = 1
    sizeof(double) = 8

sizeof(变量名)
功能:返回值是该变量所占的字节数

假设p指向char类型变量(1个字节)
假设q指向int类型变量(4个字节)
假设r指向double类型变量(8个字节)
请问:p、q、r、本身所占的字节数是否一样?
答案:p、q、r本身所占字节数是一样的
总结:
一个指针变量,无论他指向的变量占几个字 节该指针变量本身只占八个字节(64位操作 系统下,32位占4个字节)

一个变量的地址就是用该变量首字节的地址来表示

如何用被调函数修改主调函数中数组元素的值:

/*
	被调函数如何修改主调函数中数组元素的值。也可以用来作为数组元素的排序、查找。 
*/

#include<stdio.h>

void g(int *p,int j)//接收数组的首地址和长度 
{
	int i;
	for(i=0; i<j; i++)
	{
		p[i] = 100;//p接收了数组a的地址,那么p = a;*(p+i)			等价于a[i]也等价于p[i]也等价于*(a+i)也等价于i[a]; 
	}
	
	return 0}

int main()
{
	int a[5]={1,2,3,4,5};
	int i;
	
	g(a,5);//a等价于&a[0],&a[0]是整形指针变量,向被调函数发				送数组的首地址a和数组的长度5; 
	for(i=0; i<5; i++)
	{
		printf("%d\n",*(a+i));
	}
	
	return 0;
} 

/*
	输出结果
			100
			100
			100
			100
			100 
*/

多级指针

在这里插入图片描述
用法:

#include<stdio.h>

void f(int **q)
{
    **q = 100;//q是int **类型, 所谓int **类型就是指q只能存放int *类型变量的地址
}

int main()
{
    int i = 10;
    int *p = &i;
    int **q = &p;
int ***r = &q;
    f(&p);
    printf("%d\n",*p);
    				//*q = &p; error
				//**q = &i;error
    printf("%d\n",**q);
printf("%d\n",***r);
    return 0;
}

输出结果:
	100
	100
	100
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值