欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 艺术 > C语言家教记录(八)

C语言家教记录(八)

2024/10/24 11:15:07 来源:https://blog.csdn.net/C_eeking/article/details/141330904  浏览:    关键词:C语言家教记录(八)

C语言家教记录(八)

  • 导语
  • 指针的高级应用
    • 动态分配、使用、释放
    • 链表
    • 指向指针的指针
    • 指向函数的指针
  • 流和文件
    • 文件操作
    • 变量和格式化io
  • 总结和复习

导语

本次授课的内容如下:指针的高级应用,流和文件

辅助教材为 《C语言程序设计现代方法(第2版)》

指针的高级应用

动态分配、使用、释放

malloc,calloc(一般不用),realloc(一般不用)
null 空指针,也可以用0

null的使用

if(p==NULL)
if(!p)
if(p!=NULL)
if(p)

malloc的使用

p=malloc(n+1);//不常用
p=(char*)malloc(n+1);//常用,malloc的分配单位是字节int* a;
a=malloc(n*sizeof(int));
for(int i=0;i<n;i++)a[i]=0;

calloc的使用

a=calloc(n,sizeof(int));//自动初始化
struct point { int x, y; } *p;
p = calloc(1, sizeof(struct point));//x,y都为0

realloc的使用,规则见书

realloc(p,n*sizeof(int));

释放存储空间,例子见书

p=malloc();
q=malloc();
free(p);
p=q;char*p=malloc(...);
free(p);
strcpy(p,"abc");//报错,悬空指针问题

示例程序

char *concat(const char *s1, const char *s2)
{char *result ;result = malloc(strlen(s1) + strlen(s2) + 1);if (result == NULL) {printf("Error: malloc failed in concat\n");exit (EXIT_FAILURE);}strcpy(result, s1);strcat(result, s2);return result;
}
p=concat("abs","def");

链表

概念和例子见书

struct node
{int value;struct node *next;
};//链表的节点定义
struct node* first =NULL;//节点的创建,图见书
struct node* p;
p=malloc(sizeof(struct node));
(*p).value=10;
//等价于
p->value=10;

示例程序

解释插入链表的实现,解释图

struct node *add_to_list(struct node *list, int n)
{struct node *new_node;new_node = malloc(sizeof(struct node));if (new_node == NULL) {printf("Error: malloc failed in add_to list\n");exit(EXIT_FAILURE);}new_node->value = n;new_node->next = list;return new_node;
}

搜索链表,用书上例子解释

struct node *search_list(struct node *list, int n)
{struct node *p;for (p = list; p != NULL; p = p->next)if (p->value == n)return p;return NULL;
}struct node *search_list(struct node *list, int n)
{while (list != NULL && list->value != n)list = list->next;return list;
}

删除节点,根据书上例子

struct node *delete_from_list(struct node *list, int n)
{struct node *cur, *prev;for (cur = list, prev = NULL;cur != NULL && cur->value != n;prev = cur, cur = cur->next);if (cur == NULL)return list; /* n was not found */if (prev == NULL)list = list->next; /* n is in the first node */elseprev->next = cur->next; /* n is in some other node */free (cur);return list;
}

指向指针的指针

如果不进行返回,添加结点可能会失效,见书上例子

void_add_to_list(struct node **list, int n)
{struct node *new_node;new_node = malloc(sizeof(struct node));if (new_node == NULL) {printf("Error: malloc failed in add_to_list\n");exit(EXIT_FAILURE);}new_node->value = n;new_node->next = *list;*list = new_node;
}

指向函数的指针

void (*pf)(int);
pf=f;//赋值
(*pf)(i);//调用
pf(i);//调用
//pf 可以指向任何带有int 型形式参数并且返回void 型值的函数double integrate(double (*f)(double), double a, double b);
double integrate(double f(double), double a, double b);//等价result=integrate(sin,0.0,PI/2);integrate内可以调用
y=(*f)(x);

qsort函数

void qsort(void *base, size_t nmemb, size_t size,int (*compar) (const void *, const void *));//函数原型qsort(inventory, num_parts, sizeof(struct part), compare_parts);//调用格式int compare_parts(const void *p, const void *q)
{const struct part *p1 = p;const struct part *q1 = q;if (p1->number < q1->number)return -1;else if (p1->number == q1->number)return 0;elsereturn 1;
}
//等价于
int compare_parts(const void *p, const void *q)
{return strcmp(((struct part *) p)->name,((struct part *) q)->name);
}

流和文件

stdin,stdout,stderr简单介绍

简单介绍二进制文件

简单介绍输入输出重定向和命令行

文件操作

fopen,fclose,freopen等
tmpfile,fflush,remove,rename跳过

FILE *fopen(const char * restrict filename, const char * restrictmode);//函数原型fp=fopen("a.txt","r");//路径和模式,运行之后输入从键盘改成文件
//解释参数r w a r+ w+ a+,参数可以组合int fclose(FILE *stream);//关闭文件FILE *freopen(const char * restrict filename, const char * restrict mode, FILE * restrict stream);//重定向if (freopen("foo","w", stdout) == NULL) {/* error; foo can't be opened */
}//最好先关闭再重定向//解释从命令行获取文件名
int main(int argc, char *argv[])
{...
}

示例程序

#include <stdio.h>
#include <stdlib.h>
#define FILE_NAME "example.dat"
int main(void)
{FILE *fp;fp = fopen(FILE_NAME, "r");if (fp == NULL) {printf("Can't open %s\n", FILE_NAME);exit(EXIT_FAILURE);}...fclose(fp);return 0;
}#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{FILE *fp;if (argc != 2) {printf("usage: canopen filename\n");exit (EXIT_FAILURE);}if ((fp = fopen(argv[1], "r")) == NULL) {printf("%s can't be opened\n", argv[1]);exit (EXIT_FAILURE);}printf("%s can be opened\n", argv[1]);fclose(fp);return 0;
}

变量和格式化io

简介fprintf和printf,见书

简介fscanf和scanf,见书

简介fputc,putc,putchar,fgets,gets

sprintf,snprintf,针对字符数组的输出

sscanf,针对字符数组的输入

文件定位和块输入输出跳过,简单勾一下

示例程序

#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{FILE *source_fp, *dest_fp;int ch;if (argc != 3) {fprintf(stderr, "usage: fcopy source dest\n");exit(EXIT_FAILURE);}if ((source_fp = fopen(argv[1], "rb")) == NULL) {fprintf (stderr, "Can't open %s\n", argv[1]);exit(EXIT_FAILURE);}if ((dest_fp = fopen(argv[2], "wb")) == NULL) {fprintf (stderr, "Can't open %s\n", argv[2]);fclose(source_fp);exit(EXIT_FAILURE);}while ((ch = getc(source_fp)) != EOF)putc (ch, dest_fp);fclose(source_fp);fclose(dest_fp);return 0;
}

总结和复习

本次授课讲述第17章和第22章内容,关键点:指针的高级应用和输入输出

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com