C语言基础之——指针

目录

一,什么是指针?

二,指针的注意事项

三,指针与数组

五,指针与堆空间


一,什么是指针?

C语言中变量是容器,可看作装酒的酒杯,只不过装的不是酒,是各种内存。

而指针是一种特殊的变量:因为是变量,所以能保存具体值;特殊之处就在于指针保存的值是内存的地址;

内存地址:计算机中每个存储单元都有编号,这些编号就是内存地址。

需要清楚的事实:程序中一切元素都存储在内存中,因此可以通过访问地址来使用元素,而指针的作用就是作为一个容器存储地址,对地址的一切操作都要通过指针来完成。

如何获取具体地址:

通过取地址操作符——来获得。

&的作用:可以获取变量,数组,函数的地址。

确定一个具体的地址是通过:确定起始地址+长度来确定

各种数据类型长度:

指针定义语法:type* pointer;

type 数据类型,决定访问内存的长度;

注意:指针的类型统一只占4字节或8字节。

* 指针访问操作符,标志为指针变量。

pointer 变量名,遵循C语言命名规则。

int main()
{
    char* pChar;
    int* pInt;
    double* pDouble;
    
    return 0;
}
int var=0 ;            //定义变量var初始值为0;
int* pvar=NULL ;       //定义pvar的所占地址的开始值为NULL,即0值;
pvar = &var;           //把var变量的地址赋值给pvar.
*pvar = var;           //把var的值赋值给*pvar.

归类:var,*pvar为int类型变量;

           pvar,&var为变量地址;


二,指针的注意事项

type* 类型的指针只能存储type类型变量的地址;

禁止不同类型的指针相互赋值;

通过指针参数:

——能够实现函数交换变量的值;

——能够从函数中"返回"多个值;而return只能返回一个值;


三,指针与数组

在数组中,元素本身就是地址。所以数组名虽然不是指针,但可以看作指针;

这样的话,数组元素就可以直接对指针赋值,数组名也可以对指针赋值。

数组名可直接看作一个指针,表示数组中0元素的地址;

a等价于&a[0]

不过&a则表示整个数组的地址,虽然值和0元素的地址一样,但意义不同。

——&a代表数组地址,类型为:int(*)[ ] 

——a代表数组0号元素地址,类型为:int*

看得出两者类型不一致,所以不能相互赋值。

所以定义:

指向数组的指针:int (*pName)[ ] = &a;

指向数组0号元素的指针:int* pName = a; 
 

当指针指向数组元素时,可以进行指针移动。

int a[] = {1, 2, 3, 4, 5};
int* pa = a;
p = p + 1;             //现在p指向了下一个元素。

指针与字符串:

字符串其实就是特殊的数组,特殊在于该数组最后元素的值为'\0'。

字符串常量就是一种char*类型,一种指针类型,存在的地址为全局变量区。

使用字符串的时候,其实就是在使用char*类型的数据。

例如用&对"Hello"取地址,结果为"Hello"在全局变量区的起始地址。

"Hello"可看作一个地址;

*"Hello"看作从这个地址中取值;

四,指针与函数

函数的本质就是内存中的一段代码:

函数的类型,函数类型由返回类型和参数类型列表决定:


 

函数名就是函数体代码的起始地址;

通过函数名调用函数,本质为指定具体地址的跳转执行

因此,可以通过指针,保存函数入口地址;

函数指针:

对于函数为type func (type 1,  type 2)格式的

指向该函数的指针为:type (*pfunc)(type 1,  type 2) = func/NULL;

值得注意的是,函数指针只是单纯的保存函数的入口地址,所以只能通过函数指针调用目标函数。
 

当数组作为参数时:

当数组作为参数,会退化成为一个指针;

int demo(int arr[ ],int len) → int demo(int* arr, int len).

因此,不包含数组实参的长度信息。使用数组名调用时,传递的是0号元素的地址。


五,指针与堆空间

各类内存空间不同,用途不同:

——全局数据区:存放全局变量,静态变量;

——栈空间:存放函数参数,局部变量;

——堆空间:用于动态创建变量

堆空间的本质:

  • 备用的“内存仓库”,以字节为单位预留可用内存。

  • 程序可在需要时申请借内存。(动态借)

  • 借完后需要及时归还。(动态还)

问:如何从对卡申请借内存,如何归还呢?

预备知识——void*

  1. void类型时基础类型,对应指针类型为void*

  2. void*为指针类型,其指针变量能够保存地址

  3. 通过void*指针无法获取内存中的数据(无长度信息)

  4. void*保存的内存有起始地址,但没有长度信息。能够保存任意类型的地址,能转换到其它指针类型的变量。

  5. 不可以用void*指针直接获取内存数据,不过void*与其它数据指针可以相互赋值。

堆空间的使用原则:

  1. 有借有还。

  2. malloc申请内存后,应该判断是否申请成功。

    =NULL,则申请不成功。
    !=NULL,则申请成功。
  3. free负责释放申请到的内存。

Guess you like

Origin blog.csdn.net/m0_58702068/article/details/118771982