一、程序remind.c用动态内存实现
1.先回顾13.5中remind.c的实现,如下是自己看书以及自己的体会写成的程序
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#define MSG_LEN 60
#define MAX_REMIND 50
int read_message(char msg_str[],int n);
int main(void)
{
int i,j,num_remind = 0,day; //这里不能忘记num_remind的初始值
char day_str[3],msg_str[MSG_LEN + 1],*reminders[MAX_REMIND];
for(;;)
{
if(num_remind == MAX_REMIND)
{
printf("-- No space left-- \n");
break;
}
printf("Enter day and remind: ");
scanf("%2d",&day);
if(day == 0)
{
break;
}
sprintf(day_str,"%2d",day);
read_message(msg_str,MSG_LEN);
//查找新提醒的合适的插入位置
for(i = 0;i < num_remind; ++ i)
{
if(strcmp(day_str,reminders[i]) < 0)
{
break;
}
}
//移动i后的提醒
for(j = num_remind; j > i; -- j)
{
reminders[j] = reminders[j - 1];
}
reminders[i] = malloc(strlen(msg_str) + 4);
//分配内存后,必须检测是否分配成功,否则程序会出现不可预料的结果
if(reminders[i] == NULL)
{
printf("-- No space left --\n");
exit(EXIT_FAILURE);
}
strcpy(reminders[i],day_str);
strcat(reminders[i]," ");
strcat(reminders[i],msg_str);
++ num_remind;
}
printf("Day Reminder\n");
for(i = 0;i < num_remind; ++ i)
{
printf("%s\n",reminders[i]);
}
//释放动态分配内存
for(i = 0;i != num_remind; ++ i)
{
free(reminders[i]);
}
return 0;
}
int read_message(char msg_str[],int n)
{
char ch;
int i = 0;
while(isspace(ch = getchar()))
;
while(ch != '\n' && i < n)
{
msg_str[i ++] = ch;
ch = getchar();
}
msg_str[i] = '\0';
return i;
}
运行结果:
Enter day and reminders: 24 Susan's birthday
Enter day and reminders: 5 6:00 - Dinner with Marge and Russ
Enter day and reminders: 26 Movie - "Chinatown"
Enter day and reminders: 7 10:30 - Dental appointment
Enter day and reminders: 12 Movie - "Dazed and Confused"
Enter day and reminders: 5 Saturday class
Enter day and reminders: 12 Saturday class
Enter day and reminders: 0
Day Reminder
5 Saturday class
5 6:00 - Dinner with Marge and Russ
7 10:30 - Dental appointment
12 Saturday class
12 Movie - "Dazed and Confused"
24 Susan's birthday
26 Movie - "Chinatown"
下面是自己的写的dynamic storage版本的:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#define MSG_LEN 60
#define MAX_REMIND 50
int read_message(char msg_str[],int n);
int main(void)
{
int i,j,num_remind = 0,day; //这里不能忘记num_remind的初始值
char day_str[3],msg_str[MSG_LEN + 1],*reminders[MAX_REMIND];
for(;;)
{
printf("Enter day and remind: ");
scanf("%2d",&day);
if(day == 0)
{
break;
}
sprintf(day_str,"%2d",day);
read_message(msg_str,MSG_LEN);
//查找新提醒的合适的插入位置
for(i = 0;i < num_remind; ++ i)
{
if(strcmp(day_str,reminders[i]) < 0)
{
break;
}
}
//移动i后的提醒
for(j = num_remind; j > i; -- j)
{
reminders[j] = reminders[j - 1];
}
reminders[i] = malloc(strlen(msg_str) + 4);
//分配内存后,必须检测是否分配成功,否则程序会出现不可预料的结果
if(reminders[i] == NULL)
{
printf("-- No space left --\n");
exit(EXIT_FAILURE);
}
strcpy(reminders[i],day_str);
strcat(reminders[i]," ");
strcat(reminders[i],msg_str);
++ num_remind;
}
printf("Day Reminder\n");
for(i = 0;i < num_remind; ++ i)
{
printf("%s\n",reminders[i]);
}
//释放动态分配内存
for(i = 0;i != num_remind; ++ i)
{
free(reminders[i]);
}
return 0;
}
int read_message(char msg_str[],int n)
{
char ch;
int i = 0;
while(isspace(ch = getchar()))
;
while(ch != '\n' && i < n)
{
msg_str[i ++] = ch;
ch = getchar();
}
msg_str[i] = '\0';
return i;
}
运行结果:
Enter day and remind: 12 j89adfjia9psdfjasdf
Enter day and remind: 23 jiasdmfioasdf
Enter day and remind: 4 ajiosdfmiopasdmf asdf
Enter day and remind: 56 jiasmdfio;asdf asdf
Enter day and remind: 13 jioasmdf;ioasdf asdf
Enter day and remind: 2 jiouasdnmfio;asdf as
Enter day and remind: 0
Day Reminder
2 jiouasdnmfio;asdf as
4 ajiosdfmiopasdmf asdf
12 j89adfjia9psdfjasdf
13 jioasmdf;ioasdf asdf
23 jiasdmfioasdf
56 jiasmdfio;asdf asdf
下面自己第一次复习动态分配内存建立链表的一个例子?一编译就错了?错在哪里了?
找到答案了,原来是把问面名给弄错了。c文件的后缀是.c,如果写成c++,gcc编译器就会报错了。
下面是自己改正后的代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
static int cnt = 0;
struct node {
int value;
struct node * next;
};
//插入后,首节点就是实实在在的首节点,没有头节点
struct node * add_node(struct node * list,int n)
{
struct node * new_node = malloc(sizeof(struct node));
if(new_node == NULL)
{
printf("-- no space left --\n");
exit(EXIT_FAILURE);
}
new_node -> value = n;
new_node -> next = list;
++ cnt;
return new_node;
}
//print a link list 's data
void print(struct node * list)
{
struct node * ptr;
//ptr = list不能换成 ptr = list -> next
for(ptr = list; ptr != NULL ; ptr = ptr -> next)
{
printf("%d\n",ptr -> value);
}
}
int main()
{
struct node * ptr = NULL;
struct node * ret = add_node(ptr,10);
ret = add_node(ret,20);
ret = add_node(ret,30);
print(ret);
return 0;
}
自己编写的另一个程序,给一个链表的基础上增加一个链表。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
static int cnt = 0;
struct node {
int value;
struct node * next;
};
struct node * add_node(struct node * list,int n)
{
struct node * new_node = malloc(sizeof(struct node));
if(new_node == NULL)
{
printf("-- no space left --\n");
exit(EXIT_FAILURE);
}
new_node -> value = n;
new_node -> next = list;
++ cnt;
return new_node;
}
//print a link list 's data
void print(struct node * list)
{
struct node * ptr;
//ptr = list不能换成 ptr = list -> next
for(ptr = list; ptr != NULL ; ptr = ptr -> next)
{
printf("%d\n",ptr -> value);
}
}
//在link list ptr的基础上,添加一些列数据,如果ptr ==NULL
//相当于直接创建一个新的 link list
struct node *add_list(struct node * ptr)
{
int n;
struct node * new_node = NULL;
for(;;)
{
printf("enter a integer number:");
scanf("%d",&n);
if(n == 0)
return ptr;
new_node = malloc(sizeof(struct node));
if(new_node == NULL)
{
printf(" --no space left --\n");
exit(EXIT_FAILURE);
}
new_node -> value = n;
new_node -> next = ptr;
ptr = new_node;
}
}
int main()
{
struct node * ptr = add_list(NULL);
print(ptr);
return 0;
}
17.3.3函数指针的其他用途
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
void tabulate(double (*f)(double),double,double,double);
int main()
{
double final,increment,initial;
printf("Enter initial value:");
scanf("%lf",&initial);
printf("Enter final value:");
scanf("%lf",&final);
printf("Enter increment:");
scanf("%lf",&increment);
printf(" x sin(x)\n"
"_ _ _ _ _ _ _ _\n");
tabulate(&sin,initial,final,increment);
printf(" x cos(x)\n"
"_ _ _ _ _ _ _ _\n");
tabulate(&cos,initial,final,increment);
printf(" x tan(x)\n"
"_ _ _ _ _ _ _ _\n");
tabulate(&tan,initial,final,increment);
return 0;
}
void tabulate(double (*f)(double),double first,double last,double incr)
{
double x;
int i,num_increment;
num_increment = ceil((last - first) / incr);
for(i = 0; i <= num_increment; ++ i)
{
x = first + i * incr;
printf("%10.5f %10.5f\n",x,(*f)(x));
}
}
注:gcc编译器中命令行结尾需要加 -lm,如下所示(123是编译后可执行文件名称):
[r@localhost 17]$ gcc 2.c -o 123 -lm
运行结果:
Enter initial value:0
Enter final value:.5
Enter increment:.1
x sin(x)
_ _ _ _ _ _ _ _
0.00000 0.00000
0.10000 0.09983
0.20000 0.19867
0.30000 0.29552
0.40000 0.38942
0.50000 0.47943
x cos(x)
_ _ _ _ _ _ _ _
0.00000 1.00000
0.10000 0.99500
0.20000 0.98007
0.30000 0.95534
0.40000 0.92106
0.50000 0.87758
x tan(x)
_ _ _ _ _ _ _ _
0.00000 0.00000
0.10000 0.10033
0.20000 0.20271
0.30000 0.30934
0.40000 0.42279
0.50000 0.54630
关于qsort函数的使用方法:
qsort原型:
void qsort(void *base,size_t nmem,size_t size,int (*compare)(const void*,const void *));
各参数介绍(注意原型中很有很多通用指针void*)
base:必须指向数组的第一个元素(如果是对数组的一段区域进行排序,那么base指向这段区域的第一个元素),在一般的情况下,base就是数组的名字。
nmem:是要排序的元素的数量(不一定是数组中元素的数量)。
size是每个数组的元素的大小,用字节衡量。
compare是指向比较函数的指针。
例题1.把一个整数数组进行排序。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int compareInt(const void *p,const void *q )
{
return *((int *)p) - *((int *)q);
}
int main()
{
int a[] = {1,2,100,3,45,67};
qsort(a,sizeof(a) / sizeof(a[0]),sizeof(a[0]),compareInt);
int i;
for(i = 0;i != 6; ++ i)
{
printf("%d ",a[i]);
}
return 0;
}
例题2.对字符数组(内放c型字符串)进行排序
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int compareChar(const void* p,const void *q)
{
return *((char*)p) - *((char*)q);
}
int main()
{
char arr[] = "asdfaajklx";
size_t sz = sizeof(arr) / sizeof(arr[0]);
//因为sizeof把数组末尾的\0也算在内了,所以长度是sz-1
qsort(arr,sz - 1,sizeof(char),compareChar); //如果长度传入sz,那么原来数组末尾的\0也参与排序,
//原来数组将不会以\0结尾了,用%s输入时候直接空
int i;
printf("%s",arr);
return 0;
}
运行结果:
aaadfjklsx
解决方法:改正compareString,解释如下:
//这里注意:p和q中存放指向元素的指针,本题中元素类型是char*,所以元素指针类型是char**,
//char**再经过解引用即可转换成char*类型,char*类型字符串即可采用strcmp比较大小,如下:
int compareString(const void* p,const void *q)
{
return strcmp(*(char**)p,*(char**)q);//先转换成元素的指针类型,char**
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)