2020春-C高级--第三周和第四周--内容大纲

1.2.2 动态内存分配

  • 动态内存分配函数:int *a = (int*)malloc(n*sizeof(int));,申请的空间大小以字节为单位。
  • malloc返回结果是void*,需要强制类型转为需要的类型,如果没有申请成功,返回0/NULL,那么你的电脑能申请多大空间那?
  • 申请了空间,一定要记得返回,free()函数返还空间。
  • 良好编程习惯:定义指针就初始化为0或NULL。根据C99中free的定义,free(0/NULL)不会发生任何事也不会出错。若P不是malloc来的,如果释放p,c99的解释这种行为是未定义,有些编译器会出错误,有些比如devc++则不会出错误。
另外,C语言的语法库可查看网页: https://www.runoob.com/cprogramming/c-tutorial.html ,其中关于NULL指针问题的详细信息有
  • 良好编程习惯:malloc后配着free,申请了必须还!

1.3.1 单字符的输入输出

  • putchar()函数打印一个字符,返回值int类型,是大于0的数,表示打印的字符的格式,返回值是-1/EOF(宏EOF的值是-1),表示打印失败,一般不检查putchar的返回值。
  • getchar()函数读入一个字符,返回值int类型,若返回值是-1/EOF,表示读入失败,否则读入成功。
    • 结束输入状态快捷键/输入EOF,Windows:Ctrl+Z,Unix:Ctrl+D
    • Ctrl+C强制结束程序
- 上述程序两种写法等价,另外getchar每次只能读一个字符,但当输入很多个字符时,按下回车会输出输入的字符,主要是因为缓冲区的存在。CPU和键盘之间是有缓冲区的。

1.3.2 字符串和字符串指针

  • \(\color{red}{字符串数组部分会在第11章专门讲解!}\)
  • 关于 agrc和argv,devc++可菜单栏上的运行-->参数打开给主函数输入数据的窗口
- 字符串的定义有字符数组和字符指针两种方式,区别是字符数组定义的字符串在数据区,字符指针定义的字符串在代码区。

1.4 字符串函数的实现

  • string length函数:strlen(const char *s) 返回s的字符串长度,不包括结尾的\0.
  • string compare函数:strcmp(const char *s1,const char *s2),返回值有三种:0表示s1==s2,1表示s1>s2,-1表示s1<s2。注意该函数实质是依次比较字符串中各字符的ascii码。
  • string copy函数:strcpy(char *restrict dst,const char* restrict src), src拷贝到dst,返回dst,restrict表明src和dst不重叠。
  • string concat函数:strcat(char * _restrict Dest,const char * restrict Source),Dest连接Source,返回指针Dest。
  • 字符输入函数gets()和字符输出函数puts()。
  • 字符串搜索函数strchr、strrchr、strstr
    • char *strchr(const char *str, int c) 在参数 str 所指向的字符串中搜索第一次出现字符 c(一个无符号字符)的位置。找到则返回表示c在s中位置的指针,否则返回NULL。
    • char *strrchr(const char *str, int c) 在参数 str 所指向的字符串中搜索最后一次出现字符 c(一个无符号字符)的位置。找到返回位置,未找到返回一个空指针。
    • char *strstr(const char *haystack, const char *needle) 在字符串 haystack 中查找第一次出现字符串 needle 的位置,不包含终止符 '\0'。

更多函数内容可查看手册:https://www.runoob.com/cprogramming/c-function-strchr.html

PTA第三次作业 字符串


此题正确选项是D,但是A和B在编译器中运行时确实能够打印出ABCDE,那么A和B为何不正确那?
A和B中字符的定义都是字符数组的形式,并不是字符串,即末尾都没有‘\0’, 非字符串使用字符串函数puts来输出是不正确的。
但是为何A和B这两种情况反倒能输出正确结果那?puts函数输出字符串专用,遇到‘\0’停止输出,找不到就一直输出。
其实不是涉及到边界对齐,查看下每个字符数组的地址就能看出来了
这就涉及到存储中的边界对齐存储的知识了:

一个字节是8个字符,如果字符数组长度是小于8个,比如例题中的5个,那么因为边界对齐存储原因,该字节中只存放5个字符,剩下的3个字符都为0,使用puts函数输出字符数组时,就会把后面的0识别为‘\0’。而当数组长度是8或者8的倍数时,puts函数找不到后面的0,打印就会出现问题。
如果我们将数组改为8个元素,那么后面的\0就需要读取下一个字节中的数据了,对于长度为8个元素或者8的倍数的字符数组使用puts函数,结果就不正确了。

不仅8个字符不正确,连续定义几个字符数组,用puts输出都会不正确

C答案错误是因为指针定义了,但是并没有初始化,指向一个空间,scanf函数反而向空间里写东西。

作业答疑1:NULL是什么?EOF是什么?string.h是什么?

  • 宏定义和预编译 课本10.3节有介绍
  • 在Devc++中右击NULL找到stdio.h中NULL和EOF的定义
- stdio.h中NULL的定义
- stdio.h中EOF的定义

作业答疑2:unix是什么,shell是什么

作业答疑3:视频1.4.4 字符串hello,修改p怎么使得输出llo

  • 指针p是变量,可指向数组的任何一个位置,并可以从该位置开始加1
  • 此种例子还有mooc中的小测验1.1 中的第1题和第4题

作业答疑4:什么是缓存?

posted on 2020-03-16 07:44  niuxiaoxia  阅读(234)  评论(0编辑  收藏  举报

导航