> 文章列表 > C语言入门篇——数据篇

C语言入门篇——数据篇

C语言入门篇——数据篇

目录

1、变量与常量

1.1变量

1.2常量

1.2.1#define 定义的标识符常量

1.2.2枚举常量

2、数据类型关键字

3、整数

4、浮点数

5、基本数据类型

5.1、int型数据

5.2、char型数据

5.3、_Bool类型

5.4、float、double和long double

5.5、复数和虚数类型

6、总结


1、变量与常量

有些数据类型在程序使用之前已经预先设定好了,在整个程序的运行过程中没有变化,这些称为常量。

其他数据类型在程序与运行期间可能会改变或被赋值,这些称为变量。

1.1变量

变量的定义:

数据类型(type) 变量名字(name);

type:一个有效的 C 数据类型

命名规则:可以使用小写字母、大写字母、数字和下划线(_)来命名。而且,名称的第一个字符必须是字符或下划线,不能是数字

变量又分为局部变量和全局变量 (主函数外定义)

当一个程序代码里面有着同名的局部变量和全局变量则优先使用局部变量。

 那全局变量和局部变量有着什么区别呢?

主要是在于作用域和生命周期

作用域:程序设计概念,通常来说,一段程序代码中所用到的名字并不总是有效/可用的

1. 局部变量的作用域是变量所在的局部范围。

2. 全局变量的作用域是整个工程。

生命周期:变量的创建到变量的销毁之间的一个时间段

1. 局部变量的生命周期是:进入作用域生命周期开始,出作用域生命周期结束。

2. 全局变量的生命周期是:整个程序的生命周期。

1.2常量

C语言的常量分为以下几种:

1、字面常量

2、const 修饰的常变量

3、#define 定义的标识符常量

4、枚举常量

字面常量包括:整形常量,字符型常量,字符串常量。注意:不存在数组常量,结构体常量等结构型的字面常量。但是存在结构型的符号常量。指的是直接输入到程序中的值

const是一个关键字,用const修饰的变量pai叫做常变量,在C语言中只是在语法层面限制了变量pai不能直接被改变,但是pai本质上还是一个变量,所以叫常变量

1.2.1#define 定义的标识符常量

符号常量也叫明示常量,用#define预处理器指令来定义符号变量。#define预处理器指令和其他预处理指令一样,以#号作为一行的开始。ANSI和后来的标准都允许#号前面有空格或制表符,而且还允许在#和指令的其余部分之间有空格。但是旧版本的C要求指令从一行的最左边开始,,而且#和只能怪其余部分之间不能有空格。指令可以出现在源文件的任何地方。

预处理指令从#开始运行,到后面的第一个换行符为止。在预处理开始前,编译器会把多行物理行处理为一行逻辑行。

每行#define(预处理)都由3部分组成。第一部分是#define指令本身。第二部分是选定的缩写,也成为宏。有些宏代表值,这些宏被称为类对象宏。C语言还有类函数宏。第3部分被称为替换列表或替换体,一旦预处理器在程序中找到宏实例后,就会用替换体替换该宏。从宏变成最终替换文本的过程称为宏展开。注意,可以在#define行使用标准C注释,每条注释都会被一个空格代替。

#define PI 3.1415

#define MAX(x,y) (x)>(y)?(x):(y) 

1.2.2枚举常量

可以用枚举类型声明符号名称来表示整型常量。使 用enum关键字,可以创建一个新“类型”并指定它可具有的值(实际上,enum 常量是int类型,因此,只要能使用int类型的地方就可以使用枚举类型)。枚举类型的目的是提高程序的可读性。它的语法与结构的语法相同。

枚举格式:

enum enumerate {枚举符1,枚举符2,...,枚举符N};

enum enumerate {枚举符1=值1,枚举符2=值2,...,枚举符N};

虽然枚举符是int类型,但是枚举变量可以是任意整数类 型,前提是该整数类型可以储存枚举常量。C语言是允许枚举变量使用++运算符。

默认情况下,枚举列表中的常量都被赋予0、1、2等。在枚举声明中,可以为枚举常量指定整数值:

enum spectrum {red, orange=100, yellow};

如果只给一个枚举常量赋值,没有对后面的枚举常量赋值,那么后面的常量会被赋予后续的值。

枚举的优点:

1. 增加代码的可读性和可维护性

2. 和#define定义的标识符比较枚举有类型检查,更加严谨。

3. 防止了命名污染(封装)

4. 便于调试

5. 使用方便,一次可以定义多个常量

枚举常用于switch语句中,充当case标签后面的表达式。

2、数据类型关键字

C通过识别一些基本的数据类型来区分和使用这些不同的数据类型。

C语言的数据类型关键字
最初K&R给出的关键字 C90标准添加的关键字 C99标准添加的关键
int signed _Bool
long void _Complex
short _Imaginary
unsingned
char
float
double

2

在C与语言中,用int关键字来表示基本的整数类型。后三个关键字(long,short和unsigned)和C90新增的signed用于提供基本证书类型的变式。另外,char类型也可以表示较小的整数。float、double和long double表示带小数点的数。_Bool类型表示布尔值(true或false),_Complex和_Imaginary分别表示复数和虚数。

通过关键字创建的类型,按计算机的存储方式可分为两大基本类型:整数类型和浮点数类型

学习整数类型和浮点数类型之前,我们首先要知道几个概念

位,字节和字

位、字节和字是描述计算机数据单元或存储单元的术语

最小的存储单元是位(bit),可以储存0或1(或者说,位用于设 置“开”或“关”)。虽然1位储存的信息有限,但是计算机中位的数量十分庞 大。位是计算机内存的基本构建块。

字节(byte)是常用的计算机存储单位。对于几乎所有的机器,1字节 均为8位。这是字节的标准定义,至少在衡量存储单位时是这样。既然1位可以表示0或1,那 么8位字节就有256(2的8次方)种可能的0、1的组合。通过二进制编码(仅用0和1便可表示数字),便可表示0~255的整数或一组字符。

字(word)是设计计算机时给定的自然存储单位。对于8位的微型计算 机(如,最初的苹果机),1个字长只有8位。从那以后,个人计算机字长增至16位、32位,直到目前的64位。计算机的字长越大,其数据转移越快, 允许的内存访问也更多。

现在的电脑都是32位或64位,我们可以写一个测试代码来查看一下各种类型数据的字节大小:

 可以敲敲键盘测试自己的编译软件会给自己返回什么答案。(sizeof作为一个关键字,这里用于判断变量或数据类型的字节大小)

3、整数

和数学的概念一样,在C语言中,整数是没有小数部分的数。例如,1111,2222和-1111都是整数,而3.14和2.7就不是整数。计算机是以二进制数字存储整数,以整数11来做一个例子:

而整数实质上是4个字节,剩下三个字节系统会给你自动补为0。

4、浮点数

浮点数与数学中实数的概念差不多。3.14,3.15E10和3e-3都是浮点数。注意,在一个值后面加上一个小数点,这个值就成为一个浮点值。浮点数有许多的书写格式,浮点数和整数的存储方式不一样。计算机把浮点数分成效数部分和指数部分来表示,而且分开存储这两个部分。

 整数和浮点数的实际区别:

1、整数没有小数部分,浮点数有小数部分

2、浮点数可以表示的范围比整数大

3、对于一些算数运算,浮点数损失的精度更多

4、计算机的浮点数不能表示区间内所有的值。浮点数通常只是实际值的近似值

5、浮点运算比整数运算慢

5、基本数据类型

5.1、int型数据

C语言提供了许多整数类型,C语言让程序员针对不同情况选择不同的类型。特别是,C语言中的整数类型可表示不同的取值范围和正负值。一般情况使用int类型即可,但是为满足特定任务和机器的要求,还可以选择其他类型。ISO C规定int的取值范围最小为-32768~32767。一般而言,系统用一个特殊位的值表示有符号整数的正负号。

5.1.1、声明int变量

声明格式:

int 变量名;

int 变量名1,变量名2...变量名N;

int 变量名 = 值;

声明多个变量的时候,可以单独声明每个变量,也可以在int后面列出多个变量名,变量名之间用逗号(,)分隔。声明变量创建了变量,但是并没有给它们赋值。此时访问变量的值是未知的。程序中获取值途径方法:1、赋值 2、通过函数获得值 3、初始化变量

5.1.2、初始化变量

初始化变量就是给变量赋一个初始值。在C语言中,初始化可以直接在声明中完成。只需要在变量名后面加上给复制运算符( = )和变量值就可以了。

注意:不要把初始化的变量和未初始化的变量放在同一条声明,这给程序员会带来很糟糕的印象。

声明为变量创建和标记存储空间,并为其指定初始值

3、打印int值

用printf()函数打印int类型的值。%d指明了在一行中打印整数的位置。%d称为转换说明,它指定了printf()应使用什么格式 来显示一个值。格式化字符串中的每个%d都与待打印变量列表中相应的int 值匹配。这个值可以是int类型的变量、int类型的常量或其他任何值为int类型的表达式。作为计算机小白,低级的错误可不要犯,一定要确保转换说明的数量与待打印值的数量相同,不然会报错。

通常,C语言都假定整型常量是十进制,但是有一些情景需要我们使用八进制或者十六进制。八进制和十六进制技术系统在表达与计算机相关的值时很方便。怎么利用printf()函数输出不同进制的数呢?以十进制显示数字,使用%d;以八进制显示数字,使用%o;以十六进制显示数字,使用%x。如果需要显示各进制的前缀0、0x和0X,则必须分别使用%#o、%#x、%#X。

写一个相关代码来测试一下以上的内容,否则读者也不知道是否是正确的,读者也可以尝试敲敲代码,通过代码可以更好的吸收以上的知识点:

 代码没有报错,也能成功运行出结果,检验运行效果和上面是否一致。

4、其他整数类型

初学者可能认为对于整数来说,一个int型就可以满足大多数程序的需求,但我们还需要了解一下整型的其他形式。

C语言提供三个附属关键字修饰基本整数类型:short,long和unsigned。

short int类型(或者简写为short)占用的存储空间可能比int类型少,常用于较小数值的场合以节省空间。与int类似,short是有符号类型。

long int或long占用的存储空间可能比int多,适用于较大数值的场合。与 int类似,long是有符号类型。

long long int或long long(C99标准加入)占用的储存空间可能比long多, 适用于更大数值的场合。该类型至少占64位。与int类似,long long是有符号 类型。

unsigned int或unsigned只用于非负值的场合。这种类型与有符号类型表 示的范围不同。例如,16位unsigned int允许的取值范围是0~65535,而不 是-32768~32767。用于表示正负号的位现在用于表示另一个二进制位,所 以无符号整型可以表示更大的数。 

在C90标准中,添加了unsigned long int或unsigned long和unsigned int或 unsigned short类型。C99标准又添加了unsigned long long int或unsigned long long。

在任何有符号类型前面添加关键字signed,可强调使用有符号类型的意图。例如,short、short int、signed short、signed short int都表示同一种类型。

5、整数溢出

当整数超出相应类型的取值范围会怎样呢?有的人可能会认为不会错误,也有人可能认为程序会报错,我们直接通过一段代码来进行判断:

 程序并没有给我们的代码报错,而是正常输出结果,但结果可能会有些奇怪,但是确实是正常的。我们可以把无符号整数max_uint看作是汽车的历程表,当达到它能表示的最大值时,会重新从起始点开始。整数max_int也是类似的情况,最大的区别就是,在超过最大值时,unsigned int类型的变量从0开始,而int类型的变量从负数开始。当出现整数溢出这种情况,系统并不会通知我们,因此我们在编程的时候要注意整数溢出的问题。

 

 读者可以写写代码测试一下其他整数类型的有符号和无符号数据的最大值以及它们数据溢出发生的情况,下面附上climits中的符号常量:

符号常量 表示
CHAR_BIT char 的位数
CHAR_MAX char的最大值
CHAR_MIN char 的最小值
SCHAR_MAX signed char的最大值
SCHAR_MIN signed char 的最小值
UCHAR_MAX unsigned char的最大值
SHRT_MAX short的最大值
SHRT_MIN short 的最小值
USHRT_MAX unsigned short 的最大值
INT_MAX int 的最大值
INT_MIN int 的最小值
UNIT_MAX unsigned int的最大值
LONG_MAX long 的最大值
LONG_MIN long 的最小值
ULONG_MAX unsignedlong 的最大值
LLONG_MAX long long 的最大值
LLONG_MIN long long 的最小值
ULLONG_MAX unsignedlong long 的最大值

5.2、char型数据

 char型数据用于存储字符(如,字母或标点符号),但它实际上也是整数类型,因为char类型实际上储存的是整数而不是字符。计算机使 用数字编码来处理字符,即用特定的整数表示特定的字符。美国最常用的编码是ASCII编码。标准ASCII码的范围是0~127,只需7位二进制数即可表示。通常,char 类型被定义为8位的存储单元。

ASCLL打印字符表
ASCII 码 字符 ASCII 码 字符 ASCII 码 字符 ASCII 码 字符
十进位 十六进位 十进位 十六进位 十进位 十六进位 十进位 十六进位
032 20 056 38 8 080 50 P 104 68 h
033 21 ! 057 39 9 081 51 Q 105 69 i
034 22 " 058 3A : 082 52 R 106 6A j
035 23 # 059 3B ; 083 53 S 107 6B k
036 24 $ 060 3C < 084 54 T 108 6C l
037 25 % 061 3D = 085 55 U 109 6D m
038 26 & 062 3E > 086 56 V 110 6E n
039 27 ' 063 3F ? 087 57 W 111 6F o
040 28 ( 064 40 @ 088 58 X 112 70 p
041 29 ) 065 41 A 089 59 Y 113 71 q
042 2A * 066 42 B 090 5A Z 114 72 r
043 2B + 067 43 C 091 5B [ 115 73 s
044 2C , 068 44 D 092 5C \\ 116 74 t
045 2D - 069 45 E 093 5D ] 117 75 u
046 2E . 070 46 F 094 5E ^ 118 76 v
047 2F / 071 47 G 095 5F _ 119 77 w
048 30 0 072 48 H 096 60 ` 120 78 x
049 31 1 073 49 I 097 61 a 121 79 y
050 32 2 074 4A J 098 62 b 122 7A z
051 33 3 075 4B K 099 63 c 123 7B {
052 34 4 076 4C L 100 64 d 124 7C |
053 35 5 077 4D M 101 65 e 125 7D }
054 36 6 078 4E N 102 66 f 126 7E ~
055 37 7 079 4F O 103 67 g 127 7F DEL

 这里我列出ASCIl 打印字符,还有ASCLL非打印字符和扩展ASCLL打印字符我就不详细介绍了。

1、声明char类型变量

char类型变量的声明方式与其他类型变量的声明方式相同。

2、字符常量和初始化

如果要把一个字符常量初始化为字母 A,不必背下 ASCII 码,用计算机语言很容易做到。通过以下初始化把字母A赋给grade即可:

char grade = 'A';

在C语言中,用单引号括起来的单个字符被称为字符常量(character constant)。编译器一发现'A',就会将其转换成相应的代码值。单引号必不可少。如果忽略单引号,编译器会认为是一个变量名;如果写成双引号,编译器则认为是字符串(后面将介绍)。实际上,字符是以数值形式储存的,所以也可使用数字代码值来赋值。

想一想,如果char类型数据在printf()函数里面用%d输出会显示什么内容?

 可以看到%c形式输出就是我们的char型数据原来的值,而%d形式输出的就是其对应的ASCll的值,通过下面这张图片来更为深刻的了解其工作原理:

3、有符号还是无符号

有些C编译器把char实现为有符号类型,这意味着char可表示的范围 是-128~127。而有些C编译器把char实现为无符号类型,那么char可表示的 范围是0~255。根据C90标准,C语言允许在关键字char前面使用signed或unsigned。这样,无论编译器默认char是什么类型,signed char表示有符号类型,而 unsigned char表示无符号类型。

5.3、_Bool类型

C99标准添加了_Bool类型,用于表示布尔值,即逻辑值true和false。因 为C语言用值1表示true,值0表示false,所以_Bool类型实际上也是一种整数 类型。但原则上它仅占用1位存储空间,因为对0和1而言,1位的存储空间足够了。程序通过布尔值可选择执行哪部分代码。(后面将详细介绍)

5.4、float、double和long double

各种整数类型对大多数软件开发项目而言够用了。然而,面向金融和数 学的程序经常使用浮点数。C语言中的浮点类型有float、double和long double 类型。浮点类型 能表示包括小数在内更大范围的数。浮点数的表示类似于科学记数法(即用 小数乘以10的幂来表示数字)。该记数系统常用于表示非常大或非常小的数。

计数法示例
数字 科学计数法 指数计数法
3.1415 1.0×10 9 1.0e9
0.212 5.6×10-5 5.6e-5

C标准规定,float类型必须至少能表示6位有效数字,且取值范围至少是 10 -37~10 +37。前一项规定指float类型必须至少精确表示小数点后的6位有效 143 数字,如33.333333。后一项规定用于方便地表示诸如太阳质量(2.0e30千克)、一个质子的电荷量(1.6e-19库仑)或国家债务之类的数字。通常, 系统储存一个浮点数要占用32位。其中8位用于表示指数的值和符号,剩下 24位用于表示非指数部分(也叫作尾数或有效数)及其符号。

C语言提供的另一种浮点类型是double(意为双精度)。double类型和 float类型的最小取值范围相同,但至少必须能表示10位有效数字。一般情况 下,double占用64位而不是32位。一些系统将多出的 32 位全部用来表示非 指数部分,这不仅增加了有效数字的位数(即提高了精度),而且还减少了 舍入误差。另一些系统把其中的一些位分配给指数部分,以容纳更大的指 数,从而增加了可表示数的范围。无论哪种方法,double类型的值至少有13 位有效数字,超过了标准的最低位数规定。

C语言的第3种浮点类型是long double,以满足比double类型更高的精度 要求。不过,C只保证long double类型至少与double类型的精度相同。

1.声明浮点型变量

浮点型变量的声明和初始化方式与整型变量相同

2.浮点型常量

在代码中,可以用多种形式书写浮点型常量。浮点型常量的基本形式 是:有符号的数字(包括小数点),后面紧跟e或E,最后是一个有符号数表示10的指数。正号可以省略。可以没有小数点或指数部分,但是不能同时省略两者。可以省略小数部分或整数部分,但是不能同时省略两者。

有的初学者可能在定义浮点型常量的时候,不小心在中间加空格,这是一种错误的书写格式。

默认情况下,编译器假定浮点型常量是double类型的精度。在浮点数后面加上f或F后缀可覆盖默认设置,编译器会将浮点型常量看作float类型;在浮点数后面加上f或F后缀可覆盖默认设置,编译器会将浮点型常量看作float类型;没有后缀的浮点型常量是double类型。

printf()函数使用%f和%lf转换说明打印十进制记数法的float和double类型浮点数,用%e打印指数记数法的浮点数。如果系统支持十六进制格式的浮点 数,可用a和A分别代替e和E。打印long double类型要使用%Lf、%Le或%La 转换说明。

 3、浮点值的上溢和下溢

当计算导致数字过大,超过当前类型能表达的范围时,就会发生上溢(overflow)。

当除以一个很小的数时,情况更为复杂。float类型的数以指 数和尾数部分来储存。存在这样一个数,它的指数部分是最小值,即由全部可用位表示的最小尾数值。该数字是float类型能用全部精度表示的最小数字。现在把它除以 2。通常,这个操作会减小指数部分,但是假设的情况 中,指数已经是最小值了。所以计算机只好把尾数部分的位向右移,空出第 1 个二进制位,并丢弃最后一个二进制数。以十进制为例,把一个有4位有效数字的数(如,0.1234E-10)除以10,得到的结果是0.0123E-10。虽然得到了结果,但是在计算过程中却损失了原末尾有效位上的数字。这种情况叫 作下溢(underflow)。

C语言把损失了类型全精度的浮点值称为低于正常的浮点值。

5.5、复数和虚数类型

许多科学和工程计算都要用到复数和虚数。C99 标准支持复数类型和虚 数类型,但是有所保留。C语言有3种复数类型:float_Complex、double_Complex和 long double _Complex。C语言的3种虚数类型是float _Imaginary、double _Imaginary和long double _Imaginary。如果包含complex.h头文件,便可用complex代替_Complex,用imaginary 代替_Imaginary。这里不多加介绍,有兴趣可以通过其他途径学习。

6、总结

到这里,我们已经学习了C语言的部分基本数据类型,对此做个总结:

关键字:基本数据类型由11个关键字组成:int、long、short、unsigned、char、float、double、signed、_Bool、_Complex和_Imaginary

有符号整型可用于表示正整数和负整数。

int ——系统给定的基本整数类型。C语言规定int类型不小于16位。

short或short int ——最大的short类型整数小于或等于最大的int类型整数。C语言规定short类型至少占16位。

long或long int ——该类型可表示的整数大于或等于最大的int类型整数。 C语言规定long类型至少占32位。

long long或long long int ——该类型可表示的整数大于或等于最大的long 类型整数。Long long类型至少占64位。

一般而言,long类型占用的内存比short类型大,int类型的宽度要么和 long类型相同,要么和short类型相同。

无符号整型:只能用于表示零和正整数,因此无符号整型可表示的正整数比有符号整型的大。在整型类型前加上关键字unsigned表明该类型是无符号 整型:unsignedint、unsigned long、unsigned short。单独的unsigned相当于 unsigned int。

字符类型:可打印出来的符号(如A、&和+)都是字符。根据定义,char类型表示 一个字符要占用1字节内存。

char ——字符类型的关键字。有些编译器使用有符号的char,而有些则 使用无符号的char。在需要时,可在char前面加上关键字signed或unsigned来 指明具体使用哪一种类型。

布尔类型:布尔值表示true和false。C语言用1表示true,0表示false。

_Bool ——布尔类型的关键字。布尔类型是无符号 int类型,所占用的空间只要能储存0或1即可。

实浮点类型:实浮点类型可表示正浮点数和负浮点数。

float ——系统的基本浮点类型,可精确表示至少6位有效数字。

double ——储存浮点数的范围(可能)更大,能表示比 float 类型更多的有效数字(至少 10位,通常会更多)和更大的指数。

long long ——储存浮点数的范围(可能)比double更大,能表示比 double更多的有效数字和更大的指数。

复数和虚数浮点数:虚数类型是可选的类型。复数的实部和虚部类型都基于实浮点类型来构 成

如何声明简单变量:

1.选择需要的类型。

2.使用有效的字符给变量起一个变量名。

3.按以下格式进行声明: 类型说明符 变量名;

4.可以同时声明相同类型的多个变量,用逗号分隔各变量名

5.在声明的同时还可以初始化变量