Bo2SS

Bo2SS

1 语言入门基础

课程内容#

C 语言概述#

  • 为什么要学 C 语言?
汇编语言C 语言(编译型语言、高级语言)
强依赖于硬件设备 - 寄存器可移植性
直接与寄存器等沟通,代码复杂,效率更高简单、可读、开发效率高
举例:想与外国人交流
学英语找翻译
  • C 的重要性

    • 先有 C,再有 Linux
      • 操作系统 Unix 收费,所以有 Linux,李纳斯开发的
      • Linux 底层是用 C 语言实现的
    • Java、C++、Python 底层都是 C
      PS:Mac OS 是基于 Unix 的
  • 学习思维逻辑、编程范式

    • 而不仅仅是语法
    • C 语言只支持一种:面向过程
    • C++ 支持四种:面向过程、面向对象、泛型编程、函数式编程

输入与输出函数#

类比人的听、说

  • 输出函数:printf
头文件stdio.h
⭐原型int printf(const char *format, ...);输出的都是字符
返回值,int,成功输出的字符数'\n' 是一个字符
参数 1,format,格式控制字符串
可变参数列表,...合法语句,可以通过编译
  • 输入函数:scanf
头文件stdio.h
⭐原型int scanf(const char *format, ...);
返回值,int,成功读入的参数个数<0,不合法;≥0,合法(包括 0)
while(scanf(...) != EOF)-1 <=> EOF (隐藏的文件描述符)
  • 键盘输入文件结束符 EOF:
      1. Unix:Ctrl+D
      1. Windows:Ctrl+Z
  • 也可以使用 Ctrl+C 中断循环

C 语言文档与编码规范#

  • 利用维基百科查看函数

  • cpp reference 权威文档

  • 编码规范(more code, more bug)谷歌是爸爸

    • 百度 + 谷歌
    • 阿里 + 谷歌
    • 降低 bug 率
  • 工具书(1 个月足矣;该书为跨界编写)

    • 图片

随堂练习#

  • 图片
  • 不用 while 函数,可以直接使用 printf 的返回值
  • printf () 嵌套
  • 代码
图片
  • 图片
  1. %[^\n]s

// 目的:
char str[100] ={0};
scanf ("% s", str); // 遇到空格等分隔符就会进入下一个参数的赋值
scanf ("%[^\n] s", str); // 可以把空格当做字符读取,[] 后的 s 可有可无

|[]| 字符匹配集 |
|:----:|:----|:----:|:----|
|^| 取非 / 除了 |
|\n | 换行符 |

  1. 当循环读入时,会有问题

while (scanf("%[^\n]s", str) != EOF) {
...
}

  • 输入 Hello World,输出不会停止,一直循环输出 Hello World
  1. 因为 \n 被当做分隔符进入下一个参数的赋值,但 \n 不会被吞掉

自己的理解思路,与上面有点出入

  • 将 scanf 的输出显示,可以看到只有第一次成功读入了 1 个参数,后面全是 0

  • 图片
  • 按照我的理解,\n 如果在正则里被【取非】了后,就无法把 \n 读进去了,但是会当成分隔符,所以进入输出语句,但一直读不进,所以又卡在那循环读入;

  • 而没有正则的时候,\n 被当做分隔符读入,且继续读取下一个字符,所以停止了,只是遇到空格就会进入到下一个参数的赋值。

  • 图片
  1. 使用 getchar (),可以吞掉一个字符,比如 \n

    • 打印 getchar () 的值,可以发现吞掉的是 \n,这样继续读取下一行了
  • 图片
  • 红框为输出被吞掉的字符:\n,可见下图代码的 15~20 行

  • 也许也可以通过循环读取 char 的方式来读取包含空格的字符串,使用二维字符数组,遇到 \n 就进入下一行。

  • 另一个角度的思考,参考scanf 中的 \n 问题-CSDN

  • 代码

  • 图片

亮点笔记#

  • scanf 利用分隔符(空格、换行等)来分隔几个变量输入
  • 赋值运算符(=,-= 等)的优先级很低(结合方向:右到左),低于 == 运算符
  • 赋值运算符形成的表达式的值就是所赋的值

int ret;
printf("%d\n", ret = 3);
// 输出 3

  • ./a.out > output 可以将输出放在 output 文件里(覆盖原文件),而不显示在终端

    • > 的含义是标准输出重定向
  • vim 基本操作,可进行 vimtutor 练习,见石墨文档 -Linux 下常用命令:Vim

  • printf () 的格式控制字符串中,如果不用 \n,末尾有个 %

    • 这个百分号是 shell 给你加的,因为你自己没有输入换行。

​ 想想如果你没输入换行的话,shell 后面的那个提示符它是不是应该紧接着你的输出 (如 hello word) 去写,显得乱

  • 注意:% c 慎用,什么都会读进去

代码演示#

printf 函数#

printf 家族基础知识#

  • printf:打印到标准输出(stdout)

图片

  • spirnf:打印到字符串(string)
    • 可用于字符串拼接
    • sprintf(str, "", ...);
  • fprintf:打印到文件中(file)
    • 先打开文件,fopen:w 写,r 读,a 追加
      • 返回 FILE 类型的指针
    • fprintf (FILE 指针,"", ...);
    • “...”:读变参列表变量的地址
      • 字符串变量本身传的就是其首地址
图片

int main()
{
FILE* fp;
int i = 617;
char* s = "that is a good new";
fp = fopen("text.dat", "w");
fprintf (fp, "% d\n", i); // 传变量名即可,不用传地址
fprintf(fp, "%s", s);
fclose (fp); // 记得与 fclose 呼应,关闭文件
return 0;
}

练习#

  1. 根据 n 的末尾三位二进制的值,给 str 分别加不同类型的括号
  • 图片
  • n 的定义在 printf 开头部分

  • 使用宏定义方式定义 swap 函数

  • 图片

  • __typeof 获取变量类型,直接用来声明中间变量的类型

  • sprintf 的两个参数不能一样?

    • 💡名字不能一样
      • 如果前后参数都用 str,见下:
  • 图片
  • 结果如下:其中,() 里的值长度与原值一样,输出的内容 ()似乎会覆盖原来的内容

    • 图片
    • 一定要用指针的方式传地址?
      • 如果直接使用变量,可以,见下:
  • 图片
      • 但是有多个条件判断,琢磨琢磨不用指针的话,交换字符数组好弄吗???
        • ❓其实字符数组的变量名代表的就是字符数组首地址,可以直接交换地址?失败告终,应该是不行的,毕竟数组怎么会轻易移动,但可以移动指向数组的指针
        • 所以还是学会用指针~
        • fprintf 的 FILE 指针也可以是 stdout 和 stderr
  • 图片
      • 最后输出如下:
  • 图片
      • stdout 和 stderr 有什么区别呢?
        • 可以使用 > 将标准输出 stdout重定向,对于 stderr 不会重定向,见下:
  • 图片

​ ⭐:可以单独看 error 信息,而屏蔽掉大量的正常输出

        • 同样,也可以使用 2> 只将错误输出重定向,见下:
  • 图片

附加知识点#

思考点#

  • 为什么 scanf 中参数列表要传地址?
    • scanf 需要修改参数的值,如果传值的话,将无法改变其值
加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。