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++则不会出错误。
- 良好编程习惯: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强制结束程序
1.3.2 字符串和字符串指针
- (color{red}{字符串数组部分会在第11章专门讲解!})
- 关于 agrc和argv,devc++可菜单栏上的运行-->参数打开给主函数输入数据的窗口
1.4 字符串函数的实现
- string length函数:strlen(const char *s) 返回s的字符串长度,不包括结尾的 .
- 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 的位置,不包含终止符 ' '。
更多函数内容可查看手册:https://www.runoob.com/cprogramming/c-function-strchr.html
PTA第三次作业 字符串
此题正确选项是D,但是A和B在编译器中运行时确实能够打印出ABCDE,那么A和B为何不正确那?
A和B中字符的定义都是字符数组的形式,并不是字符串,即末尾都没有‘ ’, 非字符串使用字符串函数puts来输出是不正确的。
但是为何A和B这两种情况反倒能输出正确结果那?puts函数输出字符串专用,遇到‘ ’停止输出,找不到就一直输出。
其实不是涉及到边界对齐,查看下每个字符数组的地址就能看出来了
这就涉及到存储中的边界对齐存储的知识了:
一个字节是8个字符,如果字符数组长度是小于8个,比如例题中的5个,那么因为边界对齐存储原因,该字节中只存放5个字符,剩下的3个字符都为0,使用puts函数输出字符数组时,就会把后面的0识别为‘ ’。而当数组长度是8或者8的倍数时,puts函数找不到后面的0,打印就会出现问题。
如果我们将数组改为8个元素,那么后面的 就需要读取下一个字节中的数据了,对于长度为8个元素或者8的倍数的字符数组使用puts函数,结果就不正确了。
不仅8个字符不正确,连续定义几个字符数组,用puts输出都会不正确
C答案错误是因为指针定义了,但是并没有初始化,指向一个空间,scanf函数反而向空间里写东西。
作业答疑1:NULL是什么?EOF是什么?string.h是什么?
- 宏定义和预编译 课本10.3节有介绍
- 在Devc++中右击NULL找到stdio.h中NULL和EOF的定义
作业答疑2:unix是什么,shell是什么
- 这个文档中有答案 http://c.biancheng.net/view/707.html
- 实验楼里可尝试Linux系统,在Linux系统中也可以使用ctrl+c和ctrl+d
作业答疑3:视频1.4.4 字符串hello,修改p怎么使得输出llo
- 指针p是变量,可指向数组的任何一个位置,并可以从该位置开始加1
- 此种例子还有mooc中的小测验1.1 中的第1题和第4题