第九章指针类型

第九章指针类型
第九章指针类型

9.1 指针类型的声明

指针类型在任何语言中都是比较难以理解也是比较灵活的一种数

据类型

指针常是它所指的变量的内存地址。声明指针类型的语法如下:

Type

〈指针类型标志符〉=^〈基类型〉;

其中,指针类型标志符即是指针类型名,基类型可以是简单类

型,如整型,实型,字符型等,也可以是结构类型,如数组,记

录,集合等。

指针类型声明示例:

Type

Tr = ^Integer;

PI = ^real;

Word = Record

Name: String[10];

Age: Integer;

Scores: Real;

End;

BytePtr = ^Byte;

WordPtr = ^Word;

上例中,声明了4个指针类型。其中,BytePtr是一个指向字节类型的数据;而WordPtr是一个指向记录类型Word的数据Object Pascal不要求基类型一定是要在前面已声明的,也可以是一个标志符,然后在同一个模块内声明基类型。

声明了指针类型后,就可以声明指针类型的变量,如:

Var

BP: BytePtr;

WP: WordPtr;

或:

Var

BP: ^Bytel;

指针所指的基类型可以是简单类型,也可以是构造类型,如:Type

Student = Record

Name: String;

Age: Integer;

Sex: (Man, Woman);

End;

Var

StuPtr: ^Student;

上例中,声明了一个指向记录类型的Student指针变量StuPtr,以后程序中就可以使用StuPtr^来表示记录类型Student的动态变量。要访问其中的Name字段,可以写成StuPtr^.Name。这里介绍动态变量的概念,动态变量的构成是用指针类型的变量标志符后加一个“^”符号,就构成指针所指向的基类型的动态变量,如上例中的StuPtr^就是Student的动态变量。

与通常的变量一样,一旦声明了指针变量,编译器将给指针分配存储单元,但存储单元中的值尚未确定。要想让指针指向确定的地址,必须通过赋值语句或New标准过程来实现。如:Label 1,2,3,4,5;

Var

M: Integer;

X1, X2: ^Integer;

Begin

1: M:= 20;

2: X1:= @M;

3: New(X2);

4: X2^:= 150;

5: Dispose(X2);

End;

执行上述语句段时,若编译器给变量M分配的内存地址为$,那么,执行标号为3的语句后,指针变量X1和变量M的关系如下:

X1 $

$20

即指针变量X1的值为变量M的内存地址。

执行语句3时,编译器首先在内存中分配适宜存放指针X2所指向的数据(这里为正数)的一组存储单元(假设为$01100A),然后将这组单元的首地址写入指针X2。这里X2^称为动态存储变量。使用New建立了动态存储变量后,它的值是不确定的,以后可以将某个整数值存储在该单元中。

X2 $01100A

$01100A?

X2 $01100A

$01100A150

执行语句5后,标准过程Dispose将释放由New分配的内存单元。在程序段中,标号过程New和Dispose应配对使用。当用New分配的动态存储空间不再使用时,应及时地释放所分配的存储空间,避免发生错误。如果

分配存储空间时内存不够,将触发一个异常错误(EoutOfMemory),程序随

即终止。上例中的运算符“@”和“^”专用于指针类型,分别称为取址和应用

运算符。

9.2 指针的运算

Delphi提供了专门的过程和函数来操作指针,

这些过程和函数是:

New过程,

@操作符,

PTR函数,

GetMem过程

1)New过程

New是Object Pascal中的标准例程(在System单元中声明),用于在应用程序中为动态变量分配一块区域,并把该区域的地址赋给指针变量。所分配区域的大小由指针所指的类型决定。如果分配存储空间时内存不够,将触发一个异常错误(EoutOfMemory)

New过程的声明如下:

Procedure New(Var P: Pointer);

其中P是一个指针变量,调用了New过程后,程序就可以用P^作为指针所指类型的动态变量。相应地,当程序不再需要使用动态变量时,就应当调用标准例程Dispose删除New创建的动态变量,并释放所分配的空间。程序示例如下:

Type

PlisEntry =^ TlistEntry;

TlistEntry = Record

Next : PlistEntry;

Text : String;

Count: Integer;

End;

Var

List, P: PlistEntry;

Begin

……

New(P);

P^.Next := List;

P^.Text := ’Hellow world’;

P^.Count := 1;

List:= P;

Dispose(P);

……

End;

2)@操作符

@操作符是一个一元操作符,用于获得操作数的的地址,@后面的操作数可以是变量,过程,函数或类型中的方法,程序示例如下:

Procedure ChangeValue(X: Integer);

Var

IntPtr: ^Integer;

Begin

Intptr:= @X;

Writeln(IntPtr^);

IntPtr^:= 20;

End;

如果主程序如下:

Var

Param: Integer;

Begin

Param:= 10;

ChangeValue(Param);

Writeln(Param);{10}

End;

上例中,ChangeValue过程首先声明了一个指向整数类型数的指针IntPtr,然后用@操作符取出X的地址赋予IntPtr指针,并显示IntPtr指针指向的数,最后改变这个数。

3)PTR函数

PTR 函数是Pascal中的标准例程,用于把一个指定的地址转换为指针,

语法为:

Function Ptr(Address: Integer): pointer;

其中,Address是一个整数,用于表示一个32位地址,函数执行的结果是把32为地址转化为指针。

4)GetMem过程

GetMem 过程也是Pascal中的标准例程,类似于New,用于在应用程序中堆栈中为动态变量申请一块指定大小的区域,并把该区域的地址赋予指针变量。语法为:

Procedure GetMem(var P:Pointer;Size:Integer);

其中P是一个指针变量,Size指定区域的字节数。所分配区域的大小由指针变量P的基类型决定。如果在应用程序堆栈中没有足够的内存空间供分配,将触发EOutOfMemory异常。如果程序不再需要该动态变量时,可以调用标准例程FreeMem释放该变量分配的内存空间。程序如下:

Var

F: file;

Size: Integer;

Buffer: Pchar;

Begin

AssignFile(F, ’test.txt’);

Reset(F,1);

Try

Size:= FileSize(F);

GetMem(Buffer, Size);

Try

BlockRead(F, Buffer^,Size);

ProcessFile(Buffer, Size);

Finally

FreeMem(Buffer);

End;

Finally

CloseFile(F);

End;

End;

上例打开一个名字Test.txt为的文件,并把文件读入动态分配的缓冲区,缓冲区大小为文件的大小,然后对文件进行处理,最后释放动态分配的缓冲区,并关闭文件。Pascal中有一个特殊的保留字nil,这是一个空指针常量,当指针的值为nil时,表示指针当前没有指向任何动态变量。值为nil的指针变量不能访问动态变量。指针变量除了能被赋值外,还能进行相等或不相等的比较,比较只限于类型兼容的指针变量之间。当两个指针指向同一个对象时,指针才相等。

9.3 无类型指针

无类型指针是指指针变量在声明时没有指明基类型。

无类型指针在声明中只使用Pointer。如:

Var

PAnyPOint: Pointer;

指针PAnyPOint可以指向任何变量类型。无类型的指针的作用是它可以指向任何类型,但是,不能用指针变量符后加“^”的形式引用它的动态变量。要引用Pointer类型指针指向的变量,应先将其转换为确定的类型,

如:

Type

Tpinte: ^Integer;

Var

M, N: Integer;

P: Pointer;

Pt: Tpinte;

Begin

M:= 150;

P:= @M;

Pt:= Tpinte(P)

N:= Pt^;

End;

9.4 字符指针类型

字符指针类型即PChar 数据类型,

是一个指向以NULL(不是零)字符结尾的字符串的指针。这种类型主要用于

与外部函数中如在Windows API 中所用的函数兼容。与Pascal字符串不同,Windows和C字符串没有一个长度字节。取而代之的是它们0字节索引开始,以一个NULL结束。Pascal RTL字符函数根据长度决定存储在字符串变量中的字符数目。在Pascal中使用这些函数就需要PChar类型变量。内存将分配给变量并被所需函数使用。

除了PChar外,Delphi还包含PAnsiChar和PWideChar数据类型。

?PAnsiChar数据类型是一个指向以NULL字符结尾的AnsiChar字符串的指针,在Delphi中,PCHAR等同于PAnsiChar。

?PWideChar数据类型是一个指向以NULL字符结尾的WideChar字符串的指针,用于UniCode字符集。

实际上,PAnsiChar和PWideChar数据类型的定义为:

Type

PansiChar = ^AnsiChar;

PwideChar = ^WideChar;

Pchar = PansiChar;

字符串类型与PChar类型赋值兼容,即一个字符串可以直接赋给一个PChar

类型的变量,如:

var

P: Pchar;

……

Begin

P:= ’Hello World’;

End;

9.5 动态存储结构的实现

指针常用于描述动态存储结构的实现。

动态存储结构中常用的有链表,堆栈,队列等存储结构。

可以把堆栈和队列看成特殊的链表

本节只是简单介绍一下如何利用指针和记录来实现链表结构。

链表是一组元素的序列,在这个序列中每个元素总是与他前面的元素相链接(第一个元素除外)。这种关系可以通过指针来实现。链表中的元素称为节点,第一个节点称为表头,最后一个称为表尾。指向表头的指针称为头指针,在这个头指针里存放着表头的地址。节点一般用记录来描述,描述节点的记录至少含有两个域,一个用来存放数据,该域的类型根据要存放的数据而定,称为值域;另一个用来存放下一个节点的地址,称为指针域。表尾不指向任何节点,其指针的值为NIL。如图:

应用Object LPascal的指针和记录类型,图示的链表可以声明如下:

Type

Node:= Record;

Data: Char;

Next: ^Node;

End;

Var

Head: ^Node;

或者:

Type

Link = ^Node;

Node:= Record

Data: Char;

Next: ^Node;

End;

Var

Head: Link;

链表中相邻节点的地址是不连续的。当表头指针失去了指向表头的地址后,就无法找到整个链表,从而不能再对链表进行操作。同样,当任一节点中的指针失去了下一个节点后,链表就会断开,后边的节点就会全部消失。

若让表尾节点原有的空指针指向表头节点,就成为循环链表。如果链表的各节点既有指向前一个节点的指针又有指向后一个节点指针,这时的链表就称为双向链表。

链表可以描述许多实际问题,区别只是链表的值域有所不同。

对链表的操作有查找,插入,删除等。对于插入和删除操作来说,链表是很实用的数据结构。不论在链表的什么位置插入或删除节点,只需修改相应的指针。不必像顺序存储的数组那样需要移动数组中的每个元素。但对于链表来说,只有指针对用户来说是可见的。因此,要访问链表中某个节点的数据,必须从头指针开始依次搜索要访问的元素。

队列和堆栈是特殊的链表。所谓队列就是一个先入先出表。在该表中只允许在表头插入节点,在表尾删除节点。向队列中插入节点称作入队,新节点入队后就成为队列的新表尾;从队列的表头删除节点称为出队,出队后,其后继节

点成为表头。由于队列的插入和删除操作分别在两端进行,所以要删除的节点将是队列中最先进入的节点。堆栈则允许在链表的表头进行插入和删除操作。这里表头称为栈顶,另一端为栈底。向一个堆栈中插入新节点成为入栈或压栈,新节点插入后成为新的栈顶节点;从堆栈中删除节点称为出栈或退栈,它是把栈顶节点删除掉,是其相邻的节点成为新的栈顶。由于插入和删除仅在栈顶一端进行,后进栈的节点必然会先被删除,所以堆栈又称为先进后出表。

【例9-1】下列是一个关于在链表中利用指针处理字符串的程序。

分析:该程序的功能是通过一个文本编辑框输入一个字符串,输入后将该字符串存入一个链表中。每输入一次,在链表中新添一个节点。输入一些字符串后,单击“显示”按钮将输入的所有字符串显示在一个列表框中。通过文本编辑框输入的所有字符串显示在一个列表框中。通过文本框输入要查找的字符串,然后单击“删除”,将该字符串从链表中删除。此时再按下“显示”按钮,显示新的链表中的数据。

设计时添加一个组件Edit, 名为Edit1,添加一个组件Memo,名为Memo1, 三个Button组件:“删除”名为btnDel,“显示”名为btnList,“退出”名为btnQuit。

为了实现程序的功能,先声明一个全程的链表结构类型并命名一个该类型变量。这些在窗体单元的实现部分的开始处进行实现:

implementation

{$R *.dfm}

type

pLink = ^Node;

Node = record

Data: string[30];

Next: pLink;

end;

var

Head: pLink;

当程序创建窗体时进行变量Head的初始化:

procedure TForm1.FormCreate(Sender: TObject);

begin

Head:= Nil;

end;

当在文本编辑框中输入字符串并按下回车键后,在链表上添加一个新节点,并将输入的数据保存在该节点的数据域中,这个功能通过Edit1的OnKeyPress 处理过程实现:

procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);

var

tempP, P: pLink;

begin

if Key = #13 then//如果按下回车键

begin

New(tempP); //创建一个节点

tempP^.Data:= Edit1.Text;

tempP^.Next:= Nil;

if Head = Nil then//如果链表为空表

begin

New(Head); //创建链表

Head:= tempP;

end

else begin//如果链表不为空表

P:= Head;

while P^.Next <> Nil do //找表尾

P:= P^.Next;

P^.Next:= tempP; //将新节点添加到表尾

end;

Edit1.Clear; //清空编辑框

Edit1.SetFocus; //置编辑框为活动焦点

end;

end;

当按下“显示”时,在列表框ListBox1中显示链表中所有节点数据域中的数据:procedure TForm1.btnListClick(Sender: TObject);

var

P: pLink;

begin

Memo1.Clear;

P:= Head;

While P <> Nil do

begin

Memo1.Lines.Add(P^.Data);

P:= P^.Next;

end;

end;

在Edit1输入框中输入一个字符串后,单击“删除”,程序将按该字符串在链表中查找相应的节点,找到后删除该节点:

procedure TForm1.btnDelClick(Sender: TObject);

var

P,P1: pLink;

i: integer;

begin

i:=0;

P:= Head;

if P = nil then

ShowMessage('链表为空')

else if P^.Data = Edit1.Text then

begin //如果链表的第一个节点为要删除的节点

Head:= P^.Next;

P^.Next:= nil;

P:= Head;

end

else begin //如果链表的第一个节点不是要删除的节点

P1:= P^.Next;

if P1 <> nil then

repeat

if P1.Data = Edit1.Text then

begin

P^.Next:= P1^.Next; //如果找到一个要删除的节点

P1:= P;

i:= i+1;

end

else begin

P:= P1;

P1:= P1^.Next;

end;

Until P1 = nil;

if i = 0 then ShowMessage('无匹配的字符串'); end;

end;

procedure TForm1.btnQuitClick(Sender: TObject); begin

Close;

end;

结构体指针

C++语言结构体和指针 指针也可以指向一个结构体,定义的形式一般为: struct结构体名*变量名; 下面是一个定义结构体指针的实例: 上述代码已经测试。 注意:定义已经命名的结构体指针的时候必须用已命名结构体类型定义的结构体变量的地址进行初始化。 也可以在定义结构体的同时定义结构体指针: 上述代码已经测试 注意,结构体变量名和数组名不同,数组名在表达式中会被转换为数组指针,而结构体变量名不会,无论在任何表达式中它表示的都是整个集合本身,要想取得结构体变量的地址,必 pstu赋值只能写作: struct stu *pstu = &stu1; 而不能写作: struct stu *pstu = stu1; 还应该注意,结构体和结构体变量是两个不同的概念:结构体是一种数据类型,是一种创建变量的模板,编译器不会为它分配内存空间,就像int、float、char 这些关键字本身不占用内存一样;结构体变量才包含实实在在的数据,才需要内存来存储。下面的写法是错误的,不可能去取一个结构体名的地址,也不能将它赋值给其他变量: struct stu *pstu = &stu; struct stu *pstu = stu;

获取结构体成员 通过结构体指针可以获取结构体成员,一般形式为: (*pointer).memberName 或者: pointer->memberName 对了。 ,有了它,可以通过结构体指针 直接取得结构体成员;这C语言中的唯一用途。 上面的两种写法是等效的,我们通常采用后面的写法,这样更加直观。

运行结果: Name Num Age Group Score Zhou ping 5 18 C 145.0 Zhang ping 4 19 A 130.5 Liu fang 1 18 A 148.5 Cheng ling 2 17 F 139.0 Wang ming 3 17 B 144.5 结构体指针作为函数参数 结构体变量名代表的是整个集合本身,作为函数参数时传递的整个集合,也就是所有成员,而不是像数组一样被编译器转换成一个指针。如果结构体成员较多,尤其是成员为数组时,传送的时间和空间开销会很大,影响程序的运行效率。所以最好的办法就是使用结构体指针,这时由实参传向形参的只是一个地址,非常快速。 要铭记的一点就是:数组名称始终代表数组的指针指向第一个元素,数组名称加一始终指向下一个数组元素。

第七次作业(指针)

习题十 一、选择题 10-1.已知:int *p, a;则语句"p=&a;"中的运算符"&"的含义是。 A.位与运算B.逻辑与运算C.取指针内容D.取变量地址 10-2.已知:int a,x;则正确的赋值语句是。 A.a=(a[1]+a[2])/2; B.a*=*a+1; C.a=(x=1,x++,x+2); D.a="good"; 10-3.已知:int a, *p=&a;则下列函数调用中错误的是。 A.scanf("%d", &a); B.scanf("%d", p); C.printf("%d", a); D.printf("%d", p); 10-4.main(argc, argv)中形式参数argv的正确说明形式应当为。 ?? A.char *argv[ ] B.char argv[ ][ ] C.char argv[ ] D.char *argv 10-5.说明语句"int (*p)( );"的含义是。 A.p是一个指向一维数组的指针变量 B.p是指针变量,指向一个整型数据 C.p是一个指向函数的指针,该函数的返回值是一个整型 D.以上都不对 10-6.设有说明int (* ptr)[M];其中的标识符ptr是。 A.M个指向整型变量的指针 B.指向M个整型变量的函数指针 C.一个指向具有M个整型元素的一维数组的指针 D.具有M个指针元素的一维指针数组,每个元素都只能指向整型变量 10-7.已知:double *p[6];它的含义是。 A.p是指向double型变量的指针B.p是double型数组 C.p是指针数组D.p是数组指针 10-8.已知函数说明语句:void *f( );则它的含义是。 A.函数f的返回值是一个通用型的指针 B.函数f的返回值可以是任意的数据类型 C.函数f无返回值 D.指针f指向一个函数,该函数无返回值 10-9.已知:char s[10], *p=s,则在下列语句中,错误的语句是。 A.p=s+5; B.s=p+s; C.s[2]=p[4]; D.*p=s[0]; 10-10.已知:char b[5], *p=b;则正确的赋值语句是。 A.b="abcd"; B.*b="abcd"; C.p="abcd"; D.*p="abcd";

第九章:结构体

1、定义两个日期结构体变量(包括年、月、日)。输入两个日期值,比较两个日期的大 小(越靠后越大),输出较大的日期。 2、将1题中输入的日期进行验证,保证日期的正确性。(1)不可为负数;(2)年份 1900-2056之间,月份在1-12之间;(3)日期在1-31日以内(注意各月份的日期数判断及闰年的判断)(Year % 4 ==0 && Year % 100 !=0 || Year % 400 ==0) 3、输入两个日期,编程交换两个日期值,保证第一个日期是较大的日期(日期的大小比 较用函数表达)。 4、计算某日期是一年中的第几天。 5、计算两日期间相差的天数。 6、利用基姆拉尔森计算公式:W= (d+2*m+3*(m+1)/5+y+y/4-y/100+y/400) mod 7,计算 任意日期是星期几。说明:1)在公式中d表示日期中的日数,m表示月份数,y表示年数。2)注意:在公式中有个与其他公式不同的地方:把一月和二月看成是上一年的十三月和十四月,例:如果是2004-1-10则换算成:2003-13-10来代入公式计算。 7、打印出任意月份的日历表。 8、输入5位同学的一组信息(结构数组),包括学号、姓名、数学成绩、计算机成绩, 求得每位同学的平均分和总分,然后按照总分从高到低排序。 9、有一批图书(利用结构数组),每本书有:书名(name),作者(author) , 编号(num),出版 日期(date)四个数据,希望输入后按书名的字母顺序将各书的记录排列好,供以后查询。 今输入一本书的书名,如果查询到库中有此书,打印出此书的书名,作者,编号和出版日期。如果查不到此书,则打印出“无此书”。 10、利用指针重做9题:分别设计函数(1)结构数组的数据输入;(2)结构数组的输 出;(3)数组排序;(4)查询; 关于链表: 11、参考第8题,编写函数,建立动态链表,输入几位同学的信息(学号、姓名、数学、 计算机、平均分、总分),然后在屏幕上输出这些数据。 12、将11题中,各同学的总分与平均分计算出来,并输出所有数据; 13、建立函数,为上题中的链表添加一个新的节点。 14、建立按姓名查找某同学记录的函数,找到返回该节点的地址,未找到返回NULL; 15、在某个同学纪录之前插入一个新的节点。(某同学记录之后插入一个新的节点) 16、删除找到的某个同学记录的节点。 17、单向链表逆置;. 18、对单链表按照数学成绩从高到低排序;(只交换除指针成员next之外的其他成员变量 的值) 19、对两个链表进行连接;两个有序链表合并(保持有序);

第九章 习题及答案

第九章习题 一、选择题 1.以下选项中不能正确把cl定义成结构体变量的是( ) A)typedef struct B)struct color cl { int red; { int red; int green; int green; int blue; int blue; } COLOR; COLOR cl; }; C)struct color D)struct { int red; { int red; int green; int green; int blue; int blue; } cl; } cl; 2.有以下说明和定义语句 struct student { int age; char num[8];}; struct student stu[3]={{20,"200401"},{21,"200402"},{10\9,"200403"}}; struct student *p=stu; 以下选项中引用结构体变量成员的表达式错误的是( ) A) (p++)->num B)p->num C)(*p).num D)stu[3].age 3.有以下结构体说明、变量定义和赋值语句 struct STD {char name[10]; int age; char sex; }s[5],*ps; ps=&s[0]; 则以下scanf函数调用语句中错误引用结构体变量成员的是( )。 A)scanf(“%s”,s[0].name); B)scanf(“%d”,&s[0].age); C)scanf(“%c”,&(ps->sex)); D)scanf(“%d”,ps->age); 4.以下叙述中错误的是() A)可以通过typedef增加新的类型 B)可以用typedef将已存在的类型用一个新的名字来代表 C)用typedef定义新的类型名后,原有类型名仍有效 D)用typedef可以为各种类型起别名,但不能为变量起别名 5.有以下程序段() typedef struct node { int data; struct node *next; } *NODE; NODE p;

结构体的指针应用

什么是结构体? 简单的来说,结构体就是一个可以包含不同数据类型的一个结构,它是一种可以自己定义的数据类型,它的特点和数组主要有两点不同,首先结构体可以在一个结构中声明不同的数据类型,第二相同结构的结构体变量是可以相互赋值的,而数组是做不到的,因为数组是单一数据类型的数据集合,它本身不是数据类型(而结构体是),数组名称是常量指针,所以不可以作为左值进行运算,所以数组之间就不能通过数组名称相互复制了,即使数据类型和数组大小完全相同。 定义结构体使用struct修饰符,例如: struct test { float a; int b; }; 上面的代码就定义了一个名为test的结构体,它的数据类型就是test,它包含两个成员a和b,成员a的数据类型为浮点型,成员b的数据类型为整型。由于结构体本身就是自定义的数据类型,定义结构体变量的方法和定义普通变量的方法一样。 test pn1; 这样就定义了一个test结构体数据类型的结构体变量pn1,结构体成员的访问通过点操作符进行,pn1.a=10 就对结构体变量pn1的成员a进行了赋值操作。注意:结构体生命的时候本身不占用任何内存空间,只有当你用你定义的结构体类型定义结构体变量的时候计算机才会分配内存。 结构体,同样是可以定义指针的,那么结构体指针就叫做结构指针。 结构指针通过->符号来访问成员,下面我们就以上所说的看一个完整的例子: #include #include using namespace std; struct test//定义一个名为test的结构体 { int a;//定义结构体成员a int b;//定义结构体成员b }; void main() { test pn1;//定义结构体变量pn1 test pn2;//定义结构体变量pn2 pn2.a=10;//通过成员操作符.给结构体变量pn2中的成员a赋值 pn2.b=3;//通过成员操作符.给结构体变量pn2中的成员b赋值

第九章 结构体

一、概念题 F T T T F T T 二、判断题 1. 结构体中的成员不可以单独使用(F)。 2. 成员名可以与程序中的变量名相同,二者不代表同一对象(T)。 3. 不能将一个结构体变量作为一个整体进行输入输出(T )。 4. 结构体变量所占内存长度是各成员占的内存长度之和(T )。 5. 结构体中的成员不可以单独使用(F)。 9. 一个结构体变量的指针就是该变量所占内存段的起始地址(T)。 10. 用结构体变量作实参,形参也必须是同类型的结构体变量(T)。 三、单选题 1. 设变量定义如下,则对其中的结构分量num正确的引用是( )。 struct student { int num ; char name[20]; float score; } stud[10]; A. stud[1].num=10; B. student.stud.num=10; C. struct.stud.num=10; D. struct student.num=10; 2. 已知职工记录描述如下,设变量w中的“生日”是“1993年10月25日”,下列对“生日”的正确赋值方式是()。 struct worker { int no; char name[20]; char sex; struct birth{ int day; int month; int year;}a; }; struct worker w; A day=25;month=10;year=1993; B w.birth.day=25; w.birth.month=10; w.birth.year=1993; C w.day=25; w.month=10; w.year=1993; D w.a.day=25; w.a.month=10; w.a.year=1993; 3. 对于以下的变量定义,语句( )在语法和语义上都是正确的。 struct node { float x,y; char s[10];

指针数组函数练习(含参考答案).

作业(使用指针、数组、函数完成) 1. 编写一个通用函数,该函数可以实现判断:一个含有五位数字的整数是否是回文数。回文数的含义是从左向右与从右向左看,数是相同的。如:23732是回文数,而23564则不是。编写主程序调用该函数实现求所有5位数字中满足条件的数的个数。 #include int Judge(long num { int m,t,h,s,g; m=num/10000; t=(num-m*10000/1000; h=(num-m*10000-t*1000/100; s=(num-m*10000-t*1000-h*100/10; g=num-m*10000-t*1000-h*100-s*10; if((m==g&&(t==s return 1; else return 0; } void main( { int count=0; long i; for(i=10000;i<=99999;i++ if(Judge(i count++; printf("%d\n",count;

} 2.编写一个通用函数,该函数可以实现对数值型数组的倒序。倒序的含义是把数组的元素值前后颠倒。例数组:20,19,18,15,13,10倒序的结果为:10,13,15,18,19,20。编写主程序,数组初始化方式不限,并输出,然后调用该函数实现倒序后再输出倒序的结果。 #include #define N 6 void Transfer(double *b,int n { double temp; double *i=b; double *j=b+n-1; while(j>i { temp=*i; *i=*j; *j=temp; i++; j--; } } void main( { double array[N]={20,19,18,15,13,10}; int i; for(i=0;i printf("%.0f\t",array[i];

第九章_文件

第九章文件 一、单项选择题 【9.1】要打开一个已存在的非空文件"file"用于修改,选择正确的语句____。 A) fp=fopen("file", "r"); B) fp=fopen("file", "a+"); C) fp=fopen("file", "w"); D) fp=fopen('file", "r+"); 【9.2】当顺利执行了文件关闭操作时,fclose函数的返回值是。 A) -1 B) TRUE C) 0 D) 1 【9.3】fscanf函数的正确调用形式是。 A) fscanf (文件指针, 格式字符串, 输出列表); B) fscanf (格式字符串, 输出列表, 文件指针); C) fscanf (格式字符串, 文件指针, 输出列表); D) fscanf (文件指针, 格式字符串, 输入列表); 【9.4】使用fgetc函数,则打开文件的方式必须是。 A) 只写 B) 追加 C) 读或读/写 D) 参考答案B和C都正确 【9.5】C语言中标准输入文件stdin是指。 A) 键盘 B) 显示器 C) 鼠标 D) 硬盘 二、程序填空题 【9.6】下面程序的功能是统计文件中的字符的个数。 #include main() { long num=0; ① *fp; if((fp=fopen("fname.dat", "r"))==NULL) { printf("Can't open the file! "); exit(0); } while( ② ) { fgetc(fp); num++; } printf("num=%d\n",num); fclose(fp); } 【9.7】下面程序的功能是把从键盘输入的文件(用 @ 作为文件结束标志)复制到一个名为second.txt的新文件中。

指针和结构体练习题.

第十章指针 一.选择题 1.变量的指针,其含义是指该变量的。 A)值 B)地址 C)名 D)一个标志 2.已有定义int k=2;int *ptr1,*ptr2;且ptr1和ptr2均已指向变量k,下面不能正确执行的赋值语句是。 A)k=*ptr1+*ptr2 B)ptr2=k C)ptr1=ptr2 D)k=*ptr1*(*ptr2 3.若有说明:int *p,m=5,n;以下程序段正确的是。 A)p=&n ; B)p = &n ; scanf(“%d”,&p; scanf(“%d”,*p; C)scanf(“%d”,&n; D)p = &n ; *p=n ; *p = m ; 4.已有变量定义和函数调用语句:int a=25;print_value(&a;下面函数的输出结果是。 void print_value(int *x { printf(“%d\n”,++*x; } A)23 B)24 C)25 D)26 5.若有说明:int *p1, *p2,m=5,n;以下均是正确赋值语句的选项是。 A)p1=&m; p2=&p1 ; B)p1=&m; p2=&n; *p1=*p2 ; C)p1=&m; p2=p1 ; D)p1=&m; *p1=*p2 ; 6.若有语句:int *p,a=4;和p=&a;下面均代表地址的一组选项是。 A)a,p,*&a B)&*a,&a,*p C)*&p,*p,&a D)&a,&*p,p 7.下面判断正确的是。 A)char *a=”china”; 等价于char *a; *a=”china” ; B)char str[10]={“china”}; 等价于char str[10]; str[ ]={“china”;}

c程序设计 第九章 结构体

一、概念题 二、判断题 1. 结构体中的成员不可以单独使用(F)。 2. 成员名可以与程序中的变量名相同,二者不代表同一对象(T)。 3. 不能将一个结构体变量作为一个整体进行输入输出(T)。 4. 结构体变量所占内存长度是各成员占的内存长度之和(T)。 5. 结构体中的成员不可以单独使用(F )。 9. 一个结构体变量的指针就是该变量所占内存段的起始地址(T)。 10. 用结构体变量作实参,形参也必须是同类型的结构体变量(T )。 三、单选题 1. 设变量定义如下,则对其中的结构分量num正确的引用是( )。 struct student { int num ; char name[20]; float score; } stud[10]; A. stud[1].num=10; B. student.stud.num=10; C. struct.stud.num=10; D. struct student.num=10; 2. 已知职工记录描述如下,设变量w中的“生日”是“1993年10月25日”,下列对“生日”的正确赋值方式是()。 struct worker { int no; char name[20]; char sex; struct birth{ int day; int month; int year;}a; }; struct worker w; A day=25;month=10;year=1993; B w.birth.day=25; w.birth.month=10; w.birth.year=1993; C w.day=25; w.month=10; w.year=1993; D w.a.day=25; w.a.month=10; w.a.year=1993; 3. 对于以下的变量定义,语句( )在语法和语义上都是正确的。 struct node { float x,y; char s[10];

作业2答案

第2次作业 第2章作业: 3、程序计数器(PC)作为不可寻址寄存器有哪些特点?数据指针DPTR有哪些特点?与程序计数器(PC)有何异同? 程序计数器(PC)的特点: (1)PC是中央控制器中最基本的寄存器,是一个独立的计数器,存放着下一条将要从程序存储器中取出的指令地址; (2)PC具有自动加1的功能,这是最基本的工作方式,PC变化的轨迹决定着程序的流程; (3)PC的宽度决定着程序存储器可以直接寻找的范围。 数据指针DPTR的特点: (1)DPTR是一个16位的特殊功能寄存器,主要功能是作为片外数据存储器寻址的地址寄存器(间接地址); (2)DPTR寄存器既可以作为16位寄存器处理,也可以作为两个8位寄存器处理。 异同: (1)两者都是与地址有关的16位寄存器,其中,PC与程序存储器的地址有关;DPTR与数据存储器有关,作为地址寄存器使用时,PC与DPTR都是通过P0和P2口输出的,但是,PC的输出与ALE和PSEN有关,DPTR的输出则与ALE,WR,RD有关; (2)PC只能作为16位寄存器对待,由于有自动加1的功能,故又称计数器。PC是不可访问的,有其独特的变化方式,它的变化轨迹决定了程序执行的流程;DPTR可以作为16位寄存器对峙,也可以作为两个8位寄存器对待,是可以访问的。 4、80C51存储器在结构上有何特点?在物理上和逻辑上各有哪几种地址空间? 80C51存储器采用哈佛结构,即将程序存储器和数据存储器截然分开,程序存储器和数据存储器各有自己的寻址方式、寻址空间和控制系统。这种结构对于单片机“面向控制”的实际应用极为方便、有利。在80C51单片机中,不仅在片内驻留了一定容量的程序存储器和数据存储器及众多的特殊功能寄存器,而且还具有极强的外部存储器扩展能力,寻址范围分别可达64KB,寻址和操作方便简单。 物理地址空间上; (1)内部程序寄存器4KB; (2)外部程序寄存器64KB; (3)内部数据寄存器256B; (4)外部数据寄存器64KB。 逻辑地址空间上: (1)片内片外统一的64KB程序存储器地址空间; (2)片内128(或者256)字节数据存储器的空间; (3)片外64KB的数据存储器地址空间。 6、片内RAM低128单元划分为哪三个主要部分?各部分主要功能是什么? 片内RAM低128单元划分为三个主要部分: (1)工作寄存器区(00H~1FH),这是一个用寄存器寻址的区域,指令的数量最多,均为单周期指令,执行的速度最快; (2)位寻址区(20H~2FH),包含128位(位地址00H~7FH),是可位寻址的RAM区。这16字节单元即可进行字节寻址,又可实现位寻址。

C语言程序设计 第九章 指针

一、选择题 1、指针是一种____ A、标识符 B、变量 C、内存地址 D、运算符 2、显示指针变量P中的值,可以使用命令_____ A、Printf(“%d”,p); B、Printf(“%d”,*p); C、Printf(“%d”,*p); D、Printf(“%d”,p); 3、为指针变量P输入整型变量i的地址,可以使用命令____ A、Scanf(“%p”,&p); B、 *p=i; C、 P=&I; D、 *p=&I; 4、若有定义void *p;int *q;float *r,下面操作不对的是____ A、 p=q; B、 q=r; C、 p=r; D、 r=p; 5、若有说明#define m 20 int n=10;下面定义不正确的是______ A、 Float s[m]; B、 Float s[m*10]; C、 Float s[m+n]; D、 Float s[m+10]; 6、若有定义int a[]={1,2,0};请问a[a[a[0]]]=______ A、 0 B、1 C、2 D、3 7、若有char s[10],*p=s;则下面表达式正确的是_____ A、 s=p+s; B、 p=s+10; C、 s[2]=p[4]; D、 p=s[0]; 8、定义整型指针变量p和q,下面操作不正确的是_______ A、 Int *p,q=null; B、 Int *p,q=null,null; C、 Int *p,*q=null,null; D、 Int *p,*q=null; 9、若有定义int a[]={1,2,3},b[3]={1,2,3};,请问a==b_______ A、不能比较 B、结果为真 C、结果为假 D、结果不确定 10、以下程序有错,错误的原因是( )。 main() {int *p,i;char *q,ch; p=&i; q=&ch; *p=40; *p=*q; . . .} A)p和q的类型不一致,不能执行*p=*q;语句 B)*p中存放的是地址值,因此不能执行*p=40;语句 C)q没有指向具体的存储单元,所以*q没有实际意义 D)q虽然指向了具体的存储单元,但该单元中没有确定的值,所以不能执行*p=*q;语句 11、已有定义 int k=2;int *ptr1,*ptr2;且ptr1和ptr2均已指向变量k,下面不能正确 执行的赋值语句是( )。 A)k=*ptr1+*ptr2; B)ptr2=k; C)p1=*p2; D)*p1=p2; 12、变量的指针,其含义是指该变量的( )。

C语言中不同的结构体类型的指针间的强制转换详解

C语言中不同类型的结构体的指针间可以强制转换,很自由,也很危险。只要理解了其内部机制,你会发现C是非常灵活的。 一. 结构体声明如何内存的分布, 结构体指针声明结构体的首地址, 结构体成员声明该成员在结构体中的偏移地址。 变量的值是以二进制形式存储在内存中的,每个内存字节对应一个内存地址,而内存存储的值本身是没有整型,指针,字符等的区别的,区别的存在是因为我们对它们有不同的解读,param的值就是一个32位值,并且存储在某个内存单元中,通过这个32位值就能找到param所指向的结构的起始地址,通过这个起始地址和各个结构所包含变量离起始地址的偏移对这些变量进行引用, param->bIsDisable只是这种引用更易读的写法,只要param是指向 PAINT_PARAM的指针,那么param的值就肯定存在,param存在,偏移量已知,那么param->bIsDisable就肯定存在,只是要记住,param->bIsDisable只是代表了对param一定偏移地址的值。 不是说某个地址有那个结构体你才能引用,即使没有,你也能引用,因为你已经告诉了编译器param变量就是指向一个PAINT_PARAM结构体的变量并且指明了param的值,机器码的眼中是没有数据结构一说的,它只是机械的按照 指令的要求从内存地址取值,那刚才的例子来说,peg->x,peg->y的引用无论 0x30000000是否存在一个eg结构体都是合法的,如果0x30000000开始的8 个字节存在eg结构体,那么引用的就是这个结构体的值,如果这个位置是未定义的值,那么引用的结果就是这8个字节中的未定义值,内存位置总是存在的,而对内存中值的引用就是从这些内存位置对应的内存单元取值。 举个例子: typedefstruct_eg { int x; int y; }eg;

C语言习题及答案(第九章)

9-3编写程序,使用结构体类型,输出一年十二个月的英文名称及相应天数。 解:#include "stdio.h" struct date { char month[10] ; int daynumber ; } main() { int i ; struct date a[12]={{"January",31},{"February",29},{"March",31},{"Aprial",30},{ "May",31},{"June",30},{"july",31},{"August",31},{"September",30}, {"October",31},{"November",30},{"December",31}} ; for(i=0;i<12;i++); printf("%d 月:%s %d\n",i+1,a[i].month,a[i].daynumber) ; } 思考:如何对结构体变量进行初始化?对结构体变量的引用为何要体现为分量(或成员)的引用? 9-4 编写程序求空间任一点到原点的距离,点用结构体描述。并请考虑求空间中任意两点的距离的程序。 解:#include "stdio.h" #include "math.h" struct point { float x ; float y ; float z ; } main() { double d1,d2,d ; struct point p1,p2 ; printf("请输入第一个点的坐标:");

scanf("%f,%f,%f",&p1.x,&p1.y,&p1.z); printf("请输入第二个点的坐标:"); scanf("%f,%f,%f",&p2.x,&p2.y,&p2.z); d1=sqrt(p1.x*p1.x+p1.y*p1.y+p1.z*p1.z); d2=sqrt(p2.x*p2.x+p2.y*p2.y+p2.z*p2.z); d=sqrt((p2.x-p1.x)*(p2.x-p1.x)+(p2.y-p1.y)*(p2.y-p1.y)+(p2.z-p1.z)*( p2.z-p1.z)); printf("第一个点到原点的距离:%f\n",d1); printf("第二个点到原点的距离:%f\n",d2); printf("两点间的距离:%f\n",d); } 9-5 编写输入、输出10个朋友数据的通讯录程序,每个朋友数据包括姓名、地址、邮编、电话、传呼、手机等数据。 解:#include "stdio.h" struct AddressBook { char name[10] ; char address[30] ; char mailnumber[7] ; char telphone[12] ; char byphone[16] ; char movephone[1] ; } main() { int i ; struct AddressBook fd[10] ; for(i=0;i<10;i++) { printf("请输入第%d个朋友的信息:\n",i+1); printf("姓名:"); scanf("%s",&fd[i].name) ; printf("地址:");

计算机二级c语言第九章 数组和指针习题与答案

第九章数组和指针 1、有以下程序 main() { int a[]={2,4,6,8,10}, y=0, x, *p; p=&a[1]; for(x= 1; x< 3; x++) y += p[x]; printf("%d\n",y); } 程序运行后的输出结果是 A)10 B)11 C)14 D)15 2、有以下程序 void sum(int a[]) { a[0] = a[-1]+a[1]; } main() { int a[10]={1,2,3,4,5,6,7,8,9,10}; sum(&a[2]); printf("%d\n", a[2]); } 程序运行后的输出结果是 A)6 B)7 C)5 D)8 3、有以下程序 main() { int p[8]={11,12,13,14,15,16,17,18},i=0,j=0; while(i++< 7) if(p[i]%2) j+=p[i]; printf("%d\n",j); } 程序运行后的输出结果是 A)42 B)45 C)56 D)60 4、设有定义语句 int x[6]={2,4,6,8,5,7},*p=x,i; 要求依次输出x数组6个元素中的值,不能完成此操作的语句是 A)for(i=0;i<6;i++) printf("%2d",*(p++)); B)for(i=0;i<6;i++) printf("%2d",*(p+i)); C)for(i=0;i<6;i++) printf("%2d",*p++); D)for(i=0;i<6;i++) printf("%2d",(*p)++); 5、有以下程序 #include < stdio.h > main() { int a[]={1,2,3,4,5,6,7,8,9,10,11,12,},*p=a+5,*q=NULL; *q=*(p+5); printf("%d %d\n",*p,*q); } 程序运行后的输出结果是 A)运行后报错 B)6 6 C)6 11 D)5 10

指针与结构体 上机

指针 1.在主函数中输入一个字符串str,调用函数统计字符串中出现的字母(含大 小写)、数字、空格及其他字符出现的次数,在主函数中输出统计结果。要求写三个版本的程序:(1)用指针作参数返回统计结果。(2)用引用做参数返回统计结果(引用做参数效率更高,代码更简单。)(3)用数组做参数返回统计结果(当返回多个同类型结果时用数组做参数更简单)。 1.#include using namespace std; void stat(char *str,int *letters,int *digits,int *others){ char c; for(char *str;*str!='\0';str++) {c=*str; if((c>'a'&&c<'z')||(c>'A'&&c<'Z')) (*letters)++; else if('0'<=c&&c<='9') (*digits)++; else (*others)++; } } void main(){ char str[100]; cin.getline(str,100); int letters=0; int digits=0; int others=0; stat(str,&letters,&digits,&others); cout<<"letters="< #include using namespace std; void stat(char *str,int *a){ char c; for(int i=0;str[i]!='\0';i++) {c=str[i];

链表作业

一、选择 1.下述哪一条是顺序存储结构的优点?() A.存储密度大 B.插入运算方便 C.删除运算方便 D.可方便地用于各种逻辑结构的存储表示 2.下面关于线性表的叙述中,错误的是哪一个?()A.线性表采用顺序存储,必须占用一片连续的存储单元。 B.线性表采用顺序存储,便于进行插入和删除操作。 C.线性表采用链接存储,不必占用一片连续的存储单元。 D.线性表采用链接存储,便于插入和删除操作。 3.线性表是具有n 个()的有限序列(n>0)。 A.表元素 B.字符 C.数据元素 D.数据项 E.信息项 4.若某线性表最常用的操作是存取任一指定序号的元素和在最后进行插入和删除运算,则利用()存储方式最节省时间。 A.顺序表 B.双链表 C.带头结点的双循环链表 D.单循环链表 5.某线性表中最常用的操作是在最后一个元素之后插入一个元素和删除第一个元素,则采用()存储方式最节省运算时间。 A.单链表 B.仅有头指针的单循环链表 C.双链表 D.仅有尾指针的单循环链表 6.设一个链表最常用的操作是在末尾插入结点和删除尾结点,则选用( )最节省时间。A. 单链表 B.单循环链表 C. 带尾指针的单循环链表 D.带头结点的双循环链表 7.若某表最常用的操作是在最后一个结点之后插入一个结点或删除最后一个结点。则采用()存储方式最节省运算时间。 A.单链表 B.双链表 C.单循环链表 D.带头结点的双循环链表 8. 静态链表中指针表示的是(). A.内存地址 B.数组下标 C.下一元素地址 D.左、右孩子地址 9. 链表不具有的特点是() A.插入、删除不需要移动元素 B.可随机访问任一元素 C.不必事先估计存储空间 D.所需空间与线性长度成正比 10. 下面的叙述不正确的是() A.线性表在链式存储时,查找第i 个元素的时间同i 的值成正比 B. 线性表在链式存储时,查找第i 个元素的时间同i 的值无关 C. 线性表在顺序存储时,查找第i 个元素的时间同i 的值成正比 D. 线性表在顺序存储时,查找第i 个元素的时间同i 的值无关 13. 若长度为n 的线性表采用顺序存储结构,在其第i 个位置插入一个新元素的算法的时间复杂度为()(1<=i<=n+1)。 A. O(0) B. O(1) C. O(n) D. O(n2) 14. 对于顺序存储的线性表,访问结点和增加、删除结点的时间复杂度为()。 A.O(n) O(n) B. O(n) O(1) C. O(1) O(n) D. O(1) O(1) 15.线性表( a1,a2,…,an)以链接方式存储时,访问第i 位置元素的时间复杂性为()A.O(i) B.O(1) C.O(n) D.O(i-1) 23.在双向链表指针p 的结点前插入一个指针q 的结点操作是()。 A. p->Llink=q;q->Rlink=p;p->Llink->Rlink=q;q->Llink=q; B. p->Llink=q;p->Llink->Rlink=q;q->Rlink=p;q->Llink=p->Llink; C. q->Rlink=p;q->Llink=p->Llink;p->Llink->Rlink=q;p->Llink=q; D. q->Llink=p->Llink;q->Rlink=q;p->Llink=q;p->Llink=q;

函数、指针与结构体练习题_参考答案

函数 (一)选择题 1.以下正确的说法是_________. 建立函数的目的之一是a)提高程序的执行效率 b)提高程序的可读性 c)减少程序的篇幅 d)减少程序文件所占存 2.以下正确的函数原型声明形式是________. a)double fun(int x,int y) b)double fun(int x; int y) c)double fun(int x, int y); d)double fun(int x,y); 3.C语言规定,简单变量做实参时,它和对应形参之间的数据传递方式为______. A)地址传递 B)单向值传递 C)由实参传给形参,再由形参传回给实参 D)由用户指定传递方式 4.C语言允许函数值类型缺省定义,此时该函数值隐含的类型是______. a)float b)int c)long d)double 5.已有以下数组定义和f函数调用语句,则在f函数的说明中,对形参数组array 的错误定义方式为________. int a[3][4]; f(a); a)f(int array[][6])

b)f(int array[3][]) c)f(int array[][4]) d)f(int array[2][5]) 6.以下程序的正确运行结果是_________. #include void num() { extern int x,y;int a=15,b=10; x=a-b; y=a+b; } int x,y; main() { int a=7,b=5; x=a+b; y=a-b; num(); printf("%d,%d\n",x,y); } a)12,2 b)不确定c)5,25 d)1,12 7.以下正确的描述是____________. a)C语言的预处理功能是指完成宏替换和包含文件的调用 b)预处理指令只能位于C源程序文件的首部 c)凡是C源程序中行首以"#"标识的控制行都是预处理指令 d)C语言的编译预处理就是对源程序进行初步的语法检查 8.在"文件包含"预处理语句的使用形式中,当#include后面的文件名用< >(尖括号)括起时,找寻被包含文件的方式是_______. a)仅仅搜索当前目录 b)仅仅搜索源程序所在目录

第九章使用结构体类型处理组合数据 c语言

第九章使用结构体类型处理组合数据 1.定义和使用结构体变量 2.结构体数组 3.结构体指针 4.用结构体变量和结构体变量的指针作函数参数 5.用指针处理链表 6.共用体、枚举类型 正文 1.定义和使用结构体变量 若只保存某个学生的学号:可以使用int 变量。 若保存所有学生的学号:可以使用int 型的数组。 同理,若保存所有学生的姓名:可以使用char型的数组。 若保存所有学生某科成绩:可以使用float 型的数组。 但是,如果要同时保存某一个学生的学号,姓名,性别、入学时间及各科成绩,该用什么保存? 自己建立结构体类型 将一个学生的学号、姓名、性别、年龄和地址分别用以下变量来表示: int num; char name[20]; char sex; int age; char addr[30]; Num name sex age score addr 100101 Li Fun M 18 87.5 Beijing 声明一个结构体类型的一般形式为: struct 结构体名 {成员表列=类型名+成员名}; 如:struct student { int num;char name[20];char sex; int age;float score;char addr[30]; } 可以采取以下3种方法定义结构体类型变量:

(1)先声明结构体类型再定义变量名 例如:struct student student1, student2; | | | 结构体类型名结构体变量名 定义了student1和student2为struct student类型的变量,即它们具有struct student 类型的结构. student1 100102 WangLi F 20 98 Beijing student2 100101 ZhangXin M 19 90.5 Shanghai 在定义了结构体变量后,系统会为之分配内存单元。 例如:student1和student2在内存中各占63个字节(4+20+1+4+4+30=63)。(我们的VC) 注意: 将一个变量定义为标准类型(基本数据类型)与定义为结构体类型不同之处在于后者不仅要求指定变量为结构体类型,而且要求指定为某一特定的结构体类型,因为可以定义出许许多多种具体的结构体类型。 (2)在声明类型的同时定义变量 这种形式的定义的一般形式为: struct结构体名 { 成员表列 }变量名表列; struct student {int num; char name[20]; char sex; int age; float score; char addr[30]; }student1,student2;//它的作用与第一种方法相同,即定义了两个struct //student 类型的变量student1 student2 (3) 直接定义结构体类型变量 //注意: (2)对结构体中的成员(即“域”),可以单独使用,它的作用与地位相当于普通变量。 (3)成员也可以是一个结构体变量。 (4)成员名可以与程序中的变量名相同,二者不代表同一对象。 其一般形式为: struct { 成员表列 }变量名表列; 即不出现结构体名。 例如:struct date

相关文档
最新文档