C语言指针再回顾
This_is_Y Lv6

来自之前cnblog的博客
源地址:https://www.cnblogs.com/This-is-Y/p/12417028.html

内存

C语言内存四区:代码区,全局区,栈区,堆区

代码区:存放代码的

全局区:用于存放全局变量和静态变量, 里面细分有一个常量区,字符串常量和其他常量也存放在此。该区域是在程序结束后由操作系统释放。

栈区:由系统自动开辟,系统自动释放,并不大。

堆区:程序员动态开辟的内存,由我们手动开辟,手动释放,非常大。链表,数据结构,动态数组,动态结构体与此相关。

地址

一个字节8位,内存以单个字节位单位分开,每个字节有一个不可修改连续唯一的编号,这个编号就是地址。就像酒店里的房间。一个一个的房间就是一个一个字节,编号,也就是地址,就是门牌号,而且是刻在房间门上的,不可修改。

每个在代码里的变量都有地址,用取地址运算符:& (单目运算符,优先级仅低于“()”,从右往左)来获取地址。

首地址

一段内存空间中,第一个存储单元的地址。如定于一个int a,占用内存中4个字节,首地址就是这四个字节中,第一个字节的地址。如图:

 

 

 第二个数组的首地址是他的第一个存储单元,也就是a[0]的地址,实际上a[0]的首地址就是他的第一个字节的首地址,数值上看是一样的,但是意义并不同

指针变量

地址如上所说,是一种编号,是一种数据。用来存放地址的变量,

内存大小位4B(4个字节)

整数 int a;

字符 char b;

小数 float c;

地址  指针变量

指针变量的定义:指针变量不是单独存在的,是相对与其他数据类型来的,比如整形指针变量 int *p;,字符型指针变量 char *p; 。

   int p;//指明一个指针变量,存的数据为地址。int表明存放的地址指向的内存空间里面存放的数据类型是int。表明p这个变量是指针变量。这个指针变量名字就叫做p(不是*p)。其他的类型(char,float,……)相同

指针变量的赋值:

加入a的地址是1001,此时p中存的是a的地址,即1001,称p指向a

指针变量的引用:接上一条的代码,访问a的值。可以直接用a来访问,如一条printf语句,当然这里说指针,看到要用指针来访问,就像第二条printf语句。

 

指针访问:指针变量(为取值运算符,单目运算符,从右到左)(在定义指针变量时,只是表明后面接的变量是一个指针变量。在未定义时出现的,表示为取值运算符。

 

野指针:不能明确指向的指针变量 ,当一个指针变量指向一个为定义的变量时,这个指针变量就是野指针。(很危险!!!!有可能在未知情况下操作意料之外的数据)

解决部分,定义该指针为NULL,即内存中的第一个字节的地址,0

空指针:空指针相对于int*,float*,char*,等,空指针为void*,不知道指向什么样子的内存,比如一个4个字节的内存,可以存int,long等类型的数据,未确定时,使用void,当确定下来后,可以强制把void转化需要的类型。在后期动态内存分配,用到malloc等函数时用得更多

 

 

指针的运算

只有4个,+, -, ++, –

单纯指针加减没有意义,主要是为了指针偏移。指针变量的加减,以指针所指向的类型空间为单位进行偏移。如

 

 

从数据类型的知识可以知道,在64位windows操作系统中,int占用4个字节,char占用1个字节。 从结果中可以看到,pi+1后,指针的值比之前加了4,而pc+1后,指针的值比之前加了1。(16进制数字加减)

 

 

首地址:一段内存空间中第一个存储单元的地址,存储单元。

指针变量的加减:以指针所指向的类型空间位单位进行偏移。

一维数组和指针:

**  1.定义一个一维数组。数组中的元素依次存放,数组名是这个数组的‘首地址**

先定义一个数组int a[10]

a指向a[0] ,a[0] 的类型是int,所以a是int*类型。

a[0]这个地址指向a[0] int(*)[10]元素,字节为4,

&a这个执行整个数组。

如下,数组长度为10。

第一个a+1比a增加了4,

第二个&a+1比&a增加了40(4x10)

 

 

 

访问数组元素:

普通下标法:最常见,最基础的,

指针法: 可以使用以下几种,建议p++,单目运算符优先级比+双目运算符优先级高,建议加一个’()‘。同时也可以使用(a+i)来调用数组元素。此时不能用a++。a是数组名,a++会改变a 。数组名不能改变

 

 

二维数组与指针:

数组名是这个数组的首地址

首地址是一段内容中第一个存储单元

定义一个二维数组int a[3][4],在我们看来,这是一个3x4的矩阵,然鹅在计算机中,依然是线性的,此时

a指向a[0]这个一维数组,类型为int(*)[4], a+1一次加16B

&a指向整个二维数组,类型为int(*)[3][4]

a[0]指向a[0][0]这个int ,类型为int a[0]+1一次加4B*

&a[0]指向a[0]这个一维数组,类型为int(*)[4]  (a=&a[0])

二维数组取值

下表法:a[m][n]

指针法:(a[m]+n)*

**    ((a+m)+n)****  (a先偏移到m行数组,再用往下走一层,再偏移n个位置,走到a[m][n]的位置,再用一个取这个地址的值)**

** **

多维数组:

**  从高到低一步一步走下去,**

**  假设一个5维数组 a[][][][][]**

**  变量名        类型**

**  a           int()[][][][]*

**  a[0]           int()[][][]
*

**  a[0][0]        int()[][]*

**  a[0][0][0]      int()[]*

**  a[0][0][0][0]     int***

**  a[0][0][0][0][0]      int**

**  **

 善用*的取值和走向下一层和&的取地址功能,明白首地址的意义。可以很快理解各种奇奇怪怪的指针。

 

 

**  注意区分int**这种**多级指针int*[]这种数组指针以及int[]这种指针数组*的区别,同是还有函数指针,结构体指针,字符串与指针,指针形参的函数,

 

  这里我统称他们为自闭指针

** **

 

 

 

 

** **

 评论
评论插件加载失败
正在加载评论插件
由 Hexo 驱动 & 主题 Keep
访客数 访问量