计算机实习
Download
1 / 84

计算机实习 - PowerPoint PPT Presentation


  • 90 Views
  • Uploaded on

计算机实习. 第 1 讲. 教学任务. 作品 [ 申请成绩为优 ] 考核(结构体、文件、链表) 平时的实验 实习无补考 (2 次课堂教学 ,2 次实验 ,1 次考核 ). 3. 3. 复习数组. 1. 3. 文件的基本操作. 归纳与提高. 2. 4. 结构体数组. 目 录. 1 .数组的基本概念. 数组. #include "stdio.h" void f1(int a[],int n) { int i; for(i=0;i<n;i++) { printf(" 输入第 %d 个数据 \n",i+1);

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

PowerPoint Slideshow about ' 计算机实习' - lacey-joyner


An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript

教学任务

  • 作品[申请成绩为优]

  • 考核(结构体、文件、链表)

    • 平时的实验

    • 实习无补考(2次课堂教学,2次实验,1次考核)


3

3

复习数组

1

3

文件的基本操作

归纳与提高

2

4

结构体数组

目 录


1.数组的基本概念

数组

#include "stdio.h"

void f1(int a[],int n)

{ int i;

for(i=0;i<n;i++)

{ printf("输入第%d个数据\n",i+1);

scanf("%d",&a[i]);}}

main()

{ int x,i,s[50];

printf("输入数组的元素个数\n");

scanf("%d",&x); f1(s,x);

for(i=0;i<x;i++)

printf("%3d",s[i]);

printf("\n");getch();

}

int a[100];

例如:


利用随机数为数组元素赋值

产生 n1—n2之间的随机整数:

(int)((rand()/32768.0)*(n2-n1+1)+n1);


利用随机数为数组元素赋值

#include <stdio.h>

#include"stdlib.h"

#include "time.h"

#define N 100

void f1(int a[],int n1,int n2,int n)

{ int i;

srand( (unsigned)time( NULL ) );

for (i=0; i<n;i++)

{a[i] =(int)((rand()/32768.0)*(n2-n1+1)+n1);

printf("%4d,",a[i]); }}


利用随机数为数组元素赋值

main()

{

int a[N];

f1(a,40,150,20);

}


利用数据文件为数组元素赋值

建立数据文件:

通过excel建立数据文件,文件以文本文件形式保存

用程序读出文本文件中的数据

定义文件指针 FILE *fp;

打开文件fopen("cj.txt","r")

读文件fscanf(fp,"%d",&x[i]);

关闭文件fclose(fp);


利用数据文件为数组元素赋值

#include <stdio.h>

#define SIZE 143

main()

{ int x[SIZE],i,max,min;

FILE *fp;

printf("Enter %d integers:\n",SIZE);

if((fp=fopen("cj.txt","r"))==NULL)

{

printf("不能打开该文件,任意键退出");

getch();

exit(1);

}


利用数据文件为数组元素赋值

for(i=0;i<SIZE;i++)

fscanf(fp,"%d",&x[i]);

fclose(fp);

max=min=x[0];

for(i=1;i<SIZE;i++)

{ if(max<x[i]) max=x[i];

if(min>x[i]) min=x[i];

}

printf("Maximum is %d\n",max);

printf("Minimum is %d\n",min);

}


C文件概述

文件:存储在外部介质上数据的集合,是操作系统数据管理的单位


1文件分类

  • 按文件的逻辑结构:

    • 记录文件:由具有一定结构的记录组成(定长和不定长)

    • 流式文件:由一个个字符(字节)数据顺序组成


  • 按存储介质:

    • 普通文件:存储介质文件(磁盘、磁带等)

    • 设备文件:非存储介质(键盘、显示器、打印机等)

  • 按数据的组织形式:

    • 文本文件: ASCII文件,每个字节存放一个字符的ASCII码

    • 二进制文件:数据按其在内存中的存储形式原样存放


int型数10000

ASCII形式

0011000100110000001100000011000000110000

0010011100010000

0010011100010000

内存存储形式

二进制形式

文件特点:

文本文件特点:

存储量大、速度慢、便于对字符操作

二进制文件特点:

存储量小、速度快、便于存放中间结果


缓冲文件系统:

程序

指令区

输入文件缓冲区

磁盘文件

用户数据区

磁盘

程序数据区

a

缓冲区

输出文件缓冲区

非缓冲文件系统:

文件处理方法

  • 缓冲文件系统:高级文件系统,系统自动为正在使用的文件开辟内存缓冲区

  • 非缓冲文件系统:低级文件系统,由用户在程序中为每个文件设定缓冲区


2文件类型指针

  • 文件结构体FILE

    • 缓冲文件系统为每个正使用的文件在内存开辟文件信息区

    • 文件信息用系统定义的名为FILE的结构体描述

    • FILE定义在stdio.h中

typedef struct

{ int _fd; //文件号

int _cleft; //缓冲区中剩下的字符数

int _mode; //文件操作方式

char *_next; //文件当前读写位置

char *_buff; //文件缓冲区位置

}FILE;


文件名

文件使用

方式

操作系统

C程序

文件类型指针

磁盘

文件类型指针

  • 指针变量说明: FILE *fp;

  • 用法:

    • 文件打开时,系统自动建立文件结构体,并把指向它的指针返回来,程序通过这个指针获得文件信息,访问文件

    • 文件关闭后,它的文件结构体被释放


含义

文件使用方式

“r/rb” (只读)

为输入打开一个文本/二进制文件

“w/wb” (只写)

为输出打开或建立一个文本/二进制文件

“a/ab” (追加)

向文本/二进制文件尾追加数据

“r+/rb+” (读写)

为读/写打开一个文本/二进制文件

“w+/wb+” (读写)

为读/写建立一个文本/二进制文件

“a+/ab+” (读写)

为读/写打开或建立一个文本/二进制文件

3文件的打开与关闭

例 文件打开与测试

FILE *fp;

fp=fopen(“aa.c”,“w”);

if(fp==NULL)

{ printf(“File open error!\n”);

exit(0);

}

  • C文件操作用库函数实现,包含在stdio.h

  • 文件使用方式:打开文件-->文件读/写-->关闭文件

  • 系统自动打开和关闭三个标准文件:

    • 标准输入------键盘 stdin

    • 标准输出------显示器 stdout

    • 标准出错输出-----显示器 stderr

  • 打开文件fopen

    • 函数原型: FILE *fopen(char *name,char *mode)

例 FILE *fp;

char *filename=“c:\\fengyi\\bkc\\test.dat”

fp= fopen(filename,”r”);

例 FILE *fp;

fp= fopen (“c:\\fengyi\\bkc\\test.dat”,”r”);

使用文件方式

  • 功能:按指定方式打开文件

  • 返值:正常打开,为指向文件结构体的指针;打开失败,为NULL

要打开的文件名


Fclose

缓冲文件系统:

输入文件缓冲区

磁盘文件

程序数据区

a

fclose

输出文件缓冲区

文件关闭fclose

  • 作用:使文件指针变量与文件“脱钩”,释放文件结构体和文件指针

  • 函数原型:int fclose(FILE *fp)

  • 功能:关闭fp指向的文件

  • 返值:正常关闭为0;出错时,非0

文件打开时返回的文件类型指针

不关闭文件可能会丢失数据


4文件的读写

  • 字符I/O:fputc与fgetc

    • fputc

      • 函数原型:int fputc(int c, FILE *fp)

      • 功能:把一字节代码c写入fp指向的文件中

      • 返值:正常,返回c;出错,为EOF

  • fgetc

    • 函数原型:int fgetc(FILE *fp)

    • 功能:从fp指向的文件中读取一字节代码

    • 返值:正常,返回读到的代码值;读到文件尾或出错,为EOF

文件I/O与终端I/O

#define putc(ch,fp) fputc(ch,fp)

#define getc(fp) fgetc(fp)

#define putchar( c ) fputc(c,stdout)

#define getchar( ) fgetc(stdin)


从键盘输入字符,逐个存到磁盘文件中,直到 输入‘#“为止

#include <stdio.h>

main()

{ FILE *fp;

char ch,*filename=“out.txt”;

if((fp=fopen(filename,"w"))==NULL)

{ printf("cannot open file\n");

exit(0);

}

printf("Please input string:");

ch=getchar();

while(ch!='#')

{ fputc(ch,fp);

putchar(ch);

ch=getchar();

}

fclose(fp);

}

修改程序使之在文件out.txt中保存一句完整的C语句



I o fread fwrite
数据块编写程序,从键盘输入一个字符串,将其中的小写字母全部转换成大写字母,输出到磁盘文件“I/O: fread与fwrite

size_t fread(void *buffer,size_t size, size_t count,FILE *fp)

size_t fwrite(void *buffer,size_t size, size_t count,FILE *fp)

  • 函数原型:

  • 功能:读/写数据块

  • 返值:成功,返回读/写的块数;出错或文件尾,返回0

  • 说明:

    • typedef unsigned size_t;

    • buffer: 指向要输入/输出数据块的首地址的指针

    • size: 每个要读/写的数据块的大小(字节数)

    • count: 要读/写的数据块的个数

    • fp: 要读/写的文件指针

    • fread与fwrite 一般用于二进制文件的输入/输出


例子编写程序,从键盘输入一个字符串,将其中的小写字母全部转换成大写字母,输出到磁盘文件“

例 float f[2];

FILE *fp;

fp=fopen(“aa.dat”,“rb”);

fread(f,4,2,fp);

for(i=0;i<2;i++)

fread(&f[i],4,1,fp);

例 struct student

{ int num;

char name[20];

char sex;

int age;

float score[3];

}stud[10];

for(i=0;i<10;i++)

fread(&stud[i],sizeof(struct student),1,fp);


例 从键盘输入编写程序,从键盘输入一个字符串,将其中的小写字母全部转换成大写字母,输出到磁盘文件“4个学生数据,把他们转存到磁盘文件中去

void save()

{ FILE *fp;

int i;

if((fp=fopen("d:\\fengyi\\exe\\stu_dat","wb"))==NULL)

{ printf("cannot open file\n");

return;

}

for(i=0;i<SIZE;i++)

if(fwrite(&stud[i],sizeof(struct student_type),1,fp)!=1)

printf("file write error\n");

fclose(fp);

}

void display()

{ FILE *fp;

int i;

if((fp=fopen("d:\\fengyi\\exe\\stu_dat","rb"))==NULL)

{ printf("cannot open file\n");

return;

}

for(i=0;i<SIZE;i++)

{ fread(&stud[i],sizeof(struct student_type),1,fp);

printf("%-10s %4d %4d %-15s\n",stud[i].name,

stud[i].num,stud[i].age,stud[i].addr);

}

fclose(fp);

}

#include <stdio.h>

#define SIZE 4

struct student_type

{ char name[10];

int num;

int age;

char addr[15];

}stud[SIZE];

main()

{

int i;

for(i=0;i<SIZE;i++)

scanf("%s%d%d%s",stud[i].name,&stud[i].num,

&stud[i].age,stud[i].addr);

save();

display();

}


#include <stdio.h>编写程序,从键盘输入一个字符串,将其中的小写字母全部转换成大写字母,输出到磁盘文件“

main()

{ char s[80],c[80];

int a,b;

FILE *fp;

if((fp=fopen("test","w"))==NULL)

{ puts("can't open file"); exit() ; }

fscanf(stdin,"%s%d",s,&a);/*read from keaboard*/

fprintf(fp,"%s %d",s,a);/*write to file*/

fclose(fp);

if((fp=fopen("test","r"))==NULL)

{ puts("can't open file"); exit(); }

fscanf(fp,"%s%d",c,&b);/*read from file*/

fprintf(stdout,"%s %d",c,b);/*print to screen*/

fclose(fp);

}

int fprintf(FILE *fp,const char *format[,argument,…])

int fscanf(FILE *fp,const char *format[,address,…])

  • 格式化I/O:fprintf与fscanf

    • 函数原型:

  • 功能:按格式对文件进行I/O操作

  • 返值:成功,返回I/O的个数;出错或文件尾,返回EOF

例 fprintf(fp,“%d,%6.2f”,i,t); //将i和t按%d,%6.2f格式输出到fp文件

fscanf(fp,“%d,%f”,&i,&t); //若文件中有3,4.5 ,则将3送入i, 4.5送入t

例 从键盘按格式输入数据存到磁盘文件中去


I o fgets fputs
字符串编写程序,从键盘输入一个字符串,将其中的小写字母全部转换成大写字母,输出到磁盘文件“I/O: fgets与fputs

#include<stdio.h>

main()

{ FILE *fp;

char string[81];

if((fp=fopen("file.txt","w"))==NULL)

{ printf("cann't open file");exit(0); }

while(strlen(gets(string))>0)

{ fputs(string,fp);

fputs("\n",fp);

}

fclose(fp);

if((fp=fopen("file.txt","r"))==NULL)

{ printf("cann't open file");exit(0); }

while(fgets(string,81,fp)!=NULL)

fputs(string,stdout);

fclose(fp);

}

  • 函数原型:

char *fgets(char *s,int n,FILE *fp)

int fputs(char *s,FILE *fp)

  • 功能:从fp指向的文件读/写一个字符串

  • 返值:

    • fgets正常时返回读取字符串的首地址;出错或文件尾,返回NULL

    • fputs正常时返回写入的最后一个字符;出错为EOF

fputs把s指向的字符串写入fp指向的文件

fgets从fp所指文件读n-1个字符送入s指向的内存区,

并在最后加一个‘\0’

(若读入n-1个字符前遇换行符或文件尾(EOF)即结束)

例 从键盘读入字符串存入文件,再从文件读回显示


5编写程序,从键盘输入一个字符串,将其中的小写字母全部转换成大写字母,输出到磁盘文件“文件的定位

  • 几个概念

    • 文件位置指针-----指向当前读写位置的指针

    • 读写方式

      • 顺序读写:位置指针按字节位置顺序移动,叫~

      • 随机读写:位置指针按需要移动到任意位置,叫~

  • rewind函数

    • 函数原型: void rewind(FILE *fp)

    • 功能:重置文件位置指针到文件开头

    • 返值:无

#include <stdio.h>

main()

{ FILE *fp1,*fp2;

fp1=fopen("d:\\fengyi\\bkc\\ch12_4.c","r");

fp2=fopen("d:\\fengyi\\bkc\\ch12_41.c","w");

while(!feof(fp1)) putchar(fgetc(fp1));

rewind(fp1);

while(!feof(fp1)) fputc(fgetc(fp1),fp2);

fclose(fp1);

fclose(fp2);

}

例 对一个磁盘文件进行显示和复制两次操作


Fseek

main()编写程序,从键盘输入一个字符串,将其中的小写字母全部转换成大写字母,输出到磁盘文件“

{ int i;

FILE *fp;

if((fp=fopen("studat","rb"))==NULL)

{ printf("can't open file\n");exit(0); }

for(i=0;i<3;i+=2)

{ fseek(fp,i*sizeof(struct student_type),0);

fread(&stud[i],sizeof(struct student_type),1,fp);

printf("%s %d %d %s\n",

stud[i].name,stud[i].num,stud[i].age,stud[i].addr);

}

fclose(fp);

}

#include <stdio.h>

struct student_type

{ int num;

char name[10];

int age;

char addr[15];

}stud[3];

fseek函数

  • 函数原型: int fseek(FILE *fp,long offset,int whence)

  • 功能:改变文件位置指针的位置

  • 返值:成功,返回0;失败,返回非0值

起始点

文件开始SEEK_SET 0

文件当前位置SEEK_CUR 1

文件末尾SEEK_END 2

文件指针

位移量(以起始点为基点,移动的字节数)

>0向后移动

<0向前移动

  • ftell函数

    • 函数原型: long ftell(FILE *fp)

    • 功能:返回位置指针当前位置(用相对文件开头的位移量表示)

    • 返值:成功,返回当前位置指针位置;失败,返回-1L,

例 fseek(fp,100L,0);

fseek(fp,50L,1);

fseek(fp,-10L,2);

例 磁盘文件上有3个学生数据,要求读入第1,3学生数据并显示


6 编写程序,从键盘输入一个字符串,将其中的小写字母全部转换成大写字母,输出到磁盘文件“出错的检测

  • ferror函数

    • 函数原型: int ferror(FILE *fp)

    • 功能:测试文件是否出现错误

    • 返值:未出错,0;出错,非0

    • 说明

      • 每次调用文件输入输出函数,均产生一个新的ferror函数值,所以应及时测试

      • fopen打开文件时,ferror函数初值自动置为0


Clearerr
clearerr编写程序,从键盘输入一个字符串,将其中的小写字母全部转换成大写字母,输出到磁盘文件“函数

#include <stdio.h>

int main(void)

{ FILE *stream;

stream = fopen("DUMMY.FIL", "w");

getc(stream);

if (ferror(stream))

{ printf("Error reading from DUMMY.FIL\n");

clearerr(stream);

}

if(!ferror(stream))

printf("Error indicator cleared!");

fclose(stream);

return 0;

}

  • 函数原型: void clearerr(FILE *fp)

  • 功能:使文件错误标志置为0

  • 返值:无

  • 说明:出错后,错误标志一直保留,直到对同一文件调clearerr(fp)或rewind或任何其它一个输入输出函数

例 ferror()与clearerr()举例


proc1()编写程序,从键盘输入一个字符串,将其中的小写字母全部转换成大写字母,输出到磁盘文件“

{if((fp=fopen("book.txt","r"))==NULL)

{

printf("不能打开该文件,任意键退出");

getch();

exit(1);

}

}


int proc2(BOOK a[])编写程序,从键盘输入一个字符串,将其中的小写字母全部转换成大写字母,输出到磁盘文件“

{ int i=0;

while (!feof(fp))

{

fscanf(fp,"%s %s %s %d %d %d %f",a[i].bno,a[i].bname,a[i].cbadd,&a[i].bcdate.day,&a[i].bcdate.month,&a[i].bcdate.year,&a[i].bprice);

i++;

}

return i;fclose(fp);

}


将名单存在文本文件中,利用程序访问该文本文件后,输出学生名单。将名单存在文本文件中,利用程序访问该文本文件后,输出学生名单。


问题将名单存在文本文件中,利用程序访问该文本文件后,输出学生名单。

与实际系统不同

图书的信息包括:书号、书名、出版日期、出版地点、价格

数据的独立性


3将名单存在文本文件中,利用程序访问该文本文件后,输出学生名单。

3.6

在程序中存入变量 int x=3;float y=3.6;

{10,20,30,40}

int a[10]={10,20,30,40}

{" zhang" , 27 , " li " , 18 , " wang " , 73} ;

struct man

{ char name[20] ;

int age ; };

struct man person [N] ={ " zhang" , 27 , " li " , 18 , " wang " , 73} ;


Name age sex address将名单存在文本文件中,利用程序访问该文本文件后,输出学生名单。

wang 20 F 10#222

Zhang 19 M 16#321

Liu 18 M 16#324

zhao 20 F 10#242

问题

例:处理50个学生的信息,将学号、姓名、年龄按成绩排序

  • 解决方法:

  • 数组:相同类型数据的集合,将学号、姓名、年龄、成绩分别定义为不同的数组,相同的下标表示同一个学生的不同信息

  • 结构体:不同类型数据的集合,将不同类型的数据作为结构体的分量,定义一个结构体数组

  • 结构体:自定义数据类型


结构体将名单存在文本文件中,利用程序访问该文本文件后,输出学生名单。

一、自定义类型声明

1、注意类型名与变量名的区别:

类型定义只规定在使用此结构体时应分配的内存, 对类型名本身并不分配内存,更不能赋值、存取、运算,定义结构体变量时才分配内存

结构体类型声明:

struct结构体类型名

{ 数据类型1 成员名1;

…… 成员表列

数据类型n 成员名n;};

(1)学生信息结构体声明:

struct student

{ int num;

char name[20];

char sex;

float score;

};

2、各“成员”也可称为“结构体分量”或“域”,用“;”分隔。成员数据类型可以是各种基本类型或构造类型(包括结构体类型),成员名可以与程序中的变量名相同。

3.声明时最后的右括号后要加分号


结构体将名单存在文本文件中,利用程序访问该文本文件后,输出学生名单。

(2)为了处理通讯录,可以定义如下结构:

struct address

{ char name[30]; /* 字符数组作为结构中的成员 */

char street[40]; /* 街道名称 */

char city[20]; /* 城市 */

char state[2]; /* 省市代码 */

unsigned long zip; /* 邮政编码,无符号长整型*/

};

struct person

{char name[8]; /*姓名*/

char sex; /*性别*/

int age; /*年龄*/

float height , weight; /*身高、体重*/

char add[40]; /*住址*/

};

(3) 个人数据,包含姓名、性别、年龄、身高、体重、住址:


(5) 将名单存在文本文件中,利用程序访问该文本文件后,输出学生名单。日期, 包括年、 月、 日:

struct date

{int year; /*年*/

int month; /*月*/

int day; /*日*/

};

如考虑时间, 可作如下定义:

struct time

{int hh; /*时*/

int mm; /*分*/

int ss; /*秒*/

};

(4) 平面上的点:

struct point2

{float x; /*横坐标*/

float y; /*纵坐标*/

};

空间中的点:

struct point3

{float x; /*X坐标*/

float y; /*Y坐标*/

float z; /*Z坐标*/

};


(6) 将名单存在文本文件中,利用程序访问该文本文件后,输出学生名单。复数:

struct complex

{

float re; /*实部*/

float ie; /*虚部*/

};

(7) 三角形:

struct sjx

{

float a, b, c; /*三边*/

};


结构体将名单存在文本文件中,利用程序访问该文本文件后,输出学生名单。

声明的一般形式:

struct 结构体名

{ 成员表列

}变量名列表;

二.变量定义

用已声明的类型定义变量

1、先声明后定义

struct student s1, s2;

student:类型名称 s1, s2:变量名

2、声明类型同时定义

struct student

{ int num;

char name[20];

char sex;

int age;

float score;

char addr[30]; }s1, s2;

3、直接定义结构类型变量

struct

{成员列表

}变量名列表;

struct

{ int num; char name[20];

int age;

float score;

}s1, s2;

无类型名


Name age sex address将名单存在文本文件中,利用程序访问该文本文件后,输出学生名单。

wang 20 F 10#222

Zhang 19 M 16#321

Liu 18 M 16#324

zhao 20 F 10#242

结构体

表头

结构体成员(类型,名)

结构体变量

表中的内容


例如,对以上定义的结构体类型,我们可以定义如下一些结构体变量:例如,对以上定义的结构体类型,我们可以定义如下一些结构体变量:

struct student zhang; /*张同学情况*/

struct person p[100]; /*100个人的数据*/

struct point2 p1, p2; /*平面上的两个点*/

struct point3 po1, po2; /*空间上的两个点*/


s1例如,对以上定义的结构体类型,我们可以定义如下一些结构体变量:

num

name

age

score

结构体

说明:

(1)一旦定义了结构体变量后,则变量和其它变量一样,系统将分配其相应的存储空间.

存储空间:各个成员所占的存储单元的总和

(2)与标准类型变量不同:结构体变量的定义要有关键字struct,和结构体类型名。


结构体例如,对以上定义的结构体类型,我们可以定义如下一些结构体变量:

3.为使用方便,可将对结构体类型的声明放入一文件中,在使用时用#include将其所在文件包入。还可定义一符号常量来代表一结构体类型。

#define STUDENT struct student

STUDENT

{ int num;

char name[20];

int age;

float score;

};

STUDENT s1, s2;


结构体例如,对以上定义的结构体类型,我们可以定义如下一些结构体变量:

三、结构体类型变量的引用

  • 引用格式:结构体变量名.成员名

    “.”:成员运算符

    如:s1.num=10001;

    1.一般不将结构体作为一个整体进行操作,应对结构体变量中各成员分别实现各种操作和运算。由于结构体变量是一整体,要访问其中一个成员,必须先找到变量,通过成员运算符,从中找出某成员。

    2.可嵌套定义。若成员本身又是结构体,则要用多个成员运算符一级级找到最低一级的成员,才能进行操作


结构体例如,对以上定义的结构体类型,我们可以定义如下一些结构体变量:

例如:

(1) struct student类型变量zhang, 其所有分量如下:

zhang.no,zhang.name,zhang.sex,zhang.age,

(2) struct point2类型变量p1, 其所有分量如下:

p1.x, p1.y

(3)嵌套的结构体类型和变量:

struct data

{ int month; int day; int year; };

struct stud

{ int num;

char name[20];

struct data birthday;

}stud1;

stud1.birthday.day=12;


结构体例如,对以上定义的结构体类型,我们可以定义如下一些结构体变量:

3.对结构体变量可像普通变量一样进行各种运算,但应遵循各成员数据类型的运算规则。如: s1.age=s2.age;

++s1.age;

4.可将一结构体变量作为一个整体赋给另一同类型的结构体变量。不可将一组常量直接赋给结构体变量。如:

s1=s2;

s1={20102,“Li Hao”,20,10};


结构体例如,对以上定义的结构体类型,我们可以定义如下一些结构体变量:

5.结构体变量的I/O同样要求对变量的各成员项来进行。

可引用结构体变量成员的地址,也可引用结构体变量的地址。如:

scanf(“%d”,&s1.num);

6.成员名与变量名或其他变量同名,互不干扰:不同级,引用方式不同


结构体例如,对以上定义的结构体类型,我们可以定义如下一些结构体变量:

四、结构体类型变量的初始化

在给结构体类型变量说明的同时,可以同时给其各成员赋初值,称为结构体类型变量的初始化。如:

struct student

{ long int num;

char name[20];

char sex;

char addr[30];

}a={89031,“li lin”,’m’,“123 beijing road”};

不完全初始化,则其余成员自动初始化为0或‘\0’无初始化,则不会自动初始化为0或‘\0’


结构体例如,对以上定义的结构体类型,我们可以定义如下一些结构体变量:

说明:1.初始化时对结构体变量赋初值,而不是对类型中各成员赋初值。如:

struct student

{ long int num=89031;

char name[20]= “li lin”;

char sex=’m’;

char addr[30]= “123 beijing road”;

}student1;


结构体例如,对以上定义的结构体类型,我们可以定义如下一些结构体变量:

2、若在一个结构体类型内又嵌套另一结构体类型,对该结构体变量进行初始化时,仍按顺序写出各个初始值。

struct data

{ int month; int day; int year; };

struct stud

{ long int num;

char name[20];

char sex;

struct data birthday;;

char addr[30];

}stud1={89031,“lilin”,’m’,3,28,1988,“beijing road”};


结构体例如,对以上定义的结构体类型,我们可以定义如下一些结构体变量:

例 求平面上两点之间的距离。

main()

{ struct point

{ float x;

float y;

}p1, p2;

float d;

printf("请输入第一点的坐标: ");

scanf("%f, %f", &p1.x, &p1.y);

printf("请输入第二点的坐标: ");

scanf("%f, %f", &p2.x, &p2.y);

d=sqrt((p2.x-p1.x)*(p2.x-p1.x)+(p2.y-p1.y)*(p2.y-p1.y));

printf("两点之间的距离=%8.3f", d);

}


结构体例如,对以上定义的结构体类型,我们可以定义如下一些结构体变量:

五、结构体数组

  • 数组的每个元素皆为结构体类型变量

    1.定义:先定义结构体类型,后说明数组(三种形式)

    struct student

    { int num;

    char name[20];

    float score;

    char addr[30];

    } ;

    struct student stu[3];

    每个元素占56个字节(设整型变量占内存2个字节)


结构体例如,对以上定义的结构体类型,我们可以定义如下一些结构体变量:

2.初始化:变量定义的同时进行初始化,可在相应的三个位置进行初始化

struct student

{ int num; char name[20];

char sex; char addr[30];

}a[3]=

{{89031,“lilin”,’m’,“123 beijing road”},

{89032,“zhangmin”,’f’,“123 beijing road”},

{89033,“he li”,’m’,“123 beijing road”}};

分别对数组的各成员进行初始化


3.1 例如,对以上定义的结构体类型,我们可以定义如下一些结构体变量:结构体

3、引用

对结构体数组元素成员的引用形式为:

结构体数组名[下标].结构成员

例 选票统计

对侯选人得票进行统计。有三个候选人,每次输入一个后选人的名字, 要求最后输出各人得票结果。

#include <string.h>

struct person

{ char name[20];

int count;

} leader[3]={“li”,0,”zhang”,0,”fun”,0};

定义一个全局结构体类型数组


结构体例如,对以上定义的结构体类型,我们可以定义如下一些结构体变量:

main()

{ int i,j; char leader_name[20];

for (i=1;i<=10;i++)

{ scanf(“%s”,leader_name);

for (j=0;j<3;j++)

if(strcmp(leader_name,leader[j].name)==0)

leader[j].count++;

}

for (i=0;i<3;i++)

{ printf(“%5s:”,leader[i]. name);

printf(“%d\n”,,leader[i].count); }

}


结构体例如,对以上定义的结构体类型,我们可以定义如下一些结构体变量:

六.用结构体变量和指针函数参数

(1) 用结构体变量的成员作函数(同数组元素作参数)——值传递方式

(2) 用结构体变量作参数——值传递方式。

例:有4个学生,每个学生包括学号、姓名、成绩。要求在main()在函数中赋以值,在另一函数print中将它们打印输出。

#define FORMAT “%d\n%s\n%f\n%f\n%f\n”

struct student

{ int num; char name[20]; float score[3]; };


结构体例如,对以上定义的结构体类型,我们可以定义如下一些结构体变量:

main()

{ void print(struct student);

struct student stu;

stu.num=12345;

strcpy(stu.nam,”li lin”);

stu.score[0]=67.5; stu.score[1]=89;

stu.score[2]=78.6; print(stu);

}

void print(struct student stu)

{

printf(FORMAT,stu.num,stu.name, stu.score[0],

stu.acore[1],stu.score[2]);}


结构体例如,对以上定义的结构体类型,我们可以定义如下一些结构体变量:

(3)返回值为结构体类型的函数

struct 结构体类型名 函数名()

{ ……;

return(结构体变量名);}


#include "string.h"例如,对以上定义的结构体类型,我们可以定义如下一些结构体变量:

#include "stdio.h"

#define BOOK struct book

BOOK

{

char bno[10];

char bname[50];

struct date

{

int day;

int month;

int year;

}bcdate;

char cbadd[40];

float bprice;

};


void welcome()例如,对以上定义的结构体类型,我们可以定义如下一些结构体变量:

{ printf("\n\t\t\t*****************************\n");

printf("\t\t\t* *\n");

printf("\t\t\t* 欢迎图书管理系统 *\n");

printf("\t\t\t* *\n");

printf("\t\t\t*****************************\n");

}


void mainmenu()例如,对以上定义的结构体类型,我们可以定义如下一些结构体变量:

{

printf("\n\n\n");

printf("\t\t\t*******************************\n");

printf("\t\t\t* 1.----输入 *\n");

printf("\t\t\t* 2.----排序 *\n");

printf("\t\t\t* 3.----退出系统 *\n");

printf("\t\t\t*******************************\n");

}


void f1(BOOK a[],int n)例如,对以上定义的结构体类型,我们可以定义如下一些结构体变量:

{

int i,b1,b2,b3;float x;

printf("输入功能\n");

for(i=0;i<n;i++)

{ printf("输入%d本书的信息\n",i+1);

printf("书号:书名 出版地:\n");scanf("%s",a[i].bno);puts(a[i].bno);getch();

scanf("%s",a[i].bname);puts(a[i].bname);getch();scanf("%s",a[i].cbadd);puts(a[i].cbadd);getch();

printf("\n出版日期:");

scanf("%d%d%d",&b1,&b2,&b3);a[i].bcdate.day=b1;a[i].bcdate.month=b2;

a[i].bcdate.year=b3;

printf("\n书价:"); scanf("%f",&x);

a[i].bprice=x;

}

}


void f2(BOOK a[],int n)例如,对以上定义的结构体类型,我们可以定义如下一些结构体变量:

{ int i,j;BOOK temp;

printf("排序功能\n");

for(i=0;i<n-1;i++)

for(j=1;j<n-i;j++)

if(strcmp(a[j-1].bno,a[j].bno)>0)

{strcpy(temp.bno,a[j-1].bno);strcpy(temp.bname,a[j-1].bname);strcpy(temp.cbadd,a[j-1].cbadd);

strcpy(a[j-1].bno,a[j].bno);strcpy(a[j-1].bname,a[j].bname);strcpy(a[j-1].cbadd,a[j].cbadd);

strcpy(a[j].bno,temp.bno);strcpy(a[j].bname,temp.bname);strcpy(a[j].cbadd,temp.cbadd);

temp.bcdate.month=a[j-1].bcdate.month;

temp.bcdate.day=a[j-1].bcdate.day;

temp.bcdate.year=a[j-1].bcdate.year;

a[j-1].bcdate.month=a[j].bcdate.month;

a[j-1].bcdate.day=a[j].bcdate.day;

a[j-1].bcdate.year=a[j].bcdate.year;

a[j].bcdate.month=temp.bcdate.month;

a[j].bcdate.day=temp.bcdate.day;

a[j].bcdate.year=temp.bcdate.year;

temp.bprice=a[j-1].bprice; a[j-1].bprice=a[j].bprice;

a[j].bprice=temp.bprice; }}


void f3(BOOK a[],int n)例如,对以上定义的结构体类型,我们可以定义如下一些结构体变量:

{

int i;

printf("书号 书名 出版地 出版日期 价格 \n");

for(i=0;i<n;i++)

{printf("%s %s %s ",a[i].bno,a[i].bname,a[i].cbadd);

printf("%d-%d-%d %f\n",a[i].bcdate.day,a[i].bcdate.month,a[i].bcdate.year,a[i].bprice);}

getch();

}


void f3(BOOK a[],int n)例如,对以上定义的结构体类型,我们可以定义如下一些结构体变量:

{

int i;

printf("书号 书名 出版地 出版日期 价格 \n");

for(i=0;i<n;i++)

{printf("%s %s %s ",a[i].bno,a[i].bname,a[i].cbadd);

printf("%d-%d-%d %f\n",a[i].bcdate.day,a[i].bcdate.month,a[i].bcdate.year,a[i].bprice);}

getch();

}


void sele(BOOK a[],int n)例如,对以上定义的结构体类型,我们可以定义如下一些结构体变量:

{

int k,m;char x[30];

while(1)

{system("cls");welcome();getch();system("cls");

mainmenu();

scanf("%d",&k);

while((k>4||k<1))

{system("cls");mainmenu();scanf("%d",&k);}

switch(k)

{case 1:

printf("输入图书数\n");

scanf("%d",&m);

f1(a,m);f3(a,m);

break;

case 2:

f2(a,m);printf("排序后的图书列表\n");f3(a,m);

break;

case 3:printf("谢谢使用,再见\n");exit(0);

}}

}


main()例如,对以上定义的结构体类型,我们可以定义如下一些结构体变量:

{

BOOK s[20];

sele(s,20);

}


例如,对以上定义的结构体类型,我们可以定义如下一些结构体变量:用体

(1)

union data

{ int i; char ch; float f; }a,b,c;

(2)

union data

{ int i; char ch; float f; };

union a,b,c;

(3)

union

{ int i; char ch; float f; }a,b,c;


例如,对以上定义的结构体类型,我们可以定义如下一些结构体变量:用体

2.存储:内存长度等于最长的成员长度

二、引用

“先定义,后使用”

  • 变量名.成员名

    “.”:成员运算符 a.i ,a.ch

    注意:

    1)不能整体引用:因共用体各成员占共同的内存区域,某一时刻其所占的内存单元内只能保留某成员项的数据,所以对共用体变量的引用只能引用共用体变量中的某个成员。


例如,对以上定义的结构体类型,我们可以定义如下一些结构体变量:用体

2)某一时刻只有一个共用体成员有效,且是最后一次存放的成员有效。

例:union data

{ int i; char c; float f; }a;

main()

{ a.i=3; a.c=’A’; a.f=32;

printf(“a.i=%d,a.c=%c,a.f=%f\n”,a.i,a.c,a.f);

}

输出结果:a.i=0,a.c= ,a.f=32.0000


例如,对以上定义的结构体类型,我们可以定义如下一些结构体变量:用体

3.共用体变量的地址值等于各成员地址值

例:union data

{ int i; char c; float f; };

main()

{ union data a;

printf(“&a=%d,&a.i=%d,&a.c=%d,&a.f=%d”,&a,&a.i,&a.c,&a.f);

}

值相同,但类型不同


例如,对以上定义的结构体类型,我们可以定义如下一些结构体变量:用体

4.共用体变量不可在定义时初始化。

5.共用体变量名不可赋值,或作函数参数,但可使用共用体数组。


设有若干教师的数据,包含有教师编号、姓名、职称,若职称为讲师,则描述他们的所讲课程,若职称为教授,则描述他们所写论文数目。

/* 输入输出教师信息*/

union cf

{char clname[30]; /*所讲课程*/

int num; /*论文数目*/

};

struct teachers

{int no; /*编号*/

char name[12]; /*姓名*/

char zc; /*职称*/

union cf x; /*可变字段, 为所讲课程或论文数目*/

} teach[3];


main( ) 设有若干教师的数据,包含有教师编号、姓名、职称,若职称为讲师,则描述他们的所讲课程,若职称为教授,则描述他们所写论文数目。

{ int i;

for(i=0; i<3; i++)

{ scanf("%d, %s,%c ", &teach[i].no,teach[i].name, &teach[i].zc);

if (teach[i].zc= ='L')/*L表示讲师*/

scanf("%s", &teach[i].x .clname);

else if (teach[i].zc= ='P' )/*P表示教授*/

scanf ("%d", &teach[i].x .num);

else printf ("input data error\n");

}

for(i=0; i<3; i++)

{printf ("%d %s %c ", teach[i].no, teach[i].name,teach[i].zc);


if (teach[i].zc= ='L')printf ("%s\n" 设有若干教师的数据,包含有教师编号、姓名、职称,若职称为讲师,则描述他们的所讲课程,若职称为教授,则描述他们所写论文数目。 , teach[i].x.. clname);

else if 'teach[i].name= ='P')printf ("%d\n", teach[i].x. num);

else printf("data error\n");

}

}


课堂练习 设有若干教师的数据,包含有教师编号、姓名、职称,若职称为讲师,则描述他们的所讲课程,若职称为教授,则描述他们所写论文数目。

1. 下列关于结构体的说法错误的是。

A

结构体是由用户自定义的一种结构类型;

B

结构体中可设定若干个不同数据类型的成员

C

结构体中成员的数据类型可以是另一个已定义的结构

D

在定义结构时,可以为成员设置默认值


课堂练习 设有若干教师的数据,包含有教师编号、姓名、职称,若职称为讲师,则描述他们的所讲课程,若职称为教授,则描述他们所写论文数目。

2.下列程序中,结构体变量a所占内存字节数是。

union u

{char st[4] ;

int i;

long l;

};

struct A

{int c;

union u;

}a;

A.4 B.5 C.6 D.8


课堂练习 设有若干教师的数据,包含有教师编号、姓名、职称,若职称为讲师,则描述他们的所讲课程,若职称为教授,则描述他们所写论文数目。

3. 已知 struct fs

{ int fz; int fm; } x[ ]={{2,7}, {4,9}};

计算表达式:

x[0].fz*x[1].fm+x[1].fz*x[0].fm和x[0].fm*x[1].fm的值。

4. 设struct student

{int num;char name[20];}st;

写出printf语句:输出学生st的各个成员分量。要求按num、name的顺序输出,各成员之间使用空格分隔开。

如果利用结构体输出学生名单“0912000101 张三”,如何设计该程序?


编写一个程序实现如下功能:定义一个点的结构数据类型,实现下列功能:编写一个程序实现如下功能:定义一个点的结构数据类型,实现下列功能:

①为点输入坐标值。

②求两个点中点坐标。

③求两点间距离。


课后练习编写一个程序实现如下功能:定义一个点的结构数据类型,实现下列功能:

分数包含分子分母两项,定义一个有关分数的结构体类型,写一个函数计算两分数之和,结果仍为分数类型,注意约分。编写主函数验证之。

1

编写一个程序实现如下功能:定义一个点的结构数据类型,实现下列功能:

①为点输入坐标值。

②求两个点中点坐标。

③求两点间距离。

2


谢谢编写一个程序实现如下功能:定义一个点的结构数据类型,实现下列功能:


ad