变量与常量
为了可能更加不便的应用数据,程序员会将在程序运行期间会扭转或赋值的数据应用变量进行保留。常量则是事后定义好,在程序运行期间不会扭转的固定值
变量和常量就如同是一个盒子,能够用来装货色(数据)。在计算机中,数据是寄存在内存中的,存放数据的内存空间程序员为了不便当前的应用,都会起一个好记的名字。这个名称也由字母、数字和下划线组成,必须要以字母和下划线结尾。因为 C 语言是对大小写敏感的,所以大写字母和小写字母是不同的,也就是变量名 abc 和 Abc 是两个不同的变量。
数据类型
不同的数据类型有不同的含意,有的数据类型示意整数,有的示意字符,有的示意浮点数。常量能够是任何的数据类型,通过常量的值辨认(100 是整数,123.45 是浮点数)。而变量则须要指定数据类型。在 C 语言中有很多种数据类型,从最后的 K &R 给出的 7 个数据类型关键字,再到 C90 增加的 2 个新的关键字,到最初的 C99 增加的 3 个关键字
最后 K &R 给出的关键字 | C90 规范增加的关键字 | C99 规范增加的关键字 |
---|---|---|
int | signed | _Bool |
long | void | _Complex |
short | _Imaginary | |
unsigned | ||
char | ||
float | ||
double |
int、long、short、unsigned 和 C90 新增加的 signed 关键字用于示意整数类型,unsigned 示意无符号数,signed 则示意有符号数,整数类型的例子:unsigned short int 和 long long int
char 关键字用于寄存字母和其余字符(如:$、% 等),char 也能够用来示意较小的整数
float、double 和 long double 示意浮点数
_Bool 示意布尔类型(true 或 false)
_Complex 和_Imaginary 别离示意复数和虚数
存储大小
不同的数据类型能够寄存的数据大小是不同的,可能寄存的数据越多,值越大。
数据类型 | 存储大小 |
---|---|
char | 1 字节 |
int | 2 或 4 字节() |
short | 2 字节 |
long | 4 字节 |
float | 4 字节 |
double | 8 字节 |
long double | 16 字节 |
在 C 语言中,能够通过 sizeof
运算符查看数据类型存储字节的大小
#include<stdio.h>
int main()
{printf("char 的存储大小: %d\n", sizeof(char));
printf("short 的存储大小: %d\n", sizeof(short));
printf("int 的存储大小: %d\n", sizeof(int));
printf("long 的存储大小: %d\n", sizeof(long));
printf("float 的存储大小: %d\n", sizeof(float));
printf("double 的存储大小: %d\n", sizeof(double));
printf("long double 的存储大小: %d\n", sizeof(long double));
return 0;
}
运行后果:
这里应用到的 printf()函数,前面会进行解说,目前只须要晓得 printf()是用来打印内容到屏幕上的就能够了。
变量的定义
C 语言提供了很多种数据类型,在定义变量时须要指定变量的数据类型,如整数能够应用 int 类型,小数能够应用 float 类型等,上面将开始介绍如何定义变量。
定义变量
定义变量的语法:数据类型 变量名;
举个例子,上面的程序用于计算两个整数的和
#include<stdio.h>
int main()
{
int num1; // 定义一个变量 num1,用于寄存第一个数
int num2; // 定义一个变量 num2,用于寄存第二个数
int sum; // 定义一个变量 sum,用于寄存两个数的和
num1 = 100; // 将整数 100 赋值给变量 num1
num2 = 200;
sum = num1 + num2; // 计算 num1 与 num2 相加,并将值赋值给 sum 变量
printf("num1 + num2 = %d\n", sum); // 将 sum 的值打印到屏幕
return 0;
}
运行后果:
在申明 num1 和 num2 变量时,并没有给它们提供初始值。num1 和 num2 是通过前面的 num1 = 100;
和 num2 = 200;
获取到值的,这种行为称为初始化。初始化就是给变量一个初始值。
定义变量时初始化
在下面的例子中,定义变量与给初始化变量是分成两步的,也能够将这两步合并在一起,将程序修改后如下:
#include<stdio.h>
int main()
{
int num1 = 100; // 定义变量 num1 并将 100 赋值给 num1
int num2 = 200;
int sum = num1 + num2; //num1 与 num2 相加后的后果赋值给 sum 变量
printf("num1 + num2 = %d\n", sum); // 将 sum 的值打印到屏幕
return 0;
}
间断定义多个变量
批改后的程序比之前的简洁了,接着咱们发现 num1 和 num2 的数据类型是雷同的,都是 int 类型,那么这两个变量就能够一起定义,还是下面的例子,批改后如下:
#include<stdio.h>
int main()
{
int num1 = 100, num2 = 200; // 同时申明 num1 和 num2 并赋值
int sum = num1 + num2; //num1 与 num2 相加后的后果赋值给 sum 变量
printf("num1 + num2 = %d\n", sum); // 将 sum 的值打印到屏幕
return 0;
}
须要留神的是,为了不让人误会在同时定义多个变量时,有的变量不须要初始化,而有的变量须要进行初始化。那么不倡议写在一起,倡议离开定义,如int num1, num2= 200;
这样写很容易让人误以为 num1 和 num2 的值都是 200,所以不倡议这么写,当然这么写是不会报错的。
常量的定义
通过一个例子开始解说常量的应用,上面的程序的作用是计算圆的周长和面积:
#include<stdio.h>
int main(void)
{
float pi = 3.14159; // 圆周率
int r = 5; // 圆的半径
float area = pi * r * r; // 计算圆的面积
float circum = 2 * pi * r; // 计算圆的周长
printf("半径为 %d 的圆面积是: %.2f, 周长是: %.2f", r, area, circum);
return 0;
}
通过下面的例子能够晓得变量也能够当做常量来应用,然而在理论应用的时候不倡议这么应用,因为在程序运行过程中有可能会将定义的变量扭转,变量并非不可扭转的。那有没有更好的定义常量的办法呢?有,这就须要应用预处理语句定义一个常量,这样定义的常量也被称为符号常量。语法是:#define NAME value
应用预处理语句,批改下面的例子:
#include<stdio.h>
#define PI 3.14159 // 应用预处理语句定义圆周率
int main(void)
{
int r = 5; // 圆的半径
float area = PI * r * r; // 计算圆的面积
float circum = 2 * PI * r; // 计算圆的周长
printf("半径为 %d 的圆面积是: %.2f, 周长是: %.2f", r, area, circum);
return 0;
}
预处理语句的作用是在编译的时候将 PI 替换为 3.14159,这样就达到了常量的作用了。预处理语句肯定要写在顶部,并且 PI 和 3.14159 之间是没有等号和完结时也没有分号的。后面也说了预处理语句是在编译时替换掉值,如果有了等号和分号,那么等号和分号也会变成要替换的值了。
还有一种办法是应用限定符 const
将变量限定为只读,批改下面的例子如下:
#include<stdio.h>
int main(void)
{
const float pi = 3.14159; // 应用限定符 const,定义常量圆周率
int r = 5; // 圆的半径
float area = pi * r * r; // 计算圆的面积
float circum = 2 * pi * r; // 计算圆的周长
printf("半径为 %d 的圆面积是: %.2f, 周长是: %.2f", r, area, circum);
return 0;
}
应用 const
限定符定义的变量 pi 能够应用,能够应用 printf()
打印值,但就是无奈批改值。另外须要留神的是应用 const
限定符定义的是变量,不是常量。
输入输出
输入
在 C 语言中,通过 printf()
将内容输入到屏幕上,printf()
也被称为格式化输入,能够让变量以某种格局输入到屏幕上,如 %d 为以整数的模式显示,%f 以浮点数的模式显示,下表列出了一些转换阐明和各自对应的输入类型:
转换阐明 | 输入 |
---|---|
%a | 浮点数、十六进制和 p 记数法 |
%A | 浮点数、十六进制和 p 记数法 |
%c | 单个字符 |
%d | 有符号十进制整数 |
%e | 浮点数,e 记数法 |
%E | 浮点数,e 记数法 |
%f | 浮点数,十进制记数法 |
%g | 依据值的不同,主动抉择 %f 或 %e。%e 格局用于指数小于 - 4 或者大于或等于精度时 |
%G | 依据值的不同,主动抉择 %f 或 %E。%E 格局用于指数小于 - 4 或者大于或等于精度时 |
%i | 有符号十进制整数(与 %d 雷同) |
%o | 无符号八进制整数 |
%p | 指针 |
%s | 字符串 |
%u | 无符号十进制整数 |
%x | 无符号十六进制整数, 应用十六进制数 0f |
%X | 无符号十六进制整数, 应用十六进制数 0F |
%% | 打印一个百分号 |
一开始不须要全副都记住,只须要记住几个罕用的 (如:%d,%f,%c) 即可,其余的用到在看就能够了,用的多了就记住了。上面的例子是将一个整数以八进制和十六进制的模式显示:
#include<stdio.h>
int main(void)
{
int num = 100;
printf("100 的八进制为 %o\n", num); // 显示 num 的八进制
printf("100 的八进制为 %#o\n", num); // 显示 num 的八进制时,并在后面加上前缀
printf("100 的十六进制为 %x\n", num); // 显示 num 的十六进制
printf("100 的十六进制为 %#x\n", num); // 显示 num 的十六进制,并在后面加上前缀
return 0;
}
运行后果:
能够通过 printf()函数配合 %o 和 %x 打印出数值的八进制模式和十六进制模式。# 只是为了显示前缀,八进制以 0 结尾,十六进制以 0x 结尾
有的读者可能不太理解什么是八进制和十六进制,那就简略的介绍一下。咱们日常说的 10,100,123 等数字,都是十进制,能够发现这些数字都是逢十进一,而八进制和十六进制同理,八进制就是逢八进一,十六进制是逢十六进一。有的读者就会问了,逢十六进一?那要怎么示意十以上的数呀?十六进制由 1 到 9 和 a 到 f(也能够是 A 到 F)组成,没错,a 到 f 别离示意 10 到 15。
参数与陷阱
在应用printf()
和 scanf()
时须要确保转换阐明的数量、类型与前面的参数数量、类型匹配。因为 printf()
和 scanf()
的参数是可变的,所以无奈查看出参数的个数和类型是否正确。
那如果参数个数不匹配会怎么呢?
#include<stdio.h>
int main(void)
{
int num1 = 1;
float num2 = 1.23;
printf("%d %d %d\n", num1, num1, num1, num1); // 参数太多
printf("%d %d %d\n", num1); // 参数太少
printf("%d\n", num2); // 类型不匹配
return 0;
}
运行后果:
当应用 %d 打印一个浮点数时,不会将这个浮点数转换为 int 类型。在不同的平台下,短少参数或参数类型不匹配导致的后果会不雷同。
输出
在后面的两个数相加的例子中,两个相加的数是事后就设置好的,当要计算其余整数相加时,须要批改源文件并生成新的可执行文件,这就很麻烦,这是就能够让用户输出要进行计算的两个整数。
要想获取用户的输出能够应用 scanf()
进行接管,应用的办法与 printf()
类似,%d 示意要接管整数,%f 示意要接管一个浮点数。
批改程序:
#include<stdio.h>
int main(void)
{
int num1, num2; // 同时申明 num1 和 num2
scanf("%d %d", &num1, &num2); // 获取用户输出的 num1 和 num2 的值
int sum = num1 + num2; //num1 与 num2 相加后的后果赋值给 sum 变量
printf("num1 + num2 = %d\n", sum); // 将 sum 的值打印到屏幕
return 0;
}
运行后果:
运行完程序,应该能够发现如果这是给程序员本人应用,那当然没有任何问题,然而给其他人应用,会呈现不晓得要干嘛的状况。所以应该在程序接管用户输出之前,通知用户要做什么,再次批改程序:
#include<stdio.h>
int main(void)
{
int num1, num2; // 同时申明 num1 和 num2
printf("请输出两个须要相加的整数(例:12 34):"); // 提醒用户输出两个整数
scanf("%d %d", &num1, &num2); // 获取用户输出的 num1 和 num2 的值
int sum = num1 + num2; //num1 与 num2 相加后的后果赋值给 sum 变量
printf("num1 + num2 = %d\n", sum); // 将 sum 的值打印到屏幕
return 0;
}
运行后果:
仔细的读者会发现在 num1 和 num2 的后面有一个 & 符号,那这个 & 符号示意的是什么意思呢?& 符号示意获取地址,整个语句就是将获取到的整数放入到 num1 和 num2 的地址中。
当读取的是根本的数据类型的值时须要应用 & 符号,而读取的是字符串时,不要应用 & 符号。
整数溢出
当一个整数类型超出了它能示意的最大值会呈现溢出,通过一个例子察看溢出后的后果
#include<stdio.h>
int main(void)
{
int i = 2147483647; // 定义一个有符号整数类型的变量 i 并初始化为最大值
unsigned int j = 4294967295; // 定义一个无符号整数类型的变量 j 并初始化为最大值
printf("%d %d %d\n", i, i+1, i+2);
printf("%u %u %u\n", j, j+1, j+2);
return 0;
}
运行后果:
通过观察能够发现当一个数超过本身可能示意的最大值时,会从最小值开始。当产生溢出时零碎没有通知用户,所以在编程时须要留神。
char 类型
char 类型用于寄存字符(如:字母或标点符号),但 char 其实是整数类型,因为 char 实际上保留的是整数,而不是字符。有的读者就会有疑难了,存储整数,那要怎么晓得是哪个字符呢?在计算机中应用数字编码解决字符,即应用整数示意字符,在 ASCII 编码中 65 示意大写字母 ”A”,规范的 ASCII 的范畴是 0~127,齐全能够应用 char 类型进行存储
申明 char 类型变量
char 类型的变量在赋值时,值须要应用单引号括起来,如:char ch = 'A';
,而不能是 char ch = A;
。如果没有被单引号括起来,此时 A 示意一个变量名,而不是字符 A。
char 类型也能够间接保留整数,如 char ch = 65;
,然而不倡议这样应用,这样应用须要零碎反对 ASCII 码,最好还是应用‘A’替换 65。
举个例子
用户输出一个字符,将这个字符对应的 ASCII 码打印在屏幕上:
#include<stdio.h>
int main(void)
{
char ch; // 定义变量 ch,用于接管用户输出
printf("请输出一个字符(如:A):");
scanf("%c", &ch); // 接管用户输出的字符
printf("%c 对应的整数为 %d\n", ch, ch);
return 0;
}
运行后果:
转义字符
应用非凡的符号序列示意一些非凡的字符,这些符号序列就叫做转义序列,下表列出了转义序列及其含意
转义序列 | 含意 |
---|---|
\a | 警报(ANSI C) |
\b | 退格 |
\f | 换页 |
\n | 换行 |
\r | 回车 |
\t | 程度制表符(相当于 tab 键) |
\v | 垂直制表符 |
\\ | 反斜杠() |
\’ | 单引号 |
\” | 双引号 |
? | 问号 |
\0oo | 八进制值(oo 必须是无效八进制数) |
\xhh | 十六进制值(hh 必须是无效十六进制数) |
通过一个例子更好的了解转义字符:
#include<stdio.h>
int main(void)
{
float salary;
printf("\aEnter your desired monthly salary:");
printf("$_______\b\b\b\b\b\b\b");
scanf("%f", &salary);
printf("\n\t$%.2f a month is $%.2f a year.", salary, salary * 12.0);
printf("\rGee!\n");
return 0;
}
运行后果:
解析:
在程序的第 7 行 printf("\aEnter your desired monthly salary:");
中的 \a
会收回警报的声音(是否收回警报取决于硬件,有可能不会收回警报)
接着第 8 行的 printf("$_______\b\b\b\b\b\b\b");
先将 $_______打印进去呢,接着应用 \b
挪动光标,使光标紧跟 $ 符
在第 10 行的 printf("\n\t$%.2f a month is $%.2f a year.", salary, salary * 12.0);
首先是 \n
进行换行,接着是制表符 \t
使前面的内容缩进。光标停留在最初的点那里(.),如下图:
在第 11 行的 printf("\rGee!\n");
\r
将光标挪动到以后行是起始地位,再打印内容,最初的 \n
换行
reference
《C Primer Plus》(第六版)
大话 C 语言变量和数据类型 —C 语言中文网
C 语言转义字符 —C 语言中文网
C 数据类型 — 菜鸟教程
C 变量 — 菜鸟教程
C 常量 — 菜鸟教程