初识C语言

本文介绍了C语言的编译和链接过程,强调了预处理器指令、函数、变量、赋值、printf和scanf函数以及C99和C11的新关键字。通过实例展示了如何使用这些概念进行编程。
摘要由CSDN通过智能技术生成

a5f54036d6634557a85ee3ebe58e726a.png

欢迎来到我的博客!💃💃

🏡🏡推荐博客:August_._

一起持续学习,不断总结,共同进步🎊🎊

 

编译和链接

把程序转化为机器可以执行的形式,C语言中常包含下列转化步骤:

  • 预处理。首先程序会被交给预处理器( preprocessor )。预处理器执行以#开头的命令(通常称为指令)。预处理器有点类似于编辑器,它可以给程序添加内容,也可以修改程序。
  • 编译。修改后的程序现在可以进入编译器( compiler )了。编译器会把程序翻译成机器指令(即目标代码)。然而,这样的程序还是不可以运行的。
  • 链接。在最后一个步骤中,链接器( linker )把由编译器产生的目标代码和所需的其他附加代码整合在一起,这样才最终产生了完全可执行的程序。这些附加代码包括程序中用到的库函数(如 printf 函数)。

幸运的是,上述过程往往是自动实现的,因为预处理器通常会和编译器集成在一起,所以可能不会注意到它在工作。

集成开发环境

集成开发环境是一个软件包,我们可以在其中编辑、编译、链接、执行甚至调试程序。组成集成开发环境的各个部分可以协调工作。例如,当编译器发现程序中有错误时,它会让编辑器把包含出错代码的行突出显示。

C语言的三个特性

1、指令

在编译 C 程序之前,预处理器会首先对其进行编辑。我们把预处理器执行的命令称为指令。例如#include 指令。

#include <stdio.h>

这条指令说明,在编译前把 #include <stdio.h> 中的信息"包含"到程序中。#include <stdio.h>包含 C 标准输入/输出库的信息。 C 语言拥有大量类似于<stdio.h>的头,每个头都包含一些标准库的内容。这段程序中包含<stdio.h>的原因是 C 语言不同于其他的编程语言,它没有内置的"读"和"写"命令。输入/输出功能由标准库中的函数实现。

所有指令都是以字符#开始的。这个字符可以把 C 程序中的指令和其他代码区分开来。指令默认只占一行每条指令的结尾没有分号或其他特殊标记

2、函数

函数类似于其他编程语言中的"过程"或"子例程",它们是用来构建程序的构建块。事实上, C 程序就是函数的集合。函数分为两大类:一类是程序员编写的函数,另一类则是作为 C语言实现的一部分提供的函数。我们把后者称为库函数( library function ),因为它们属于一个由编译器提供的函数"库"。

在 C 语言中,计算数值的函数用 return 语句指定所"返回"的值。例如,对参数进行加1操作的函数可以执行语句

 return x+1;

而当函数要计算参数的平方差时,则可以执行语句:

 return y*y-z*z ;

虽然一个 C 程序可以包含多个函数,但只有 main 函数是必须有的且不能更改名字。 main 函数是非常特殊的:在执行程序时系统会自动调用 main 函数

#include <stdio.h>

int main(void)
{
    printf("Hello World\n");
    return 0;
}

main 前面的 int 表明该函数将返回一个整数值。圆括号中的 void 表明 main 函数没有参数

语句  return 0;有两个作用:

1、使 main 函数终止(从而结束程序)

2、指出 main 函数的返回值是0。这个值表明程序正常终止。如果 main 函数的末尾没有 return 语句,程序仍然能终止。但是,许多编译器会产生一条警告信息(因为函数应该返回一个整数,却没有这么做)。

3、语句

语句是程序运行时执行的命令,有两种语句:

一是返回( return )语句;

二是函数调用( function call )语句。要求某个函数执行分派给它的任务称为调用这个函数。

例如,程序为了在屏幕上显示一条字符串就调用了 printf 函数:

printf("Hello World\n");

C 语言规定每条语句都要以分号结尾

【就像任何好的规则一样,这条规则也有一个例外:后面会遇到的复合语句,就不以分号结尾。】

语句可以连续占用多行,有时很难确定结束位置,因此用分号来向编译器显示语句的结束位置。

但指令通常只占一行,因此不需要用分号结尾。

显示字符串

printf 是一个功能强大的函数,用 printf 函数显示用一对双引号包围的一系列字符最外层的双引号不会出现。当显示结束时, printf 函数不会自动跳转到下一输出行。为了跳转到下一行,必须在要显示的字符串中包含 \n(换行符),换行符就意味着终止当前行,然后把后续的输出转到下一行。
换行符可以在一个字面串中出现多次。为了显示下列信息:
Nothing is impossible
Believe yourself
可以这样写:

 printf ("Nothing is impossible\n Believe yourself\n ");

注释

我们的程序仍然缺乏某些重要内容:文档说明。符号/*标记注释的开始*/标记注释的结束。例如:

/* This is a comment */

注释几乎可以出现在程序的任何位置上。它既可以独占一行,也可以和其他程序文本出现在同一行中。下面展示的程序就把注释加在了程序开始的地方:

/* Name: Lv Meng   */
/* Hello!   */
/* Nice to meet you!  */

# include <stdio.h>

int main (void)
{
     printf ("Nice to meet you!\n");
     return 0;
}

注释还可以占用多行。如果遇到符号 /*,那么编译器读入(并且忽略)随后的内容直到遇到符号*/ 为止。如果愿意,还可以把一串短注释合并成为一条长注释:

/*
Name: Lv Meng                             
Hello!                                   
Nice to meet you!    
*/

更好的方法是用一个"盒形"格式把注释单独标记出来:

​/*******************************************

* Name: Lv Meng                            *

* Hello!                                   *

* Nice to meet you!                        *

********************************************/

简短的注释还可以与其他代码放在同一行:

int main (void)   /* Beginning of main program */

 

C99提供了另一种类型的注释,以 //(两个相邻的斜杠)开始:

// This is a comment 

这种风格的注释会在行末自动终止。如果要创建多于一行的注释,既可以使用以前的注释风格(/*...*/),也可以在每一行的前面加上 //:

// Name
// Purpose
// Author

 

新的注释风格有两个主要优点:

1、注释会在行末自动终止,不会出现未终止的注释意外吞噬部分程序的情况

2、因为每行注释前面都必须有 //,所以多行注释看上去更加醒目

变量和赋值

很少有程序会像示例那样简单。大多数程序在产生输出之前往往需要执行一系列的计算,因此需要在程序执行过程中有一种临时存储数据的方法。和大多数编程语言一样, C 语言中的这类存储单元被称为变量( variable )。

类型

每一个变量都必须有一个类型( type )。类型用来说明变量所存储的数据的种类。 C 语言拥有广泛多样的类型。选择合适的类型是非常关键的。数值型变量的类型决定了变量所能存储的最大值和最小值,同时也决定了是否允许在小数点后出现数字。 

int型变量可以存储整数,如0、392或 -2553。但是,整数的取值范围是受限制的。最大的整数通常是2147483647,但在某些计算机上也可能是32767。

float型变量可以存储比 int 型变量大得多的数值。而且,可以存储带小数位的数,如379.125。但 float 型变量也有一些缺陷。进行算术运算时 float 型变量通常比 int 型变量慢;更重要的是, float 型变量所存储的数值往往只是实际数值的一个近似值。如果在一个 float 型变量中存储0.1,以后可能会发现变量的值为0.09999999999999987,这是舍入造成的误差。

声明

在使用变量之前必须对其进行声明(为编译器所做的描述)。为了声明变量,首先要指定变量的类型,然后说明变量的名字。例如,我们可能这样声明变量 height 和 profit :

 int height;
 float profit;

如果几个变量具有相同的类型,就可以把它们的声明合并:

 int height,length,width,volume;
 float profit,loss;

注意每一条完整的声明都要以分号结尾。且必须把声明放置在语句之前建议在声明和语句之间留一个空行

赋值

变量通过赋值( assignment )的方式获得值。例如,语句

 height =8;
 length =12;

把数值8、12分别赋给变量 height 、 length ,8、12称为常量( constant )。
变量在赋值或以其他方式使用之前必须先声明。也就是说,我们可以这样写:

 int height ;
 height=8;

但下面这样是不行的:

 height = 8;
/*** WRONG ***/
 int height ;

赋给 float 型变量的常量通常带小数点。例如,如果 profit 是一个 float 型的变量,可能会这样对其赋值:

 profit = 2150.48;

当我们把一个包含小数点的常量赋值给 float 型变量时,最好在该常量后面加一个字母 f (代表 float ):

profit=2150.48f;   /*不加 f 可能会触发编译器的警告*/

显示变量的值

用 printf 可以显示出变量的当前值,例如:

 Height : h 
这里的 h 表示变量 height 的当前值。我们可以通过如下的 printf 调用来实现输出上述信息的要求:

 printf (" Height :%d\n ",height);

占位符% d 用来指明在显示过程中变量 height 的值的显示位置

注意,因为在%d后面放置了 \n ,所以 printf 在显示完 height 的值后会跳到下一行。
% d 仅用于 int 型变量。如果要显示 float 型变量,则要用% f 来代替% d 。

默认情况下,% f 会显示出小数点后6位数字。如果要强制% f 显示小数点后 p 位数字,可以把 .p放置在%和 f 之间。例如,为了显示信息
 Profit :2150.48
可以把 printf 写为如下形式:

 printf (" Profit: %.2f\n ",profit);

初始化

当程序开始执行时,某些变量会被自动设置为零,而大多数变量则不会。没有默认值并且尚未在程序中被赋值的变量是未初始化的。
如果试图访问未初始化的变量(例如,用 printf 显示变量的值,或者在表达式中使用该变量),可能会得到不可预知的结果,如随机值或者其他同样没有意义的数值。在某些编译器中,可能会发生更坏的情况(甚至是程序崩溃)。
我们当然可以总是采用赋值的方法给变量赋初始值,但还有更简便的方法:在变量声明中加入初始值。例如,可以在一步操作中声明变量 height 并同时将其初始化:

 int height=8;

按照 C 语言的术语,数值8是一个初始化器( initializer )。
在同一个声明中可以对任意数量的变量进行初始化:

int height = 8,length = 12,width = 10;

注意,上述每个变量都有属于自己的初始化器。在接下来的例子中,只有变量 width 拥有初始
化器10,而变量 height 和变量 length 都没有(也就是说这两个变量仍然未初始化):

 int height,length,width = 10;

显示表达式的值

printf 的功能不局限于显示变量中存储的数,它可以显示任意数值表达式的值。利用这一特性既可以简化程序,又可以减少变量的数量。例如,语句

 volume = height * length * width ;
 printf ("%d \n", volume);

可以用以下形式代替:

 printf("%d \n ",height*length*width);

 printf 显示表达式的值的能力说明了 C 语言的一个通用原则在任何需要数值的地方,都可以使用具有相同类型的表达式

读入输入

为了获取输入,就要用到 scanf 函数。它是 C 函数库中与 printf 相对应的函数。 scanf 中的字母 f 和 printf 中的字母 f 含义相同,都表示"格式化"的意思。  scanf 函数需要知道将获得的输入数据的格式,而 printf 函数需要知道输出数据的显示格式。

 scanf ("%d",&i);

其中,字符串"%d "说明 scanf 读入的是一个整数,而 i 是一个 int 型变量,用来存储 scanf 读入的输入。&运算符在使用 scanf 函数时通常是(但不总是)必需的

定义常量的名字

当程序含有常量时,建议给这些常量命名。可以采用称为宏定义( macro definition )的特性给常量命名:

#define N 166

这里的 #define 是预处理指令,类似于前面所讲的# include ,因而在此行的结尾也没有分号
当对程序进行编译时,预处理器会把每一个宏替换为其表示的值。例如,语句

 weight = (volume+N-1)/N;

将变为

 weight = (volume+166-1)/166;

此外,还可以利用宏来定义表达式:
# define PI (1.0f/3.14159f)
当宏包含运算符时,建议用括号把表达式括起来
注意,宏的名字只用了大写字母。这是大多数 C 程序员遵循的规范,但并不是 C 语言本身的要求。(至今, C 程序员沿用此规范已经几十年了,希望读者不要背离此规范。)

标识符

在编写程序时,需要对变量、函数、宏和其他实体进行命名。这些名字称为标识符( identifier )。在 C 语言中,标识符可以含有字母、数字下划线,但是必须以字母或者下划线开头

【在C99中,标识符还可以使用某些"通用字符名"。】

下面是合法标识符的一些示例:

get _ next _ char           _ done 
接下来这些则是不合法的标识符:
10times                         get - next - char 

不合法的原因:符号10times是以数字而不是以字母或下划线开头的;符号 get - next - char 包含了减号,而不是下划线。
 C 语言是区分大小写的;例如,下列8个标识符全是不同的:
 job       joB       job       jOB       Job      JoB        JOb        JOB 
上述8个标识符可以同时使用,且每一个都有完全不同的意义。
因为 C 语言是区分大小写的,所以许多程序员会遵循在标识符中只使用小写字母的规范(宏命名除外)。
其中所有关键字( keyword )对 C 编译器而言都有着特殊的意义,因此这些关键字不能作为标识符来使用

关键字说明
auto声明自动变量
break跳出当前循环
case开关语句分支
char声明字符型变量或函数返回值类型
const定义常量,如果一个变量被 const 修饰,那么它的值就不能再被改变
continue结束当前循环,开始下一轮循环
default开关语句中的"其它"分支
do循环语句的循环体
double声明双精度浮点型变量或函数返回值类型
else条件语句否定分支(与 if 连用)
enum声明枚举类型
extern声明变量或函数是在其它文件或本文件的其他位置定义
float声明浮点型变量或函数返回值类型
for一种循环语句
goto无条件跳转语句
if条件语句
int声明整型变量或函数
long声明长整型变量或函数返回值类型
register声明寄存器变量
return子程序返回语句(可以带参数,也可不带参数)
short声明短整型变量或函数
signed声明有符号类型变量或函数
sizeof计算数据类型或变量长度(即所占字节数)
static声明静态变量
struct声明结构体类型
switch用于开关语句
typedef用以给数据类型取别名
unsigned声明无符号类型变量或函数
union声明共用体类型
void声明函数无返回值或无参数,声明无类型指针
volatile说明变量在程序执行中可被隐含地改变
while循环语句的循环条件

C99 新增关键字

_Bool_Complex_Imaginaryinlinerestrict

C11 新增关键字

_Alignas_Alignof_Atomic_Generic_Noreturn
_Static_assert_Thread_local   

注意

有关标识符的其他限制。某些编译器把特定的标识符(如asm)视为附加关键字。属于标准库的标识符也是受限的。误用这些名字可能会导致编译或链接出错。以下划线开头的标识符也是受限的。

 

 

 

 

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值