C语言指针,指针与一位数组地址的关系

指针:(C语言的灵魂)
内存的存储是以一个字节为一个编号,也就是8位合在一起给一个编号,不是0,1就给编号。
内存分为很多个单元,每个单元就会分配一个编号。
地址:内存单元的一个编号。而指针和地址一个概念的。也就是说指针就是地址。
在这里插入图片描述
普通变量:只能存放一个值。
指针变量:同样是一个变量,但是指针变量存放其他变量的地址。
在这里插入图片描述
p代表的是p所指向的那个变量。在上图中p和i是同一个东西,但是p和p不是同一个东西。
在上图中,int * p是一个声明,开头的int * 是他的数据类型。P是变量的名字。不能理解我定义了一个整形变量,这个整形变量的名字叫做
p。所谓int *类型,实际就是存放int 变量地址的类型。
*p代表的是以p的内容为地址的变量。
解析:p的内容是一个地址,在上图中,p的内容就是i的地址,p其指向的变量当然就是i变量了。
指针和指针变量:
指针就是地址,地址就是指针。
地址就是内存单元的编号。
指针变量:存放地址的变量。而指针只是一个值,这个值是内存单元的一个编号。指针变量才是一个变量,他里面才可以存放数据。
指针和指针变量是两个不同的概念,但是需要注意的是,通常我们在叙述时会把指针变量简称为指针,实际他们含义并不一样。
指针的重要性:
在这里插入图片描述
指针的分类:
在这里插入图片描述
指针的定义:
·地址:内存单元的编号,是一个从0开始的非负整数。
范围:cpu对内存是通过控制、数据、地址三条总线来进行控制的。
控制:cup会先把内存中的数据读入,进行处理后,在返回给内存,然后内存在把数据写入硬盘。
数据:用于数据的传输,不管是把内存中的数据发送给cpu,还是把cpu的数据写如内存条,都是由数据线来完成的,但是数据传输的方向则是由控制线来控制的。
地址:地址线则是确定数据要写入内存中的那个单元。
所谓的一个单元就是一个字节。
一条地址总线能控制2的1次方,一般的机器有32个地址线,最终能够控制2的32个单元,而每个单元是八位,而最终我们的内存能够存储2的32次方
8位。
则换算为G的话,最终大小为4G.那么地址总线的范围则是4G大。
指针:指针就是地址,地址就是指针。
指针变量就是存放内存单元编号的变量。
指针变量和指针是两个不同的概念。
指针的本质就是一个操作受限的非负整数。
指针不能进行算术运算-相加 乘 除。但是能相减。
如果两个指针变量指向的是同一块连续空间的不同存储单元,则这两个指针变量才可以相减。类似于同一个小区同一楼层六牌号相减表示两房间隔。这时才有现实意义。
基本类型的指针:
在这里插入图片描述
Int *p:p只能存放int类型的地址。
P = & i:把i的地址赋给p。然后p就指向了i,*p就等于i。其实就是
1:该语句保存了i的地址。
2:p保存了i的地址,所以p指向i。
3:p既然指向i,*p就是i。
p:表示以p的内容为地址的变量。
p:p是有指向的,p里面是个垃圾值,p则是说以p的内容为地址的变量。因为不知道p的值是多少,所以不知道p到底代表的是那个变量。而p = i,i=5,最终的结果就是把5赋给了一个所不知道的单元。
在这里插入图片描述
上图中,第一个error是数据类型不符合,不能相互转
换。q代表的是整形,因为q代表的是以q的地址为内容的变量。而p是地址(int )类型。第二个error
同样有错,因为q没有赋值。
经典指针程序-互换两个数字:
1:先用函数来互换:
在这里插入图片描述
最终的输出结果没有互换,因为函数的a,b已经执行
完成,分配给内存的空间已经释放了,所以最终a,b
的值还是主函数a,b的值。互换的是形参的a,b。和
主函数没有关系。
需要注意的是,互换的只是p、q的内容,局部函数变化了,但是主函数是没有变化的。
最终正确的程序:
在这里插入图片描述
号的三种含义:
1:乘法
2:定义指针变量。Int * p,定义了一个名字叫p的变
量,int 表示p只能存放int变量的地址。
3:指针运算符。该运算符是放在已经定义好的指针变
量的前面。如果p是一个已经定义好的指针变量,则

P表示以p的内容为地址的变量。
注意理解形参,实参,和局部变量的关系。
在这里插入图片描述
指针可以是函数返回一个以上的值:
在这里插入图片描述
不使用指针的话,只能使用用return来返回一个值。
如何通过被调函数修改主调函数普通变量的值
在这里插入图片描述
在这里插入图片描述
指针和数组:
指针和一维数组:
(数组名 下标与指针关系 指针变量的运算)
·一维数组名:一维数组名是个指针常量,他存放的是
一维数组第一个元素的地址。
在这里插入图片描述
常量是不能被改变的,也就是说,一维数组名是不能被
改变的。
数组名a存放的是一维数组第一个元素的地址,也就是
a = &a。
printf(“%#X\n”,&a[0]); ===== printf(“%#X\n”,a);
指针和二维数组:
下标和指针的关系:
·如果p是个指针变量,则p[i]永远等价于
(p+i)
在这里插入图片描述
确定一个一维数组需要几个参数,【如果一个函数要处理一个一维数组,则形参需要接收该数组的哪些信息。】
确定一个一维数组需要两个参数,
1:数组名,从数组的名称就可以知道数组的第一个值,因为一维数组的名称就是数组的第一个元素的地址。
2:是数组的个数。来计算该数组有多少个值。
区别于 字符串(只需要一个参数—首地址)
因为字符串默认其后面都有一个“/0”作为结束标志。而数组并没有相关约定。
在这里插入图片描述
在上图中,a是个指针变量,所以上面局部函数f的pArr则要定义成指针函数才可以,而len则是int类型。代表接收的是整型的数字。
在这里插入图片描述
总结:pArr[i] = a[i] = (pArr+i) = (a+i)
在这里插入图片描述
在上图中因为数组a的名称代表的是a的第一个元素的地址,所以在函数f中所定义的指针变量pArr和a是相同的,因为a也是指针变量类型。也就是说pArr=a=a[0],pArr[1]=a[1]=
(pArr+1)=
(a+1),pArr[2]=a[2]=
(pArr+2) =
(a+2).
通过上图,我们知道,我们在f函数中修改数组的值,相当于修改主函数中相对应的值。

何谓变量地址 / 一个指针占几个字节
Sizeof(变量名/数据类型) 其返回值就是该变量或数据类型所占字节数。
一个指针变量无论其指向变量占几个字节,其本身所占大小都是4字节。
*p具体指向几个字节,要靠前面类型确定,如果为int则为4字节,如果double则占8字节。
CPU 与 内存 交互时 有32根线,每根线只能是1或0两个状态,所有总共有232个状态。
1 个状态 对应 一个单元。如全为0 全为1 等。
内存中第一个单元,即32根线状态全为0。
0000 0000 0000 0000 0000 0000 0000 0000
其大小为4字节
所有每个地址(硬件所能访问)的用4个字节保存(而不是一 位bit)
一个变量的地址—用该变量首字节的地址表示。这也就是为什么指针变量始终只占4字节的原因。

需要C语言基础详细笔记,扫码关注微信公众号 二维码如下 后台回复数字:104291542,就可以获取下载地址了
在这里插入图片描述
如链接失效,后台联系我。

发布了43 篇原创文章 · 获赞 3 · 访问量 1346

猜你喜欢

转载自blog.csdn.net/it_xiangqiang/article/details/104293817
今日推荐