结构指针变量作函数参数
将一个结构体变量的值传递给另一个函数,有3个方法:
(1)用结构体变量的成员作参数
(2)用结构体变量作实参
(3)用指向结构体变量(或数组)的指针作实参,将结构体变量(或数组)的地址传给形参
例题: 有一个结构体变量stu,内含学生学号、姓名和3门课程的成绩。通过调用函数print中将它们输出。
#if 1
#include <stdio.h>
#include <string.h>
struct student
{
int num;
char* name;
float score[3];
};
void print(struct student);
void main()
{
struct student stu;
stu.num = 8;
stu.name = "Fishc.com!";
stu.score[0] = 98.5;
stu.score[1] = 99.0;
stu.score[2] = 99.5;
print(stu);
}
void print(struct student stu)
{
printf("\tnum : %d\n", stu.num);
printf("\tname : %s\n", stu.name);
printf("\tscore_1 : %5.2f\n", stu.score[0]);
printf("\tscore_2 : %5.2f\n", stu.score[1]);
printf("\tscore_3 : %5.2f\n", stu.score[2]);
printf("\n");
}
#endif
#if 1
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
struct student
{
int num;
char name[20];
float score[3];
};
void print(struct student *);
void main()
{
struct student stu;
stu.num = 8;
strcpy(stu.name, "Fishc.com!");
stu.score[0] = 98.5;
stu.score[1] = 99.0;
stu.score[2] = 99.5;
print( &stu );
}
void print( struct student *p )
{
printf("\tnum : %d\n", p -> num);
printf("\tname : %s\n", p -> name);
printf("\tscore_1 : %5.2f\n", p -> score[0]);
printf("\tscore_2 : %5.2f\n", p -> score[1]);
printf("\tscore_3 : %5.2f\n", p -> score[2]);
printf("\n");
}
#endif
动态存储分配
在数组一章中,曾介绍过数组的长度是预先定义好的,在整个程序中固定不变。C语言中不允许动态数组类型。
例如: int a[n];
用变量表示长度,想对数组的大小作动态说明,这是错误的。
但是在实际的编程中,往往会发生这种情况,即所需的内存空间取决于实际输入的数据,而无法预先确定。
所以对于这种问题,用数组的办法很难解决!
为了解决上述问题,C语言提供了一些内存管理函数,这些内存管理函数可以按需要动态地分配内存空间,也可把不再使用的空间回收待用,为有效地利用内存资源提供了手段。
常用的内存管理函数有以下三个:
1. 分配内存空间函数 malloc、calloc
2. 释放内存空间函数 free
函数原型为void *malloc(unsigned int size);
其作用是在内存的动态存储区中分配一个长度为size的连续空间(size是一个无符号数)。
此函数的返回值是一个指向分配域起始地址的指针(类型为void)。
如果此函数未能成功地执行(例如内存空间不足),则返回空指针(NULL)。
函数原型为
void *calloc(unsigned n, unsigned size);
其作用是在内存的动态存储区中分配n个长度为size的连续空间。
函数返回一个指向分配域起始地址的指针;
如果分配不成功,返回NULL。
用calloc函数可以为一维数组开辟动态存储空间,n为数组元素个数,每个元素长度为size。
函数原型为void free(void *p);
其作用是释放由p指向的内存区,使这部分内存区能被其他变量使用。
p是最近一次调用calloc或malloc函数时返回的值。
free函数无返回值。
什么是链表?
链表是一种常见的重要的数据结构,是动态地进行存储分配的一种结构。
链表的组成:
头指针:存放一个地址,该地址指向第一个元素
结点:用户需要的实际数据和链接节点的指针
#if 1
#include <stdio.h>
struct student
{
long num;
float score;
struct student* next;
};
void main()
{
struct student a, b, c, *head;
a.num = 10010;
a.score = 97.7;
b.num = 10011;
b.score = 97.8;
c.num = 10012;
c.score = 97.9;
head = &a;
a.next = &b;
b.next = &c;
c.next = NULL;
do
{
printf("%ld %5.1f\n", head->num, head->score);
head = head->next;
}
while (head != NULL);
}
#endif
建立动态链表
所谓建立动态链表是指在程序执行过程中从无到有地建立起一个链表,即一个一个地开辟结点和输入各结点数据,并建立起前后相链的关系。
作业:根据下面的分析写一函数建立一个含有学生(学号,成绩)数据的单向动态链表。
(约定:我们约定学号不会为零,如果输入的学号为0,则表示建立链表的过程完成,该结点不应连接到链表中。)
#if 1
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#define LEN sizeof(struct student)
struct student *creat(); //创建链表
void print(struct student *head); //打印链表
struct student
{
int num;
float score;
struct student *next;
};
int n; //全局变量,用来记录存放了多少数据。
void main()
{
struct student *stu;
stu = creat();
print( stu );
printf("\n\n");
system("pause");
}
struct student *creat()
{
struct student *head;
struct student *p1, *p2;
p1 = p2 = (struct student *)malloc(LEN);
printf("Please enter the num :");
scanf("%d", &p1->num);
printf("Please enter the score :");
scanf("%f", &p1->score);
head = NULL;
n = 0;
while( p1->num )
{
n++;
if( 1 == n )
{
head = p1;
}
else
{
p2->next = p1;
}
p2 = p1;
p1 = (struct student *)malloc(LEN);
printf("\nPlease enter the num :");
scanf("%d", &p1->num);
printf("Please enter the score :");
scanf("%f", &p1->score);
}
p2->next = NULL;
return head;
}
void print(struct student *head)
{
struct student *p;
printf("\nThere are %d records!\n\n", n);
p = head;
if( head )
{
do
{
printf("学号为 %d 的成绩是: %f\n", p->num, p->score);
p = p->next;
}while( p );
}
}
#endif
链表作业很难 需要多次看