计算机实习
Download
1 / 145

计算机实习 - PowerPoint PPT Presentation


  • 212 Views
  • Uploaded on

计算机实习. 第 2 讲. 复习. 结构体 struct 结构体类型名 { 类型 成员 1; 类型 成员 2; 类型 成员 n; };. 复习. 结构体 struct 结构体类型名 { 类型 成员 1; 类型 成员 2; 类型 成员 n; } 变量 1, 数组 1;. 复习. #include "stdio.h" #include "math.h" struct point { float x; float y; };. 复习.

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 ' 计算机实习' - elliot


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

复习

结构体

struct 结构体类型名

{ 类型 成员1;

类型 成员2;

类型 成员n;

};


复习

结构体

struct 结构体类型名

{ 类型 成员1;

类型 成员2;

类型 成员n;

}变量1,数组1;


复习

#include "stdio.h"

#include "math.h"

struct point

{

float x;

float y;

};


复习

void input(struct point a[])

{

int i;

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

{ printf("输入第%d点的坐标\n",i+1);

scanf("%f%f",&a[i].x,&a[i].y);

}

}


复习

void midpoint(struct point a[])

{

int i;struct point m;m.x=0;m.y=0;

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

{m.x=m.x+a[i].x;

m.y=m.y+a[i].y;}

m.x=m.x/2;m.y=m.y/2;

a[2].x=m.x;a[2].y=m.y;

}


复习

float dis(struct point a[])

{

int i;float s;struct point m;m.x=a[0].x;m.y=a[0].y;

{ m.x=m.x-a[1].x;m.y=m.y-a[1].y;}

s=sqrt(m.x*m.x+m.y*m.y);

return s;

}


复习

main()

{

struct point a[3];

input(a);

printf(" 第1点%f %f 第2点%f %f\n",a[0].x,a[0].y,a[1].x,a[1].y);

midpoint(a);

printf(" 中点%f %f \n",a[2].x,a[2].y);

printf("距离%f\n",dis(a));

}


复习

#include "stdio.h"

#include "string.h"

struct data

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

struct stud

{ char name[20];

char tele[12];

char zip[7];

struct data birthday;

char addre[30];

};

struct stud stud1[30]={"liming","1331187907","210020",3,14,1988,"beijing","chaening","13789087907","260020",8,14,1980,"tianjing","being","13678987907","710020",9,14,1990,"nanjing"};


main()

{ int k,i,j,n=3;

struct stud temp;

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

{ k = i;

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

if (strcmp(stud1[j].name,stud1[k].name)<0)

k =j;

temp= stud1[i];

stud1[i]= stud1[k];

stud1[k]= temp;

}

printf("姓名 电话 邮编 生日 地址\n");

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

printf("%10s%12s%8s %2d-%2d-%4d %15s\n",stud1[i].name,stud1[i].tele,stud1[i].zip,stud1[i].birthday.month,stud1[i].birthday.day,stud1[i].birthday.year,stud1[i].addre);

}


复习

文件

1.定义

FILE *指针名;

2.打开文件

if((指针名=fopen("file9_3.txt","w"))==NULL)

{ printf("%s不能打开\n","e:\\file9_3.txt");

exit(1);

}


复习

文件

3.读或写文件

fprintf(指针名,"%5d ",b[i]);

4.关闭文件

fclose(fp);


复习

对职工工资进行统计。职工信息包含工号和姓名、基本工资、奖金、提成、实发工资,分别统计平均工资、最高工资和最低工资,将职工工资信息存入文件(diy2.dat)中。


#include "stdio.h"

#include "string.h"

struct staff

{

int num;

char name[20];

float basic_wage;

float percentage;

float bonus;

float real_wages;

float wages_should;

}sp[200]={901,"张川",432,120,66,0,0,902,"李洪",488,123,75,0,0,903,"罗庆",423,240,24,0,0,904,"秦汉",356,789,72,0,0,905,"刘少文",530,765,114,0,0,906,"苏南昌",488,456,87,0,0,907,"孙红",530,345,102,0,0};

FILE *fp3;


void file(struct staff a[],int n)

{ int i;FILE *fp3;

if((fp3=fopen("diy2.dat", "w"))==NULL)

{

printf("Open error \n");exit(0);

}

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

{

fprintf(fp3,"%d,%s,%f,%f,%f,%f,%f",a[i].num,a[i].name,a[i].basic_wage,a[i].percentage,a[i].bonus,a[i].real_wages,a[i].wages_should);

}

fclose(fp3);

}


int max(struct staff a[],int n)

{

int imax=0,i;

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

if(a[i].basic_wage>a[imax].basic_wage) imax=i;

return imax;

}


int min(struct staff a[],int n)

{

int imin=0,i;

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

if(a[i].basic_wage<a[imin].basic_wage) imin=i;

return imin;

}


void comput(struct staff a[],int n)

{

int i;

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

{a[i].wages_should=a[i].basic_wage+a[i].percentage+a[i].bonus;

a[i].real_wages=a[i].wages_should-a[i].wages_should*0.1;

}

}


float ave(struct staff a[],int n)

{

int i;float ave=0;

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

ave=ave+a[i].basic_wage;

ave=ave/n;

return ave;

}


main()

{ int m=7;

comput(sp,m);

printf("最高工资 %f 最低工资 %f 平均工资%f\n",sp[max(sp,m)].basic_wage,sp[min(sp,m)].basic_wage,ave(sp,m));

file(sp,m);

}


项目评分标准

  • 数据类型

  • 数据文件

  • 算法

  • 界面

  • 综合


项目合作与分工

  • 数据类型

  • 数据文件

  • 算法


练习

  • 计算5名学生3门课成绩的平均分,学生信息为:

  • struct stud

  • { int no;

  • char name[16];

  • float mark[3];

  • float ave;

  • };

  • 将5名学生写入文件AA.dat中


void file(struct stud a[],int n)

{ int i;

FILE *fp3;

if((fp3=fopen(“AA.dat", "w"))==NULL)

{

printf("Open error \n");exit(0);

}

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

{

fprintf(fp3,"%d,%s,%f,%f,%f,%f\\n",a[i].num,a[i].name,a[i]. mark[0],a[i].mark[1],a[i].mark[2].a[i].ave);

}

fclose(fp3);

}


指针基本概念

基础教研室


目 录

3

3

内存与地址

1

3

指针与指针变量

2

指针初始化

指针运算

4


内存

0

…...

2000

2001

2002

2003

2005

…...

  • 变量与地址

内存中每个字节有一个编号-----地址

程序中: int i;

float k;

i

编译或函数调用时为其分配内存单元

k

变量是对程序中数据

存储空间的抽象


…...

整型变量i

2000

10

2001

2002

2003

变量i_pointer

2004

2005

变量地址(指针)

指针变量

2006

地址存入

指针变量

指向

…...

变量值

变量

指针

变量的内容

变量的地址

2000

指针变量


  • 一般形式: [存储类型]数据类型 *指针名;

例 int*p1,*p2;

float *q ;

static char *name;

表示定义指针变量

不是‘*’运算符

合法标识符

指针变量本身的存储类型

指针的目标变量的数据类型

注意:

1、int *p1, *p2;与 int *p1, p2;

2、指针变量名是p1,p2 ,不是*p1,*p2

3、指针变量只能指向定义时所规定类型的变量

4、指针变量定义后,变量值不确定,应用前必须先赋值


…...

整型变量i

2000

10

2001

2002

2003

变量i_pointer

2004

2000

指针变量

2005

2006

…...

地址符&与指针运算符*

含义:取指针所指向变量的内容

单目运算符

优先级: 2

结合性:自右向左

含义: 取变量的地址

单目运算符

优先级: 2

结合性:自右向左

i_pointer &i &(*i_pointer)

i *i_pointer *(&i)

i_pointer=&i=&(*i_pointer)

i=*i_pointer =*(&i)

i_pointer-----指针变量,它的内容是地址量

*i_pointer----指针的目标变量,它的内容是数据

&i_pointer---指针变量占用内存的地址


例题1

  • #include <stdio.h>

  • int main( )

  • { int i = 100, j=200;

  • int *p;

  • p = &i; //变量i的地址赋给p

  • printf("&i=%d *(&i)=%d\n", &i, *(&i));

  • printf(" p=%d *p =%d\n\n", p, *p);

  • p = &j; //变量j的地址赋给p

  • printf("&j=%d *(&j)=%d\n", &j, *(&j));

  • printf(" p=%d *p =%d\n", p, *p);

  • return 0;

  • }

||


指针初始化

  • 当指针变量被定义时应立即赋值,这个过程称为初始化

  • “野指针”--未被初始化,该指针是游离的,可能指向任意一个地址单元

例 int i;

int *p=&i;

例 int i;

int *p=&i;

int *q=p;


例题2

…...

整型变量i

2000

10

2001

2002

2003

指针变量p

2004

2005

随机

2006

…...

  • main( )

  • { int i=10;

  • int *p;

  • *p=i;

  • printf(“%d”,*p);

  • }


指针运算

  • 算术运算

    • 指针 ± 整型数

    • 如果指针变量的定义为 datatype *p; p初始地址值为DS, 那么p ± n = DS ± n*sizeof(datatype)。

    • 常运用到数组应用中

  • 关系运算

    • 前提就是必须指向的是连续的存储单元,比如同一个数组

    • 常用来测试是否循环结束 ,如p<=&a[3]判断是否是数组的最后一个元素



案例

…...

main()

{ int *p1,*p2,*p,a,b;

scanf("%d,%d",&a,&b);

p1=&a; p2=&b;

if(a<b)

{ p=p1; p1=p2; p2=p;}

printf("a=%d,b=%d\n",a,b);

printf("max=%d,min=%d\n",*p1,*p2);

}

2008

2000

指针变量p1

2006

2002

2006

2004

指针变量p2

指针变量p

整型变量b

整型变量a

5

2006

9

2008

…...


指针与一维数组

数组名是一个地址常量,表示数组的首地址值,是一个指针常量。

int a[10];

下标法a[i]来表示某个数组元素

a+i ——该a[i]元素的首地址。

*(a+i)——该a[i]元素的值


用指针变量引用数组元素

  • 定义指向数组的指针变量

    int a[5];

    int *p;

    p=&a[0];

    p=a;

  • 用指针法引用数组元素

    *(p+i)表示a[i]元素


地址

p[0]

a[0]

a[0]

a[0]

*p

*a

元素

地址

元素

*(p+1)

*(a+1)

p[1]

a[1]

a[1]

a[1]

*(p+2)

*(a+2)

p[2]

a[2]

a[2]

a[2]

p

a

a[3]

a[3]

p+1

a+1

p+2

a+2

a[9]

p[9]

a[9]

*(a+9)

*(p+9)

a[9]

...

...

p+9

a+9

指针法

下标法

[] 变址运算符

a[i] *(a+i)

a[i]  p[i]  *(p+i) *(a+i)


pa

a[0]

1

a[1]

2

a[2]

3

a[3]

4

a[4]

5

例 数组元素的引用方法

main()

{ int a[5],*pa,i;

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

a[i]=i+1;

pa=a;

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

printf("*(pa+%d):%d\n",i,*(pa+i));

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

printf("*(a+%d):%d\n",i,*(a+i));

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

printf("pa[%d]:%d\n",i,pa[i]);

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

printf("a[%d]:%d\n",i,a[i]);

}


指向数组元素的指针变量的运算

  • p++; ++p; /*使p指向数组的后一个元素 */

  • p--; --P; /*使p指向数组的前一个元素 */

  • p+n; /*使p往后移n个元素 */

  • p-n; /*使p往前移n个元素 */

  • p-q; /*若p与q指向同一数组,求指针变量p和q之间元素的个数,且q在p前*/


p指向int型数组,且p=&a[0];

则p+1 指向a[1]

例 int a[10];

int *p=&a[2];

p++;

*p=1;

例 int a[10];

int *p1=&a[2];

int *p2=&a[5];

则:p2-p1=3;



字符串的表示形式

string

string[0]

I

string[1]

string[2]

l

string[3]

o

string[4]

v

string[5]

e

string[6]

string[7]

C

string[8]

h

string[9]

i

string[10]

n

string[11]

a

string[12]

!

string[13]

\0

  • 用字符数组实现

例 main( )

{ char string[]=“I love China!”;

printf(“%s\n”,string);

printf(“%s\n”,string+7);

}


字符指针

  • 定义

    char *pstr;

  • 初始化

    char *pstr=“C language”;

    char *pstr;

    pstr= "C language";


字符串的表示形式

string

I

l

o

v

e

C

h

i

n

a

!

\0

  • 用字符指针表示

例 main( )

{ char *string=“I love China!”;

printf(“%s\n”,string);

string+=7;

while(*string)

{ putchar(string[0]);

string++;

}

}


案例—字符串的复制

main( )

{ char a[80],b[80],*pa,*pb;

pa=a;pb=b;

scanf("%s",pa);

while(*pa!= '\0')

*(pb++)=*(pa++);

*pb=’\0’;

printf("%s",b) }


关于指针变量的运算

1、p++ (或p+=1) 使p指向下一个元素的地址。

2、若有*p++ 由于++ 和 * 同优先级,其结合方向为

自右而左,因此它等价于 *(p++)。

main()

{ int a[8]={2,4,6,8,10,12,14,16}, i, *p;

for(p=a, i=0; i<8; i++)

printf(“%d,”, *p++);

}


p

p

p

3、*(p++)与 *(++p) 作用不同。前者是先取*p的值

后使 p 加1; 后者是先使 p 加1,再取 *p。

a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7]

*(p++)

2

*(++p)

4

*(++p)与*++p 等价

4、(*p)++表示是 p 所指向的元素值加 1。

a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7]

5

(*p)++

3

4


练习

若已定义了一个结构体变量和基类型为同一结构体类型的指针变量,并使该指针指向同类型的变量,则有3种形式来引用结构体变量中的成员。结构体变量名也可以是已经定义的结构体数组的数组元素,形式如下:

  • 结构体变量名.成员名

  • 指针变量名 –> 成员名

  • (*指针变量名).成员名


练习

(1) 设有定义 struct date{

int day;

char month;

int year;

} dd, *pd = &dd;

试写出引用结构变量dd的成员dd.day的其他两种描述形式。

(2) 设有如下程序段:

int a[4] = {0,4,5,13}, *p;

p = &a[2];

printf("++(*p)= %d\n", ++(*p));

printf("*--p=%d\n", *--p);

printf("*p++=%d\n", *p++);

printf("%d\n",a[0]);

试写出执行该程序段后的输出结果。


练习

  • 执行下列程序后,b和c的值各为多少?

  • #include <stdio.h>

  • void main()

  • { int *a[10],b,c;

  • a[0]=&b;

  • *a[0]=5;

  • c=(*a[0])++;

  • printf(“%d %d\n”,b,c);

  • }


练习

  • 下列程序的输出结果是什么?

  • #include <stdio.h>

  • main()

  • { int c1=0,c2=0,c3=0,c4=0;

  • char *p=”12395632123378”;

  • while (*p)

  • { switch (*p)

  • { case ‘1’ : c1++; break;

  • case ‘2’ : c2++;

  • case ‘3’ : c3++; break;

  • default : c4++;

  • }


练习

p++;

}

printf(“c1=%d c2=%d c3=%d c4=%d\n”,c1,c2,c3,c4);

}


本程序运行时,从键盘不断接收用户输入的字符串并进行处理,直到用户输入的字符串为“本程序运行时,从键盘不断接收用户输入的字符串并进行处理,直到用户输入的字符串为“end”时终止。对用户输入的每个字符串的处理是:将字符串内的每一个十进制数字字符置换成下列表格中右边所对应的一个字符串(所有其他字符不变),然后将转换的结果显示在屏幕上;并分别计算每个数字的置换次数。


例如,若用户输入的字符串为本程序运行时,从键盘不断接收用户输入的字符串并进行处理,直到用户输入的字符串为“

Page112-Line3,

则程序5的输出是:

Page(One) (One) (Two)-Line(Three)

数字0到9的置换次数分别是 0 2 1 1 0 0 0 0 0 0


#include <stdio.h>本程序运行时,从键盘不断接收用户输入的字符串并进行处理,直到用户输入的字符串为“

void main()

{ char *table[]={"(Zero)"," (One)"," (Two)"," (Three)"," (Four)",

" (Five)"," (Six)"," (Seven)"," (Eight)"," (Nine)" };

char str1[64],str2[255],*p;

int j,k,n,no[10];

for (;;) {

printf("Input:");

gets( (1) ); /*读入字符串*/


for(k=0;k<10;k++) no[k]=0;本程序运行时,从键盘不断接收用户输入的字符串并进行处理,直到用户输入的字符串为“

if(strcmp(str1,"end")==0) (2) _ ; /* 输入end时程序运行终止 */

for(j=k=0;str1[j]!='\0';++j) /* 对输入字符串进行扫描 */

{

if ( (3) ) /*当前字符不是数字字符*/

{ str2[k++]=str1[j];

continue;

}

/*当前字符是数字字符*/

n=str1[j]-'0';

no[n]++;

for(p=table[n];*p!='\0';++p)

str2[k++] = (4) ; /* 把要置换的字符串逐个连接到str2上 */

}


str2[k] = 本程序运行时,从键盘不断接收用户输入的字符串并进行处理,直到用户输入的字符串为“(5) ; /* 置字符串结束符于str2末尾 */

printf("%s\n",str2);

for(k=0;k<10;k++) printf("no[%d]=%d\t",k,no[k]);

}

}


1.本程序运行时,从键盘不断接收用户输入的字符串并进行处理,直到用户输入的字符串为“设有定义:int n1=0,n2,*p=&n2,*q=&n1;,以下赋值语句中与n2=n1;语句等价的是。

A.*p=*q; B p=q;

C.*p=&n1; D.p=*q;


2.本程序运行时,从键盘不断接收用户输入的字符串并进行处理,直到用户输入的字符串为“有以下程序

main()

{ int a[10]={1,2,3,4,5,6,7,8,9,10}, *p=&a[3], *q=p+2;

printf("%d\n", *p + *q);

}

程序运行后的输出结果是

A.16 B.10 C.8 D.6


3.本程序运行时,从键盘不断接收用户输入的字符串并进行处理,直到用户输入的字符串为“以下语句或语句组中,能正确进行字符串赋值的是______。

A.char *sp;*sp="right!";

B.char s[10];s="right!";

C.char s[10];*s="right!";

D.char *sp="right!";


4.本程序运行时,从键盘不断接收用户输入的字符串并进行处理,直到用户输入的字符串为“以下程序运行后,输出结果是。

main( )

{ char *s=“abcde”;

s+=2;

printf(“%ld\n”,s);

}

A.cde B.字符c的ASCII码值 

C.字符c的地址     D.出错


5.本程序运行时,从键盘不断接收用户输入的字符串并进行处理,直到用户输入的字符串为“有以下程序

main()

{ char s[]="159",*p;

p=s;

printf("%c",*p++);printf("%c",*p++);

}

程序运行后的输出结果是______。

A.15 B.16 C.12 D.59


6.本程序运行时,从键盘不断接收用户输入的字符串并进行处理,直到用户输入的字符串为“有以下定义

#include <stdio.h>

char a[10],*b=a;

不能给数组a输入字符串的语句是。

A.gets(a) B. gets(a[0])

C. gets(&a[0]); D. gets(b)


7.本程序运行时,从键盘不断接收用户输入的字符串并进行处理,直到用户输入的字符串为“有以下程序

#include <stdio.h>

main ()

{ char *p,*q;

p=(char*) malloc (sizeof (char)*20); q=p;

scanf ("%s %s", p, q); printf ("%s %s\n", p, q );

}

若从键盘输入:abc def<回车>,则输出结果是:。

A.def def B. abc def

C. abc d D. d d


8.本程序运行时,从键盘不断接收用户输入的字符串并进行处理,直到用户输入的字符串为“下列程序执行后的输出结果是

void func(int *a,int b[])

{ b[0]=*a+6; }

main()

{ int a,b[5];

a=0; b[0]=3;

func(&a,b); printf("%d \n",b[0]);

}

A. 6 B. 7 C. 8 D. 9


若指针本程序运行时,从键盘不断接收用户输入的字符串并进行处理,直到用户输入的字符串为“s指向存储单元a[2],p指向存储单元a[0],表达式s-p的值是


2本程序运行时,从键盘不断接收用户输入的字符串并进行处理,直到用户输入的字符串为“.执行以下语句,输出结果是___________________。

char *p, s[ ]=”abcdefgh”;

p=s;

printf(“%s”, p+3);


3.本程序运行时,从键盘不断接收用户输入的字符串并进行处理,直到用户输入的字符串为“已知有定义 char*names[]={"Wang","Li","Chen"};语句printf("Second%sFirst%s", names[1], names[0]);的运行结果为_______________________________________。

4. 已知 in a[5] = { 2, 3, 4, 5, 6 }; int *p = a+2; 表达式 *p*a[3] 的值是_________________。

5. int a[5]={1,3,5,7,9},*p=a;执行++ (*p);语句后,数组元素的值分别是。


6. 本程序运行时,从键盘不断接收用户输入的字符串并进行处理,直到用户输入的字符串为“分析下面的C语言程序,程序运行后,结果是_____________。

#include<stdio.h>

#include<string.h>

void main()

{

char *p[10]={“akshj”,“asas”,“ayusi”,“daksfhasf”,“alsjkfas”};

printf(“%d\n”,strlen(p[4]));

}

解释:/*因p[4]指向最后一个字符串,计算最后一个字符串的长度*/


6. 本程序运行时,从键盘不断接收用户输入的字符串并进行处理,直到用户输入的字符串为“分析下面的C语言程序,程序运行后,结果是_____________。

#include<stdio.h>

#include<string.h>

void main()

{

char *p[10]={“akshj”,“asas”,“ayusi”,“daksfhasf”,“alsjkfas”};

printf(“%d\n”,strlen(p[4]));

}

解释:/*因p[4]指向最后一个字符串,计算最后一个字符串的长度*/


7. 本程序运行时,从键盘不断接收用户输入的字符串并进行处理,直到用户输入的字符串为“运行下列程序,其输出结果为

#include <stdio.h>

main()

{

int a[]={10,11,12,13,14}, *p, n;

p=&a[0];

n=*(p++);

n+=*(++p);

n+=(*(p+=2))++;

n-=(*(--p))--;

n-=*(--p-1);

printf("n=%d\n",n);

printf("a[2]=%d,a[3]=%d,a[4]=%d\n",a[2],a[3],a[4]);

}


本程序运行时,从键盘不断接收用户输入的字符串并进行处理,直到用户输入的字符串为“程序2.2】

#include <stdio.h>

void func(int *x,int y)

{

static k=3;

y=*x+y;

*x=y%k;

k++;

printf("*x=%d,y=%d\n",*x,y);

}

void main()

{

int x=12,y=5;

func(&x,y);

printf("x1=%d,y1=%d\n",x,y);

func(&y,x);

printf("x2=%d,y2=%d\n",x,y);

}


1.本程序运行时,从键盘不断接收用户输入的字符串并进行处理,直到用户输入的字符串为“以下程序为简易密码变换,输入一行字符,将其中的小写字母用该字母之后的第4个字母进行替换,如将’a’替换为’e’,若替换的字母超过’z’则循环到’a’,如’w’替换为’a’。 把应填入其中 处的内容写在答卷纸的对应栏内。


#include <stdio.h>本程序运行时,从键盘不断接收用户输入的字符串并进行处理,直到用户输入的字符串为“

void trans( char *dest, char *src )

{ /*将字符串src变换为dest*/

char ch;

while ( ch= )

{

if ( ch>='a' && ch<='z' )

{

ch += 4;

if ( ch > 'z' )

ch =

}

*dest = ch;

dest ++;

}

*dest =

}

*(src++)

'a'+ch-'z'-1;

'\0‘;


2.本程序运行时,从键盘不断接收用户输入的字符串并进行处理,直到用户输入的字符串为“本程序将字符串a 中第k个字符开始的后继字符复制到b。

【程序4.2】

#include <string.h>

#include <stdio.h>

copysubstr(char *a, char *b, int k)

{ a=a+k-1;

while ( )

*b++=*a++;

*b='\0';

}

*a!='\0'


main()本程序运行时,从键盘不断接收用户输入的字符串并进行处理,直到用户输入的字符串为“

{ int position;

char *str1, *str2;

str1=(char *)malloc(80); /* 分配到可存放字符串的内存块,80字节 */

str2= ;

clrscr();

gets(str1);

scanf("%d",&position);

if (position>strlen(str1))

printf(" the value of position is error\n");

else

{ copysubstr( );

printf(" str2=%s\n",str2);

}

}

(char *)malloc(80)

str1,str2,position


1本程序运行时,从键盘不断接收用户输入的字符串并进行处理,直到用户输入的字符串为“.编写sort函数对n 个整型数按选择法降序排列并输出,要求该函数内对数据的交换采用指针,试编程。


#define N 10本程序运行时,从键盘不断接收用户输入的字符串并进行处理,直到用户输入的字符串为“

void sort(int *array,int n)

{ int i,j,k,t;

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

{ k=i;

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

if (*(array+j)>*(array+k)) k=j;

t=*(array+k);*(array+k)=*(array+i);*(array+i)=t;

}

}


main()本程序运行时,从键盘不断接收用户输入的字符串并进行处理,直到用户输入的字符串为“

{ int a[N],i;

printf(" enter the array\n");

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

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

sort(a,N);

printf(" the sorted array : \n");

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

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

printf("\n");

}


2. 本程序运行时,从键盘不断接收用户输入的字符串并进行处理,直到用户输入的字符串为“编写一函数,功能为:在字符串中查找该字符。若有相同字符, 则返回一个指向该字符串中这一位置的指针, 如果没有找到, 则返回一个空(NULL)指针。



练习编写一函数,功能为:在字符串中查找该字符。若有相同字符

设有如下程序段:

char s1[20]="P4CPU";

char s2[]="DVD+17\"CRT+56KMODEM";

s2[10]='\0';

strcat(s1,s2+3);

puts(s1);

写出执行后的输出结果。


练习编写一函数,功能为:在字符串中查找该字符。若有相同字符

以下程序的输出结果是:

main()

{ int a[ ]={1,2,3,4,5,6}, *p;

p=a; *(p+3)+=2;

printf(“%d,%d\n”, *p, *(p+3));

}


练习编写一函数,功能为:在字符串中查找该字符。若有相同字符

编程实现输入平面上3个点的坐标,判断连接这3点能否构成三角形.如果能则计算其面积.


数据组织编写一函数,功能为:在字符串中查找该字符。若有相同字符-链表

基础教研室


目 录编写一函数,功能为:在字符串中查找该字符。若有相同字符

3

3

3

线性链表

1

3

5

链表基本操作

2

堆栈结构

二叉树

队列结构

文件

4

6


链表编写一函数,功能为:在字符串中查找该字符。若有相同字符

链表的基本概念

例:在铁路的中转站,有10个集装箱待运。每

个集装箱上有如下五项说明:

① 箱号 (比如 AZ81920)

② 货物名称 (比如 苹果)

③ 重量 (比如 10吨)

④ 发货地点 (比如 山东)

⑤ 到货地点 (比如 广东)


如何在程序中来描述该列火车?编写一函数,功能为:在字符串中查找该字符。若有相同字符

  • 如何来描述火车头?

  • 如何来描述每一个集装箱?

  • 如何来描述各节车厢之间的链接关系?


需要引入一种新的数据结构:链表。链表中的编写一函数,功能为:在字符串中查找该字符。若有相同字符

每一个元素称为一个“结点”,每个结点都应该

包括两部分:一为用户需要使用的实际数据;

二为下一个结点的起始地址。另外,链表还有

一个头指针head,指向链表的首结点。

head

结点1

结点2

结点3


如何来实现链表结构?显然要用到结构体数据编写一函数,功能为:在字符串中查找该字符。若有相同字符

类型。定义如下的结构体类型:

struct Train_tag

char Num[8];

char Name[10];

int Weight;

char From[20];

char To[20];

数据域

指针域

struct Train_tag *next;


对链表的操作编写一函数,功能为:在字符串中查找该字符。若有相同字符

1. 创建静态链表

在程序中定义一组结构体变量或一个结构体

数组,然后用它们来作为链表的结点,把它

们链接成一个链表的形式。

优点:不必去关心内存的分配与释放。

缺点:需要事先知道链表结点的个数。


struct Train_tag 编写一函数,功能为:在字符串中查找该字符。若有相同字符

{

char Num[8]; /* 集装箱编号 */

char Name[10]; /* 货物名称 */

int Weight; /* 货物重量 */

char From[20]; /* 发货地点 */

char To[20]; /* 到货地点 */

struct Train_tag *next; /* 指向下一结点 */

}array[10], *head;


思路:用第编写一函数,功能为:在字符串中查找该字符。若有相同字符i(0-9)个数组元素来描述第 i + 1个链表结点

void Create( )

{

int i;

head = &array[0]; /* 链表的头指针 */

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

{

输入array[i]的各个成员变量的值;

if(i < 9) array[i].next = &array[i+1];

else array[i].next = NULL;

}

}


head编写一函数,功能为:在字符串中查找该字符。若有相同字符

结点1

结点2

结点10

array[0]

array[1]

array[9]


2. 编写一函数,功能为:在字符串中查找该字符。若有相同字符创建动态链表

在程序当中为链表的每一个结点动态地分配

相应的存储空间,并把它们链接成一个链表

的形式。

优点:按需分配,链表的长度可动态增长。

缺点:由程序员来进行内存的分配与释放。


编写一函数,功能为:在字符串中查找该字符。若有相同字符例】

创建一个链表,并输入每一个结点的各种描

述信息(集装箱编号、货物名称、货物

重量、发货地点、到货地点等),直到用户

输入的货物重量等于0,表示链表结束。


struct Train_tag 编写一函数,功能为:在字符串中查找该字符。若有相同字符

{

char Num[8]; /* 集装箱编号 */

char Name[10]; /* 货物名称 */

int Weight; /* 货物重量 */

char From[20]; /* 发货地点 */

char To[20]; /* 到货地点 */

struct Train_tag *next; /* 指向下一结点 */

};

struct Train_tag *head, *p, *q;


p编写一函数,功能为:在字符串中查找该字符。若有相同字符

q

head

创建链表的过程可归纳为如下三个步骤

① 只要用户输入的 Weight 不为 0,就要构建链表。基本思路是将一个一个的结点添加至链表中。首先用指针 p 来申请一个结构体变量的内存空间,并且装入用户输入的各种描述信息,然后将指针 q 和 head都指向它。如下图:

图 链表的第一个结点建成

DX11089

玩具

5吨

从上海

到深圳


head编写一函数,功能为:在字符串中查找该字符。若有相同字符

q

p

q

② 后继结点的创建:如果用户输入的Weight又不为 0,就要构建链表的第二个结点。首先用指针 p 来申请一个结构体变量的内存空间,并且装入用户输入的各种描述信息,然后要执行 q->next = p,把第一个结点的next指针去指向它,从而建立两个结点之间的链接关系。最后再把 q 指向新的结点。如下图:

图 链表的第二个结点建成

DX11089

玩具

5吨

从上海

到深圳

CY20011

电饭锅

8吨

从上海

到湖南


head编写一函数,功能为:在字符串中查找该字符。若有相同字符

q

p

q

第三个结点加入链表的过程:

DX11089

玩具

5吨

从上海

到深圳

CZ21026

苹果

8吨

从山东

到福建

CY20011

电饭锅

8吨

从上海

到湖南


head编写一函数,功能为:在字符串中查找该字符。若有相同字符

q

③ 链表创建过程的结束:如果用户输入的Weight等于 0,意味着链表创建过程的结束,此时指针 q 所指向的就是链表的最后一个结点,所以要把该结点的next指针赋值为NULL,即执行 q->next = NULL,表示这里已是链尾,后面不会再连结点。如下图:

DX11089

玩具

5吨

从上海

到深圳

AZ81920

花生

10吨

从山东

到广东

CY20011

电饭锅

8吨

从上海

到湖南


void Create( )编写一函数,功能为:在字符串中查找该字符。若有相同字符

{

int Weight;

head = p = q = NULL;

while( 1 )

{

printf("输入货物重量:");

scanf("%d", &Weight);

if(Weight <= 0) break;

p = malloc(sizeof(struct Train_tag));

p->Weight = Weight;

输入该结点的其他信息;

if (head == NULL) head = p; // 新建的是首结点

else q->next = p; // 不是首结点

q = p; // q指向当前尾结点

}

if (head != NULL) q->next = NULL;

}


3. 编写一函数,功能为:在字符串中查找该字符。若有相同字符访问链表

在创建好一个链表之后,可以依次地访问该

链表当中的各个结点的数据。

void Display( )

{

struct Train_tag *p;

p = head;

while(p != NULL)

{

printf("%s, %s, %d, %s, %s\n", p->Num,

p->Name, p->Weight, p->From, p->To);

p = p->next;

}

}


4. 编写一函数,功能为:在字符串中查找该字符。若有相同字符删除链表结点

假设列车现在到达长沙站,因此需要把到货地点为湖南的车厢(假设有且仅有一节),从列车上摘下来,然后列车继续向南行驶。

这里就需要用到链表结点的删除技术。


p编写一函数,功能为:在字符串中查找该字符。若有相同字符

head

情形一、待删除的是首结点

DX11089

玩具

5吨

从上海

到湖南

AZ81920

花生

10吨

从山东

到广东

CY20011

电饭锅

8吨

从上海

到深圳

head = p->next;


p编写一函数,功能为:在字符串中查找该字符。若有相同字符

q

情形二、待删除的不是首结点

DX11089

玩具

5吨

从上海

到深圳

AZ81920

花生

10吨

从山东

到广东

CY20011

电饭锅

8吨

从上海

到湖南

q->next = p->next;


删除代码编写一函数,功能为:在字符串中查找该字符。若有相同字符

void Delete( )

{

struct Train_tag *p, *q;

if(head == NULL) { printf("空链表"); return; }

p = head;

while((p != NULL) && strcmp(p->To, "湖南"))

{

q = p;

p = p->next; // 把指针p往后移动一个结点

}

if((p != NULL) && !strcmp(p->To, "湖南"))

{

if(p == head)

head = p->next; // 删除的是首结点

else

q->next = p->next; // 删除的是中间结点

}

}


5. 编写一函数,功能为:在字符串中查找该字符。若有相同字符插入链表结点

  • 原则:

  • 插入操作不应破坏原有链接关系;

  • 需要插入的这个结点应该把它放在合适的位置上,也就是说,应该有一个插入位置的查找过程。


先看下面一个简单的例子:编写一函数,功能为:在字符串中查找该字符。若有相同字符

已有一个如图所示的链表。它是按结点中的货物重量从小到大排序的。现在要插入一个新的结点,该结点的货物重量为7吨。

head


定义:编写一函数,功能为:在字符串中查找该字符。若有相同字符

struct Train_tag *head; // 头指针

struct Train_tag *p; // 链表当前结点

struct Train_tag *q; // 链表上一结点

struct Train_tag *pNode; // 待插入的结点


pNode编写一函数,功能为:在字符串中查找该字符。若有相同字符

head

第一种情况:链表为空,即 head = NULL

待插入的 pNode 结点就是链表中的第一个结点。

DX11089

玩具

5吨

从上海

到湖南

head = pNode;


第二种情况:编写一函数,功能为:在字符串中查找该字符。若有相同字符

pNode 结点的 Weight 值小于等于链表首结点的

Weight 值,即 pNode->Weight <= head->Weight

这时要将 pNode 结点插入到首结点的前面,即

执行以下两条语句:

pNode->next = head;

head = pNode;


head编写一函数,功能为:在字符串中查找该字符。若有相同字符

pNode

这种情况如下图

pNode->next = head;

head = pNode;


第三种情况:编写一函数,功能为:在字符串中查找该字符。若有相同字符

即pNode结点的 Weight 要大于首结点的 Weight

值,这时肯定地说 pNode 结点要插入到首结点之

后,但究竟插入到哪里需要先找到正确的位置。

我们设指针q和指针p分别指向相邻的两个结点,

q 在前 p 在后(即q更靠近首结点)。

首先让q = head,让 p = head->next,然后让它们

顺序往后移动,每次移动一个结点。当着满足:

q->Weight < pNode->Weight <= p->Weight

时,pNode 就插在 q 与 p 之间。


p编写一函数,功能为:在字符串中查找该字符。若有相同字符

q

p

head

q

pNode

移动指针:

q = p;

p = p->next;

插入结点:

pNode->next = p;

q->next = pNode;


void Insert(struct Train_tag *pNode)编写一函数,功能为:在字符串中查找该字符。若有相同字符

{

struct Train_tag *p, *q;

// 第一种情形,链表为空

if(head == NULL)

{

head = pNode;

return;

}

// 第二种情形,新结点的Weight小于等于首结点

if(pNode->Weight <= head->Weight)

{

pNode->next = head;

head = pNode;

return;

}


// 编写一函数,功能为:在字符串中查找该字符。若有相同字符第三种情形,循环地查找正确的插入位置

q = head; p = head->next;

while(p != NULL)

{

if(pNode->Weight <= p->Weight)

break;

else

{

q = p;

p = p->next;

}

}

// 将pNode结点插入在正确的位置(q和p之间)

pNode->next = p;

q->next = pNode;

}


如果新结点的编写一函数,功能为:在字符串中查找该字符。若有相同字符Weight大于所有结点?

while(p != NULL)

{

if(pNode->Weight <= p->Weight)

break;

else

{

q = p;

p = p->next;

}

}

在这种情形下,当循环语句结束后,指针q是

指向链表的尾结点,而指针 p = NULL。


q编写一函数,功能为:在字符串中查找该字符。若有相同字符

head

pNode

p

NULL

NULL

插入结点:

pNode->next = p;

q->next = pNode;


6. 编写一函数,功能为:在字符串中查找该字符。若有相同字符链表的释放

  • 对于静态链表,它们所占用的内存空间是由系统自动来分配和释放的;

  • 对于动态链表,必须由程序员自己来进行内存的分配与释放。


p编写一函数,功能为:在字符串中查找该字符。若有相同字符

q

p

p

head

q

q

void Destroy( )

{ struct Train_tag *p, *q;

p = head;

while(p != NULL)

{ q = p;

p = p->next;

free(q);

}

}

head = NULL;

DX11089

玩具

5吨

从上海

到深圳

CZ21026

苹果

8吨

从山东

到福建

CY20011

电饭锅

8吨

从上海

到湖南


堆栈与队列编写一函数,功能为:在字符串中查找该字符。若有相同字符

主体说明

  • 堆栈

  • 堆栈的应用

  • 队列

  • 队列的应用


堆栈编写一函数,功能为:在字符串中查找该字符。若有相同字符

  • 只允许在一端插入和删除的线性表

  • 允许插入和删除的一端称为栈顶

  • (top),另一端称栈底(bottom)

  • 特点

  • 后进先出(LIFO)


栈的基本操作编写一函数,功能为:在字符串中查找该字符。若有相同字符

1、初始化 Initiate(s)

2、进栈 push( s,x)

3、退栈 pop ( s)

4、取栈顶元素 gettop( s)

5、判栈是否非空 Notempty( s)

6、置空栈 SETNULL(s)


栈的链接表示 编写一函数,功能为:在字符串中查找该字符。若有相同字符— 链式栈

  • 链式栈无栈满问题,空间可扩充

  • 插入与删除仅在栈顶处执行

  • 链式栈的栈顶在链头

  • 适合于多栈操作


栈的链接存储结构编写一函数,功能为:在字符串中查找该字符。若有相同字符

链栈的结点定义

typedef int elemtype;

typedef struct node

{ elemtype data;

struct node *next;

} slnodetype;


h编写一函数,功能为:在字符串中查找该字符。若有相同字符

h

栈底

p

x

…...

^

链栈的进栈算法

linkstack *PUSHLSTACK(slnodetype *top, elemtype x)

{ slnodetype *p;

p=malloc(sizeof(linkstack));

p->data=x; p->next=h->next;

h->next=p;

return h;

}


top编写一函数,功能为:在字符串中查找该字符。若有相同字符

栈底

top

…...

^

链栈的出栈算法

linkstack *POPLSTACK(slnodetype *top, datatype *datap)

{ slnodetype *p;

if (top->next==NULL)

{printf(“under flow\n”); return NULL;}

else

{p=top->next;

*datap=p->data;

top->next=p->next;

free(p);

return top;

}

}


队列编写一函数,功能为:在字符串中查找该字符。若有相同字符

  • 定义

    • 队列是只允许在一端删除,在另一端插入的顺序表

    • 允许删除的一端叫做队头(front),

    • 允许插入的一端叫做队尾(rear)。

  • 特性

    • 先进先出(FIFO,First In First Out)


队列的基本操作编写一函数,功能为:在字符串中查找该字符。若有相同字符

1、置空队列

2、判定队列是否为空

3、取队列头元素

4、将新元素插入队尾

5、队列头元素出队


队列的链接表示 编写一函数,功能为:在字符串中查找该字符。若有相同字符—链式队列

  • 队头在链头,队尾在链尾。

  • 链式队列在进队时无队满问题,但有队空问题。

  • 队空条件为front == NULL


链队列结点类型定义编写一函数,功能为:在字符串中查找该字符。若有相同字符

typedef struct

{ linklist *front,*rear;

} linkqueue;


链队列置队空编写一函数,功能为:在字符串中查找该字符。若有相同字符

SETNULL(linkqueue *q)

{ q->front=malloc(sizeof(linklist));

q->front->next=NULL;

q->rear=q->front;

}


链队列判队空编写一函数,功能为:在字符串中查找该字符。若有相同字符

int EMPTY(linkqueue *q)

{ if q->front==q->rear)

return(TRUE);

else

return(FALSE);

}


链队列取队头结点编写一函数,功能为:在字符串中查找该字符。若有相同字符

datatype FRONT(linkqueue *q)

{ if (EMPTY(q))

{printf(“queue is empty\n”);return NULL;}

else

return(q->front->next->data);

}


链队列入队编写一函数,功能为:在字符串中查找该字符。若有相同字符

ENQUEUE(linkqueue *q,datatype x)

{ q->rear->next=malloc(sizeof(linklist));

q->rear=q->rear->next;

q->rear->data=x;

q->rear->next=NULL;

}


链队列出队编写一函数,功能为:在字符串中查找该字符。若有相同字符

datatype DEQUEUE(linkqueue *q)

{ linklist *s;

if (EMPTY(q))

{printf(“queue is empty\n”);return NULL;}

else

{ s=q->front;

q->front=q->front->next;

free(s);

return(q->front->data);

}

}


建立一个带有头结点的单向链表,并将存储在字符串建立一个带有头结点的单向链表,并将存储在字符串s中的字符依次转存到链表的各个结点中。然后,按相反顺序输出链表内容。


#include <stdlib.h>建立一个带有头结点的单向链表,并将存储在字符串

struct node {

char data;

struct node *next;

};

(1) create_list(char *s) { /*函数定义首部,确定函数值的返回类型*/

struct node *head,*p,*q;

head=(struct node *) malloc(sizeof(struct node));

p=q=head;

while(*s!='\0')

{ p=(struct node *) malloc(sizeof(struct node)) ;

p->data= (2) ; /*字符串中的字符存到链表中*/

q->next=p;

q= (3) ; /*工作指针q相应后移,为下一个字符转存作准备*/

s++;

}

p->next = NULL ;

return (4) ; /*返回所建立的链表*/

}


void pr_in_reverse_order(struct node *p) /*建立一个带有头结点的单向链表,并将存储在字符串采用递归算法定义*/

{

if(p!=NULL)

{ pr_in_reverse_order(p->next); /*先按相反顺序输出除去第一个节点后的链表内容*/

printf ("%2c", (5) ); /*输出第一个节点内容*/

}

}

void main()

{

char str[] = "link list";

struct node *head;

head = create_list(str);

pr_in_reverse_order(head->next);

}


ad