基础知识

一个简单的c程序

include ←包含另一个文件
该行告诉编译器把stdio.h中的内容包含在当前程序中。stdio.h是C编译器软件包的标准部分,它提供键盘输入和屏幕输出的支持。
int main (void) ←函数名
C程序包含一个或多个函数,它们是C程序的基本模块。程序清单2.1的程序中有一个名为main()的
函数。圆括号表明main()是一个函数名。int表明main()函数返回一个整数,void 表明main()不带
任何参数。这些内容我们稍后详述。现在,只需记住int和void是标准ANSIC定义main()的一部分(如
果使用ANSIC之前的编译器,请省略void;考虑到兼容的问题,请尽量使用较新的C编译器)。
/一个简单的C程序/ ←注释
注释在//两个符号之间,这些注释能提高程序的可读性。注意,注释只是为了帮助读者理解程序,
编译器会忽略它们。 // 注释单行
{ ←函数体开始
左花括号表示函数定义开始,右花括号(})表示函数定义结束。
int num; ←声明
该声明表明,将使用一个名为num的变量,而且num是int (整数)类型。
num = 1; <-赋值表达式语句
语句num=1; 把值1赋给名为num的变量。
printf(“I am a simple “); ←调用一个函数
该语句使用printf() 函数,在屏幕上显示I am a simple,光标停在同一行。printf () 是标准
的C库函数。在程序中使用函数叫作调用函数。
printf (“computer. \n”) ; ←调用另一个函数
接下来调用的这个printf ()函数在上条语句打印出来的内容后面加上“computer”. 代码\n告诉计算机另起一行,即把光标移至下一行。 换行\n。
printf (“My favorite number is %d because it is first. \n”, num) ;
最后调用的printf()把num的值(1)内嵌在用双引号括起来的内容中-并打印。%d告诉 计算机以
何种形式输出num的值,打印在何处。
return 0; <-return语句
C函数可以给调用方提供(或返回)一个数。目前,可暂时把该行看作是结束main()函 数的要求。
} ←结束 必须以右花括号表示程序结束。

头文件

include //包含头文件 standard标准 input输入 output输出
#include //如何判断每个函数相对应的头文件 直接百度
这是程序的第1行。#include 的作用相当于把stdio.h文件中的所有内容都输入该行
所在的位置。实际上,这是一-种“拷贝-粘贴”的操作。include文件提供了一种方便的途径共享许多程
序共有的信息。
.
#include这行代码是一条 C预处理器指令(preprocessor directive)。通常,C编译器在编译前会对源代码做一些准 备工作,即预处理(preprocessing)。
所有的C编译器软件包都提供stdio.h文件。该文件中包含了供编译器使用的输入和输出函数(如,printf())信息。该文件名的含义是标准输入/输出头文件。通常,在C程序顶部的信息集合被称为头文件(header)。

在大多数情况下,头文件包含了编译器创建最终可执行程序要用到的信息。例如,头文件中可以定义一些常量,或者指明函数名以及如何使用它们。但是,函数的实际代码在一个预编译代码的库文件中。简而言之,头文件帮助编译器把你的程序正确地组合在-起。

ANSI/ISO C规定了C编译器必须提供哪些头文件。有些程序要包含stdio.h,而有些不用。特定C实现的文档中应该包含对C库函数的说明。这些说明确定了使用哪些函数需要包含哪些头文件。例如,要使用printf()函数,必须包含stdio.h头文件。省略必要的头文件可能不会影响某- -特定程序,但是最好不要这样做。本书每次用到库函数,都会用#include指令包含ANSI/ISO标准指定的头文件。

main 主函数

int main(void) ;
程序清单2.1中的第2行表明该函数名为main。的确,main 是一个极其普通的名称,但是这是唯一的选择。C程序- -定从main ()函数开始执行(目前不必考虑例外的情况)。除了main()函数,你可以任意命名其他函数,而且main()函数必须是开始的函数。圆括号有什么功能?用于识别main()是一个函数。
很快你将学到更多的函数。就目前而言,只需记住函数是C程序的基本模块。
int是main()函数的返回类型。这表明main()函数返回的值是整数。返回到哪里?返回给操作系统。
我们将在第6章中再来探讨这个问题。

通常,函数名后面的圆括号中包含一些传入函数的信息。该例中没有传递任何信息。因此,圆括号内是单词void (第11章将介绍把信息从main ()函数传回操作系统的另-种形式)。
如果浏览旧式的C代码,会发现程序以如下形式开始: main()
C90标准勉强接受这种形式,但是C99和C1I标准不允许这样写。因此,即使你使用的编译器允许, 也不要这样写。
你还会看到这种形式:. void main()
一些编译器允许这样写,但是所有的标准都未认可这种写法。因此,编译器不必接受这种形式,而且许多编译器都不能这样写。需要强调的是,只要坚持使用标准形式,把程序从一个编译器移至另一个编译器时就不会出什么问题。

声明

int num; 先写上int,然后写变量名,最后加上一个分号。
其一,在函数中有一个名为num的变量(variable)。 其二,int表明num是一个整数。(即,没有小数点或小数部分的数)。int是一种数据类型。
编译器使用这些信息为num变量在内存中分配存储空间。分号;在C语言中是大部分语句和声明的一部分,作为语句的结尾。
int是C语言的一个关键字(keyword),表示一种基本的 C语言数据类型。关键字是语言定义的单词,不能做其他用途。例如,不能用int 作为函数名和变量名。
示例中的num是-一个标识符( identifier),也就一个变量、 函数或其他实体的名称。因此,声明把特定标识符与计算机内存中的特定位置联系起来,同时也确定了储存在某位置的信息类型或数据类型。
在C语言中,所有变量都必须先声明才能使用。这意味着必须列出程序中用到的所有变量名及其类型。
以前的C语言,还要求把变量声明在块的顶部,其他语句不能在任何声明的前面。也就是说,main()
函数体如下所示:
int main() //旧 规则
{
int doors;
int dogs;
doors = 5;
dogs = 3;
//其他语句
}
C99和C11遵循C++的惯例,可以把声明放在块中的任何位置。尽管如此,首次使用变量之前一 -定要
先声明它。因此,如果编译器支持这一新特性, 可以这样编写上面的代码:
int main()
{
//目前的C 规则
//一些语句
int doors;
doors=5;//第1次使用doors
//其他语句
int dogs;
dogs=3;//第1次使用dogs
//其他语句
}
多条声明
接下来,程序在一条声明中声明了两个变量,而不是-一个变量。为此,要在声明中用逗号隔开两个变量(feet和fathoms)。也就是说,
int feet, fathoms;

int feet;
int fathoms ;
等价。
命名
给变量命名时要使用有意义的变量名或标识符可以用小写字母、大写字母、数字和下划线(_ )来命名。而且,名称的第1个字符必须是字符或下划线,不能是数字。

初始化变量

初始化(initialize) 变量就是为变量赋一- 个初始值。在C语言中,初始化可以直接在声明中完成。只需
在变量名后面加上赋值运算符(=) 和待赋给变量的值即可。如下所示:
int hogs = 21;
int cows = 32,goats = 14;
int dogs,cats = 94; /有效,但是这种格式很糟糕/
以上示例的最后- -行, 只初始化了cats,并未初始化dogs。这种写法很容易让人误认为dogs也被
初始化为94,所以最好不要把初始化的变量和未初始化的变量放在同一条声明中。

赋值

num=1;
程序清单中的这行代码是赋值表达式语句’。赋值是C语言的基本操作之一-。 该行代码的意思是“把值1赋给变量num”。在执行int num;声明时,编译器在计算机内存中为变量num预留了空间,然后在执行这行赋值表达式语句时,把值储存在之前预留的位置。可以给num赋不同的值,这就是num之所以被称为变量(variable) 的原因。注意,该赋值表达式语句从右侧把值赋到左侧。另外,该语句以分号结尾,如图2.2所示。
num=1;
赋值运算符
图2.2赋值是C 语言中的基本操作之一

C语言是通过赋值运算符而不是赋值语句完成赋值操作。根据C标准,C语言并没有所谓的“赋值语句”,本书及一些其他书籍中提到的“赋值语句”实际上是表达式语句(C语言的6种基本语句之一)。本书把“赋值语句”均译为“赋值表达式语句”,以提醒初学者注意。一译者注

printf()函数

printf函数
printf(“I am a simple “) ;
printf (“computer. \n”) ;
printf (“My favorite number is号d because it is first. \n”, num) ;
这3行都使用了C语言的一个标准函数: printf()。 圆括号表明printf是-一个函数名。圆括号中
的内容是从main()函数传递给printf()函数的信息。例如,上面的第I行把Iamasimple传递给
printf()函数。该信息被称为参数,或者更确切地说,是函数的实际参数(actual argument),如图2.3所
示。(在C语言中,实际参数(简称实参)是传递给函数的特定值,形式参数( 简称形参)是函数中用于储
存值的变量。第5章中将详述相关内容。) printf ()函数用参数来做什么?该函数会查看双引号中的内容并将其打印在屏幕上。
printf (“That’s mere contrariness”) ;

实际参数
图2.3带 实参的printf()函数
第1行printf()演示了在C语言中如何调用函数。只需输入函数名,把所需的参数填入圆括号即可。
当程序运行到这-行时,控制权被转给已命名的函数(该例中是printf() )。函数执行结束后,控制权被返回至主调函数(calling function),该例中是main()。

第2行printf ()函数的双引号中的\n字符并未输出。这是为什么? \n的意思是换行。\n组合(依次输入这两个字符)代表-一个 换行符(newline character)。对于printf()而言,它的意思是“在下一-行的最左边开始新的一行”。也就是说,打印换行符的效果与在键盘按下Enter键相同。
既然如此,为何不在键入printf ()参数时直接使用Enter键?因为编辑器可能认为这是直接的命令,而不是储存在在源代码中的指令。换句话说,如果直接按下Enter键,编辑器会退出当前行并开始新的一-行。但是,换行符仅会影响程序输出的显示格式。
换行符是-一个转义序列(escape sequence)。转义序列用于代表难以表示或无法输入的字符。如,\t代表Tab键,\b 代表Backspace键(退格键)。每个转义序列都以反斜杠字符() 开始。这样,就解释了为什么3行printf ()语句只打印出两行:第1个printf ()打印的内容中不含换行符,但是第2和第3个printf ()中都有换行符。
第3个printf ()还有一些不明之处:参数中的%d在打印时有什么作用?先来看该函数的输出:
My favorite number is 1 because it is first.
对比发现,参数中的%d被数字1代替了,而1就是变量num的值。品d相当于是一个占位符,其作用是指明输出num值的位置。该行和下面的BASIC语句很像:
PRINT “My favorite number is “; num;
because it is first.
实际上,C语言的printf ()比BASIC的这条语句做的事情多-些。 &提醒程序,要在该处打印一个变
量,%d表明把变量作为十进制整数打印。printf()函数名中的f提醒用户,这是一种格式化打印函数。
printf ()函数有多种打印变量的格式,包括小数和十六进制整数。

return语句

return 语句
return 0;
return语句’是程序清单2.1的最后一条语句。int main (void)中的int表明main ()函数应返回一个整数。C标准要求main()这样做。有返回值的C函数要有return语句。该语句以return关键字开始,后面是待返回的值,并以分号结尾。如果遗漏main()函数中的return语句,程序在运行至最外面的右花括号(})时会返回0。因此,可以省略main()函数末尾的return语句。但是,不要在其他有返回值的函数中漏掉它。因此,强烈建议读者养成在main()函数中保留return语句的好习惯。在这种情况下,可将其看作是统一代码风格。但对于某些操作系统(包括Linux和UNIX),return语句有实际的用途。第11章再详述这个主题。
1 在C语言中,return语句是一种跳转语句。一译者注

调试程序

现在,你可以编写一个简单的C程序,但是可能会犯一些简单的错误。程序的错误通常叫做bug,找出并修正错误的过程叫做调试(debug)。
语法错误和语义错误
对程序的错误进行检查和修改是程序设计中非常重要的一个步骤。编译器在对C语言的源代码进行编译时,会首先对源代码的指令进行错误检查,并给出相应的错误提示,以便于程序员进行修改。原代码中存在的错误通常可以分为语法错误和语义错误两种。
语法错误:编程中代码没有遵循C语言的语法规范而造成的错误,例如,标识符命名不符合规范、错误的类型赋值操作等。语法错误是比较常见的错误,编译器也能够较好地识别这类错误,并且在编译过程中给出错误提示,错误提示一般会标识出存在错误的语句所在的行号。
语义错误:在很多时候也称为逻辑错误,存在这一类错误的语句在语法上是正确的,但是其表达的含义和逻辑关系存在错误。例如,“一年有366天”这句话在语法上是正确的,但是在逻辑上存在错误。因此,编译器基本上很难检查出语义错误,在根据程序的功能目标设计完程序后,需进行程序测试以发现这种错误。

语法错误 :
语法错误可以看作是编码出现了违反C语言规则的错误,一般编译或者链接时,
都会报错的。
而语义错误,也可以叫做逻辑错误,
也就是说你的代码完全符合C语言的规范,不会出现编译/链接的错误,
但是,在逻辑上有错误。
举个简单的例子,
加入编一个代码来统计int数组a的成员总和,成员总数为N:
for(int i=0;isum=sum+a[i];
for(int i=0;i<=N;i++) //这里多了一个i=N的取值,这是语义错误
sum=sum+a[i];

测试

32个关键字及作用

局部变量和全局变量的区别

全局变量和局部变量的定义是:
1.局部变量:“在函数内定义的变量”,即在一个函数内部定义的变量,只在本函数范围内有效。

2.全局变量:“在函数外定义的变量”,即从定义变量的位置到本源文件结束都有效。

printf 和 scanf

pritnf()函数

请求printf ()函数打印数据的指令要与待打印数据的类型相匹配。例如,打印整数时使用%d,打印字符时使用%c。这些符号被称为转换说明(conversion specification),它们指定了如何把数据转换成可显示的形式。我们先列出ANSIC标准为printf()提供的转换说明,然后再示范如何使用—些较常见的转换说明。表4.3列出了一些转换说明和各自对应的输出类型。
image.png
#include
#include
int main(void)
{
int a = 18;
float b = 185.123;
double c = 57.12;
int d = 666;
printf(“年龄:%d\n身高:%f\n体重:%lf\n学号:%d\n”, a, b, c, d);
system(“color c”);
return 0;
}
这是printf ()函数的格式:
printf(格式字符串,待打印项1,待打印项2,…);
待打印项1、待打印项2等都是要打印的项。它们可以是变量、常量,甚至是在打印之前先要计算的表达式。第3章提到过,格式字符串应包含每个待打印项对应的转换说明。例如,考虑下面的语句:
printf(“年龄:%d\n身高:%f\n体重:%lf\n学号:%d\n”, a, b, c, d);
参数1 格式字符串 参数2 待打印列表
%d,%f, %lf, %d 这些都是转换说明 年龄身高这些则是字面字符
注意:对应类型要用对应的转化说明 符

printf的说明修饰符

image.png
image.png

printf()中的标记

image.png

使用scanf ()

刚学完输出,接下来我们转至输入一学习 scanf()函数。C库包含了多个输入函数,scanf ()是最通用的一个,因为它可以读取不同格式的数据。当然,从键盘输入的都是文本,因为键盘只能生成文本字.符:字母、数字和标点符号。如果要输入整数2014, 就要键入字符2、0、1、4。如果要将其储存为数值而不是字符串,程序就必须把字符依次转换成数值,这就是scanf()要做的。scanf ()把输入的字符串转换成整数、浮点数、字符或字符串,而printf() 正好与它相反,把整数、浮点数、字符和字符串转换成显示在屏幕上的文本。
scanf()和printf()类似,也使用格式字符串和参数列表。scanf()中的格式字符串表明字符
输入流的目标数据类型。两个函数主要的区别在参数列表中。printf()函数使用变量、常量和表达式,而scanf()函数使用指向变量的指针。这里,读者不必了解如何使用指针,只需记住以下两条简单的
规则:
如果用scanf ()读取基本变量类型的值,在变量名前加上一个&;
如果用scanf ()把字符串读入字符数组中,不要使用&。
程序清单4.15中的小程序演示了这两条规则。
// input.c —何时使用&
#include
int main (void)
{
int age;//变量
float assets;//变量
char pet[30] ;//字符数组,用于储存字符串
printf (“Enter your age, assets, and favorite pet. \n”) ;
scanf (“%f”,&age, &assets) ; // 这里要使用&
scanf (“%s”,pet) ;// 字符数组不使用& 因为数组名本身就是一个地址 不用取地址
printf (“%d %.2f %s\n”, age, assets, pet) ;
return 0;
}

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. int main (void)
  4. {
  5. const int qian = 0; //固定是一个不变的量
  6. int sp = 0; //先把变量初始化
  7. int sydq = 0;
  8. sydq == qian - sp;
  9. printf ("请输入拥有的钱:");
  10. scanf ("%d",&qian);
  11. printf("请输入商品价格");
  12. scanf ("%d", &sp); //输入函数 scanf_s 消除警告
  13. printf ("剩余%d元", qian - sp);
  14. system ("pause");
  15. return 0;
  16. }

scanf()的转换说明

image.png

scanf()的转换说明中的修饰符

image.png

续表image.png