在 C 语言程序中将数据分为两种:字面量(常量)和变量。
(一) 字面量
字面量(也有叫“常量”的)指的是数值固定的量,“一看就能看出来”。在程序中,常量只能被引用,不能被修
改。
在 C 程序中常用的字面量有以下几种:
第 1 种 整型(整数类型)。例如:100、314、0、-200 等。
示例代码
#include <stdio.h>
int main()
{
printf("%d
",200);
printf("%d
",-100);
getchar();
return 0;
}
程序分析:
- 在执行 printf 函数时,整数常量将取代双引号中的%d
- ‘ ’是换行符,即输出“200”后,控制台中的光标位置移到下一行的开头,下一个输出的内容-100 会出现在该光标位置上。注意 的方向,
第 2 种 浮点型。其实就是小数。
示例代码:
#include <stdio.h>
int main()
{
printf("%f
",3.14);
printf("%f
",-12.2);
getchar();
return 0;
}
默认情况下,输出浮点型保留小数点后 6 位数字。所以 3.14 会输出 3.140000,-12.2 输出-12.20000。
第 3 种 字符型。在程序中,使用英文单引号括起来的字符被称为字符型。例如:’a’、’1’、’=’、’?’、’#’等都是合法的字符。
【注意】
字符类型只能是单个字符,不能写成’ab’、’12’、’=?’。
示例代码:
#include <stdio.h>
int main()
{
printf("%c
",'A');
printf("%c
",'#');
getchar();
return 0;
}
第 4 种 字符串。在程序中,使用英文双引号将若干个字符括起来的都是字符串(注意不包括双引号本身)。例如:”124“、”hello”、”hello world”等。
【注意】
字符串只能使用双引号包裹,不能写成’124’、’hello’、’hello world’。
示例代码:
#include <stdio.h>
int main()
{
printf("123
");
printf("hello world");
getchar();
return 0;
}
(二) 变量
在 C 语言中,一个合法的变量由 3 部分组成:变量类型、变量名、变量值。变量类型:变量的类型是用来规定变量对应内存空间的大小和能盛放的东西。 变量名:变量名是用来标记变量对应的内存空间。就好比,有 10 个一模一样的杯子,从外表看根本无法区分。但是,如果给每个杯子都做一个标记,比如依次贴上标签:“1 号”、“2号”……“10 号”,这样就不会混淆了。同理,变量名也是同样的作用,通过变量名就可以精准的找到变量对应的内存空间。变量值:变量值是变量名标记内存空间中的数据。就好比,杯子中装的可乐、咖啡等。
(三) 标识符与关键字
1. 标识符
在 C 语言中,用来对变量,函数,数组等命名的字符序列被称为标识符。比如:变量名a、函数名 printf 等都是标识符。C 语言对标识符有以下规定:
- 只能由 26 个英文字母、数字或下划线 3 种字符组成。
- 第 1 个字符只能是字母或下划线。
- 大小写敏感的。
- 不能全部是关键字。
【注意】C 语言是严格区分大小写的,比如:max,Max,MAx,MAX 就是 4 个不相同
的标识符。
2. 关键字
C 语言中具有特殊用途的单词被称为关键字。当定义标识符时,不要让标识符与关键字相同,否则编译无法通过。C 语言共有如下的关键字:break、case、char、const、for、if、void、int、long 等。
(四) 基本数据类型
定义变量并赋初值的基本语法:变量类型 变量名=变量值;
比如:int a=3; 定义一个整数类型变量 a,a 的值是 3
1. 整数类型
int 可以定义整数类型(简称整型)。int 类型数据在 printf 函数中一般采用%d 格式进行输出,%d 表示“十进制整数”形式。
#include<stdio.h>
int main()
{
int a=200;
printf("%d
",a);
getchar();
return 0;
}
解释一下:int a=200;
printf("%d
",a);的意思是:把 a 的值带入参数的这个位置。和 printf("%d
",200);效果一样
注意,不要写成 printf("%d
","a");什么都不加,才代表变量。
2. 浮点数类型
浮点型有以下几种:
- 单精度浮点型(float)。
- 双精度浮点型(double)。
float、double 的区别在于表示范围和精度不一样。需要注意的就是给 float 赋值字面量的时候需要以 f 结尾,否则会有警告。
#include<stdio.h>
int main()
{
float f=3.14f;
double d=3.14;
printf("%f
",f);
printf("%lf
",d);
getchar();
return 0;
}
输出 double 要用%lf,虽然用%f 也行,但是建议用%lf。
VS2012 中执行的是 C89 标准,变量必须在所有其他代码之前。
3. 字符型
char 类型数据在 printf 函数中一般采用%c 格式进行输出。
#include<stdio.h>
int main()
{
char c='A';
printf("%c
",c);
getchar();
return 0;
}
4. 转义字符
在 C 语言中,有一类特殊字符,该类字符是以字符开头的字符序列。例’ ’,它代表一个“换行”符。这类字符无法用一般形式表示,只能采用这种特殊的形式表示,这类字符被称为转义字符。
-
‘ ’ 代表回车换行。
#include<stdio.h> int main() { printf("hello world "); printf("hello world); getchar(); return 0; } /* 输出结果 hello world hello world */
-
” 代表双引号字符(“)。
由于在 C 语言中,双引号已经被用于表示字符串的开始与结束标志,也就是说,双引号一般都是成对出现的。例如:”ABC”,’#?*’,”123”……等等。但是,如果在字符串中显示双引号,该如何表示呢?有些读者很自然的想到了下面的写法:
“hello”world” //错误写法
这是一种错误写法,前面已经讲过双引号(“)有特殊意义:当编译器读取到第一个双引号时认为是字符串的开始,读取到第二个双引号时认为是字符串的结束,然后把两个双引号之间的内容当做字符串解析。
由于编译器会把前两个双引号之间的内容当做字符串解析,把第三个单引号当做字符串开始标志对待,然后编译器会再去寻找下一个双引号当做字符串的结束标志,如果找不到就报错。
为了解决这种问题,在 C 语言中使用对双引号进行转义例如:”,此时双引号就是普通字符,不再具有特殊的意义。#include<stdio.h> int main() { printf("hello "world"); getchar(); return 0; }
-
单斜线()也是字符,该如何显示呢?使用对反斜线进行转义例如:\。
#include<stdio.h> int main() { printf("%c ",'\'); printf("hello\world"); getchar(); return 0; }
5. 字符与字符串的关系
在 C 语言中是没有字符串类型的,所谓的字符串本质上是由单个的字符构成,例如:”rupeng.com”,注意使用双银行包裹起来。”helloworld”可以看作由字符’h’、’e’、’l’、’l’、‘o’、’w’、’o’、’r’、’l’、’d’组成(其实结尾还有一个' ',初学者先不用理解这一点)。
在 printf 中用%s 输出字符串。
字符串是被拆分为单个字符进行存储,输出时也按照存储的顺序连续输出。做个形象的比喻:如果把字符串当做一串糖葫芦,字符就是每一个山楂:
6. printf 与数据类型
占位符 | 类型 | 说明 |
---|---|---|
%d 或者%i | int | 以十进制输出,%i 是老用法 |
%f | float | 还可以指定精度,%.2f 就是保留 2 位小数。 |
%lf | double | |
%c | char | 也可以用%d 输出 char,输出的就是字符的 ASCII 码 |
%s | 字符串 |
printf 中数据类型一定不能用错,float 类型必须用%f,整数必须用%d,如果用错了会发现结果很怪异。比如下面的错误代码:
printf("%f",3);
printf("%d",3.14f);
原理层面,这涉及到数据在内存中表示格式的问题
还有,在 printf 中也可以同时使用多个占位符,只要和参数的类型、个数能够对的上就
行:
printf("name=%s,age=%d,height=%f","djb",18,3.14f);
(五) 注释
C 语言中允许使用(双斜线)//注释一行代码,使用/* */注释多行代码,被注释的代码会被编译器忽略。
注释的作用主要有 2 点:
- 方便自己和他人理解这段代码。
- 暂时屏蔽不想参与编译的代码。
1. 单行注释
只能注释一行。在程序中,行注释以//开始,本行后面的内容都会被编译器忽略。
#include<stdio.h>
int main()
{
printf("My name is oldwang!"); //oldwang
//printf("oldwang
");
getchar();
return 0;
}
2. 块注释
块注释又被称为多行注释,/*表示注释开始,*/表示注释结束,/*与*/之前的内容将被编译器忽略。
#include<stdio.h>
int main()
{
printf("hello world");
/*
printf("hello world");
printf("hello world");
printf("hello world");
*/
getchar();
return 0;
}
注意/**/不能嵌套。
(六) 变量
1. 定义变量
在 C 语言中,变量只有被定义,才能使用,定义变量有两种形式:
第 1 种:先定义,后赋值,语法如下:
变量类型 变量名;
变量名 = 数据;
例如:
int a; //先定义 int 型变量 a
a =200; //然后将 200 赋值给变量 a
第 2 种 定义并赋值,语法如下:
变量类型 变量名=数据;
例如:
int a=200; //定义 int 变量 a 并赋值为 200
2. 引用变量
变量就是一个数据的“名字”,可以在代码中通过引用变量使用变量。分为 2 种情况:
- 给变量进行赋值。
- 读取变量中保存的数据。
如果变量出现在=号左边,就是给变量进行赋值,例如:a =100;
如果变量出现在=号右边,或单独出现就是读取变量中的保存的数据。例如:
a=100;
b=200;
a=b;
printf(“%d
”,a);
上述第 3 行,变量 a 在=号左边,变量 b 在=号右边。因此,a=b 执行过程为:先读取变
量 b 中保存的数据 200,然后赋值给变量 a,此时变量 a 的值是 200。
第 4 行,在 printf 函数中变量 a 是单独出现的,表示读取变量 a 中保存的数据。
3. 定义多个变量
C 语言中,定义多个变量有 2 种形式:
第 1 种: 在一行语句中,定义多个变量,语法结构:
变量类型 变量名 1,变量名 2,变量名 3,……; //变量之间以逗号分割
第 2 种:多行语句,定义多个变量,语句结构:
变量类型 变量名 1;
变量类型 变量名 2;
……
下面通过例子来了解在程序中如何定义多个变量。
定义多个变量。
#include<stdio.h>
int main()
{
int a=100,b=200; //一行定义 int 变量 a、b 且赋值
int c=300; //定义变量 c 且赋值
int d=400; //定义变量 d 且赋值
printf("a=%d
",a);
printf("b=%d
",b);
printf("c=%d
",c);
printf("d=%d
",d);
getchar();
return 0;
}
#include<stdio.h>
int main()
{
int a,b;
a=3;
b=4;
getchar();
return 0;
}
4. 语句与语句块
在 C 语言中,程序执行的最小单位为语句,一条合法的语句必须在末尾有一个分号。
C 语言中常用的语句有 5 种:
- 赋值语句
- 函数调用语句
- 空语句
- 复合语句(语句块)
- 控制语句
1. 赋值语句
赋值语句是 C 语言中最基本的语句,需要使用到赋值符号=,该符号的作用是将一个数据赋值给一个变量,例如:
a = 100; //将 100 赋值给变量 a
【注意】赋值语句中,赋值号=的左边必须是变量,不能是常量。
2. 函数调用语句
函数调用语句是 c 程序中,比较常用的语句,由函数调用与分号构成,例如:
printf(“hello world”);
3.空语句
该语句只有一个分号,例如:
;
空语句经常作为循环语句的循环体,表示什么也不做。
4. 复合语句(语句块)
复合语句又被称为语句块,在程序中,使用{ }将多行语句括起来就可以成为复合语句,
例如:
{
int a=3;
printf("a=%d
",a);
}
左花括号{表示复合语句开始,右花括号}表示复合语句结束。复合语句不会影响程序的正常执行,常常和控制语句一起使用。
语句块可以嵌套。
一般建议语句块中的代码进一步缩进,VS 也是默认这样控制的。
5. 顺序结构
顺序结构是 C 程序中最简单的程序结构。顺序结构的程序从第一行语句开始,按照代码排列的顺序,从上到下依次逐句执行,上一条语句执行结束下一条语句才能执行,直到最后一条语句结束。
#include<stdio.h>
int main()
{
int a=10;
printf("a=%d
",a);
a=20;
printf("a=%d
",a);
a=30;
printf("a=%d
",a);
getchar();
return 0;
}
解释:
int a=10;//声明变量 a,并且给 a 赋值为 10
a=20;//给 a 赋值为 20
6. 变量需要注意的问题
1.变量必须定义才能使用
#include<stdio.h>
int main()
{
a=200; //出错代码
printf("%d
",a); //出错代码
getchar();
return 0;
}
2. 所有变量要声明在方法的最开始
#include<stdio.h>
int main()
{
printf("hello"); //出错代码
int a=200;
printf("%d
",a);
getchar();
return 0;
}
VS2012 用的是 C89 标准,变量的定义必须在方法或者语句块的最开始,变量声明之前不能写其他代码。到了 VS2017 就没这个问题。
3. 变量重名问题
C 语言规定,同一作用域内变量定义不能重名。由于尚未学习函数,读者可以暂时理解为,同一个{ }中的变量名不能相同。
#include<stdio.h>
int main()
{
int a=100;
char a='A'; //出错代码
printf("%d
",a);
printf("%c
",a); //出错代码
getchar();
return 0;
}
(七) 局部变量
C 语言中,变量定义的位置可以分为 3 种:
- 在函数内定义。
- 在函数内的语句块中定义。
- 在函数外部定义。
在函数内部定义的变量被称为局部变量,在函数外部定义的变量被称为全局变量。前面编写的 C 程序中只包含一个 main 函数,并且变量也都定义在 main 函数中,因此前面中定义的变量都是局部变量。
1. 局部变量的作用域
变量的作用域指的是变量的有效作用范围,而局部变量的作用域仅限于函数内部以及语句块中。
局部变量的作用域需要分 2 种情况来讨论:
(1)在函数内部定义的变量只在本函数范围内有效,也就是说只有本函数内才能引用,本函数之外都不能引用这些变量。
(2)在函数内部语句块中定义的变量,只在本语句块范围内有效,也就是说只有在该语句块内才能引用,该语句块之外都不能引用这些变量。
#include<stdio.h>
int main()
{
{ //语句块开始
int a=200;
} //语句块结束
printf("a=%d
",a); //出错代码
getchar();
return 0;
}
在 C 语言中,局部变量的作用域以花括号进行区分
#include<stdio.h>
int main()
{
int a=100;
{
int b=200;
printf("a=%d
",a);
printf("b=%d
",b);
}
printf("a=%d
",a);
getchar();
return 0;
}
语句块中可以定义变量,也必须定义在其他语句之前
#include<stdio.h>
int main()
{
int a=100;
printf("hello");
{
int b=200;
printf("a=%d,b=%d
",a,b);
}
printf("a=%d
",a);
getchar();
return 0;
}
2. 局部变量使用前,必须初始化
在 C 语言中,第一次对变量进行的赋值操作被称为初始化。变量的初始化分为两种情况:
第一种 定义变量并且初始化,例如:
int a = 10; //定义并且初始化
第二种 先定义,后初始化,例如:
int a;
a=10;
变量初始化本质上就是赋值,不过只有第一次给变量赋值才能被称为初始化。而变量赋值就没有次数限制了,第几次都可以。
在 C 语言中,如果定义了局部变量,但是并未进行初始化,编译器并不会自动初始化局部变量,该局部变量的值将是未知的。因此,在程序中使用这样的变量是存在风险的。为了防止这种情况发生,在 VS2012 中,如果程序中使用了没有初始化的局部变量,调试程序的时候将报错(如果在运行模式下会输出不确定的值),下面通过例子来了解一下。
#include<stdio.h>
int main()
{
int a;
printf("a=%d
",a); //出错代码,使用了未初始化的局部变量
getchar();
return 0;
}