第一章第1节:语言入门基础
汇编与C语言
c语言(第一门高级语言偏软件)与汇编语言(低级语言偏硬件)比较
优点:
- 集成化程度更高,代码量更少,开发效率更高
- 程序的可移植性更高
缺点:
-
c语言(方便给人看,集成化程度更高,不方便给机器看)程序运行更慢
-
汇编(不方便给人看,集成化程度更低,方便给机器看)程序运行更快
集成化程度(Python > C++ > C )越高,程序运行越慢
封装上层逻辑、文件批量处理等用更高级语言,底层的具体实现(如要求运算更快对时间要求更高)用c
扩展-如何正确地学习一门编程语言
应该清楚地认识到在实际开发中会用到这门语言所支持的哪一种编程范式,继而沿着这种编程范式进行去学习
编程范式 \编程语言 | C | C++ |
---|---|---|
面向过程(一步步;表现在封装了大量的函数) | 支持 | 支持 |
面向对象 | 不支持 | 支持 |
泛型编程 | 不支持 | 支持 |
函数式编程 | 不支持 | 支持 |
… |
操作系统继承表
C语言为什么nb
- linux(ubuntu)用c开发的
- Unix(mac-os)后期用c重构
输出函数说明
printf 函数
头文件 :stdio.h
原型 :int printf(const char *format, …);
format :格式控制字符串
… :可变参数列表(任意多个参数,可能为0)
返回值 :输出(成功向屏幕打印的)字符的数量
int a = 123;
printf("%d", a);
// printf函数返回值为3
扩展-数据的表现形式与存储形式
int a = 97;
char ch = 'a';
// 不同的表现形式只是给人看的,计算机都是二进制存储
输入函数说明
scanf函数
原型 :int scanf(const char *format, …);
返回值 :成功读入的参数个数(根据定义返回值可为0即成功读入0个参数、而不能为-1)
scanf("hello ");
// 循环读入
while (scanf() != EOF)
while (scanf() != -1)
while (~scanf())
// EOF <=> end of file <=> -1
// 隐藏在文件末尾的文件描述符
~按位取反
注意 :用scanf()时应避免使用%c而用%s即用字符串的第一位去存字符
char ch[10];
scanf("%s", ch);
// ch[0]即为读入字符
随堂练习题-1
请使用printf函数,求解一个数组n的十进制表示的数字位数
源码:
#include<stdio.h>
int main() {
int n;
while (scanf("%d", &n) != EOF) {
//n = printf("%d", n);
//printf(" has %d digits!\n", n);
printf(" has %d digits!\n", printf("%d", n));
}
return 0;
}
运行结果:
源文件命名
编程语言\命名规范 | xxx.c | xxx.cpp |
---|---|---|
c语言 | 支持 | 不支持 |
c++ | 支持 | 支持 |
编译链接执行的基本命令(详见工程项目开发)
// 默认的编译链接命令
gcc/g++ + 源文件名 不报错则会生成一个可执行文件默认叫a.out
// 执行命令
./ + 可执行文件名
linux下一切接文件,哪怕是一个命令如ls
随堂练习题-2
请写一个程序,读入一个行字符串(可能包含空格),输出这个字符串中字符的数量。
多参读入:
scanf()读入(对于人来讲就是输入)多个参数时,根据分隔符如空格逗号回车等来区分
以下代码因将scanf()函数原型的返回值定义:==成功读入的参数==的个数,想当然成了成功读入的字符个数故出错
#include <stdio.h>
int main() {
char str[100] = {0};
//printf("%s has %d characters!", str, scanf("%[^\n]", str));
int res = scanf("%[^\n]", str);
printf("%s has %d characters!", str, res);
return 0;
}
运行结果
正解
#include <stdio.h>
int main() {
char str[100] = {0};
scanf("%[^\n]", str);
printf(" has %d characters!\n", printf("%s", str));
return 0;
}
运行结果
采用循环读入带空格字符串未考虑每次输入后的‘\n’字符
#include <stdio.h>
int main () {
char str[100] = {0};
// 利用scanf()函数原型返回值的定义即成功读入参数的个数来debug
int ret = 0;
while (ret = scanf("%[^\n]", str)) { // 根据debug结果定位出错位置在该行
printf("input %s, ret = %d\n", str, ret);
}
return 0;
}
debug截图
正解
#include <stdio.h>
int main() {
char str[100] = {0};
while (~scanf("%[^\n]", str)) {
getchar();
printf(" has %d characters!\n", printf("%s", str));
}
return 0;
}
运行结果
重定向
// 标准输入重定向:<
// 标准输出重定向:
// > 如果文件存在则覆盖
// >> 如果文件存在则追加到末尾
扩展-c语言中有bool类型吗
有,查cppreference知C99之后支持布尔类型
课后练习
代码演示
#include <stdio.h>
int main() {
int n;
char str[100] = {0};
scanf("%d", &n); // stdin
printf("n = %d\n", n); // stdout stderr
sprintf(str, "%d.%d.%d.%d", 192, 168, 1, 2); // 多用来解决字符串拼接问题
printf("str = %s\n", str);
FILE *fout = fopen("output", "w");
//fprintf(fout, "%s\n", str);
fprintf(stdout, "stdout = %s\n", str);
fprintf(stderr, "stderr = %s\n", str); //
return 0;
}
运行截图
terminal-标准输入与标准输出
文件描述符 | |
---|---|
EOF | -1 |
stdin | 0 |
stdout | 1 |
stderr | 2 |
不带restrict皆为C99前
scanf()函数家族
函数原型 | |
---|---|
int scanf(const char *format, …); | 从stdin读取数据 |
int sscanf(const char *buffer, const char *format, …); | 从空终止字符串buffer读取数据 |
int fscanf(const char *stream, const char *format, …); | 从文件流stream读取数据 |
printf()函数家族
函数原型 | |
---|---|
int printf(const char *format, …); | 写结果到stdout |
int sprintf(char *buffer, const char *format, …); | 写结果到字符串buffer |
int fprintf(FILE *stream, const char *format, …); | 写结果到文件流stream |
文件访问
这里只罗列了一般常见的
函数原型 | |
---|---|
FILE *fopen(const char *filename, const char *mode); | 打开filename(关联到文件系统的文件名-文件所在路径)所指示的文件,并返回指向关联到该文件的文件流的指针。mode(空终止字符串)用于确定文件访问模式 |
int fclose(FILE *stream); | 关闭给定的文件流 |
文件访问模式字符串 | 含义 | 解释 | 若文件已存在 | 若文件不存在 |
---|---|---|---|---|
“r” | 读 | 打开文件以读取 | 从头读 | 打开失败 |
“w” | 写 | 创建文件以写入 | 销毁内容 | 创建新文件 |
“a” | 后附/追加 | 后附/追加到文件 | 写到结尾 | 创建新文件 |
“r+” | 读扩展 | 打开文件以读/写 | 从头读 | 错误 |
“w+” | 写扩展 | 创建文件已读/写 | 销毁内容 | 创建新文件 |
“a+” | 后附扩展 | 打开文件以读/写 | 写到结尾 | 创建新文件 |
不同阶段的学习方法和学习目标
前期靠记笔记,后期在学完了所有内容后要在头脑中建立起知识网络