变量与常量

为了可能更加不便的应用数据,程序员会将在程序运行期间会扭转或赋值的数据应用变量进行保留。常量则是事后定义好,在程序运行期间不会扭转的固定值

变量和常量就如同是一个盒子,能够用来装货色(数据)。在计算机中,数据是寄存在内存中的,存放数据的内存空间程序员为了不便当前的应用,都会起一个好记的名字。这个名称也由字母、数字和下划线组成,必须要以字母和下划线结尾。因为C语言是对大小写敏感的,所以大写字母和小写字母是不同的,也就是变量名abc和Abc是两个不同的变量。

数据类型

不同的数据类型有不同的含意,有的数据类型示意整数,有的示意字符,有的示意浮点数。常量能够是任何的数据类型,通过常量的值辨认(100是整数,123.45是浮点数)。而变量则须要指定数据类型。在C语言中有很多种数据类型,从最后的K&R给出的7个数据类型关键字,再到C90增加的2个新的关键字,到最初的C99增加的3个关键字

最后K&R给出的关键字C90规范增加的关键字C99规范增加的关键字
intsigned_Bool
longvoid_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别离示意复数和虚数

存储大小

不同的数据类型能够寄存的数据大小是不同的,可能寄存的数据越多,值越大。

数据类型存储大小
char1字节
int2或4字节()
short2字节
long4字节
float4字节
double8字节
long double16字节

在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 常量---菜鸟教程