清华大学出版社 TSINGHUA UNIVERSITY PRESS 第10章指针 10.1 地址和指针的概念 10.2 变量的指针和指向变量的指针变量 10.3 数组的指针和指向数组的指针变量 10.4 字符串的指针和指向字符串的指针变量 10.5 函数的指针和指向函数的指针变量 10.6 返回指针值的函数 10.7 指针数组和指向指针的指针 10.8 有关指针的数据类型和指针运算的小结 习题
第10章 指 针 10.1 地址和指针的概念 10.2 变量的指针和指向变量的指针变量 10.3 数组的指针和指向数组的指针变量 10.4 字符串的指针和指向字符串的指针变量 10.5 函数的指针和指向函数的指针变量 10.6 返回指针值的函数 10.7 指针数组和指向指针的指针 10.8 有关指针的数据类型和指针运算的小结 习题
清华大学出版社 TSINGHUA UNIVERSITY PRESS 指针是C语言中的一个重要的概念,也是C语言的 一个重要特色。正确而灵活地运用它,可以有 效地表示复杂的数据结构;能动态分配内存;能方 便地使用字符串;有效而方便地使用数组;在调用 函数时能得到多于1个的值;能直接处理内存地址 等,这对设计系统软件是很必要的。掌握指针 的应用,可以使程序简洁、紧凑、高效。每一 个学习和使用C语言的人,都应当深入地学习和 掌握指针。可以说,不掌握指针就是没有掌握C 的精华
指针是C语言中的一个重要的概念,也是C语言的 一个重要特色。正确而灵活地运用它,可以有 效地表示复杂的数据结构;能动态分配内存;能方 便地使用字符串;有效而方便地使用数组;在调用 函数时能得到多于1个的值;能直接处理内存地址 等,这对设计系统软件是很必要的。掌握指针 的应用,可以使程序简洁、紧凑、高效。每一 个学习和使用C语言的人,都应当深入地学习和 掌握指针。可以说,不掌握指针就是没有掌握C 的精华
清华大学出版社 TSINGHUA UNIVERSITY PRESS 指针的概念比较复杂,使用也比较灵活,因此初学 时常会出错,务请在学习本章内容时十分小心, 多思考、多比较、多上机,在实践中掌握它。我 们在叙述时也力图用通俗易懂的方法使读者易于 理解
指针的概念比较复杂,使用也比较灵活,因此初学 时常会出错,务请在学习本章内容时十分小心, 多思考、多比较、多上机,在实践中掌握它。我 们在叙述时也力图用通俗易懂的方法使读者易于 理解
清华大学出版社 TSINGHUA UNIVERSITY PRESS 10.1地址和指针的概念 内存用户数据区 为了说清楚什么是指针, 必须弄清楚数据在内 存中是如何存储的, 2000 3 变量i 又是如何读取的。 2002 6 变量j 如果在程序中定义了一 2004 9 变量k 个变量,在编译时就 给这个变量分配内存 3010 2000 变量i_pointer 单元。系统根据程序 中定义的变量类型, 分配一定长度的空间。 例如,一般微机使用 图10.1 的C系统为整
10.1 地址和指针的概念 为了说清楚什么是指针, 必须弄清楚数据在内 存中是如何存储的, 又是如何读取的。 如果在程序中定义了一 个变量,在编译时就 给这个变量分配内存 单元。系统根据程序 中定义的变量类型, 分配一定长度的空间。 例如,一般微机使用 的C系统为整 图10.1
清华大学出版社 TSINGHUA UNIVERSITY PRESS 型变量分配2个字节,对实型变量分配4个字节, 对字符型变量分配1个字节。内存区的每一个字节 有一个编号,这就是“地址”,它相当于旅馆中 的房间号。在地址所标志的内存单元中存放数据, 这相当于旅馆中各个房间中居住旅客一样。请务 必弄清楚一个内存单元的地址与内存单元的内容 这两个概念的区别,如图10.1所示。假设程序已 定义了3个整型变量i、j、k,编译时系统分配2000 和2001两个字节给变量i,2002,2003字节给j, 2004,2005给k。在程序中一般是通过变量名来 对内存单元进行存取操作的。其实程序经过编译 以后己经将变量名转换为变量的地址,对变量值 的存取
型变量分配2个字节,对实型变量分配4个字节, 对字符型变量分配1个字节。内存区的每一个字节 有一个编号,这就是“地址”,它相当于旅馆中 的房间号。在地址所标志的内存单元中存放数据, 这相当于旅馆中各个房间中居住旅客一样。请务 必弄清楚一个内存单元的地址与内存单元的内容 这两个概念的区别,如图10.1所示。假设程序已 定义了3个整型变量i、j、k,编译时系统分配2000 和2001两个字节给变量i,2002,2003字节给j, 2004,2005给k。 在程序中一般是通过变量名来 对内存单元进行存取操作的。其实程序经过编译 以后己经将变量名转换为变量的地址,对变量值 的存取
清华大学出版社 TSINGHUA UNIVERSITY PRESS 都是通过地址进行的。例如,printf(%D”,)的 执行是这样的:根据变量名与地址的对应关系(这 个对应关系是在编译时确定的),找到变量的地址 2000,然后从由2000开始的两个字节中取出数据 (即变量的值3),把它输出。输入时如果用 scanf("%D",&i),在执行时,就把从键盘输入 的值送到地址为2000开始的整型存储单元中。如 果有语句“k=i+j”,则从2000、2001字节取出的 值(3),再从2002、2003字节取出i的值(6),将它们 相加后再将其和(9)送到k所占用的2004、2005字节 单元中。这种按变量地址存取变量值的方式称为 “直接访问”方式
都是通过地址进行的。例如,printf(“%D”,i)的 执行是这样的:根据变量名与地址的对应关系(这 个对应关系是在编译时确定的),找到变量i的地址 2000,然后从由2000开始的两个字节中取出数据 (即变量的值3),把它输出。输入时如果用 scanf("%D",&i),在执行时,就把从键盘输入 的值送到地址为2000开始的整型存储单元中。如 果有语句“k=i+j”,则从2000、2001字节取出i的 值(3),再从2002、2003字节取出j的值(6),将它们 相加后再将其和(9)送到k所占用的2004、2005字节 单元中。这种按变量地址存取变量值的方式称为 “直接访问”方式
清华大学出版社 TSINGHUA UNIVERSITY PRESS 还可以采用另一种称之为“间接访问”的方式,将 变量的地址存放在另一个变量中。按C语言的规 定,可以在程序中定义整型变量、实型变量、字 符变量等,也可以定义这样一种特殊的变量,它 是存放地址的。假设我们定义了一个变量i-pointer,. 用来存放整型变量的地址,它被分配为3010、3011 字节。可以通过下面语句将的刂?2000)存放到i- pointer中。 i-pointer=&i; 这时,i-pointer的值就是2000,即变量所占用单元 的起始地址。要存取变量的值,也可以采用间接 方式:先找到存放“的地址”的变量,从中取出i 的地址(2000),然后到2000、2001字节取出的值 3)
还可以采用另一种称之为“间接访问”的方式,将 变量i的地址存放在另一个变量中。按C语言的规 定,可以在程序中定义整型变量、实型变量、字 符变量等,也可以定义这样一种特殊的变量,它 是存放地址的。假设我们定义了一个变量i-pointer, 用来存放整型变量的地址,它被分配为3010、3011 字节。可以通过下面语句将i的刂?2000)存放到ipointer中。 i-pointer=&i; 这时,i-pointer的值就是2000,即变量i所占用单元 的起始地址。要存取变量i的值,也可以采用间接 方式:先找到存放“i的地址”的变量,从中取出i 的地址(2000),然后到2000、2001字节取出i的值 (3)
清华大学出版社 TSINGHUA UNIVERSITY PRESS 打个比方,为了开一个A抽屉,有两种办法,一种 是将A钥匙带在身上,需要时直接找出该钥匙打开 抽屉,取出所需的东西。另一种办法是:为安全起 见,将该A钥匙放到另一抽屉B中锁起来。如果需 要打开A抽屉,就需要先找出B钥匙,打开B抽屉, 取出A钥匙,再打开A抽屉,取出A抽屉中之物, 这就是“间接访问”。图10.2是直接访问和间接访 问的示意图
打个比方,为了开一个A抽屉,有两种办法,一种 是将A钥匙带在身上,需要时直接找出该钥匙打开 抽屉,取出所需的东西。另一种办法是:为安全起 见,将该A钥匙放到另一抽屉B中锁起来。如果需 要打开A抽屉,就需要先找出B钥匙,打开B抽屉, 取出A钥匙,再打开A抽屉,取出A抽屉中之物, 这就是“间接访问”。图10.2是直接访问和间接访 问的示意图
清华大学出版社 TSINGHUA UNIVERSITY PRESS 2000 i pointer 2000 2000 图10.2
图10.2
清华大学出版社 TSINGHUA UNIVERSITY PRESS 为了表示将数值3送到变量中,可以有两种表达方法: (1)将3送到变量所标志的单元中。见图10.2上。 (2)将3送到变量i-pointer)所“指向”的单元(即i所标 志的单元)中。见图10.2下。 所谓“指向”就是通过地址来体现的。i-pointer中的 值为2000,它是变量的地址,这样就在i-pointer和 变量之间建立起一种联系,即通过i-pointer能知道i 的地址,从而找到变量的内存单元。图10.2中以箭 头表示这种“指向”关系。 由于通过地址能找到所需的变量单元,我们可以说, 地址“指向”该变量单元(如同说,房间号“指向 “某一房间一样)。因此在C语言中,将地址形象化 地称为
为了表示将数值3送到变量中,可以有两种表达方法: (1) 将3送到变量i所标志的单元中。见图10.2上。 (2) 将3送到变量i-pointer所“指向”的单元(即i所标 志的单元)中。见图10.2下。 所谓“指向”就是通过地址来体现的。i-pointer中的 值为2000,它是变量i的地址,这样就在i-pointer和 变量i之间建立起一种联系,即通过i-pointer能知道i 的地址,从而找到变量i的内存单元。图10.2中以箭 头表示这种“指向”关系。 由于通过地址能找到所需的变量单元,我们可以说, 地址“指向”该变量单元(如同说,房间号“指向 “某一房间一样)。因此在C语言中,将地址形象化 地称为