第八章地址和指针

合集下载

C++程序设计 第八章 指针和引用

C++程序设计  第八章 指针和引用
C++

在程序运行时变量和函数都存放在内存中,通过变量名来访问数据、通过函数名来调用函数都是直接访问方式。还有另一种间接访问方式就是用指针。指针的本质是内存地址。指针往往用于说明函数的形参,使实参能通过指针传递,以提高函数调用的效率。利用指针能动态地使用内存,以提高内存使用效率。指针也能用来表示数据关联,以构成复杂的数据结构。指针是C程序中最常见的类型。引用是C++扩展的新概念,主要用于函数形参和返回类型。本章将详细介绍指针和引用的概念及应用。
首先,这6个变量的地址是按递减次序排列,这是因为局部变量都存储在堆栈中,堆栈是先入后出的。先入栈的数据存放在较大地址位置,后入栈的数据存放在较小地址位置。如果这些变量改为全局变量,它们的排列次序就会颠倒过来。
其次,尽管变量s只占2字节,变量c只占1字节,但却分别占用4字节空间。这是因为按字对齐(32位数据)能提高CPU访问内存的效率,而且一次压栈和出栈操作也是以32位数据为单位,代价是浪费一些内存。如果这些变量改为全局变量,它们将按实际大小存储。
怎样能知道一个变量在运行时刻的内存地址?把取地址运算符&放在变量前面就得到它的首地址。例如b是一个变量,那么&b就表示它的地址。下面例子能看到一组局部变量的首地址。
例8-1显示一组局部变量的首地址。
#include<iostream.h>
void main(){
bool b = true;
char c = 'c';
其中,<类型名>是这个指针变量所指向的对象的类型,简称指针类型,它可以是任何一种类型。*表示这个变量是一个指针变量。这个变量的类型就是“<类型名>*”。<变量名>是一个标识符。指针变量可以进行初始化,等号之后给出一个变量的地址,要求这个变量的类型与指针类型相符。

《C语言程序设计》基本知识点

《C语言程序设计》基本知识点

《C语言程序设计》基本知识点第一章C语言基本知识1.C源程序的框架尽管各个C源程序的功能千变万化,但框架是不变的,主要有:编译预处理、主函数()、函数n()等,主函数的位置不一定在最前面,可以在程序的中部或后面,主函数的名字固定为main。

2.C语言源程序的书写规则:(1)C源程序是由一个主函数和若干个其它函数组成的。

(2)函数名后必须有小括号,函数体放在大括号内。

(3)C程序必须用小写字母书写。

(4)每句的末尾加分号。

(5)可以一行多句。

(6)可以一句多行。

(7)可以在程序的任何位置加注释。

3.语句种类语句是程序的基本成分,程序的执行就是通过一条条语句的执行而得以实现的,根据表现形式及功能的不同,C语言的基本语句可以分为五大类。

(1)流程控制语句流程控制语句的功能是控制程序的走向,程序的流程有三种基本结构:顺序结构、分支结构和循环结构,任何复杂的程序都可以由这三种基本结构复合而成。

其中后两种结构要用特定的流程控制语句实现。

(2)表达式语句表达式语句的形式是:表达式;,即表达式后跟一分号“;”,分号是语句结束符,是一个语句必不可少的成分。

表达式和表达式语句的区别在于表达式代表的是一个数值,而表达式语句则代表一种动作。

最常见的表达式语句是赋值语句。

(3)函数调用语句函数调用语句实际上也是一种表达式语句,形式为:在一次函数调用的小括号后面加上一个分号。

(4)空语句空语句的形式就是一个分号,它不代表任何动作,常常作为一个意义转折点使用。

(5)复合语句复合语句从形式上看是多个语句的组合,但在语法意义上它只相当于一个语句,在任何单一语句存在的地方都可以是复合语句。

注意复合语句中最后一个语句末尾的分号不能少。

复合语句右大括号后面没有分号。

4.运算符用来表示数据各种操作的符号称为运算符。

运算符实际上代表了一种类型数据的运算规则。

不同的运算符具有不同的运算规则,其操作的数据类型必须符合该运算符的要求,运算结果的数据类型也是固定的。

C语言 第八章

C语言 第八章

p
printf(“%d,%d\n”,a,b); printf(“%d,%d\n”,*p1,*p2);}
三、指针变量作为函数参数 作用:将一个变量的地址传送到另一个函数中。 作用:将一个变量的地址传送到另一个函数中。 例1:编写实现两个数的交换的函数 : swap(int *p1, int *p2) *p2) void swap(int *p1, int swap(int x,int y) {{ int temp; 定义为*temp? ? int temp; 定义为 { int temp; temp=*p1; temp=x; temp=*p1; *p1=*p2; x=y; *p1=*p2; y=temp; } *p2=temp; } *p2=temp; } main() main() main() { int a,b,*p1,*p2; { int a,b; { int a,b p1=&a;p2=&b; scanf("%d,%d",&a,&b); scanf(“%d%d”,&a,&b); scanf(“%d%d”,p1,p2); swap(a,b); swap(&a,&b); swap(p1,p2); printf("\n%d,%d\n",a,b); printf("%d, %d\n",a,b); printf("%d, %d\n",a,b); }} }
个字节的问题) 个字节的问题)
二、指针变量的引用 “&”(地址运算符 取变量的存储地址。如:&a求变量 的地址。 地址运算符) 取变量的存储地址。 地址运算符 求变量a的地址 求变量 的地址。 “*” (引用运算符 取指针所指向变量的内容。&与*优先级相同, 引用运算符) 取指针所指向变量的内容。 与 优先级相同 引用运算符 优先级相同, 但按自右至左的结合方向。 但按自右至左的结合方向。 例如: 例如:int i=3,*p; p=&i;

《C语言程序设计》第8章指针

《C语言程序设计》第8章指针
}
10.3.3 指针变量和数组作函数参数 数组名作形参时,接收实参数组的起始地址;
作实参时,将数组的起始地址传递给形参数组。
引入指向数组的指针变量后,数组及指向数 组的指针变量作函数参数时,可有4种等价形式 (本质上是一种,即指针数据作函数参数):
(1)形参、实参都用数组名 (2)形参、实参都用指针变量 (3)形参用指针变量、实参用数组名 (4)形参用数组名、实参用指针变量
(4)指针变量的++、--与&、*的结合
对于指针变量的++、--与&、*的结合 使用,关键要注意按照运算符的优先级和 结合性进行。
例如: int a=2, *p; p=&a;
•表达式:(*p)++,按运算符的优先级,等价于 a++。其含义为:取出指针变量p所指向的内存单 元的值(即a的值),a的值加1,送回a的内存单 元,a的值变为3,p的值未发生变化,仍然指向 变量a。
程序说明:printf("%s\n",s);语句 通过指向字符串的指针变量s,整体引
用它所指向的字符串的原理:系统首先输出s 指向的第一个字符,然后使s自动加1,使 之指向下一个字符;重复上述过程,直至遇到 字符串结束标志。
main() { char string[ ]=”I love Beijing.”; printf(“%s\n”,string); }
3.数组元素的引用 数组元素的引用,既可用下标法,也可用
指针法。
10.3.2 通过指针引用数组元素 如果有“int a [10],*p=a;” ,则: (1)p+i和a+i都是数组元素a [i]的地址。
(2)*(p+i)和*(a+i)就是数组元素a [i]。 int a [3]; a [0]——*a a [1]——*(a +1) a [2]——*(a +2)

C语言 第八章.用户自定义数据类型

C语言   第八章.用户自定义数据类型
printf("%c,%c\n",u2.c[0],u2.c[1]); }
u2占2个字节
例:以下程序输出结果是?
union example { struct { int x,y; e.b e.a e.in.x }in; e.in int a; e.in.y int b; }e; void main() { e.a=1;e.b=2; e.in.x=e.a*e.b; e.in.y=e.a+e.b; printf("%d,%d",e.in.x,e.in.y); }
内存低地址 01100001 00001010
字符变量c占1个字节
整型变量i占2个字节 单精度实型变量f占4个字节
u1.i=10;
例:以下程序输出结果是?
union u_type { char c[2]; u1
p
内存高地址 内存低地址 ‘a’ ‘b’ c1 c2 c[1] c[0] u1占2个字节 内存高地址 内存低地址 ‘A’ ‘B’ ‘a’ ‘b’ c1 c2 c[1] c[0]
{"0208103322","lisi",19,'M'},{"0208103323","lili",20,'F'}, {"0208103324","xulin",21,'M'}};
学号(number) 姓名(name) 年龄(age) 性别(sex)
stu[0] stu[1] stu[2] stu[3]
char name[8];
int age; char sex;
定义结构体类 sizeof(stu) 型的同时创建 =? 结构体数组

C二级 第8章 指针

C二级 第8章 指针

1.以下定义语句中正确的是A) int a=b=0; B) char A=65+1,b='b';C) float a=1,*b=&a,*c=&b; D) double a=0.0; b=1.1;参考答案:B【解析】A选项语句中b变量还没有定义不能直接用于给a变量赋值。C选项语句中*b、*c表示的是一个实型变量的地址,不能再将&b赋值给指针型变量c。D选项语句中a=0.0后面应该为逗号,不能是分号。2.有以下程序#include <stdio.h>void f(int *p,int *q);main(){ int m=1,n=2,*r=&m;f(r, &n);printf("%d,%d",m,n);}void f(int *p,int *q){ p=p+1;*q=*q+1;}程序运行后的输出结果是A) 2,3 B) 1,3 C) 1,4 D) 1,2参考答案:B【解析】在f(int *p,int*q)函数中,执行p=p+1是将p所对应的地址加1,而*q=*q+1是将q所指向的n的地址所对应的值加1,所以m的得知所对应的值没有变,而n的值则为3了。

因此B选项正确。

3.以下叙述中正确的是A) 如果p是指针变量,则&p是不合法的表达式B) 如果p是指针变量,则*p表示变量p的地址值C) 在对指针进行加、减算术运算时,数字1表示1个存储单元的长度D) 如果p是指针变量,则*p+1和*(p+1)的效果是一样的参考答案:C【解析】B选项中,如果p是指针变量,则*p表示变量p所指向的地址的值;A选项中,如果p是指针变量,则&p表示变量p的地址;D选项中,如果p是指针变量,*p+1表示将p所指的值加上1,而*(p+1)表示的是先将指针右移一位再取所指向变量的值。

因此C选项正确。

4.以下叙述中正确的是A) 基类型不同的指针变量可以相互混用B) 函数的类型不能是指针类型C) 函数的形参类型不能是指针类型D) 设有指针变量为double *p,则p+1 将指针p移动8个字节参考答案:D【解析】B选项中,所谓函数类型是指函数返回值的类型。

c语言程序设计谭浩强第四版

c语言程序设计谭浩强第四版

c语言程序设计谭浩强第四版C语言程序设计是计算机科学与技术领域中非常重要的基础课程之一。

谭浩强教授所著的《C语言程序设计》自问世以来,以其通俗易懂的语言和丰富的实例,深受广大学生和编程爱好者的喜爱。

第四版在继承前三版优点的基础上,对内容进行了更新和完善,更加符合现代编程教育的需求。

第一章:C语言概述本章主要介绍了C语言的发展历程、特点以及C语言在计算机编程领域中的应用。

C语言以其高效、灵活和可移植性,成为系统编程、嵌入式开发等领域的首选语言。

第二章:C语言的基本概念本章详细讲解了C语言的基本组成元素,包括数据类型、变量、常量、运算符和表达式等。

这些是编写C程序的基础,也是理解程序逻辑的关键。

第三章:顺序结构程序设计顺序结构是最简单的程序结构,本章通过实例讲解了如何使用顺序结构编写程序,以及如何通过输入输出函数实现数据的交互。

第四章:选择结构程序设计本章介绍了条件语句if、switch等选择结构的使用,通过这些结构可以实现程序的分支逻辑,使程序能够根据不同的条件执行不同的代码块。

第五章:循环结构程序设计循环结构是程序设计中不可或缺的部分,本章详细讲解了for、while、do-while等循环语句的用法,以及如何使用循环结构实现重复操作。

第六章:数组数组是存储多个同类型数据的集合,本章介绍了一维数组和二维数组的定义、初始化和使用,以及如何通过数组实现数据的批量处理。

第七章:函数函数是程序模块化的基础,本章讲解了函数的定义、声明、调用以及参数传递机制,包括值传递和地址传递的区别和应用。

第八章:指针指针是C语言中非常强大的特性之一,本章详细介绍了指针的基本概念、指针与数组的关系、指针的运算以及指针在函数中的应用。

第九章:结构体与联合体本章介绍了如何使用结构体和联合体来定义复杂的数据类型,以及如何通过这些复合数据类型实现数据的组织和管理。

第十章:预处理命令预处理命令是C语言编译过程中的特殊指令,本章讲解了宏定义、文件包含、条件编译等预处理命令的用法。

计算机操作系统第八章-磁盘存储器的管理

计算机操作系统第八章-磁盘存储器的管理

第八章磁盘存储器的管理第一节文件的物理结构和外存的分配方式一、概述磁盘是一种可直接存取的随机存储器(这一点与内存相似),一个逻辑盘可以看作一片连续的存储空间。

确定外存空间的分配方式(组织文件的物理结构)主要考虑:提高文件的访问速度、有效地利用外存空间。

常用的外存分配方法有:连续分配、链接分配、索引分配。

二、磁盘存储空间的结构磁盘说明图1盘块(扇区)是磁盘上的最小存储分配单位,每个盘块有唯一编号;地址是:磁道(柱面)号+扇区号+盘面号;从盘块编号到地址的转换由硬件完成,在OS中一个盘块的地址就是盘块编号。

一般一个盘块的大小与内存分页中页(内存块)的大小一致,一页存放到一个盘块中。

三、连续分配1、思想方法为每个文件分配一组位置相邻接的盘块(磁盘上的地址连续/盘块编号连续的盘块),文件中的逻辑页被顺序地存放到邻接的各物理盘块中。

这保证了文件中的逻辑顺序与文件占用盘块顺序的一致性。

这样物理结构的文件称为顺序文件;每个文件都从分配给它的一个盘块的第一个字节开始存放。

文件地址:在文件的目录中,存放该文件的第一个记录所在的盘块号和文件的长度(共占多少块)。

1230567491011813141512171819162122232025262724list29303128mailcountfile start length coun t 02tr 143mail 196list 284f62????tr f图 8-1 磁盘空间的连续分配2、优缺点◆存取容易,存取速度较快;◆必须事先知道文件的长度,不利于文件的动态增长; ◆存放一个文件要求足够大的连续存储空间; ◆存储空间的管理存在“碎片”问题,须定时整理。

四、链接分配1、思想方法:为每个文件分配一组位置离散的盘块,每个盘块中存放文件的一个逻辑页;通过给每个盘块设置一个指针,将属于同一个文件的盘块链接在一起,链接的顺序和文件的逻辑页的顺序一致。

这样物理结构的文件称为链接文件。

23_变量的地址和指针、指针变量的定义和指针变量的基本类型、给指针变量赋值

23_变量的地址和指针、指针变量的定义和指针变量的基本类型、给指针变量赋值
图81变量分配的存储单元与地址c语言规定当一个变量占用一个字节时该字节的地址就是该变量的地址如果变量占用连续的多个字节那么第一个字节的地址就是该变量的地址
本次课要点: 8.1 变量的地址和指针 8.2 指针变量的定义和指针变量的基类型 8.3 给指针变量赋值
8.1 变量的地址和指针 1.变量及其地址 在C的程序中要定义许多变量,用来保存程序 中用到的数据,包括输入的原始数据、加工的中 间结果及最终数据。C编译系统会根据定义中变 量的类型,为其分配一定字节数的内存空间(如 字符型占1个字节,整型占2字节,实型占4字节, 双精度型占8字节等),此后这个变量的地址也就 确定了。
(2)通过指针变量获得地址值 可以通过赋值运算,把一个指针变量中的地址 值赋给另一个指针变量,从而使这两个指针变量 指向同一地址。例如,若有以上定义,则语句: p=q; 使指针变量p中也存放了变量k的地址,也就是 说指针变量p和q都指向了变量k。 注意:在赋值号两边指针变量的基类型必须相同。 (3)通过标准函数获得地址值 可以通过调用库函数malloc和calloc在内存中开 辟动态存储单元,并把所开辟的动态存储单元的 地址赋给指针变量。
8.3.2 给指针变量赋“空”值 除了给指针变量赋地址值外,还可以给指针变 量赋NULL值。 例如:p=NULL; NULL是在stdio.h头文件中的预定义符。NULL 的代码值为0,当p=NULL时,称p为空指针。因 为NULL的代码值是0,所以上面语句等价于: p=’\0’; 或 p=0; 这时,指针p并不是指向地址为0的存储单元, 而是具有一个确定的值——“空”。企图通过一个 空指针去访问一个存储单元时,将会得到一个出 错信息。
例如有变量定义语句:char a, int b, float c; 编译系 统给变量分配的存储空间如图8-1所示。

《地址和指针》PPT课件

《地址和指针》PPT课件

p 2000 2050
q 1010 2000
a5 1010

7.2.2 指针变量的基类型的作用
在C语言中,不同的数据类型变量系统为它们开辟的存储空 间的字节数是不同的。int类型的数据存储空间是2个字节, float类型的数据存储空间是4个字节, char类型的数据存储 空间是1个字节。
系统表示每一个存储空间的地址时,是取该存储空间的第1 个字节的地址作为该变量存储空间的地址。根据指针变量p 中存放的“地址”,只能寻找到变量a第1个字节的存储空间, 它并不是变量a的原值,因为变量a原值是通过2个字节来 数据。
第七章 地址和指针
主要内容 地址和指针的概念 指针变量的定义 给指针变量赋值 对指针变量的操作 指针在函数方面的应用
7.1 地址和指针的概念
7.1.1地址和指针的概念 1.“地址”的概念
在计算机里每一个存储数据的存储单元也都必须 具有一个唯一的“地址”,以示区别不同存储单 元的位置。
NULL是在stdio.h头文件中定义的预定义符,因此使用NULL时,应该在程 序的前面应加上预定义命令行:#include “stdio.h”
7.4 对指针变量的操作
7.4.1通过指针或地址引用一个存储单元 当指针变量中存放了一个确切的地址值时,通过指针可以用
“间接运算符”(*)来引用该地址所代表的存储单元。 1.在赋值号右边由“*”运算符和指针变量组成的表达式,代表
指针所指存储单元的内容。 例如:int *p,i=10,j;
p=&i;
j=*p; 2.在赋值号左边由“*”和指针变量组成的表达式,代表指针
所指的存储单元。 例如:int *p,k=0;
p=&k; *p=150; 整数150存入变量k中。

C语言笔记

C语言笔记

C语言笔记第一章程序设计基本概念1.C语言是一种结构化的程序设计语言。

2.C语言中没有子程序的概念,它提供的函数可以完成子程序的所有功能。

3.C语言允许对函数进行单独编译,从而可以实现模块化。

第二章 C语言设计的初步知识1.C语言的模块化主要是通过函数实现的。

2.C语言有高级语言和低级语言的功能,技能编写系统软件,又能编写应用软件3.程序中main()是主函数的起始行,也是C程序执行的起始行。

4.一个C程序总是从主函数开始执。

5.分号是C语句的一部分,不是语句之间的分隔符。

6.程序中“﹟include 〈stdio.h〉”通常称为命令行,命令行必须用“﹟”号开头,行尾不能有“;”号,它不是C程序中的语句。

7.标识符必须由字母、数字和下划线组成,,并且第一个字符必须是字母或下划线。

8.在C语言中,大写字母和小写字母被认为是两个不同的字符。

9.C语言标识符分为三类:关键字、预定义标识符和用户标识符。

10.常量分为数值型常量(整型常量(短整型、基本整型、长整型、无符号型)和实行常量)、字符型常量和字符串常量。

11.一个变量实际上代表了内存上的某个存储单元。

12.对变量的定义通常放在函数体内的前部,但是也可以放在函数的外部和复合语句的开头。

13.十六进制中的a、b、d、e、f既可以是小写也可以是大写。

14.在C语言中,只有十进制可以是负数,八进制和十六进制只能是整数。

15.整型变量只能存放整型数值。

16.C语言规定,可以在定义变量的同时给变量赋初值,也称变量初始化。

17.无符号常量不能表示成小于0的负数。

-200u是不合法的。

18.如果一台计算机以两个字节(16个二进制位)来存放一条计算机命令,则称此计算机的字长是16位。

19.通常把一个字节中的最右边一位称为最低位,最左边一位称为最高位。

对于一个有符号整数,其中最高位(最左边一位)用来存放整数的符号,称为符号位。

正整数最高位放0,负整数最高位放1.20.负整数在内存中是以“补码”的形式存在的。

8.指针

8.指针

例 p指向int型数,则 p+1 p+12 例 p指向int型数组,且p=&a[0]; 则p+1 指向a[1] 例 int a[10]; int *p=&a[2]; p++; *p=1; 1
p+i
a[3]
a[4] a[5] a[6] a[7] a[8] a[9]
p+9
指针的算术运算: 若指针变量p1与p2都指向同一数组,如执行p2-p1, 结果是两个地址之差除以数组元素的长度。 即 p2-p1(p2-p1)/d 假设p2指向实型数组元素a[5],p2的值为2020;p1指 向a[3] ,其值为2012, 则p2-p1的结果是(2020-2012)/4=2. 这个结果是有意义的,表示p2所指的元素与p1所指的 元素之间差2个元素。 p1+p2 无实际意义
a+9
a[9] *(a+9)
p+9
*(p+9)
下标法 a[i] *(p+i) *(a+i)
指针法
例 输出数组中的全部元素。
假设有一个a数组,整型,有10个元素。要输出 各元素的值有三种方法:
(1)下标法。
(2) 通过数组名计算数组元素地址,找出元素的值。
(3) 用指针变量指向数组元素。
(1)下标法。(8-3(1).c) #include <stdio.h> void main() { int a[10]; int i; for(i=0;i<10;i++) scanf(″%d″,&a[i]); printf(″\n″); for(i=0;i<10;i++) printf(″%d″,a[i]); }
2000 3 a 2002 4 b

TP8

TP8

ACCP V4.0
指针使用示例2
内存 void main() { ptr1 num1 int num1 = 50, num2 = 100; 12ff7c 50 int *ptr1, *ptr2; ptr1 = &num1; 12ff7c printf(" num1 的值是: %d", *ptr1); ptr2 num2 printf("\n num1 的地址是: %x \n", ptr1); 12ff78 ptr2 = &num2; 50 100 printf("\n num2 的值是: %d", *ptr2); 12ff78 printf("\n num2 的地址是: %x \n", ptr2); *ptr2 = *ptr1; printf("\n 重新赋值后 num2 的值是: %d", *ptr2); printf("\n 重新赋值后 num2 的地址是: %x\n", ptr2); }
arr_num[0] arr_num[1] arr_num[2] arr_num[3] arr_num[4] arr_num[5] arr_num[6] arr_num[7]
41 60
23 15 60 41 49 13 39
14
ACCP V4.0
指针关系运算
比较两个指针
#include<stdio.h> void main () { int *ptrnum1, *ptrnum2; int value = 1; ptrnum1 = &value; value += 10; ptrnum2 = &value; if (ptrnum1 == ptrnum2) printf("\n 两个指针指向同一个地址\n"); else printf("\n 两个指针指向不同的地址\n"); }

第8章 指针2-xujh

第8章 指针2-xujh
a[0]=’c’;a[1]=’o’;a[2]=’m’;a[3]=’p’;……;a[7]=’r’; 但语句: p=”computer”; 是合法的。
指针数组与命令行参数
• 在操作系统命令状态下可以输入程序或命 令使其运行,称命令行状态。输入的命令 (或运行程序)及该命令(或程序)所需 的参数称为命令行参数
*(a[0]+1) *(*(a+0)+1)
a+1
对于二维数组: (1)a是数组名, 包含三个元素 a[0],a[1],a[2] (2)每个元素a[i] 又是一个一维 数组,包含4个 元素
a+2
2016 a[2]
a[2][2]
a[2][3]
int a[3][4];
a
2000 2000
a[0]
a+12008
指针数组
• •
指针数组是指针变量的集合 定义形式:类型标识符 *数组名[数组长 度说明]
– 如: int *p[10];

注意事项:
– 字符数组中每个元素可存放一个字符,而字符 指针变量存放字符串首地址,千万不要认为字 符串是存放在字符指针变量中的 – 对字符数组而言,与普通数组一样,不能对其 进行整体赋值,只能给各个元素赋值,而字符 指针变量可以直接用字符串常量赋值
P[0] P[1] P[2]
B A S I C \0 C + + \0 P A S C A L \0
字符指针数组举例(1)
• • • • • • • • • • • • • 例:有若干本书,将书名按字典顺序排序 #include<stdio.h> #include<string.h> main() { char *bname[ ]={"Programming in ANSI C","BASIC","Visual C++ 6.0 Programming ","TRUBO C 2.0"}; int i,m; void sort(char *name[],int); m=sizeof(bname)/sizeof(char *); /*字符串个数*/ sort(bname,m); /* 排序,改变指针的连接关系*/ printf("\n"); for (i=0;i<m;i++) /* 输出排序结果*/ printf("%8s",bname[i]); }

chap8(指针)

chap8(指针)

务必记住:*(a+i) 和 a[ i] 是等价的。
如果 a 是一维数组名,则a[ i]代表第 i+1个元素所占的 内存单元。但如果a是二维数组,则a[ i ]代表一维数组名, a[i]本身是不占用内存单元的, 也不存放元素值,而只是 一个地址。 a、a+i、a[ i]、*(a+i)、*(a+i)+j、a[ i]+j都是地址, 而*(a[ i]+j)、*(*(a+i)+j)是二维数组元素a[ i][ j]的值。
二、 字符串指针作函数参数
可以用地址传递的方式,即用字符数组名作 参数或用指向字符串的指针变量作参数,将一个 字符串从一个函数传递到另复制。 用字符数组作参数 void copy_string( from , to ) char from[ ] , to[ ] ; { int i = 0 ; while ( from[i] != „\0‟ ) { to[i] = from[i] ; i + + ; } to[i] = „\0‟ ; 运行结果: } string_a = I am a teacher. string_b = I am a teacher. main( ) {char a[ ] = “I am a teacher.” ; char b[ ] = “you are a student.” ; copy_string( a , b) ; printf( “string_a = %s\nstring_b = %s\n”,a,b); }
形参用字符指针变量 void copy_string(from , to) char *from , *to ; { for ( ; *from != „\0‟; from++; to++) *to = *from ; *to = „\0‟; } main( ) { char *a= “I am a teacher.”; char *b= “you are a student.”; copy_string(a,b); printf( “string_a = %s\nstring_b = %s\n”,a,b) ; }

C语言程序设计(第二版)-电子教案-丁亚涛-8587 第8章 指针

C语言程序设计(第二版)-电子教案-丁亚涛-8587 第8章 指针
}
8.5.3 指针与二维数组
• 二维数组其实可以看成由一维数组构造而成。就相当于 几个队列构成一个方阵,方阵由队列组成,队列由具体 的元素--人组成。
• 一级指针只能管理队列,如果管理方阵,则需要二级指 针。
•int a=1000,*pa,**ppa; • pa=&a; • ppa=&pa;
• *(*(ppa)) ≡ *(pa) ≡ a ≡ 1000
• p是二级指针 • *p相当于*(p+0),级别降低为一级指针,相当于p[0] • **p相当于*(*(p+0)+0),级别降低为数组元素(普通变量),
也相当于p[0][0]
• p[1][2],相当于*(*(p+1)+2) • &p[1][2], 级别提升为一级指针,相当于:
• p[1]+2,*(p+1)+2 • &p[1],级别提升为二级指针,相当于:
f=f4; printf("a/b=%d\n",f(a,b));
8.5 指针与数组
• 8.5.1 指针与字符数组 • char str[100]= "Hello World"; • char *p=str; • 字符w可以有如下多种表示形式: • str[6] • *(str+6) • p[6] • *(p+6)
【例8-2】演示指针和数组的关系。
#include <stdio.h>
接可存取,由于p中存储的是x的信息。访问p可以获取x的信 息,再对银行存款进行操作。
8.1 借钱的故事
8.2 指针的概念
• C语言允许使用变量名、数组名[下标]、函数名等标 识符来访问内存

C语言程序设计第八章 指针的使用

C语言程序设计第八章 指针的使用

第八章指针的使用【学习目标】本章将详细介绍在C语言中如何使用指针。

学习要点包括如下几点:(1)掌握指针和指针变量的概念,了解指针变量的特点以及直接访问数据和间接访问数据的原理。

(2)掌握指针变量的定义、赋值方法及指针运算符的使用,熟练运用指针访问简单变量。

(3)熟悉指针和一维数组的关系,掌握指向一维数组的指针变量的定义方法,熟练使用指针变量访问一维数组元素。

(4)了解指针与字符串的关系,能熟练使用指针处理字符串。

(5)熟练掌握用指针变量作函数的参数时函数的定义和调用方法、数组名作函数的参数用法。

(6)指向指针的指针的运用。

【学习导航】本章的在整个课程中的位置如图5-1所示。

图8-1 本章学习导航在本书的第一章介绍C语言有一个灵活性的特点,那么它的灵活性具体体现在哪里呢?其实就是指针。

指针是C语言的精华部分,通过利用指针,我们能很好地利用内存资源,使其发挥最大的效率。

有了指针技术,我们可以描述复杂的数据结构,对字符串的处理可以更灵活,对数组的处理更方便,使程序的书写简洁,高效。

8.1 地址和指针指针是C语言的一种数据类型,类似于整型、字符型等。

既然指针也是一种类型,那么也可以定义该类型的变量,称为指针变量。

指针变量和其他类型的变量的区别是:指针变量存储的是地址。

所以要学好指针,就一定要明白数据在内存中是如何存储的。

计算机所有数据都是存储在存储器里,系统的内存可看作编了号的小房间,如果要取房间的东西(读取数据)就需要得到房间编号。

地址就是内存区中对每个字节的编号。

下面通过两个整型变量来说明。

整型变量x、y(基本整型需4个字节)在内存中的存储如图8-2所示(假设内存编号是从2000开始)。

把变量所占用的存储单元首字节的地址作为变量的地址。

C语言中利用取地址运算符“&”获取变量的存储地址。

例如,&c将返回c的首地址;&x将返回x的首地址。

2000H2004H2008H2012H...图8-2 变量x和y在内存中的存储图8-2中2000H和2004H就是内存单元的地址。

郑秋生版c++答案习题八

郑秋生版c++答案习题八

第八章指针与引用习题答案一、选择题CBCBCC二、简答题(1)&运算符:取地址运算符,用来得到一个普通变量的地址。

*运算符:间接引用运算符,用来获取指针变量所指向变量的值。

(2)指针:一个变量在内存中所占存储单元的首地址称为该变量的指针,也就是指向该变量的指针。

指针中存储的地址是其所指向的变量的地址,指针中存储的地址里的值就是其所指向变量的值。

(3)引用与指针的区别是,通过某个指针变量指向一个对象后,对它所指向的变量通过*运算符进行间接操作,程序中使用指针,程序的可读性差;而引用本身就是目标变量的别名,对引用的操作就是对目标变量的操作。

可以建立数组的指针,但不能建立数组的引用,因为数组是一个由若干个元素所组成的,所以就无法建立一个数组的别名。

(4)const int *p1 表示p1所指向的int变量为常量,int *const p1 表示p1为常量三、改错题(1)int a;b; 改成int a, b;pointer_1=a; 改成pointer_1=&a;cout<<*a<<" "<<*b<<endl; 改成cout<<a<<" "<<b<<endl;cout<<pointer_2*a<<endl; 改成cout<<(*pointer_2)*a<<endl;(2)有int *p,a=9;p=&a;cout<<”the value of p is ”<<*p;四、阅读程序写结果(1)ABCDEFG(2)x=1.5 y=2.5z=4(3)20 50 50 41(4)m-n=15五、编程题(1)实现字符串逆序输出。

#include <iostream.h>#include <string.h>const char *fun( const char *p1 ){while (*p1++);p1--;return p1;}int main(void){char s1[100];const char *q,*p1;cout<<"输入一个字符串:";cin.getline( s1,100);cout<<"逆向输出串:";q=s1;p1=fun(s1);do{cout<<*p1;p1--;}while(q<=p1);return 0;}(2)输入任意一个字符串,将其中的大写字母转换成小写字母。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

第八章地址和指针8.1变量的地址和指针在程序中变量实际上代表了内存中的某个存储单元。

那么C是怎样存取这些单元的数据内容的呢?我们知道计算机的内存是以字节为单位的一片连续的存储空间,每个内存单元都有一个唯一的编号,我们将其称为“内存地址”。

计算机对数据的存取操作都是依赖于内存地址进行的。

因为计算机的内存空间是连续的,所以内存中的地址空间也是连续的,并且用二进制数据来表示,为了方便和直观,我们将用十进制数据进行描述。

若在程序中定义了一个变量,C编译系统就会自动根据变量的类型,为其分配一定字节数量的存储空间。

如int型2个字节,float型4个字节,double型8个字节,char型1个字节等。

此后,这个变量的内存地址也就唯一的确定了。

一般情况下,我们在程序中只要给出变量名,不需要知道每个变量在内存中的具体地址,变量与地址之间的联系由C编译系统来完成。

程序中我们对变量进行存取操作,实际上就是对变量地址的存储单元进行操作。

这种直接按照变量地址进行存取的操作方式称为“直接存取”方式。

在C语言中我们还可以定义一种特殊的变量,这种变量只是用于存放内存变量地址的。

如:p93 图8.2这种通过变量p间接得到变量a的地址,然后再存取变量a的值的方式称为“间接存取”的方式。

这种用来存放地址的变量称为“指针变量”或“指针”。

由此我们可以知道,在C语言中,地址是指变量在内存中的存放的位置,即存放该变量的内存单元的名字。

而指针是指一个变量,在该变量中存放的是其指向的那个变量在内存存储单元的地址。

也就是说,变量的地址就可以理解为指针。

在C语言中,指针被广泛使用,他可以使程序简洁并高效运行,但使用不当就会产生意料不到的严重后果。

因此,正确使用和掌握指针是十分必要的。

8.2 指针变量的定义和基本类型定义指针变量的形式:类型名*指针变量名1,*指针变量名2,……;例如:int *pi,*pj;float *i,*j,*k;double *l,*m,*n;char *c,*s;在每个变量前面的星号*是一个指针说明符,用来说明该变量是指针类型。

变量前面的星号*不可以省略。

指针变量名前面的类型定义是说明指针指向的数据类型。

另外,我们还可以定义一个指向指针的指针变量。

定义形式为:类型名**指针变量名1,**指针变量名2,……;例如:int * * p,*s,k=90;s=&k; p=&s;其中&符号表示取变量的内存单元地址运算,后面介绍。

为什么指针变量要有类型之分呢?如前面所述,指针变量中存放的是一个内存单元的地址,这里“一个内存单元”中的“一”所代表的字节数是不同的。

如int型2个字节,float型4个字节,double型8个字节,char型1个字节等。

在后面的指针运算中我们经常要对指针进行加、减、移动等操作,此时指针操作的单位是一个存储单元,而不是一个字节,因此对于不同类型的指针变量来说,其操作时所跨越的内存字节数是不同的。

如:定义一个指针变量i(存放的初始地址为2060H),当我们执行i++操作时,不同类型的指针变量所移动的字节数是不同的。

8.3 指针变量赋值一、给指针变量赋地址值一个指针变量可以通过不同的方式获得一个确定的地址值,从而指向一个具体的操作对象。

1、通过取地址运算符(&)获得地址值单目运算符“&”的作用是用来获取变量的内存单元地址。

其使用格式为:&变量名。

如:int k=80, h=100, *p, *q; 则赋值语句为p=&k; q=&h;其指向关系见书p94图8.3我们可以说:指针p指向了整型变量k,和指针q指向了整型变量h。

即:指针变量p中存放了整型变量k所在的存储单元地址,和指针变量q中存放了整型变量h所在的存储单元地址。

取地址运算符(&)只能够用于变量和以后将要介绍的数组元素,不能够应用于表达式、常量或者被说明为register的变量(第12章介绍)。

另外,&符号必须要放在运算对象的左边,而且运算对象的类型必须与指针变量的基本类型相同。

在调用scanf函数时,我们输入的各变量之前必须要加&符号。

如:scanf (“%d%c%f”, &a, &b, &c );2、通过指针变量获得地址值我们可以通过赋值,把一个指针变量中地址赋给另一个指针变量,从而使两个指针变量指向同一个地址。

如:int k=80, *p, *q;p=&k; q=p;此时,指针变量p 和q都同时指向了整型变量k 所在的内存单元地址。

但是要注意,进行赋值运算时,赋值号两边指针变量的基本类型必须要相同。

二、给指针变量赋“空”值有时我们还需要给指针变量赋“空”值,形如:p=NULL;NULL是在”stdio.h”头文件中定义的预定义符号,因此在使用NULL时,应在程序的前面出现预定义行:# include “stdio.h”。

NULL的ASCII代码值为0,当执行了以上的赋值语句后,称指针p为空指针。

因此上述语句也可以书写为:p=’\0’;或p=0;这时p并不指向地址为0的存储单元,而是具有一个确定的值——“空”。

8.4 对指针变量的应用一、通过指针来引用一个存储单元C语言提供了一个可以间接访问地址的单目运算符:星号“*”。

当指针变量中存放了一个确定的地址值时,就可以使用指针访问运算符对存储单元中的数据进行访问。

如:int *p, i=10, j;p=&i;则以下赋值语句:j=*p;的作用是将变量i 的值赋予变量j,这里*p 代表指针p 所指向的变量i。

等价于j=i;间接地址访问运算符是一个单目运算符,必须出现在运算对象的左边,其运算对象或者是存放地址的指针变量或者是内存单元地址。

例如:j=*(&i);由于运算符*和&的优先级别相同,且结合方向为自右至左,因此表达式中的括号可以省略。

写成:j=*&i;又例如:j=*p+1;由于*的运算优先级高于+,因此语句功能为:取指针变量p所指向的存储单元中的内容并加1后送给变量j。

有例如:int *p, k=0;p=&k;则语句*p=100;的作用是将整数100送给变量k。

等价于k=100。

此后若有语句*p=*p+1;则功能为:取指针变量p中所指存储单元中的数据,加1后再存放到指针变量p 所指的存储单元中。

相当于k++或k=k+1;以上语句还可以书写成:*p+=1;或++*p;或(*p)++;注意:在表达式+ + * p中,++和*两个运算符的优先级相同,但按照自右至左的方向结合,因此++*p等价于++(*p)。

而在表达式(*p)++中,一对括号不可以缺少,(*p)++表示先取指针变量p所指向的存储单元中的值,然后加1作为表达式的值。

不可以写成*p++,否则将先计算*p作为表达式的值(在此为100),然后使指针变量p自身增1,所以*p++并不使p所指内存单元的数据加1,而是将指针向后移动了一个存储单元。

例如:用指针指向两个变量,通过指针运算选出值大的那个数据。

# include “stdio.h”main ( ){ int a, b,max, *pa, *pb, *pmax;pa=&a; pb=&b; pmax=&max;printf (“input a and b:”);scanf (“%d%d”, &a,&b); // scanf (“%d%d”, pa,pb);printf ( “a=%d b=%d\n”, a, b);*pmax=*pa;if ( *pa<*pb ) *pmax=*pb;printf ( “max=%d\n”, max );//printf ( "max=%d\n", *pmax );}二、移动指针所谓移动指针就是对指针变量加上或减去一个整数,或通过运算使指针变量指向其他存储单元。

因此,只有当指针指向一个连续的存储单元时,指针的移动才有意义。

当指针指向一个连续的存储单元时,即可以对指针变量进行加减运输,也可以对指针进行逻辑和其它C语言支持的运算。

例如:假定在内存中开辟了下列6个int型存储单元,如下表所示编号a[0] a[1] a[2] a[3] a[4] a[5]数据地址2001H 2003H 2005H 2007H 2009H 200BH 指针p↑q↑则分别执行下列语句后,运行结果分别是什么?(1)p++; (2)q++; (3)q=p+2; (4)a=q-p;(5)a=*p; (6)a=*q; (7)a=*(p+2) (8)a=*p++;(9)a=*p+2; (10)a=p<=q;用下列程序进行演示# include “stdio.h”main ( ){ int a[6], a,, *p, *q;a[0]=11; a[1]=22; a[2]=33; a[3]=44; a[4]=55; a[5]=66;p=&a[1]; q=&a[4];带入上面语句printf ( 根据情况进行打印操作); }通过上面例子我们可以知道,指针的运算是以存储单元为基本单位的,而不是以字节为基本单位的,因此,不同类型的数据(int、char、float、double)存储单元是不一样的。

且当指针进行比较运算时,是以其所指向的地址值的大小作为依据的。

8.5 函数之间地址值的传递一、形参为指针变量时实参和形参之间的数据传递若函数的形参为指针变量,在调用该函数时,对应的实参也必须是基本类型相同的地址值或是已经指向某个存储单元的指针变量。

例如:从键盘输入两个数据,在子函数中完成数据交换,主函数与子函数之间的数据传递以地址的形式进行。

# include “stdio.h”main( ){ void swap(int * ,int * ); /* 函数声明,参数是指针类型*/ int a,b;printf("Please input two integer numbers(a,b):");scanf("%d,%d",&a,&b);swap(&a,&b); /* 引用调用 */printf("a=%d\tb=%d\n",a,b); /* 调用swap( )后a 与b 的值 */ }void swap(int *x,int *y){ int temp;temp=*x;*x=*y;*y=temp; /* 数据值交换,而不是地址交换*/ printf("x=%d\ty=%d\n",*x,*y);}在程序执行过程中,主函数调用swap 函数时,系统自动为swap 函数的形参x 和y 开辟了两个类型为int 型的指针变量,并通过实参&a 和&b 将变量a 和b 的地址传递给它们,如下图所示,这时,指针x 指向变量a ,指针y 指向变量b 。

相关文档
最新文档