第二章 初窥天机之基础知识讲解

工欲善其事必先利其器,上一章我们讲解了VC++6.0的安装,这一把C语言编程的利器,那么现在是不是有种把持不住要写C语言的冲动呢?哈哈,好期待哟!想着要学习C语言,变成编程高手,最后成为隐藏在复杂网络背后的一个充满神秘感的黑客。咳咳,想想都开心!不过学习任何编程语言都需要基础理论知识的铺垫,就像我们日常生活中的常识一样必须去了解它。这样我们就可以万丈高楼平地起了。废话不多说,走起!

2.1 数据类型分类

在现实生活中家庭人口多的买大房子,家庭人口一般的买中等房子,而家庭人口少的适当的就买小房子,这些不同的家庭都是按照自己的实际需求和经济条件,来选择适合自己的房子。C语言也是类似。在C语言中就像家庭人口多少一样。划分不同的类型。比如:字符型,整型以及浮点型。字符型占1个字节,家里人少嘛。整型占4个字节,属于人口中等。浮点型和整型一样,也是占4个字节。但是如果是双精度的浮点型这一家人口就比较多了,占8个字节。

那么C语言有多少种数据类型呢?请看图2.1。而各个变量对应的存储空间大小也会在后续的部分中给出。

图2.1 C语言各种数据类型

2.1.1 常量与变量

常量,顾名思义就是恒定不变的量。在C语言中常量分为:整型常量、实型常量、字符型常量、字符串常量、符号常量。

整型常量如下:

a = a * 2;

其中的2就是整型数。

实型常量如下:

a = a * 3.1415;

其中的3.1415就是实型常量。

字符型常量如下:

a = 32 + 'A';

其中的'A'就是字符型常量。字符串型常量是多个字符型常量的一个集合。字符型常量是单引号引起来一个字符,而字符串常量则是双引号引起的多个字符,比如:"ABCD","China","1a2b3c"等。

符号常量如下:

#define N 1024

这就是把N定义为1024,这个值在程序运行中是不会改变的。预处理命令一般都是以“#”开头的。

那变量呢?变量,顾名思义就是可以改变的量。整型变量、实型变量、字符型变量、字符串变量。当然后续还会有指针变量、结构体变量、枚举类型变量等,各种类型的变量。

那么变量那么多我们怎么去定义呢?这就涉及到C语言中的一些关键字,我们通过这个关键字来定我们所需大小的变量。就像家庭人口多的,我们就定义一个较大的变量关键字。如果需要所需存储空间较小,那么我们就分配空间较小的关键字。这就造成了关键的不同。C语言中共有32个关键字,如表2.1所示,为C语言所有的关键字。以字母在单词表中出现的顺序排列。

表2.1 C语言关键字

auto

break

case

char

const

continue

default

do

double

else

enum

extern

float

for

goto

if

int

long

register

return

short

signed

sizeof

static

struct

switch

typedef

union

unsigned

void

volatile

while

当然里面有很多我们暂时用不到的关键字,那些用不到的关键字不用管它。我们只关注暂时用到的关键字,这些关键字主要有八个:char、short、int、long、float、double、signed、unsigned。

这些关键字怎么使用呢?哈哈,此处卖个关子,在下几节我们将会对这个八个关键字进行详细的说明。

在绝大多数程序的开头我们都会见如下定义:

#include <stdio.h>
int main()
{
    int a,b;
    ...
}

在这个程序中,我们发现第4行定义:

int a,b;

其中int为关键字,就是要买的房子的大小。由于我们使用的是VC++6.0的编译器,所以开辟了4个字节的存储空间。“a”“b”就是对应的变量名。C语言遵循先定义后使用的原则。现在问题来了,我们为什么要定义成a,b呢?为什么不定义成其他的名字?如c,bb,ab等。所以这就引出来了变量名的命名规则。也就是比较文艺范说法的“标识符”。

什么是标识符?标识符是用来表示不同变量相互区分的一种符号。标识符不仅仅是可以表示变量名,还可以表示函数名、文件名,数组名等,这也就解释为什么有时候我们用一些不常见的字符命名文件夹的时候,会命名失败,并提示出现非法字符。

如何定义标识符?不仅在C语言中,在很多其他的编程语言中,比如C++、java、C#、PHP等编程语言中都遵循标识符规则。

C语言合法命名规则:

  1. 标识符只能由字母、数字和下划线构成。
  2. 第一个字符必须是字母或下划线。
  3. 区分字母大小写。
  4. 标识符最少是1个字符,最多是32个字符。

常用的有四种命名法则:驼峰命名法、匈牙利命名法、帕斯卡命名法、下划线命名法。好的命名不仅可以增加程序的可读性,而且还便于对程序的理解和后期维护。各个命名方法我们就不详细讲解了,我们会在程序中做简要的讲解,这样比现在枯燥的说明更能加深大家的理解。如果大家想要了解更多详细的信息,可以寻求百度大神的帮忙。只需要输入相应的命名方法,就可以百度出巨多的有用信息。

再回到之前的问题,是否可以命名为c,bb,ab等?回答是肯定的,只要我们满足上述命名规则即可作为变量名。但变量名不能相同。

下面几节该回到我们关键字的说明了,在讲解关键字的同时,我们就可以开启我们的编程脚步了。一步两步,一步两步,似魔鬼的步伐...。咳咳,有点小激动脚步停不下来。

2.1.2 整型数据

整型数据分为好几种:基本整型(int型)、短整型(short int型)、长整型(long int型)、双长整型(long long int型)、无符号整型(unsigned int型)、无符号短整型(unsigned short)、无符号长整型(unsigned long)。无符号类型的整数就是不包括符号位,就是只能表示正数。而普通的整型既可以表示正数也可以表示负数。废话不多说直接看表2.2,这样比较直观。

表2.2 VC++6.0下整型数据取值范围和所占字节数

类型

取值范围

字节数

int(基本整型)

 

4

unsigned int(无符号基本整型)

 

4

short(短整型)

 

2

unsigned short(无符号短整型)

 

2

long(长整型)

 

4

unsigned long(无符号长整型)

 

4

long long(双长型)

 

8

unsigned long long(无符号双长型)

 

8

上表2.2中详细列举了VC++6.0下各种整型数据取值范围和所占字节数。在表内容的第三行我们发现它写成了:short,没有int。事实上完整的写法就是:short int,但实际编程中int可以省略,所以就写成了表中的形式。其实这也是程序员的习惯写法。

比如:

short int a = 5;

就可以写成:

short a=5;

其中long、unsigned long、long long、unsigned long long都是可以省略int的。

下面就让我们看看如何定义这些变量吧?

  1. long c = 3;
  2. unsigned long d = 4;
  3. long long e = 5;
  4. unsigned long long f = 6;

在本书中和对于初学者来说,暂时不会把所有的数据类型使用一遍,等我们功力深厚了,自然就会接触这些知识,相应的就会使用的,在上表所有的类型中我们使用的int基本整型比较多,其他的希望大家后续学习。

当你学完本书之后,估计其他类型你已经开始使用了。所以我们暂时只记住表内容中的第一行就行了。记住哟,是int型,是int型,是int型。重要的事情说三遍哟。对于int型我们将会用如下实例进行说明。

【例2.1】int型的使用。

编写程序:

#include <stdio.h>
int main()
{
    int a;//定义整型变量a
    a = 2;//把2赋值给变量a
    printf("%d\n", a);//输出赋值后的变量a
    return 0;//正常返回,返回值为0
}

运行结果:

2

Press any key to continue

 

程序分析:我们第四行定义一个int型变量a,然后用“=”号的形式,把2赋值给变量a。最后用printf函数输出int型变量a的值2。printf函数中的“%d”表示以十进制形式输出。printf函数我们将会在下一章进行讲解。大家暂时就按照我所写的格式写即可。

终于开始了我们的程序路。

2.1.3 实型数据

如果说上节的整型没有小数位,那么现在要隆重登场的“实型数据”就具有小数位了。

实型数据有时候我们又称浮点型数据。用来表示具有小数点的实数。在C语言中,浮点型数据是以指数形式存储在内存单元中的。比如地球的重量是,它的表示形式就是指数形式。

浮点数类型包括float(单精度浮点型)、double(双精度浮点型)、long double(长双精度浮点型)。同样不废话,直接上表2.3。

表2.3 VC++6.0下浮点型数据取值范围和字节数

类型

取值范围

字节数

有效字节

float(单精度浮点型)

4

6

double(双精度浮点型)

8

15

long double(长双精度浮点型)

8

15

实际上不同的编译器对long double型分配不同的存储空间,大家在使用不同的编辑器时需要注意此点。由于我们使用的是VC++6.0,所以分配了8个字节。如果使用Turbo C编译器,会分配16个字节。所以不同的编辑器对于同一类型可能分配不同的存储空间。上一节的整型也是如此。因为对于现阶段编写的程序来说,不会剑走偏锋搞细节。这也是为什么上节并无详解相关信息。等大家有了基础就会究其细节,再做研究了。定能全面掌握。

在表的最后一列,出现了有效字节。那么我们就需要了解一些二进制了。实际上计算机中是用二进制来表示小数部分以及用2的幂次来表示指数部分。在32位系统中,多少位表示小数部分,多少位表示指数部分,是由具体的编译器决定的。有的编译系统以24位表示小数部分和符号,用8位表示指数部分。由于存储单元的长度有限,用二进制表示一个实数是不可能得到完全精确的值的,只能尽可能的接近我们所需的值。小数部分占的位数越多,有效数字就越多,精度也就越高。指数部分占的位数越多,能表示的数值范围越大。

比如:

float f = 314.159;

又可表示为:

float f = 3.14159*e100;

双精度的表示:

double d = 3.1415926;

那么我们具体会用到浮点数类型的那些关键字呢?由于我们使用的编译器VC++6.0,所以double和long double其实是一样的。我们编程中常用到float和double类型,float和double类型,float和double类型哟!

【例2.2】float和double类型的使用。

编写程序:

#include <stdio.h>
int main()
{
    float f;//定义单精度浮点数f
    double d;//定义双精度浮点数d
    f = 2.34;//把2.34赋值给单精度f
    //输出赋值后的结果,%f表示以单精度格式输出结果,"\n"表示换行
    printf("%f\n", f);
    d = 3.1415;//把3.1415赋值双精度d
    //输出赋值后的结果,%lf表示以双精度格式输出结果
    printf("%lf\n", d);
    return 0;
}

运行结果:

2.340000

3.141500

Press any key to continue

 

程序分析:第4行定义单精度变量f。第5行定义双精度变量d。第6行把2.34赋值给单精度变量f。第8行输出单精度f的结果。第9行把3.1415赋值给双精度变量d。第11行输出双精度d的结果。printf函数中的%f和%lf分别表示以单精度格式输出和以双精度格式输出。我们将会在下一章进行讲解。

2.1.4 字符型数据

C99中把字符类型看做是整型的一种,因为字符是按照整数的形式存储的。大多数系统采用的是ASCII字符集,都包括127个字符。具体请参考附录CASCII表。在ASCII表中,我们会发现有:字母、数字、专门符号、空格符、还有一些不能显示的字符。在ASCII表中可以看到有大写字母和小写字母,他们对应不同的十进制值。

字符型数据包括两种。一种是signed char(有符号字符型)。一种是unsigned char(无符号字符型)。详细信息看表2.4。

表2.4 VC++6.0下字符型数据取值范围和字节数

类型

取值范围

字节数

signed char(无符号字符型)

1

unsigned char(无符号字符型)

1

我们之前已经说过,由于字符是按照整型形式在内存中存储的,所以字符型变量即可以赋值为整数,又可以赋值为字符。首先我们看看如何赋值为整数。

比如:

  1. signed char a = 65;
  2. unsigned char b = 66;

如果我们输出a和b对应的字符,就会发现结果分别为字符‘A’和字符‘B’。因为在ASCII表中整数65对应的字符为‘A’,66为‘B’。详情请参考附录C。

定义变量时如果即不加signed,又不加unsigned时,不同的编辑器会自动添加上signed或者unsigned,视编译器而定。我们使用的是VC++6.0,所以默认为signed char。我们可以通过程序2.3进行验证。

【例2.3】char的默认值。

编写程序:

#include <stdio.h>
int main()
{
    signed char a;//定义有符号变量a
    unsigned char b;//定义无符号变量b
    char c;//定义默认字符变量c
    //把a,b,c的值都初始化为127
    a = 127;
    b = 127;
    c = 127;
    //让a,b,c的值都自加1
    a = a + 1;
    b = b + 1;
    c = c + 1;
    //最后输出三种定义形式的整数值
    printf("a = %d\n", a);
    printf("b = %d\n", b);
    printf("c = %d\n", c);
    return 0;
}

运行结果:

a = -128

b = 128

c = -128

Press any key to continue

 

程序分析:我们首先在第4~6行定义三个变量,第一个变量是有符号的a,第二个变量是无符号的b,第三个变量是默认形式的c。然后在第8~10行给这个三个变量分别赋值。a赋值为127,b赋值为127,c赋值为127。为什么赋值为127呢?因为有符号的字符最大值是127,我们只需要查看他们对应变量增加1后,变量c的结果值与哪一个相同,那么就会默认为那种类型。所以第12~14行对应变量增加1。第16~18为要输出的结果。我们从运行结果中发现变量c的值和变量a的值相同,这就说明如果char之前不加关键字signed或unsigned,则默认为signed。注意printf函数中的%d表示以整数形式输出,详细信息我们将会在下一章介绍。

上面是以整数形式来说明字符变量的,因为字符是按照整数形式存储的。下面我们看一看字符的表示形式。

比如signed char和unsigned char的定义:

  1. signed char a = 'A';
  2. unsigned char b = 'B';

在赋值方式上,两者不没有区别,只是在取值范围上有区别。我们将会在下一个例题中介绍。

【例2.4】char基本操作。

编写程序:

#include <stdio.h>
int main()
{
    signed char a = 'A';//定义并初始化有符号变量a
    unsigned char b = 'B';//定义并初始化无符号变量b
    //输出变量a和变量b的值
    printf("%c\n", a);
    printf("%c\n", b);
    //变量a和变量b分别32后,再赋值给自己
    a = a + 32;
    b = b + 32;
    //输出变量a和变量b改变后的值
    printf("%c\n", a);
    printf("%c\n", b);
    return 0;
}

运行结果:

A

B

a

b

Press any key to continue

程序分析:第4行定义了一个有符号的变量a,第5行定义了无符号的变量b。第7~8行输出对应变量初始化的值。第10~11行让有符号的变量和无符号的分别加32,然后再赋值给自己。我们之前已经说过字符可以赋值给整数,由于‘A’和‘B’分别对应的ASCII值为65和66。它们加32再赋值给自己后‘A’、‘B’对应的值分别是97和98。所以我们在第13~14行以字符形式输出的结果为‘a’、‘b’。‘a’对应的ASCII值为97,‘b’对应的ASCII值为98。记得参考附录C哟。注意%c表示以字符形式输出结果,我们仍会在下一章进行讲解。

2.2 N-S与流程图简介

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值