二手书到了,好消息,前主人看的很认真,坏消息,只看到这页了
啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊最后几题好难啊啊啊啊啊,再议
目录
1.1 入门
1.2 变量与算数表达式
练习1-3 //打印温度对照表
练习1-4 //摄氏-华氏温度对照表【只输出了0-120,负数没有输出】
1.3 FOR语句
练习1-5 //温度对照表-逆序
1.4 符号常量
1.5 字符输入/输出
1.5.1 文件复制
练习1-6 //(c=getchar())!=EOF)等于0 OR 1
练习1-7 //打印EOF数值
参考答案:
1.5.2 字符计数
1.5.3行计数
练习1-8 //统计各种字符
练习1-9 //输入复制到输出,一个空格代替连续多个
练习1-10 //制表回退符替换输出
BUG:\B无法输入(读入不行--【用 下面的_getch()替换getchar(),因为 getchar() 函数输入流先处理了。】--这个东西也奇奇怪怪的反正,暂时搞不懂,
1.5.4 单词计数
练习1-11 如何测试单词计数程序,如果存在错误,什么样的输入最有可能发现错误
参考答案:
练习1-12 每行一个单词打印其输入
1.6 数组
练习1-13 打印单词长度直方图【水平竖直】
0.1 横向-只统计单词,THAT'S属于五个长度的一个单词
0.2 竖向——使用数组,有限制
练习1-14 打印字符出现频度直方图
1.7 函数
练习1-15,函数实现温度转换计算
1.8 参数——传值调用
1.9 字符数组
练习1-16 修改MAIN,使之可以打印任意长度输入行的长度,并尽可能多打印文本
错误--GPT版本:
参考答案:
练习1-17 打印长度大于80字符所有行
练习1-18 删除每个输入行末尾的的空格及制表符,删除完全是空格的行
练习1-19 函数reserve(s),颠倒字符串s的字符顺序,写程序每次颠倒一个输入行中的字符顺序
1.10 外部变量与作用域
1.1 入门
源程序.C,可执行文件A,OUT,
结构:标准库【头文件】,函数,语句,返回值
转义字符:\b \n \\ \"
#include <stdio.h>
int main(int argc, char *argv[]) {
printf("\t \\ \"hello,,\bworld\" \\ \n");
return 0;
}
1.2 变量与算数表达式
声明;变量:整型 INT-16,-32768~+32767 浮点型 FLOAT- 32 字符char【一个字节】 短整型short 长整型long 双精度浮点型double
WHILE循环语句
整型算数运算,舍位,浮点算数运算
打印格式:%6d六个字符宽 %.2d两位小数 %6.2d【&】 %o八进制 %x十六进制 %c字符 %s字符串 %%【%】
练习1-3 //打印温度对照表
#include <stdio.h>
int main(int argc, char *argv[]) {
int fahr;
double celsius;
int lower,upper,step;
lower=0;
upper=300;
step=20;
fahr=lower;
printf("华氏温度-摄氏温度对照表\n\n");
while(fahr<=upper){
celsius=5.0*(fahr-32)/9.0;
printf("%6d\t%6.2f\n",fahr,celsius);
fahr+=step;
}
return 0;
}
练习1-4 //摄氏-华氏温度对照表【只输出了0-120,负数没有输出】
#include <stdio.h>
int main(int argc, char *argv[]) {
//0,20……300打印温度对照表
double fahr;
int celsius;
int lower,upper,step;
lower=-20;
upper=120;
step=5;
fahr=lower;
printf("摄氏温度-华氏温度对照表\n\n");
while(celsius<=upper){
fahr=(9.0*celsius/5.0)+32;
printf("%6d\t%6.0f\n",celsius,fahr);
celsius+=step;
}
return 0;
}
1.3 FOR语句
允许使用某种类型变量值的任何场合,都可以使用该类型的更复杂的表达式
练习1-5 //温度对照表-逆序
#include <stdio.h>
int main(int argc, char *argv[]) {
int fahr;
double celsius;
int lower,upper,step;
lower=0;
upper=300;
step=20;
printf("华氏温度-摄氏温度对照表\n\n");
for(fahr=upper;fahr>=lower;fahr-=step)
{
celsius=5.0*(fahr-32)/9.0;
printf("%6d\t%6.2f\n",fahr,celsius);
}
return 0;
}
1.4 符号常量
#include <stdio.h>//温度对照表
#define LOWER 0
#define STEP 20
#define UPPER 300
int main(int argc, char *argv[]) {
int fahr;
double celsius;
printf("华氏温度-摄氏温度对照表\n\n");
for(fahr=UPPER;fahr>=LOWER;fahr-=STEP)
{
celsius=5.0*(fahr-32)/9.0;
printf("%6d\t%6.2f\n",fahr,celsius);
}
return 0;
}
1.5 字符输入/输出
文本流,行末是一个换行符
#include <stdio.h>//一次读写一个字符
int main(int argc, char *argv[]) {
int c;
c=getchar();
putchar(c);
return 0;
}
1.5.1 文件复制
EOF=end of file
【\N和EOF】没有关系,见20240321,行编辑,SHELL只有在换行符之后,才会把暂存的东西输给用户,但是循环还在继续】
#include <stdio.h>//一次读写一串
int main(int argc, char *argv[]) {
int c;
c=getchar();
while(c!=EOF) {
putchar(c);
c=getchar();
}
return 0;
}
#include <stdio.h>
int main(int argc, char *argv[]) {
int c;
while((c=getchar())!=EOF) {
putchar(c);
}
return 0;
}
练习1-6 //(c=getchar())!=EOF)等于0 OR 1
#include <stdio.h>
int main(int argc, char *argv[]) {
int c;
while(((c=getchar())!=EOF)==1) {
putchar(c);
}
return 0;
}
练习1-7 //打印EOF数值
【空格直接结束,ctrl^z输出-1】
#include <stdio.h>
int main(int argc, char *argv[]) {
int c;
while((c=getchar())==EOF) {
printf("%d\n",c);
}
return 0;
}
参考答案:
#include <stdio.h>
int main() {
printf("EOF is %d\n",EOF);
return 0;
}
1.5.2 字符计数
long-->%ld,float,double-->%.0f
空语句
要先ENTER,再^Z,才能输出,空格算一个字符
^Z之后的字符都不计数,但是空格计数,^Z也不计数;紧挨着^Z的最后一个\N不算
4月10回来补充,男神的SHELL,行编辑说清楚了
#include <stdio.h>//字符计数1
int main(int argc, char *argv[]) {
long nc=0;
while(getchar()!=EOF)
nc++;
printf("%ld\n",nc);
return 0;
}
#include <stdio.h>//字符计数2
int main(int argc, char *argv[]) {
double nc=0;
for(nc=0;getchar()!=EOF;nc++)
;
printf("%.0f\n",nc);
return 0;
}
1.5.3行计数
==,字符常量‘A’==56,ASCII字符表,‘\N’==10
#include <stdio.h>
int main(int argc, char *argv[]) {
int nl=0;
int c;
while((c=getchar())!=EOF){
if(c=='\n')
nl++;
}
printf("换行符=%d\n",nl);
return 0;
}
练习1-8 //统计各种字符
【不能在括号里面再直接用getchar()=='\n',每次执行GETCHAR都是要输入的】
#include <stdio.h>
int main(int argc, char *argv[]) {
int nl=0;
int nt=0;
int nk=0;
int c;
while((c=getchar())!=EOF){
if(c=='\n')
nl++;
else if(c=='\t')
nt++;
else if(c==' ')
nk++;
}
printf("空格=%d,制表符=%d,换行符=%d\n",nk,nt,nl);
return 0;
}
练习1-9 //输入复制到输出,一个空格代替连续多个
输入连续的几个空格,只输出一个,因为不知道会有几个,所以是第一个
#include <stdio.h>
int main(int argc, char *argv[]) {
int a;
int cnt=0;
while((a=getchar())!=EOF){
if(a!=' '){
putchar(a);
cnt=0;
}
else{
cnt++;
if(cnt==1)
putchar(a);
else
cnt++;
}
}
return 0;
}
练习1-10 //制表回退符替换输出
转义字符是就是输出的时候识别的,难顶,所以要输出文本“\T,\B,\\"
#include <stdio.h>//错误
int main(int argc, char *argv[]) {
int a;
char b='\b';
char t='\t';
char c='\\';
while((a=getchar())!=EOF){
if(a==t)
putchar('\t');
else if(a==b)
putchar(b);
else if(a==c)
putchar(c);
else
putchar(a);
}
return 0;
}
BUG:\B无法输入(读入
不行--【用 <conio.h> 下面的_getch()替换getchar(),因为 getchar() 函数输入流先处理了。】--这个东西也奇奇怪怪的反正,暂时搞不懂,
#include <stdio.h>
int main(int argc, char *argv[]) {
int a;
while((a=getchar())!=EOF){
if(a=='\t')
printf("\\t");
if(a=='\b')
printf("\\b");
if(a=='\\')
printf("\\\\");//输出\ 输出B
else
putchar(a);
}
return 0;
}
1.5.4 单词计数
&&,||
除第一个单词外,每一个单词一定跟在制表符,换行符,空格的后面,用单词的首字母来计数
#include <stdio.h>
#define IN 0
#define OUT 1
int main(int argc, char *argv[]) {
int a;
int nl,nw,n;
nl=nw=n=0;
int state;
state=OUT;
while((a=getchar())!=EOF){
n++;
if(a=='\n'){
nl++;
}
if(a=='\t'||a=='\n'||a==' '){
state=OUT;
}else if(state==OUT){
state=IN;
nw++;
}
}
printf("行数=%d,单词数=%d,字符数=%d\n",nl,nw,n);
return 0;
}
练习1-11 如何测试单词计数程序,如果存在错误,什么样的输入最有可能发现错误
错误:字符的输入计入单词中
#include <stdio.h>//统计单词
#define OUT 0
#define IN 1
int main(int argc, char *argv[]) {
int c;
int cnt=0;int cnum=0;
int taste=OUT;
while((c=getchar())!=EOF){
if(c>='a'&&c<='z'||c>='A'&&c<='Z'||c=='\''){
taste=IN;
cnt++;
if(cnt==1)
cnum++;
}else{
taste=OUT;
cnt=0;
}
}
printf("单词数%d\n",cnum);
return 0;
}
参考答案:
满足边界条件的输入——包括:
——没有输入(0行,0字符,0单词)
——没有单词(只有换行符)
——没有单词(只有空格,制表,换行符)
——每个单词各占一行(没有空格,制表)
——单词出现在文本行行首
——单词出现于一串空格之后
练习1-12 每行一个单词打印其输入
#include <stdio.h>
int main(int argc, char *argv[]) {
int a;
int cnt=0;
while((a=getchar())!=EOF){
if(a=='\t'||a=='\n'||a==' '){
if(cnt==0)
printf("\n");
cnt++;
}else {
putchar(a);
cnt=0;
}
}
return 0;
}
1.6 数组
else if语句,c-'0'
#include <stdio.h>//统计数字,空白符[空格,制表,换行],及其他字符出现的次数
int main()
{
int c,i,nwhite,nother;
int ndigit[10];
nwhite=nother=0;
for(i=0;i<10;i++){
ndigit[i]=0;
}
while((c=getchar())!=EOF){
if(c==' '||c=='\t'||c=='\n'){
nwhite++;
}else if(c>='0'&&c<='9'){
ndigit[c-'0']++;
}else{
nother++;
}
}
printf("空白符-%d 其他字符%d\n",nwhite,nother);
for(i=1;i<10;i++){
printf("数字%d-%d\n",i,ndigit[i]);
}
return 0;
}
练习1-13 打印单词长度直方图【水平竖直】
0.1 横向-只统计单词,THAT'S属于五个长度的一个单词
#include <stdio.h>//打印单词长度直方图【水平竖直】
int main()
{
int cnt=0;
int i=1;
int c;
while((c=getchar())!=EOF){
if(c>='a'&&c<='z'||c>='A'&&c<='Z'){
if(cnt==0){
printf("单词");
}
cnt++;
}else if(c=='\''){
cnt=cnt;
}else if((c<'a'||c>'z')&&(c>'A'||c<'Z')&&c!='\''&&cnt!=0){
printf("%d\t",i);
i++;
while(cnt>0){
printf("口");
cnt--;
}
printf("\n");
}
}
return 0;
}
0.2 竖向——使用数组,有限制
测试输入 :d dfd df gwge ffdsf sdwesf dwweeef ddskjeda sqwqhjiss weweqwqqaa
#include <stdio.h>//打印单词长度直方图【水平竖直】
int main()
{
int cnt = 0;
int c;
int nword[10] = { 0 };
while ((c = getchar()) != EOF && cnt < 10) {
if (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z') {
nword[cnt]++;
}
else if (c == '\'') {
nword[cnt] = nword[cnt];
}
else if ((c < 'a' || c>'z') && (c > 'A' || c < 'Z') && c != '\'' && nword[cnt] != 0) {
cnt++;
}
}
int max=0;
for (int i = 0; i < 10; i++) {
max = max > nword[i] ? max : nword[i];
}
/*printf("%d\n", max);
for (int i = 0; i < 10; i++) {
printf("%d", nword[i]);
}*/
printf("\n");
for (int i = 0; i < max; i++) {
for (int y = 0; y < 10; y++) {
if (max - nword[y] > 0) {
printf(" \t");
}
else {
printf("口\t");
}
nword[y]++;
}
printf("\n");
}
for (int i = 0; i < 10; i++) {
printf("单词%d ", i);
}
printf("\n");
return 0;
}
练习1-14 打印字符出现频度直方图
#include <stdio.h>//各个字符出现频度
int main()
{
int c;
int nword[24] = { 0 };
while ((c = getchar()) != EOF ) {
if (c >= 'a' && c <= 'z' ) {
nword[c-'a']++;
}
}
for (int i = 0; i < 24; i++) {
printf("%c出现频度\t",i+'a');
while (nword[i] != 0) {
printf("口");
nword[i]--;
}
printf("\n");
}
return 0;
}
1.7 函数
power(m,n)计算整数M的N次幂;函数声明,定义
#include <stdio.h>
#include <stdlib.h>
int power(int m, int n);
int main() {
for (int i = 0; i < 10; i++) {
printf("%d,\t%d,\tx%d\n", i, power(2, i), power(-3, i));
}
return 0;
}
int power(int m, int n) {
int i, p;
p = 1;
for (i= 0; i < n; i++) {
p *= m;
}
return p;
}
练习1-15,函数实现温度转换计算
#include <stdio.h>
#include <stdlib.h>
void cs(int lower, int upper, int step) {
int fahr = lower;
double celsius;
while (fahr <= upper) {
celsius = 5.0 * (fahr - 32) / 9.0;
printf("%6d\t%6.2f\n", fahr, celsius);
fahr += step;
}
}
int main(int argc, char* argv[]) {
int lower, upper, step;
lower = 0;
upper = 300;
step = 20;
printf("华氏温度-摄氏温度对照表\n\n");
cs(lower, upper, step);
return 0;d
}
1.8 参数——传值调用
POWER函数2.0——少一个变量
#include <stdio.h>
#include <stdlib.h>
int power(int m, int n);
int main() {
for (int i = 0; i < 10; i++) {
printf("%d,\t%d,\tx%d\n", i, power(2, i), power(-3, i));
}
return 0;
}
int power(int m, int n) {
int p;
for (p= 1; n >0; n--) {
p *= m;
}
return p;
}
1.9 字符数组
'\0'(空字符)插入数组末尾,标记字符串数组的结束——“h e l l o \n \0"
#include <stdio.h>
#include <stdlib.h>
#define MAXLINE 1000
int getline(char line[], int maxline);
void copy(char to[], char from[]);
/*记录输入中最长的一行,并输出*/
int main() {
int len, max;//当前长度,最长行长度
char line[MAXLINE];//当前输入行
char longest[MAXLINE];//用以保存最长行
max = 0;
while ((len = getline(line, MAXLINE)) > 0) {
if (len > max) {
max = len;
copy(longest, line);//已知行数,不需要检查溢出
}
}
if (max > 0) {
printf("%s", longest);
}
return 0;
}
//将一行读入数组,并返回其长度
int getline(char line[], int maxline) {
int i;
char c;
for (i = 0; i < maxline - 1 && (c = getchar()) != EOF && c != '\n'; ++i) {
line[i] = c;
}
if (c == '\n') { //插入\n
line[i] = c;
++i;
}
line[i] = '\0'; //插入\0
return i;
}
//form复制到to,假设TO足够大
void copy(char to[], char from[]) {
int i = 0;
while ((to[i] = from[i]) != '\0') {
++i;
}
}
练习1-16 修改MAIN,使之可以打印任意长度输入行的长度,并尽可能多打印文本
错误--GPT版本:
getline函数在I=999时会退出函数,大循环还在继续,该方式是每一行都输出,字符串长度超过数组上限会输出999,退出-重新进入循环,//单行处理
#include <stdio.h>
#include <stdlib.h>
#define MAXLINE 1000
int getline(char line[], int maxline);
void copy(char to[], char from[]);
/*记录输入中所有行的长度,并输出*/
int main() {
int len;//当前长度
char line[MAXLINE];//当前输入行
while ((len = getline(line, MAXLINE)) > 0) {
printf("Length of the line: %d\n", len);
printf("Content of the line: %s", line);
}
return 0;
}
//将一行读入数组,并返回其长度
int getline(char line[], int maxline) {
int i;
char c;
for (i = 0; i < maxline - 1 && (c = getchar()) != EOF && c != '\n'; ++i) {
line[i] = c;
}
if (c == '\n') { //插入\n
line[i] = c;
++i;
}
line[i] = '\0'; //插入\0
return i;
}
参考答案:
可以打印任意长度输入行的长度—— i记录字符串的长度,持续记录;J记录被复制到字符串LINE中的的字符的个数,超过996停止
并尽可能多打印文本——最大打印数组容量,原来是这个意思……
输入^Z之后,会输出,最长行的前998个字符
#include <stdio.h>
#include <stdlib.h>
#define MAXLINE 1000
int getline(char line[], int maxline);
void copy(char to[], char from[]);
int main() {
int len, max;
char line[MAXLINE];
char longest[MAXLINE];
max = 0;
while ((len = getline(line, MAXLINE)) > 0) {
printf("%d ,%s",len, line);//修改,打印输入行的长度和尽可能打印数组LINE里的字符
if (len > max) {
max = len;
copy(longest, line);
}
}
if (max > 0) {
printf("%s", longest);
}
return 0;
}
//将一行读入数组,并返回其长度
int getline(char line[], int maxline) {
int i, c, j;
j = 0;
for (i = 0; (c = getchar()) != EOF && c != '\n'; ++i) { //不再检查字符是否超出数组限制,该限制不是循环终止条件
if (i < maxline - 2) { //数组最后一个下标MAXLINE-1,读取了输入字符MAXLINE-2,i最大是MAXLINE-3,加上\N,\0
line[j] = c;
++j;
}
}
if (c == '\n') {
line[j] = c; //插入\n
++j;
++i;
}
line[j] = '\0'; //插入\0 ,J有\0,I没有
return i; //i记录字符串的长度,J记录被复制到字符串LINE中的的字符的个数
}
//form复制到to,假设TO足够大
void copy(char to[], char from[]) {
int i = 0;
while ((to[i] = from[i]) != '\0') {
++i;
}
}
练习1-17 打印长度大于80字符所有行
#include <stdio.h>
#include <stdlib.h>
#define MAXLINE 1000
int getline(char line[], int maxline);
void copy(char to[], char from[]);
int main() {
int len, max;
char line[MAXLINE];
char longest[MAXLINE];
max = 0;
while ((len = getline(line, MAXLINE)) > 0) {
if (len >=80) {
printf("%d ,%s", len, line);
}
}
return 0;
}
//将一行读入数组,并返回其长度
int getline(char line[], int maxline) {
int i, c, j;
j = 0;
for (i = 0; (c = getchar()) != EOF && c != '\n'; ++i) { //不再检查字符是否超出数组限制,该限制不是循环终止条件
if (i < maxline - 2) { //数组最后一个下标MAXLINE-1,读取了输入字符MAXLINE-2,i最大是MAXLINE-3,加上\N,\0
line[j] = c;
++j;
}
}
if (c == '\n') {
line[j] = c; //插入\n
++j;
++i;
}
line[j] = '\0'; //插入\0 ,J有\0,I没有
return i; //i记录字符串的长度,J记录被复制到字符串LINE中的的字符的个数
}
练习1-18 删除每个输入行末尾的的空格及制表符,删除完全是空格的行
无语,答案都看了好几遍才看懂
#include <stdio.h>
#include <stdlib.h>
#define MAXLINE 1000
int getline(char line[], int maxline);
int remove(char s[]);
int main() {
char line[MAXLINE];
while ( getline(line, MAXLINE)> 0) {
if (remove(line) > 0) {
printf("%s", line);
}
}
return 0;
}
//将一行读入数组,并返回其长度
int getline(char line[], int maxline) {
int i, c, j;
j = 0;
for (i = 0; (c = getchar()) != EOF && c != '\n'; ++i) { //不再检查字符是否超出数组限制,该限制不是循环终止条件
if (i < maxline - 2) { //数组最后一个下标MAXLINE-1,读取了输入字符MAXLINE-2,i最大是MAXLINE-3,加上\N,\0
line[j] = c;
++j;
}
}
if (c == '\n') {
line[j] = c; //插入\n
++j;
++i;
}
line[j] = '\0'; //插入\0 ,J有\0,I没有
return i; //i记录字符串的长度,J记录被复制到字符串LINE中的的字符的个数
}
int remove(char s[]) {
int i = 0;
while (s[i] != '\n') //找到换行符,i累加
++i;
--i; //倒退一个位置
while (i >= 0 && (s[i] == ' ' || s[i] == '\t')) //从后向前检查空格或制表符
//直到找到一个不是空格或者没有字符可以让她继续倒退(i<0)为止
--i;
if (i >= 0) { //说明至少还有一个字符
++i;
s[i] = '\n'; //将换行符和字符串结束符写回输入行
++i;
s[i] = '\0';
}
return i;
}
练习1-19 函数reserve(s),颠倒字符串s的字符顺序,写程序每次颠倒一个输入行中的字符顺序
#include <stdio.h>
#define MAXLINE 1000
int getline(char line[], int maxline);
void re(char s[]);
/* 函数reserve(s),颠倒字符串s的字符顺序,写程序每次颠倒一个输入行中的字符顺序*/
int main() {
char line[MAXLINE];
while ( getline(line, MAXLINE)> 0) {
re(line);
printf("%s", line);
}
return 0;
}
int getline(char line[], int maxline) {
int i, c, j;
j = 0;
for (i = 0; (c = getchar()) != EOF && c != '\n'; ++i) { //不再检查字符是否超出数组限制,该限制不是循环终止条件
if (i < maxline - 2) { //数组最后一个下标MAXLINE-1,读取了输入字符MAXLINE-2,i最大是MAXLINE-3,加上\N,\0
line[j] = c;
++j;
}
}
if (c == '\n') {
line[j] = c; //插入\n
++j;
++i;
}
line[j] = '\0'; //插入\0 ,J有\0,I没有
return i; //i记录字符串的长度,J记录被复制到字符串LINE中的的字符的个数
}
void re(char s[]) {
int i = 0;
while (s[i] != '\n') //找到换行符
{
++i;
}
for (int j = i; j >i/2; j--) {
int temp = s[j];
s[j] = s[i - j];
s[i - j] = temp;
}
}
1.10 外部变量与作用域
声明:说明变量的性质,但是不分配存储单元
定义:创建变量或分配存储单元
#include <stdio.h>
#define MAXLINE 1000
//外部变量
int max;
char line[MAXLINE];
char longest[MAXLINE];
int getline(void);
void copy(void);
int main() {
int len;
extern int max;
extern char longest[];
max = 0;
while ((len = getline()) > 0) {
if (len > max) {
max = len;
copy();
}
}
if (max > 0) {
printf("%s", longest);
}
return 0;
}
int getline(void) {
int i;char c;
extern char line[];
for (i = 0; i < MAXLINE - 1 && (c = getchar()) != EOF && c != '\n'; ++i) {
line[i] = c;
}
if (c == '\n') { //插入\n
line[i] = c;
++i;
}
line[i] = '\0'; //插入\0
return i;
}
void copy(void) {
extern char line[], longest[];
int i = 0;
while ((longest[i] = line[i]) != '\0') {
++i;
}
}