计算机考研复试之C语言(第八章)

文章目录

    • 8.1 指针是什么
    • 8.2 指针变量
    • 8.3 通过指针引用数组
    • 8.4 通过指针引用字符串
    • 8.5 指向函数的指针
    • 8.6 返回指针值地函数
    • 8.7 指针数组和多重指针
    • 8.8 动态内存分配与指向它的指针变量
    • 8.9 各种指针变量类型的总结

8.1 指针是什么

  • 1、存储地址与存储内容
    如下图所示的变量的存储地址和存储内容示意图。其中2000、2004、2008分别为i、j、k的存储地址,而3、6、9分别为其存储内容
    计算机考研复试之C语言(第八章)_第1张图片
  • 2、访问方式
    • (1)直接访问
      直接按变量名进行的访问,称为直接访问方式。如下图所示:
      计算机考研复试之C语言(第八章)_第2张图片
    • (2)间接访问
      将变量i的地址存放在另一个变量中,然后通过该变量来找到变量i的地址,从而访问变量i,如下图所示:
      计算机考研复试之C语言(第八章)_第3张图片
  • 3、指针和指针变量
    一个变量的地址称为该变量的指针。如果有一个变量专门用来存放另一变量的地址(即指针),则称为指针变量。指针变量是指地址变量,用来存放地址,指针变量的值是地址(即指针)。

8.2 指针变量

  • 1、定义指针变量
    类型名 *指针变量名;
    左端的类型名是在定义指针变量时必须指定的基类型,指针变量的基类型用来指定此指针变量可以指向的变量的类型。
  • 2、引用指针变量
    • (1)引用指针变量的不同情况
      ①给指针变量赋值;
      ②引用指针变量指向的变量;
      ③引用指针变量的值。
    • (2)&和*的区别
      ①“&”是取地址运算符。&a是变量a的地址;
      ② * 是指针运算符(或称间接访问运算符),*p代表指针变量p指向的对象。
  • 3、指针变量作为函数参数
    函数的参数不仅可以是整型、浮点型、字符型等数据,还可以是指针类型。它的作用是将一个变量的地址传递到另一个函数中。

8.3 通过指针引用数组

  • 1、数组元素的指针
    如图8-3所示为数组元素的指针。其中令p=&a[0],即指针p指向数组首元素的地址。如下图:
    计算机考研复试之C语言(第八章)_第4张图片
  • 2、在引用数组元素时指针的运算
    当指针指向数组元素的时候,允许对指针进行加和减的运算。
    • (1)运算分类
      ①加一个整数(用+或+=),如p+1。
      ②减一个整数(用-或-=),如p-1。
      ③自加运算,如p++,++p。
      ④自减运算,如p–,--p。
      ⑤两个指针相减,如p1-p2(只有p1和p2都指向同一数组中的元素时才有意义)。
    • (2)详细说明
      ①指针变量p+1或p-1是加上或减去一个数组元素所占用的字节数。
      ②如果p的初值为&a[0],则p+i和a+i是指数组元素a[i]的地址,如下图所示:
      计算机考研复试之C语言(第八章)_第5张图片
      ③*(p+i)或 *(a+i)是p+i或a+i所指向的数组元素,即a[i]。
      ④如果指针变量p1和p2都指向同一数组,则可执行减法计算,如果是p2-p1的值(两个地址之差)除以数组元素的长度。
  • 3、通过指针引用数组元素
    引用数组元素的形式:
    ①下标法,如a[i]形式;
    ②指针法,如*(a+i)或* (p+i)。其中a是数组名,p是指向数组元素的指针变量,其初值p=a。
  • 4、用数组名作函数参数
    • (1)概述
      当用作数组名作参数时,实参数组名将数组首元素地址传给形参,因此如果形参数组中各元素的值发生变化,实参数组元素的值随之变化。
    • (2)变量名与数组名做函数参数的比较
      下面把用变量名作为函数参数和用数组名作为函数参数做一下比较,如下表所示:
      计算机考研复试之C语言(第八章)_第6张图片
  • 5、通过指针引用多维数组
    • (1)多维数组元素的地址
      如下图所示是一个多维数组元素地址示意图。其中a代表的是首行(即序号为0的行)的首地址、a+1与a+2分别为序号为1和2的行。
      计算机考研复试之C语言(第八章)_第7张图片
      如下图所示,a[0]为序号为0的行的首列元素地址,即& [0][0],故a[0]+1为行序号为0、列序号为1的元素地址, 即&a[0][1],其他以此类推。
      计算机考研复试之C语言(第八章)_第8张图片
      二维数组a的有关指针如下表所示:
      计算机考研复试之C语言(第八章)_第9张图片
    • (2)指向多维数组元素的指针变量
      ①指向数组元素的指针变量
      如下图所示,现令p=a[0],则p指向第0行的首列元素, 而a[2][3]为数组第11个元素(从0开始计数),故可以用p +11表示a[2][3]的地址。
      计算机考研复试之C语言(第八章)_第10张图片
      ②指向由m个元素组成的一维数组的指针变量
      若让p指向a[0],即p=&a[0],则p+1指向a[1],p的增值以 一维数组的长度为单位,如下图所示。
      计算机考研复试之C语言(第八章)_第11张图片

8.4 通过指针引用字符串

  • 1、字符串的引用方式
    字符串的引用方式有两种:
    ①用字符数组存放一个字符串,可以通过数组名和下标引用字符串中一个字符,也可以通过数组名和格式声明“%s”输出该字符串;
    ②用字符指针变量指向一个字符串常量,通过字符指针变量引用字符串常量。
  • 2、字符指针作函数参数
    如果想把一个字符串从一个函数传递到另一个函数,可以用地址传递的办法,即用字符数组名作参数,也可以用字符指针变量作参数。在被调用的函数中可以改变字符串的内容,在主调函数中可以引用改变后的字符串。
  • 3、使用字符指针变量和字符数组的比较
    字符指针变量与字符数组存储及运算字符串的区别如下表所示:
    计算机考研复试之C语言(第八章)_第12张图片
    说明:
    ①变量值可改变指针变量存储的地址可以改变,而数组名只能是数组的首地址不能改变;
    ②指针引用数组元素的前提是指针指向了数组。

8.5 指向函数的指针

  • 1、定义
    如果在程序中定义了一个函数,在编译时,编译系统为函数代码分配一段存储空间,这段存储空间的起始地址(又称入口地址)称为这个函数的指针。

  • 2、用函数指针变量调用函数
    如果想调用一个函数,除了可以通过函数名调用以外,还可以通过指向函数的指针变量来调用该函数。

  • 3、定义和使用指向函数的指针变量

    • (1)一般形式
      类型名(*指针变量名)(函数参数列表);
    • (2)详细说明
      ①指向函数的指针变量只能指向定义时指定的类型函数,在一个程序中可以先后指向同类型的不同函数。
      ②如果要用指针调用函数,必须先使指针变量指向该函数。
      ③在给函数指针变量赋值时,只须给出函数名而不必给出参数。
  • 4、用指向函数的指针作函数参数
    设函数fun的定义为fun(int (*x1)(int),int (*x2)(int,int)),函数f1和f2的定义分别为f1(int x)、f2(int x,int y),则用指向函数的指针作函数参数为:
    fun(f1,f2);
    此时x1与x2指向函数f1与f2,如下图所示,这样在函数fun中就可以调用f1和f2函数。
    在这里插入图片描述

8.6 返回指针值地函数

一个函数可以返回一个整型值、字符值、实验值等,也可以返回指针型的数据,即地址。其概念与以前类似,只是返回的值地类型是指针类型而已,其一般形式为:
类型名 *函数名(参数列表);

说明:
在“*函数名”两侧没有括号,即不是表示函数指针,因此“函数名(参数列表)”表示一个函数形式,而“类型名 *”表示该函数返回的指针所指向的类型。

8.7 指针数组和多重指针

  • 1、指针数组
    一个数组,若其元素均为指针类型数据,则称为指针数组,即指针数组中的每一个元素都存放一个地址,相当于一个指针变量,其一般形式为:
    类型名 *数组名[数组长度];
    说明:
    在“*数组名”两侧没有括号,即不是表示指向一维数组的指针,因此“数组名[数组长度]”表示一个一维数组,而“类型名 *”表示该一维数组中的元素都为指针,且指向该类型。
  • 2、指向指针数据的指针
    指向指针数据的指针变量定义为:
    char **p;
    如下图所示,p指向name数组元素,而数组元素各自指向一个字符串。
    计算机考研复试之C语言(第八章)_第13张图片
  • 3、指针数组作main函数的形参
    • (1)概述
      C语言程序中main函数也可以有形参,形式为:
      int main(int argc,char *argv[])
      其中argc表示参数个数,而argv表示一个char *指针数组,其中每一个元素指向命令行的一个字符串。
    • (2)命令行
      在操作命令状态下,实参是和执行文件的命令一起给出的,命令行的一般形式为:
      命令名 参数1 参数2…参数n
      其中命令名是可执行文件名(包含main函数),命令行参数应当都是字符串,这些字符串的首地址构成一个指针数组,如下图所示,设命令行为file1 China Beijing。
      计算机考研复试之C语言(第八章)_第14张图片

8.8 动态内存分配与指向它的指针变量

  • 1、内存的动态分配
    全局变量是分配在内存中的静态存储区的,非静态的局部变量(包括形参)是分配在内存中的动态存储区的,这个存储区是一个称为栈(stack)的区域。
    而C语言还允许建立内存动态分配区域,不必声明和定义,随时需要随时开辟,不需要时随时释放,这个特别的自由存储区称为堆(heap)区。
  • 2、怎样建立内存的动态分配
    • (1)malloc函数
      void *malloc(unsigned int size);
      说明:
      此函数返回值是所分配区域的第一个字节的地址,指针的基类型为void,即不指向任何类型的数据,只提供一个地址。如果此函数未能成功地执行(例如内存空间不足),则返回空指针(NULL)。
    • (2)calloc函数
      void *calloc(unsigned n,unsigned size);
      说明:
      其作用是在内存的动态存储区中分配n个长度为size的连续空间,这个空间一般比较大,足以保存一个数组。
    • (3)free函数
      void free(void *p);
      说明:
      其作用是释放指针变量p所指向的动态空间,使这部分空间能重新被其他变量使用。
    • (4)realloc函数
      void *realloc(void *p,unsigned int size);
      说明:
      如果已经通过malloc函数或calloc函数获得了动态空间,想改变其大小size,可以用realloc函数重新分配。
      以上4个函数的声明在stdlib.h头文件中,在用到这些函数时应当用“#include”指令把stdlib.h头文件包含到程序文件中。
  • 3、void指针类型
    C99允许使用基类型为void的指针类型。可以定义一个基类型为void的指针变量(即void *型变量),它不指向任何类型的数据。
    说明:
    不能把“指向void类型”理解为能指向“任何的类型”的数据,在将它的值赋给另一指针变量时由系统对它进行类型转换,使之适合于被赋值的变量的类型。

8.9 各种指针变量类型的总结

各类型的指针变量如下表所示:
计算机考研复试之C语言(第八章)_第15张图片

你可能感兴趣的:(C语言,计算机考研复试)