Skip to content

c语言笔记

初次开发

介绍

C 语言是一种 编译型语言 ,源码都是文本文件,本身无法执行。 必须通过编译器,生成二进制的可执行文件,才能执行。 目前,最常见的 C 语言编译器是自由软件基金会推出的 GCC 编译器,可以免费使用。Linux 和 Mac 系统可以直接安装 GCC,Windows 系统可以安装 MinGW 。

MinGW和GCC的区别

GCC是一个跨平台的编译器集合,可用于多种操作系统和处理器 架构,包括Windows;而MinGW是GCC在Windows平台上的移植版 本,主要用于在Windows上本地编译C和C++代码。

MinGW

下载MinGW

MinGW下载 直接点击红色区域的按钮下载即可

安装

点击continue

进入下面的对话框,这是一个 名为 “ MinGW Installer Manager ” 的软件,借助它,我们可 以随时根据需要修改 GCC 编译器的配置。 保存 选择“Apply”。然后耐心等待,直至安装成功,即可关闭此界面。

配置环境变量

就是将你的编译器所在的位置配置到环境变量中

创建第一个c工程

创建好之后是下面这样的

运行main.c

插件

C/C++ Single File Execution

当一个工程存在两个main函数时,项目会无法启动 例子:

  • 在chapter01包下创建01_Hello.c文件
  • 将main.c中的helloworld复制到01_Hello.c中
  • 运行01_Hello.c或者main.c,出现下面的报错

安装完成插件后 对着main方法右键===>为这个c/c++文件添加可运行

对着编译好的包点击重新加载

重新运行即可

原理

实际上是在CMakeLists.txt文件中加上了对应的单个c/c++入口文件的路径

c 程序运行机制

编辑

编写C语言源程序代码,并以文件的形式存储到磁盘中。源程序文件以“.c”作为扩展名。

编译

将C语言源程序转换为目标程序(或目标文件)。如果程序没有错误,没有任何提示,就会生成一个扩展名为“.obj”的二进制文件。C语言中的每条可执行语句经过编译后最终都将被转换成二进制的机器指令。

链接/连接

将编译形成的目标文件“.obj”和库函数及其他目录文件连接/链接,形成统一的可执行的二进制文件“.exe”。

为什么需要链接库文件呢?

因为我们的C程序中会使用 C程序库的内容,比如<stdio.h> 、<stdlib.h> 中的函数printf()、system()等,这些函数不是程序员自己写的,而是C程序库中提供的,因此需要链接。链接后,生成的.exe 文件,比obj 文件大了很多。

运行

有了可执行的exe文件,我们可以在控制台下直接运行此exe文件。

注意

对修改后的xxx.c源文件需要重新编译、链接,生成新的exe文件后,再执行,才能生效。

注释

c
// 单行注释
/*  
 * 多行注释  
 * */

代码细节剖析

main函数

  • 每一个程序(或工程)可以定义很多函数(后面讲),但有且只有一个main()函数,作为程序执行的入口,在 main()函数结尾结束整个程序的运行。
  • 空括号(),表示 main 不接受任何参数。
  • 写在main之前的“int”称为关键字,代表数据类型是整型。它是main()的返回值类型。即在执行main()函数后会得到一个整型值(即函数值)。
  • C 语言约定: return 0,表示main()函数终止运行,且运行成功;如果返回其它非零整数,就表示运行失败。默认情况下,如果 main() 里面省略 return 0 这一行,编译器会自动加上,但是为了保持统一的代码风格,不建议省略。

函数体

  • 一对花括号{}定义了函数的主体,所有函数都必须以大括号开头和结尾,成对出现。
  • C 程序中的函数体指的是作为该函数一部分的语句。它可以是任何操作,比如搜索、排序、打印等。
  • 每一个执行语句后面都会有一个英文分号“;”作为语句结束的标志。
  • 一行内可写几条语句,一条语句也可写在几行上。

printf()

printf()函数是产生格式化输出的函数,作用是将参数文本输出到屏幕。它名字里面的 f 代表 format (格式化),表示可以指定输出文本的格式。

c
printf("Hello World"); //将字符串输出到控制台,行尾不换行

// 为了让光标移到下一行的开头,可以在输出文本的结尾,添加一个换行符 \n 。
printf("Hello World\n");

// ①限定宽度
printf("num is %10d\n", 123);//%10d表示有10位数字,默认右对齐
// ①左对齐
printf("num is %-10d\n", 123);//%-10d表示有10位数字,-表示左对齐

printf()标准格式

c
printf(格式控制字符串,输出列表);

其中,

  • "格式控制字符串"是用双引号括起来的一个字符串。包括:
    • 普通字符:普通字符即需要在输出时原样输出的字符。
    • 占位符:由“%”和格式字符组成。这个位置可以用其它值代入。
  • "输出列表"是程序需要输出的一些数据,可以是常量、变量或表达式。用于替换占位符的位置。

注意

printf() 参数与占位符是一一对应关系。如果参数个数少于对应的占位符, printf() 可能会输出内存中的任意值。

占位符

占位符的第一个字符是 % ,第二个字符表示占位符的类型。

printf() 的占位符有许多种类,与 C 语言的数据类型相对应。

下面按照字母顺序,列出占位符如下,方便查阅(红色为常用的):

%a :浮点数(仅C99有效) %A :浮点数(仅C99有效) %c :char型数据%d :十进制整数(int) %e :使用科学计数法的浮点数,指数部分的 e 为小写 %E :使用科学计数法的浮点数,指数部分的 E 为大写 %i :整数,基本等同于 %d %f :浮点数(float) %g :6个有效数字的浮点数。整数部分一旦超过6位,就会自动转为科学计数法,指数部分的 e 为小写 %G :等同于 %g ,唯一的区别是指数部分的 E 为大写 %hd :十进制 short int 类型 %ho :八进制 short int 类型 %hx :十六进制 short int 类型 %hu :unsigned short int 类型 %ld :十进制整数(long) %lo :八进制 long int 类型 %lx :十六进制 long int 类型 %lu :unsigned long int 类型 %lld :十进制 long long int 类型 %llo :八进制 long long int 类型 %llx :十六进制 long long int 类型 %llu :unsigned long long int 类型 %le :科学计数法表示的 long double 类型浮点数 %lf :十进制浮点数(double) %n :已输出的字符串数量。该占位符本身不输出,只将值存储在指定变量之中 %o :八进制整数 %p :指针%s :字符串%u :十进制无符号整数(unsigned int) %x :十六进制整数 %zd: size_t 类型 %% :%%会输出一个百分号

举例

%d
c
int num = 10;  
printf("count is %d\n",num);  //输出:count is 10  

printf("There are %i students\n", 5);   //输出:There are 5 students
%lf 和 %f
c
float f = 3.1415926535f;    // 单精度浮点数  
double d = 3.1415926535;  // 双精度浮点数  

// 使用 %f 输出单精度浮点数  
printf("Float: %f\n", f);  //Float: 3.141593  
// 使用 %lf 输出双精度浮点数  
printf("Double: %lf\n", d); //Double: 3.141593  

// 使用 %f 输出单精度浮点数  
printf("Float: %.8f\n", f);  //Float: 3.14159274  
// 使用 %lf 输出双精度浮点数  
printf("Double: %.8lf\n", d); //Double: 3.14159265
%c
c
char level = 'A';  
printf("this score level is:%c\n",level); //输出:this score level is:A
%s
c
printf("%s是我最喜欢的冷门歌手.\n","孙燕姿"); //输出:孙燕姿是我最喜欢的冷门歌手.
多个占位符

输出文本里面可以使用多个占位符。

c
printf("%s%d部手机\n", "老板", 2); //输出:老板有2部手机

输出格式

printf() 可以定制占位符的输出格式。

限定宽度

printf() 允许限定占位符的最小宽度。

c
printf("%5d\n", 123); // 输出为 "  123"

说明:%5d 表示这个占位符的宽度至少为5位。如果不满5位,对应的值的前面会添加空格。

输出的值默认是右对齐,即输出内容前面会有空格;如果希望改成左对齐,在输出内容后面添加空格,可以在占位符的 % 的后面插入一个 - 号。

c
printf("%-5d\n", 123); // 输出为 "123  "

对于小数,这个限定符会限制所有数字的最小显示宽度

c
printf("%12f\n", 123.45); // 输出 "  123.450000"

%12f 表示输出的浮点数最少要占据12位。由于小数的默认显示精度是小数点后6位,所以123.45 输出结果的头部会添加2个空格。

总是显示正负号

默认情况下, printf() 不对正数显示 + 号,只对负数显示 - 号。如果想让正数也输出 + 号,可以在占位符的 % 后面加一个 + 。

c
printf("%+d\n", 11); // 输出 +11
printf("%+d\n", -11); // 输出 -11
限定小数位数

输出小数时,有时希望限定小数的位数。举例来说,希望小数点后面只保留两位,占位符可以写成 %.2f 。

c
printf("Number is %.2f\n", 0.8); // 输出 Number is 0.80

这种写法可以与限定宽度占位符,结合使用。

c
printf("%6.2f\n", 0.8); // 输出为 "  0.80"

说明:%6.2f 表示输出字符串最小宽度为6,小数位数为2。整体长度不足 6 位时,右对齐显示。

最小宽度和小数位数这两个限定值,都可以用 * 代替,通过 printf() 的参数传入。

c
printf("%*.*f\n", 6, 2, 0.8);
//等同于
printf("%6.2f\n", 0.8);//  0.80

标准库、头文件

printf() 是在标准库的头文件 stdio.h 中定义的。要想在程序中使用这个函数,必须在源文件头部引入这个头文件。

c
#include <stdio.h>

何为标准库

程序需要用到的功能,不一定需要自己编写,C 语言可能已经自带了。程序员只要去调用这些自带的功能就可以了。C 语言自带的所有这些功能,统称为“标准库”(standard library),包含C 内置函数、常量和头文件。 因为它们是写入标准的,到底包括哪些功能,应该怎么使用,都是规定好的,我们直接调用即可。

何为头文件

不同的功能定义在不同的文件里,这些文件统称为“头文件”(header file)。如果系统自带某一个功能,就一定会自带描述这个功能的头文件,比如 printf() 的头文件就是系统自带的 stdio.h 。头文件的后缀通常是 .h

预处理命令:#include命令

如果要使用某个功能,就必须先加载其对应的头文件,加载使用的是 #include 命令,声明在各文件模块的开头。C语言中以 # 号开头的命令称为预处理命令。顾名思义,在编译器对当前C程序进行编译前执行预处理操作。

c
#include <stdio.h>//编译系统在系统头文件所在目录搜索

#include "stdio.h"//编译系统首先在当前的源文件目录中查找 stdio.h,找不到的话,再转向系统头文件所在目录搜索。

stdio.h是系统提供的一个文件名,stdio是standard input & output的缩写。

结论:

  • 引用系统头文件,两种形式都会可以,#include <>效率高。
  • 引用用户头文件,只能使用 #include ""
常用的C头文件
  • stdio.h——定义核心输入和输出函数
    • printf()、scanf()、getchar()、putchar()
  • stdlib.h——定义数值转换函数、伪随机网络生成器和内存分配
  • string.h——定义字符串处理函数
  • stdint.h——定义精确宽度的整数类型
  • math.h——定义常用的数学函数
    • sin()、sqrt()
  • stddef.h——定义了几个有用的类型和宏

关键字

被C语言赋予了特殊含义,用做专门用途的字符串(或单词)

类型具体关键字
控制语句关键字(12 个)break, case, continue, default, do, else, for, goto, if, return, switch, while
数据类型关键字(12 个)char, enum, double, long, float, int, short, signed, struct, unsigned, union, void
存储类型关键字(4 个)auto, extern, register, static
其他关键字(4 个)const, sizeof, typedef, volatile
后续,1999年,C99标准增加了5个关键字:inlinerestrict_Bool_Complex_Imaginary

2011年,C11标准又增加了7个关键字:_Alignas_Alignof_Atomic_Static_assert_Noreturn_Thread_local_Generic

说明

1、ANSI C、C99和C11,它们之间差别并不大,在大多数情况下,它们都是和谐共处的。 2、不需要死记硬背,学到哪里记到哪里即可。