C语言程序设计(第三版_第1页
C语言程序设计(第三版_第2页
C语言程序设计(第三版_第3页
C语言程序设计(第三版_第4页
C语言程序设计(第三版_第5页
已阅读5页,还剩293页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、语言程序设计 (第三版) (第十-十四章),第十章,指针,10.1地址和指针的概念,为了说清楚什么是指针,必须弄清楚数据在内存中是如何存储的,又是如何读取的。,内存区的每一个字节有一个编号,这就是“地址” 。如果在程序中定义了一个变量,在对程序进行编译时,系统就会给这个变量分配内存单元。,、按变量地址存取变量值的方式称为“直接访问”方式,另一种存取变量值的方式称为“间接访问”的方式。即,将变量的地址存放在另一个变量中。,在语言中,指针是一种特殊的变量,它是存放地址的。假设我们定义了一个指针变量i_pointer用来存放整型变量的地址,它被分配地址为(3010)、(3011)的两个字节。可以通过

2、语句:i_pointer ; 将的地址(2000)存放到i_pointer中。这时, i_pointer的值就是(2000) ,即变量所占用单元的起始地址。要存取变量的值,可以采用间接方式:先找到存放“的地址”的变量i_pointer ,从中取出的地址(2000),然后到2000 、 200字节取出的值()。,一个变量的地址称为该变量的“指针”。 例如,地址2000是变量的指针。如果有一个变量专门用来存放另一变量的地址(即指针),则它称为“指针变量”。上述的i_pointer就是一个指针变量。,指针和指针变量的定义:,指针变量的值(即指针变量中存放的值)是地址(即指针)。请区分“指针”和“指针

3、变量”这两个概念。,10.2 变量的指针和指向变量的指针变量,10.1 定义一个指针变量,定义指针变量的一般形式为 基类型 *指针变量名;,下面都是合法的定义: float *pointer_; / pointer_是指向float型变量的指针变量 char *pointer_; /pointer_是指向字符型变量的指针变量 可以用赋值语句使一个 指针变量得到另一个变 量的地址,从而使它指 向一个该变量。如: pointer_; pointer_;,在定义指针变量时要注意两点:,10. 指针变量的引用,请牢记,指针变量中只能存放地址(指针), 不要将一个整数(或任何其他非地址类型的数据) 赋给

4、一个指针变量。,例10. 通过指针变量访问整型变量,#include voidmain ( ) int ,; int*pointer_, *pointer_; ; pointer_; /*把变量的地址赋给 pointer_1 */,pointer_; /*把变量的地址赋给 pointer_ */ printf(%,%,); printf(%,%,*pointer_, *pointer_); ,对“”和“*”运算符说明: 如果已执行了语句 pointer_; (1)* pointer_的含义是什么?“”和“*”两个运算符的优先级别相同,但按自右而左方向结合,因此先进行* pointer_的运算,

5、它就是变量,再执行运算。因此,* pointer_与相同,即变量a的地址。如果有pointer_2 * pointer_ ; 它的作用是将(的地址)赋给pointer_2 ,如果pointer_2原来指向,经过重新赋值后它已不再指向了,而指向了。,(2) *的含义是什么?先进行运算,得的地址,再进行*运算。即所指向的变量,也就是变量a。*和*pointer_的作用是一样的,它们都等价于变量。即*与等价。,(3) (*pointer_)相当于。注意括号是必要的,如果没有括号,就成为了*pointer_,从附录可知:+和*为同一优先级别,而结合方向为自右而左,因此它相当于*(pointer_)。由

6、于+在pointer_1的右侧,是“后加”,因此先对pointer_的原值进行*运算,得到的值,然后使pointer_的值改变,这样pointer_不再指向了。,例10 . 2 输入和两个整数,按先大后小的顺序输出 和。,#include void main() int *1,*2,*,; scanf(,); 1; if() ; printf(=,=,); printf(max=,min=,*1,*2); ,运行情况如下: , , , 当输入,时,由于,将和交换。交换前的情况见图(),交换后见图()。,10.3 指针变量作为函数参数,例10 . 3 对输入的两个整数按大小顺序输出,#inclu

7、de void main() void swap(int *,int *); int ,; int *pointer_,*pointer_; scanf(,); pointer_ ; pointer_2 ; if(swap( pointer_ , pointer_2 ); printf(,); ,void swap(int *,int *) int temp; temp*1; *; *temp; ,例10. 输入、 3个整数,按大小顺序输出,#include void main() void exchange(int *1, int *2, int *3); int ,*,*,*; scanf

8、(%,%,%, if(*) swap(,); if(*) swap(,); if(* swap(,); void swap(int *, int *) int temp; temp*; *; *temp; ,10.3 数组与指针,一个变量有地址,一个数组包含若干元素,每个数组元素都在内存中占用存储单元,它们都有相应的地址。指针变量既然可以指向变量,当然也可以指向数组元素(把某一元素的地址放到一个指针变量中)。所谓数组元素的指针就是数组元素的地址。,定义一个指向数组元素的指针变量的方法,与以前介绍的指向变量的指针变量相同。例如: ; (定义为包含个整型数据的数组) *; (定义为指向整型变量的指

9、针变量) 应当注意,如果数组为型,则指针变量的基类型亦应为型。,10.3.1 指向数组元素的指针,对该指针变量赋值: ; 把元素的地址赋给指针变量。也就是使指向数组的第号元素,如图:,10.通过指针引用数组元素,引用一个数组元素,可以用: () 下标法,如形式; () 指针法,如*()或*()。其中是数组名,是指向数组元素的指针变量,其初值。,例10.5 输出数组中的全部元素,假设有一个数组,整型,有个元素。要输出各元素的值有三种方法:,(1)下标法 #include void main() int ; int; for(;) scanf(,); printf(); for(;) printf

10、(,); ,(2) 通过数组名计算数组元素地址,找出元素的值。 #include voidmain() int ; int ; for(; ) scanf(,); printf(); for(;) printf(,*(); ,(3) 用指针变量指向数组元素。 #include void main() int ; int *,; for(;) scanf(,); printf(); for(;();) printf( ,*); ,例10. 通过指针变量输出数组的个元素。,有人编写出以下程序: #include void main() int*,; ; for(; ) scanf(,); prin

11、tf(); for(;, ) printf(,*); ,这个程序乍看起来好像没有什么问题。有的人即使已被告知此程序有问题,还是找不出它有什么问题。我们先看一下运行情况: 1 2 3 4 5 6 7 8 9 0 22153 234 0 0 30036 25202 11631 8259 8237 28483 显然输出的数值并不是数组中各元素的值,解决这个问题的办法,只要在第二个循环之前加一个赋值语句: ;,#include void main() int*,; ; for(;) scanf(,); printg(); p=a; for(;, ) printf(,*); ,10.3 用数组名作函数参

12、数,在第8章8.7节中介绍过可以用数组名作函数的参数 如: void main() i(int ,int ); int ; (,); void (int ,int ) ,f (int arr , int n) 但在编译时是将arr按指针变量处理的,相当于将函数f的首部写成 f (int *arr, int n) 以上两种写法是等价的。,需要说明的是:C语言调用函数时虚实结合的方法都是采用“值传递”方式,当用变量名作为函数参数时传递的是变量的值,当用数组名作为函数参数时,由于数组名代表的是数组首元素地址,因此传递的值是地址,所以要求形参为指针变量。,例10 将数组中个整数按相反顺序存放,#inc

13、lude void main() void inv(int ,int ); int , ,; printf(The original array:); for(;) printf (,); printf(); inv (,); printf(The array has been in verted:); for(;) printf (,); printf (); ,void inv(int ,int ) /*形参x是数组名*/ int temp,(); for(;) ; temp; ; temp; return; ,运行情况如下: The original array: , The array

14、 has been inverted: ,,#include void main() void inv(int *,int ); int , ,; printf( The original array: ); for(;) printf (,); printf (); inv(,); printf ( The array has been in verted: ); for(;) printf (,); printf ();,对这个程序可以作一些改动。将函数inv中的形参改成指针变量。,void inv(int *,int ) /*形参x为指针变量*/ int,temp,*,*,(); ; f

15、or(;,) emp*;*;*temp; return; ,归纳起来,如果有一个实参数组,想在函数中改变此数组中的元素的值,实参与形参的对应关系有以下种情况:,(1) 形参和实参都用数组名,如: void main() void (int ,int ) int ; (,); ,(2) 实参用数组名,形参用指针变量。如: void () void (int *,int ) int ; (,); ,(3)实参形参都用指针变量。例如: void main() void (int *,int ) int , *p=a; (p,); ,(4) 实参为指针变量,形参为数组名。如: void main()

16、void (int x ,int ) ,*p=a; (p,); ,#include void main() void inv(int *,int ); int ,*; printf(The original array:n ); for(;,) scanf(,); printf(); ; inv(,); /* 实参为指针变量 */ printf(The array has been inverted :); for(; ) printf(,*); printf(); ,void inv(int *,int ) int,temp,*,*; (); ; for(;,) emp*;*;*temp;

17、return; ,例109 用选择法对个整数按由大到小顺序排序,#include void main() void sort(int ,int ); int*,10; ; for(;) scanf(,); ; sort(,); for(,;) (,*); ,void sort(int ,int ) int ,; for(;) ; for(;) () ; (!) ; ; ; ,10. 多维数组与指针,用指针变量可以指向一维数组中的元素,也可以指向多维数组中的元素。但在概念上和使用上,多维数组的指针比一维数组的指针要复杂一些。,1. 多维数组元素的地址,先回顾一下多维数组的性质,可以认为二维数组是

18、“数组的数组”,例 : 定义int a34=1,3,5,7,; 则二维数组a是由3个一维数组所组成的。设二维数组的首行的首地址为 ,则,例10.0 输出二维数组有关的值,#include define FROMAT, void main() int 341,3,5,7,9, ,; printf(,*); printf(,0 , *(); printf(,0,00); printf(,1,); printf(,10,*(+)+); printf(,*(); printf(,); printf(,*(*( ); ,某一次运行结果如下: , (0行首地址和0行0列元素地址) , (0行0列元素地址)

19、 , (0行0首地址和0行0列元素地址) , (1行0列元素地址和1行首地址) , (1行0列元素地址) , (2行0列元素地址) , (2行首地址) , (1行0列元素的值),2 . 指向多维数组元素的指针变量,在了解上面的概念后,可以用指针变量指向多维数组的元素。 (1) 指向数组元素的指针变量,例10.11 用指针变量输出二维数组元素的值,#include void main() int 341,3,5,7,9,11,13,15,17,19,21,23; int*; for(;) () printf(); printf(,*); ,运行结果如下: 1 3 5 7 9 11 13 15 1

20、9 21 23,可将程序最后两个语句改为 printf(addr, value2,*); 在TC+环境下某一次运行时输出如下: , , , , , , , , , , , ,,(2) 指向由个元素组成的一维数组的指针变量,例10.13 出二维数组任一行任一列元素的值,#include void main ( ) int 1,3,5,7,9,11, 13,15,; int (*),; ; scanf( ,); printf(, ,*(*(); ,运行情况如下: , (本行为键盘输入) ,,运行情况如下: ,(本行为键盘输入) ,,3. 用指向数组的指针作函数参数,例10.13 有一个班,个学生,

21、各学门课,计算总平均分数以及第个学生的成绩。这个题目是很简单的。只是为了说明用指向数组的指针作函数参数而举的例子。用函数求总平均成绩,用函数找出并输出第个学生的成绩。,#include void main() void average(float *p,int n); void search(float (*p)4,int n); float score34=65,67,70,60,80, 87,90,81,90,99,100,98; average(*score,12);*求12个分数的平均分* search(score,);*求序号为的学生的成绩* ,void average(float

22、*,int ) float*_; float ,; _; (;_;) (*); ; printf(average,aver); ,void search(float (*)4,int ) / * p是指向具有4个元素的一维数组的指针 */int ; printf(the score of No. % are:,); for(;) printf(5.2,*(*(); 程序运行结果如下: : .,例10.4 在上题基础上,查找有一门以上课程不及格的学生,打印出他们的全部课程的成绩。,#include void main() void search(float (*p)4,int n);/*函数声明

23、*/ float score34=65,57,70,60,58,87, 90,81,90,99,100,98; search(score,); ,void search(float (*p)4,int ) int ,; for(;) flag; for(;) if(*(*())flag; if() printf(No.%d fails,his scores are:n,j+1); for(;) printf(%.,*(*(); printf(); ,程序运行结果如下: s, : . . . . s, . . . .,10. 字符串与指针,10字符串的表示形式,例 10.5 定义一个字符数组,对

24、它初始化, 然后输出该字符串,#include void main() char string !; printf(,); ,(1) 用字符数组存放一个字符串,然后输出该字符串。,(2) 用字符指针指向一个字符串,可以不定义字符数组,而定义一个字符指针。用字符指针指向字符串中的字符。 例106 定义字符指针 #include void main() charstring !; printf(,); ,例10.7 将字符串复制为字符串,对字符串中字符的存取,可以用下标方法,也可以用指针方法,#include void () char am a boy,20; int ; for(;*()!;)

25、*()*(); *(); printf(string a is :,); printf( :); for(;!;) printf(,); printf(); ,也可以设指针变量,用它的值的改变来指向字符串中的不同的字符。,例10.8 用指针变量来处理例107问题。,#include void main() char =I am a boy. ,20,*p1,*p2; int ; ; for(;*!;p1,p2),*; *; printf(string is:,); printf( :); for(;!;) printf(,); printf(); ,程序必须保证使和同步移动。,10. 字符指针

26、作函数参数,例1019 用函数调用实现字符串的复制,#include void main() void copy_string(char from , char to ); char a = am a teacher; char =you are a student; printf(“string a= string , ,); printf(copy string a to string b:n ); copy_string (,); printf(nstring a=%snstring b=%sn,a,b); ,(1) 用字符数组作参数,void copy_string(char from

27、 , char to ) int ; while(!) ; ; ,程序运行结果如下: copy string a to string b: ,() 形参用字符指针变量,#include void main() void copy_string(char *, char *); char * am a teacher .; char *you are a student ; printf(string a= ,); printf(copy string a to string b:n ); _(,); printf(nstring a=%snstring b=%sn,a,b); ,void co

28、py_string(char *,char *) for(;*from!;from,to) *; *; ,() 对 copy_string 函数还可作简化,1、将copy_string函数改写为 void copy_string (char *,char *) while(*)!) ; ,2、 copy_string函数的函数体还可改为 while(*to*from)!); ,3、copy_string函数的函数体还可写成 while(*!) *; *; ,4、上面的while语句还可以进一步简化为下面的while语句: while(*); 它与下面语句等价: while(*to*from)!

29、); 将*赋给*,如果赋值后的*值等于,则循环终止(已赋给*),5、函数体中语句也可以改用语句: for(;(*to*from)!;); 或 for(;*to*from;);,6、也可用指针变量,函数copy_string可写为 void copy_string (char from ,char ) *,*; ; while(*p2*p1)!); ,10. 对使用字符指针变量和字符数组的讨论,虽然用字符数组和字符指针变量都能实现字符串的存储和运算,但它们二者之间是有区别的,不应混为一谈,主要有以下几点:,(1) 字符数组由若干个元素组成,每个元素中放一个字符,而字符指针变量中存放的是地址(字符

30、串第1个字符的地址),决不是将字符串放到字符指针变量中。 (2)赋值方式。对字符数组只能对各个元素赋值,不 能用以下办法对字符数组赋值。 char str; str !; 而对字符指针变量,可以采用下面方法赋值: char*; !; 但注意赋给的不是字符,而是字符串第一个元素 的地址。,(3)对字符指针变量赋初值: char * love China!;等价于 char*; !; 而对数组的初始化: char str love China!; 不能等价于 char str; str !;,(4) 如果定义了一个字符数组,在编译时为它分配内存单元,它有确定的地址。而定义一个字符指针变量时,给指针

31、变量分配内存单元,在其中可以放一个字符变量的地址也就是说,该指针变量可以指向一个字符型数据,但如果未对它赋予一个地址值,则它并未具体指向一个确定的字符数据。,如: char str; scanf(,str);是可以的。 而常有人用下面的方法,目的是想输入一个字符串,虽然一般也能运行,但这种方法是危险的 : char*; scanf(,);,应当这样: *,; ; (,);,(5) 指针变量的值是可以改变的,如:,例10.0改变指针变量的值,#include void () char*I love China!; ; printf(,); ,需要说明,若定义了一个指针变量,并使它指向一个字符串,

32、就可以用下标形式引用指针变量所指的字符串中的字符。例101 #include voidmain() char* love hina!; int ; printf ( “ The sixth character is %cn,a5); for(;!;) printf(,); ,10. 指向函数的指针,10. 用函数指针变量调用函数,可以用指针变量指向整型变量、字符串、数组,也可以指向一个函数。一个函数在编译时被分配给一个入口地址。这个函数的入口地址就称为函数的指针。,例10.2 求和中的大者。先列出按一般 方法的程序。,#include voidmain() int max(int,int);

33、int ,; scanf(,); (,); printf(, ,); int max(int ,int ) int ; if(); else ; return(); ,将 main 函数改写为 #include voidmain() int (int,int); int (*)(); int ,; ; scanf(,); (*)(,); printf(, ,); ,10. 用指向函数的指针作函数参数,函数指针变量常用的用途之一是把指针作为参数传递到其他函数。前面介绍过,函数的参数可以是变量、指向变量的指针变量、数组名、指向数组的指针变量等。现在介绍指向函数的指针也可以作为参数,以实现函数地址的

34、传递,这样就能够在被调用的函数中使用实参函数。它的原理可以简述如下:有一个函数(假设函数名为sub),它有两个形参(x1和x2),定义x1和x2为指向函数的指针变量。在调用函数sub时,实参为两个函数名和,给形参传递的是函数和的地址。这样在函数中就可以调用和函数了。,实参函数名 f1 void (int (*x1)(int),int (*x2)(int,int)) int ,; (*)(); *调用函数* (*)(,);*调用函数* ,例10.3 设一个函数process,在调用它的时候,每次实现不同的功能。输入和两个数,第一次调用process时找出和中大者,第二次找出其中小者,第三次求与之

35、和。,#include void main() int max(int,int); /* 函数声明 */ int min(int,int); /* 函数声明 */ int add(int,int); /* 函数声明 */ void process (int,int,int(*fun)(); /* 函数声明 */ int ,; printf( :); scanf(,);,(); (,); (); (,); (); (,); ,int (int ,int ) /* 函数定义 */ ; (); ; (); int (int ,int ) /* 函数定义 */ ; (); ; (); ,int (in

36、t ,int ) /* 函数定义 */ ; ; (); void process(int ,int ,int (*fun)(int,int) ; (*)(,); (,); ,10. 返回指针值的函数,一个函数可以带回一个整型值、字符值、实型值等,也可以带回指针型的数据,即地址。其概念与以前类似,只是带回的值的类型是指针类型而已。 这种带回指针值的函数,一般定义形式为 类型名 *函数名(参数表列); 例如: *(int ,int );,例104 有若干个学生的成绩(每个学生有门课程),要求在用户输入学生序号以后,能输出该学生的全部成绩。用指针函数来实现。,#include void main()

37、 float *score 4=60,70,80,90, 56,89,67,88,34,78,90,66; float*search(float (*pointer)4,int n); float*; int ,; printf(enter the number of student:); scanf(,); printf(The scores of No are:,);,search(,); for(; printf(,*(); ,float * search(float (*)4,int ) float *; *(); return(); 运行情况如下: enter the number

38、of student: The scores of No. are: 56.00 89.00 67.00 88.00,例105 对上例中的学生,找出其中有不及格课程的学生及其学生号。,#include void main() float score 4=60,70,80,90,56, 89,67,88,34,78,90,66; float search(float (*pointer)4); float*; i ,;,f(;) (); (*() printf(scores:,); for(;) printf(,*(); printf(); ,10.指针数组和指向指针的指针,10. 指针数组的概

39、念,一个数组,若其元素均为指针类型数据,称为指针数组,也就是说,指针数组中的每一个元素都相当于一个指针变量。一维指针数组的定义形式为 类型名数组名数组长度; 例如: *;,例106 将若干字符串按字母顺序(由小到大)输出。,#include #include void main() void sort(char *name ,int n); void printf(char *name ,int n); char *name =Follow me,BASIC,Great Wall,FORTRAN,Computer design; int ; sort(,); print(,); ,void s

40、ort(char * ,int ) char *; int ,; for(; ; for(; if(strcmp(name,name)0)=; if(!) temp=namei; namei=namek; namek=temp; ,void print(char * ,int ) ; (;) printf(,); ,运行结果为: ,10 指向指针的指针,怎样定义一个指向指针数据的指针变量呢?如下: *; 的前面有两个*号。*运算符的结合性是从右到左,因此*相当于*(*),显然*是指针变量的定义形式。如果没有最前面的*,那就是定义了一个指向字符数据的指针变量。现在它前面又有一个*号,表示指针变量

41、是指向一个字符指针变量的。*就是所指向的另一个指针变量。,例107 使用指向指针的指针,#include void main() char *name=Follow me,BASIC,Great Wall,FORTRAN,Computer design; char *; int ; for(;) ; printf(,*); ,例10.28 一个指针数组的元素指向整型数据的简单例子,#include void main() int ,; int *num5= char name20; char sex; int age; int char addr30;,应当把它们组织成一个组合项,在一个组合

42、项中包含若干个类型不同(当然也可以相同) 的数据项。,11.1 概述,声明一个结构体类型的一般形式为: struct 结构体名 成员表列; 如:struct student int num;char name20;char sex; int age;float score;char addr30; ,结构体名,类型名,成员名,11.2 定义结构体类型变量的方法,可以采取以下3种方法定义结构体类型变量: (1)先声明结构体类型再定义变量名 例如:struct student student1, student2; | | | 结构体类型名 结构体变量名 定义了student1和student2为

43、struct student类型的变量,即它们具有struct student类型的结构.,11.2 定义结构体类型变量的方法,在定义了结构体变量后,系统会为之分配内存单元。 例如:student1和student2在内存中各占59个字节(2+20+1+2+4+30=59)。,注意: 将一个变量定义为标准类型(基本数据类型)与定义为结构体类型不同之处在于后者不仅要求指定变量为结构体类型,而且要求指定为某一特定的结构体类型,因为可以定义出许许多多种具体的结构体类型。,11.2 定义结构体类型变量的方法,(2)在声明类型的同时定义变量 这种形式的定义的一般形式为: struct结构体名 成员表列

44、变量名表列;,11.2 定义结构体类型变量的方法,例如: struct student int num; char name20; char sex; int age; float score; char addr30; student1,student2;,它的作用与第一种方法相同,即定义了两个struct student 类型的变量student1, student2,11.2 定义结构体类型变量的方法,(3) 直接定义结构体类型变量 其一般形式为: struct 成员表列 变量名表列; 即不出现结构体名。,注意: (1) 类型与变量是不同的概念,不要混同。只能对变量赋值、存取或运算,而不

45、能对一个类型赋值、存取或运算。在编译时,对类型是不分配空间的,只对变量分配空间。,注意: (2)对结构体中的成员(即“域”),可以单独使用,它的作用与地位相当于普通变量。 (3)成员也可以是一个结构体变量。 (4) 成员名可以与程序中的变量名相同,二者不代表同一对象。,11.2 定义结构体类型变量的方法,例如:struct date /*声明一个结构体类型*/ int num; char name20; char sex; int age; float score; struct date birthday; /*birthday是struct date类型*/ char addr30; st

46、udent1,student2;,先声明一个struct date类型,它代表“日期”,包括3个成员:month(月)、day(日)、year(年)。然后在声明struct student类型时,将成员birthday指定为struct date类型。,11.3结构体变量的引用,在定义了结构体变量以后,当然可以引用这个变量。但应遵守以下规则: (1)不能将一个结构体变量作为一个整体进行输入和输出。 例如: 已定义student1和student2为结构体变量并且它们已有值。 printf(%d,%s,%c,%d,%f,%n,student1);,11.3结构体变量的引用,引用结构体变量中成员的

47、方式为 结构体变量名.成员名 例如, student1.num表示student1变量中的num成员,即student1的num(学号)项。可以对变量的成员赋值,例如:student1.num=10010;“.”是成员(分量)运算符,它在所有的运算符中优先级最高,因此可以把student1.num作为一个整体来看待。上面赋值语句的作用是将整数10010赋给student1变量中的成员num。,11.3结构体变量的引用,(2) 如果成员本身又属一个结构体类型,则要用若干个成员运算符,一级一级地找到最低的一级的成员。只能对最低级的成员进行赋值或存取以及运算。 例如: 对上面定义的结构体变量stud

48、ent1, 可以这样访问各成员: student1.num student1.birthday.month,注意: 不能用student1.birthday来访问student1变量中的成员birthday,因为birthday本身是一个结构体变量。,11.3结构体变量的引用,(3) 对结构体变量的成员可以像普通变量一样进行各种运算(根据其类型决定可以进行的运算)。 例如: student2.score=student1.score; sum=student1.score+student2.score; student1.age+; +student2.age;,由于“”运算符的优先级最高,因

49、此是对进行自加运算,而不是先对进行自加运算。,11.3结构体变量的引用,(4) 可以引用结构体变量成员的地址,也可以引用结构体变量的地址。 例如: scanf(%d, (输入student1.num的值) printf(%o,student1); (输出student1的首地址),11.3结构体变量的引用,但不能用以下语句整体读入结构体变量, 例如: scanf(%d,s,c,d,f,s,student1); 结构体变量的地址主要用作函数参数, 传递结构体变量的地址。,11.结构体变量的初始化,但不能用以下语句整体读入结构体变量, 例如: scanf(%d,s,c,d,f,s,student1

50、); 结构体变量的地址主要用作函数参数,传递结构体变量的地址。,例11.1 对结构体变量初始化.#include void main() struct student long int num; char name20; char sex; char addr20; a=10101,LiLin,M,123 Beijing Road; /* 对结构体变量a赋初值*/printf(No.:%ldnname:%snsex:%cnaddress:%sn,a.num,,a.sex,a.addr); ,运行结果: No.:10101 name:LiLin sex: address:123 Be

51、ijing Road,11.5 结构体数组,一个结构体变量中可以存放一组数 据(如一个学生的学号、姓名、成绩等 数据)。如果有个学生的数据需要 参加运算,显然应该用数组,这就是结 构体数组。结构体数组与以前介绍过的 数值型数组不同之处在于每个数组元素 都是一个结构体类型的数据,它们都分 别包括各个成员(分量)项。,11.5 结构体数组,11.5.1定义结构体数组 和定义结构体变量的方法相仿,只需说明其为数组即可。例如: struct student int num;char name20;char sex;int age; float score;char addr30; ;struct st

52、udent3;,以上定义了一个数组stu,数组有个元素,均为struct student类型数据。,11.5 结构体数组,也可以直接定义一个结构体数组,例如: struct student int num; ;stu3; 或: strcut student int num; ;stu3;,图11-4,11.5 结构体数组,11.5.2 结构体数组的初始化 与其他类型的数组一样,对结构体数组可以初始化。例如: struct student int num;char name20; char sex; int age; float score; char addr30; ;stu210101,Li

53、Lin,M,18,87.5,103 BeijingRoad,10102,Zhang Fun,M,19,99,130 Shanghai Road;,图11-5,11.5 结构体数组,当然,数组的初始化也可以用以下形式: struct student int num; ; struct studentstr,; 即先声明结构体类型,然后定义数组为该结构体类型,在定义数组时初始化。,结构体数组初始化的一般形式是在定义数组的后面加上“初值表列;”。,11.5 结构体数组,11.5.3 结构体数组应用举例,例11.2对候选人得票的统计程序。设有3个候选人,每次输入一个得票的候选人的名字,要求最后输出各人

54、得票结果。#include #include struct person char name20;in count; ;leader3=“Li”,0,”Zhang”,0,”Fun”,0,例11.2void main() int i,j; char leader_name20; for(i=1;i=10;i+) scanf(“%s”,leader_name); for(j=0;j3;j+) if(strcmp(leader_name,)=0) leaderj.count+; printf(“n”); for(i=0;i3;i+) printf(“%5s:%dn”,lead

55、,leaderi.count);,运行结果: : : :,11.5 结构体数组,程序定义一个全局的结构体数组leader,它有个元素,每一个元素包含两个成员name(姓名)和count(票数)。在定义数组时使之初始化,使3位候选人的票数都先置零. 在主函数中定义字符数组leader-name,它代表被选人的姓名,在10次循环中每次先输入一个被选人的具体人名,然后把它与3个候选人姓名相比,看它和哪一个候选人的名字相同。在输入和统计结束之后,将3人的名字和得票数输出。,11.6 指向结构体类型数据的指针,一个结构体变量的指针就是该变量所占据的内存段的起始地址。可以设一个指针变量,用

56、来指向一个结构体变量,此时该指针变量的值是结构体变量的起始地址。指针变量也可以用来指向结构体数组中的元素. 11.6.1 指向结构体变量的指针 下面通过一个简单例子来说明指向结构体变量的指针变量的应用。,例1指向结构体变量的指针的应用#include #include void main()struct studentlong num;char name20; char sex; float score; struct student stu_1; struct student* p; p= ,定义指针变量p,指向struct student 类型的数据,指向的结构体变量中的成员,运行结果:

57、:89101 name:LiLin sex: score:89.500000 :89101 name:LiLin sex: score:89.500000,11.6 指向结构体类型数据的指针,程序分析: 在函数的执行部分将结构体变量-的起始地址赋给指针变量,也就是使指向-,然后对-的各成员赋值。第一个函数是输出-的各个成员的值。用-表示-中的成员,依此类推。第二个函数也是用来输出-各成员的值,但使用的是(*)这样的形式。,图11-7,11.6 指向结构体类型数据的指针,以下3种形式等价: 结构体变量成员名 (*)成员名 -成员名 其中-称为指向运算符。,请分析以下几种运算: -得到指向的结构体变量

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论