C 语言学习笔记(一)C 语言介绍

1. C 语言起源

  1972 年,贝尔实验室的 丹尼斯·里奇(Dennis Ritch)和 肯·汤姆逊(Ken Thompson)在研究 Unix 操作系统时设计了 C 语言。C 语言是在 B 语言(汤姆逊发明)的基础上进行设计的。

2. C 语言标准

2.1 K&R C 标准

  1978 年,布莱恩·柯林汉(Brain Kernighan)和丹尼斯·里奇(Dennis Ritch)合著的 The C Programming Language (《C 语言程序设计》)第一版是公认的 C 标准,通常称之为 K&R C 或经典 C。

2.2 ANSI/ISO C 标准

  美国国家标准协会(ANSI)于 1983 年组建一个委员会开发了一套新标准,并于 1989 年正式公布。该标准(ANSI C)定义了 C 语言和 C 标准库。国际标准化组织(ISO)于 1990 年采用了这套 C 标准(ISO C)。所以两者是完全相同的标准。ANSI/ISO 标准通常也叫作 C89 或 C90。

2.3 C99 标准

  1994 年,ANSI/ISO 联合委员会开始修订 C 标准,最终在 1999 年发布了 C99 标准。(并不是所有的编译器都支持 C99)

2.4 C11 标准

  2011 年标准委员会发布了 C11 标准。(C99 的一些特性成为 C11 的可选项)

3. 编程机制

  用 C 语言编写程序时,编写的内容被存储在文本文件中,该文件被称为源代码文件(source code file),该文件以 .c 结尾(如:hello.c)。在文件名中,点号(.)前面的部分称为基本名(basename),点号后面的部分称为扩展名(extension)。

3.1 目标代码文件、可执行文件和库

  C 语言编程的基本策略是,用程序将源代码文件转换成可执行文件。典型的 C 实现通过编译和链接两个步骤来完成这一过程。编译器将源代码转换成中间代码,链接器将中间代码和其他代码合并,生成可执行文件。
  中间文件有很多种形式,其中最普遍的是把源代码转换成机器语言代码,并把结果放在目标代码文件中(简称目标文件或目标代码)。虽然目标文件中含有机器语言代码,但是并不能直接运行该文件,因为首先目标文件中缺少启动代码(startup code),启动代码充当着程序和操作系统之间的接口;其次,目标文件还缺少库函数,几乎所有的 C 程序都要使用 C 标准库中的函数。
  链接器在作用是,把目标代码、系统的标准启动代码和库代码这 3 部分合并成一个文件,即可执行文件。对于库代码,链接器只会把程序中要用到的库函数代码提取出来。
在这里插入图片描述

3.2 Linux 系统

  Linux 系统中要编写运行 C 程序,需要使用 GNU 提供的 GCC 公用域 C 编译器。如果 Linux 之前没有安装 GCC,则需要输入以下命令安装GCC。

yum install gcc

  gcc 指令基本语法如下:

gcc -o 可执行文件名 源代码文件

例子:在 Linux 系统中编写一个 C 程序。

  1. 创建 hello.c 文件
vim hello.c
  1. 在 hello.c 中编写源代码并保存
#include <stdio.h>

int main(void)
{
	printf("hello world!\n");
	return 0;
}
  1. 编译
gcc -o hello.out hello.c
  1. 运行可执行文件
./hello.out

在这里插入图片描述

4. C 程序示例

#include <stdio.h>

void hello(void);	/*ANSI/ISO C 函数原型*/

int main(void)
{
	int num;	/*声明(定义)一个名为num的变量*/
	num = 1;	/*为num赋一个值1*/
	printf("hello world!\n");	// 使用printf函数,打印“hello world!”
	hello();
	return 0;
}

void hello(void)	// 函数定义的开始
{
	printf("hello C!");
}

4.1 #include 指令和头文件

  #include 这行代码是一条 C 预处理器指令。通常,C 编译器在编译前会对源代码做一些准备工作,即预处理。所有的 C 编译器都提供 stdio.h 文件。该文件名的含义是标准输入/输出头文件。该文件包含了供编译器使用的输入和输出函数(printf 函数)信息。通常,在 C 程序顶部的信息集合被称为 头文件(header)。
  头文件包含了编译器创建最终可执行程序要用到的信息。例如,头文件中可以定义一些常量,或者指明函数名以及如何使用它们。但是,函数的实际代码在一个预编译代码的库文件中。

4.2 main 函数

  C 程序一定从 main() 函数开始执行(目前不需要考虑额外情况)。除了 main() 函数,我们还可以任意命名其他函数,但是 main() 函数必须是开始函数。圆括号用于识别这是一个函数。
  int 是 main() 函数的返回类型,代表返回的值是整数。这里的返回值返回给了操作系统。
  通常,函数名后面的圆括号中包含了一些传入函数的信息。该例中没有传递任何信息,因此圆括号内是单词 void。
  如果浏览旧式的 C 代码,可能会发现程序以如下形式开始:main()。C90 勉强接受这种形式,但是 C99 和 C11 标准不允许这样写。此外,我们还可以看到这样的形式:void main()。一些编译器允许这样写,但是所有的标准中都未认可这种写法。所以这种写法不推荐使用。

4.3 注释

  在程序中,被 /* */ 两个符号括起来的部分是程序的注释。较长的注释可单独放一行或者多行,在 /* 和 */ 之间的内容都会被编译器忽略。C99 新增了另一种风格的注释,普遍用于 C++ 和 Java。这种风格使用 // 符号创建注释,但仅限于单行。

4.4 花括号、函数体和块

  在上面的程序中,花括号 { } 把 main 函数括起来。一般而言,所有的 C 函数都使用花括号标记函数体的开始和结束。这是规定,不能省略。花括号还可以把函数中的多条语句合并为一个单元或块。

4.5 声明

  声明是 C 语言最重要的特性之一。在该例中,声明完成了两件事,第一,在程序中有一个名为 num 的变量(variable)。第二,int 表名 num 是一个整数。int 是一种数据类型。编译器使用这些信息为 num 变量在内存中分配存储空间。

  int 是 C语言的一个 关键字,表示一种基本的 C 语言数据类型。关键字是语言定义的单词,不能做其他用途,比如,不能用关键字作为函数名或者变量名。示例中 num 是一个 标志符(identifier),也就是一个变量、函数或者其他实体的名称。因此, 声明把特定标志符与计算机内存中的特定位置联系起来,同时也确定了储存在某位置的信息类型或者数据类型。

  标志符的命名规则:由字母、数字和下划线构成,数字不能作为第一个字符。

  在 C 语言中,所有的变量必须先声明才能使用。这意味着必须列出程序中用到的所有变量名及其类型。以前的 C 语言,还要求把变量的声明放在块的顶部,其他语句不能在任何声明前面。但是 C99 和 C11 遵循 C++ 的惯例,可以把声明放在块中的任何位置。尽管如此,首次使用变量之前一定要先声明它。

  当一行中声明两个或多个变量时,变量之间用逗号分隔。

  hello() 函数在程序中出现了三次,第 1 次是函数原型(prototype),告知编译器在程序中要使用该函数;第 2 次是以函数调用的形式出现在 main() 函数中;最后一次出现在函数定义中,函数定义即函数本身的源代码。

  C90 标准新增了函数原型,函数原型是一种声明形式,告知编译器正在使用某函数,因此函数声明也被称作函数声明。函数原型还指明了函数的属性,比如函数的返回值类型,参数。C 标准建议,要为程序中所有的函数提供函数原型。早期的 C 语言支持一种更简单的函数声明,只需指定返回类型,不用描述参数。C90、C99 和 C11标准都承认旧版本的形式,但是也表明会逐渐淘汰这种过时的写法。

4.6 赋值

  赋值是 C 语言的基本操作之一。num = 1;的意思是 “把值 1 赋给变量 num”。在声明变量时,编译器在计算机内存中为变量 num 预留了空间,然后执行赋值语句时,把值存储在之前的预留位置。可以个给 num 赋不同的值,这就是 num 被称为变量的原因。
  赋值表达式语句从右侧把值赋到左侧。

4.7 printf() 函数

  printf() 函数是 C 语言的一个标准函数。圆括号中内容是从 main() 函数传递给 printf() 函数的信息,该信息称为参数,更确切的说是函数的实际参数(actual argument)。在 C 语言中,实际参数(简称实参)是传递给函数的特定值,形式参数(简称形参) 是函数中用于存储值的变量。
  printf() 函数会查看其双引号中的内容,并将其打印在屏幕上。
  printf() 函数的双引号中的 \n 代表是一个换行符。换行符是一个 转义序列(escape sequence)。转义序列用于代表难以表示或无法输入的字符。每个转义序列都以反斜杠字符(\)开始。

4.8 return 语句

  int main(void) 中 int 表明 main 函数应该返回一个整数。有返回值的 C 函数要有 return 语句,该语句以 return 关键字开始,后面是待返回的值,并以分号结尾。如果遗漏 main() 函数中的 return 语句,程序在运行至最外面的右花括号( })时会返回 0。因此可以省略 main() 函数末尾的 return 语句。但是不要在其他有返回值的函数中遗漏它。

5. 关键字和保留标识符

ISO/ANSI C 标准 32 个关键字:

auto break case char const continue default do
double else enum extern float for goto if
int long register return short signed sizeof static
struct switch typeof union unsigned void volatile while

关键字含义百度百科

C99 标准新增 5 个关键字:

inline restrict _Bool _Complex _Imaginary

C11 标准新增 7 个关键字:

_Alignas _Alignof _Atomic _Static_assert _Noreturn _Thread_local _Generic

  关键字是 C 语言的词汇,不能用它们作为标志符。如果关键字使用不当,编译器会视为语法错误。还有一些保留标志符,C 语言已经指定了它们的用途或保留了它们的使用权,也不能作为标识符。保留标识符包括那些以下划线字符开头的标识符和标准库函数名,如 printf()。

6. 基本数据类型

6.1 基本类型关键字

最初 K&C 的关键字 C90 标准添加的关键字 C 90 标准添加的关键字
int signed _Bool
long void _Complex
short _Imaginary
unsigned
char
float
double

  其中,int 关键字表示基本的整数类型,long、short、signed 和 unsigned 用于提供基本整数类型的变式。char 关键字用于指定字母和其它字符,也可以表示较小的整数。float、double 和 long double 代表浮点数类型。_Bool 代表布尔类型(true 或 false,1 表示 true,0 表示 false)。_Complex 代表复数,_Imaginary 代表虚数。

6.2 整数类型

有符号整型:

  • int
  • char
  • signed char
  • shortshort int
  • longlong int
  • long longlong long int

无符号整型:

  • unsigned int
  • unsigned char
  • unsigned short
  • unsigned long

6.2 浮点类型

  • float (单精度)
  • double (双精度)
  • long double

6.3 类型大小

  sizeof 是 C 语言的内置运算符,以字节为单位指定类型的大小,C99 和 C1 提供 %zd 转换说明匹配 sizeof 的返回类型。一些不支持 C99 和 C11 的编译器可以用 %u 或 %lu 代替 %zd。

#include <stdio.h> 

int main(void) 
{
	/* C99为类型大小提供%zd转换说明 */ 
	printf("Type int has a size of %zd bytes.\n", sizeof(int)); 
	printf("Type char has a size of %zd bytes.\n", sizeof(char)); 
	printf("Type long has a size of %zd bytes.\n", sizeof(long)); 
	printf("Type long long has a size of %zd bytes.\n", sizeof(long long)); 
	printf("Type double has a size of %zd bytes.\n", sizeof(double)); 
	printf("Type long double has a size of %zd bytes.\n", sizeof(long double)); 
	return 0; 
}

在这里插入图片描述
注意:C 语言中,各种类型的存储大小与系统的位数有关,但目前通用以 64 位为主。以下列出了 32 位系统和 64 位系统的存储大小差别(windows 相同) :

在这里插入图片描述

发布了14 篇原创文章 · 获赞 33 · 访问量 1524

猜你喜欢

转载自blog.csdn.net/weixin_42837961/article/details/104433097