0
点赞
收藏
分享

微信扫一扫

深入浅出C语言:(六)基础部分 NO.1 数据类型和运算符、表达式和语句


 

目录

 

​​一、数据类型​​

​​1、变量(Variable)​​

​​2、数据类型(Data Type)​​

​​3、C 语言中的整数(short,int,long)​​

​​4、二进制数、八进制数和十六进制数的表示​​

​​5、二进制数、八进制数和十六进制数的输出​​

​​6、C 语言中的正负数及其输出​​

​​7、C 语言中的小数(float,double)​​

​​8、在 C 语言中使用英文字符​​

​​9、C 语言转义字符​​

​​二、运算符、表达式和语句​​

​​1、对取余运算的说明​​

​​2、C 语言自增(++)和自减(--)运算符​​

​​3、C 语言运算符的优先级和结合性​​

​​4、C 语言数据类型转换(自动转换+强制转换)​​

​​5、sizeof和size_t类型​​

一、数据类型

1、变量(Variable)

(1)赋值是指把数据放到内存的过程。

(2)int a;   创造了一个变量 a,我们把这个过程叫做变量定义。 a=123;  把 123 交给了变量 a,我们把这个过程叫做给变量赋值;又因为是第一次赋值,也称变量的初始化,或者赋初值。
 

2、数据类型(Data Type)

(1)顾名思义,数据类型用来说明数据的类型,确定了数据的解释方式,让计算机和程序员不会产生歧义。

(2)数据类型只在定义变量时指明,而且必须指明;使用变量时无需再指明(包括指针,因为此时的数据类型已经确定了。

(3)在 C 语言中,每一种数据类型占用的字节数都是固定的,知道了数据类型,也就知道了数据的长度。

说 明

字符型

短整型

整型

长整型

单精度浮点型

双精度浮点型

数据类型

char

short

int

long

float

double

长 度

1

2

4

4

4

8

3、C 语言中的整数(short,int,long)

让整数占用更少的内存可以在 int 前边加 short,让整数占用更多的内存可以在 int 前边加 long。

short int a = 10;
short int b, c = 99;
long int m = 102023;
long int n, p = 562131;

这样 a、 b、 c 只占用 2 个字节的内存,而 m、 n、 p 可能会占用 8 个字节的内存。也可以将 int 省略,只写 short 和 long

(1)short、 int、 long 是 C 语言中常见的整数类型,其中 int 称为整型, short 称为短整型, long 称为长整型。

(2)整型的长度:

  • 在 16 位环境下short 的长度为 2 个字节, int 也为 2 个字节, long 为 4 个字节。 16 位环境多用于单片机和
  • 低级嵌入式系统,在 PC 和服务器上已经见不到了。
  • 对于 32 位的Windows、 Linux 和 Mac OS,short 的长度为 2 个字节, int 为 4 个字节, long 也为 4 个字节。PC 和服务器上的 32 位系统占有率也在慢慢下降,嵌入式系统使用 32 位越来越多。
  • 在 64 位环境下,不同的操作系统会有不同的结果

操作系统

short

int

long

Win64(64 位 Windows)

2

4

4

类 Unix 系统(包括 Unix、 Linux、 Mac OS、 BSD、 Solaris 等)

2

4

8

(3)不同整型的输出

使用不同的格式控制符可以输出不同类型的整数,它们分别是:

  • %hd 用来输出short int 类型, hd 是 short decimal 的简写;
  • %d 用来输出int 类型, d 是 decimal 的简写;
  • %ld 用来输出 long int类型, ld 是 long decimal 的简写。

4、二进制数、八进制数和十六进制数的表示

表示一个十进制数字不需要任何特殊的格式。但是,表示一个二进制、八进制或者十六进制数字就不一样了
(1)二进制:

二进制由 0 和 1 两个数字组成,使用时必须以 0b 或 0B(不区分大小写)开头

合法的二进制
int a = 0b101; 换算成十进制为 5
int b = -0b110010; 换算成十进制为 -50
int c = 0B100001; 换算成十进制为 33
非法的二进制
int m = 101010; 无前缀 0B,相当于十进制
int n = 0B410; 4不是有效的二进制数字

        读者请注意,标准的 C 语言并不支持上面的二进制写法,只是有些编译器自己进行了扩展,才支持二进制数字。 换句话说,并不是所有的编译器都支持二进制数字,只有一部分编译器支持,并且跟编译器的版本有关系。
(2)八进制:
八进制由 0~7 八个数字组成,使用时必须以 0 开头(注意是数字 0,不是字母 o)

合法的八进制数
int a = 015; 换算成十进制为 13
int b = -0101; 换算成十进制为 -65
int c = 0177777; 换算成十进制为 65535
非法的八进制
int m = 256; 无前缀 0,相当于十进制
int n = 03A2; A不是有效的八进制数字

(3)十六进制:
十六进制由数字 0~9、字母 A~F 或 a~f(不区分大小写)组成,使用时必须以 0x 或 0X(不区分大小写)开头。

合法的十六进制
int a = 0X2A; 换算成十进制为 42
int b = -0XA0; 换算成十进制为 -160
int c = 0xffff; 换算成十进制为 65535
非法的十六进制
int m = 5A; 没有前缀 0X,是一个无效数字
int n = 0X3H; H不是有效的十六进制数字

(4)十进制

十进制由 0~9 十个数字组成,没有任何前缀,和我们平时的书写格式一样,不再赘述。

5、二进制数、八进制数和十六进制数的输出

① 十六进制数字的表示用到了英文字母,有大小写之分,要在格式控制符中体现出来:

  • %hx、 %x 和 %lx 中的 x 小写,表明以小写字母的形式输出十六进制数;
  • %hX、 %X 和 %lX 中的 X 大写,表明以大写字母的形式输出十六进制数。

② 八进制数字十进制数字不区分大小写,所以格式控制符都用小写形式

 

short

int

long

八进制

%ho

%o

%lo

十进制

%hd

%d

%ld

十六进制

%hx 或者 %hX

%x 或者 %X

%lx 或者 %lX

③ 输出时加上前缀

       区分不同进制数字的一个简单办法就是,在输出时带上特定的前缀。在格式控制符中加上 # 即可输出前缀,例如 %#x、 %#o、 %#lX、 %#ho 等,请看下面的代码:

short a = 0b1010110;   二进制数字
int b = 02713; 八进制数字
long c = 0X1DAB83; 十六进制数字
printf("a=%#ho, b=%#o, c=%#lo\n", a, b, c); 以八进制形似输出
printf("a=%hd, b=%d, c=%ld\n", a, b, c); 以十进制形式输出
printf("a=%#hx, b=%#x, c=%#lx\n", a, b, c); 以十六进制形式输出(字母小写)
printf("a=%#hX, b=%#X, c=%#lX\n", a, b, c); 以十六进制形式输出(字母大写)

运行结果:
a=0126, b=02713, c=07325603
a=86, b=1483, c=1944451
a=0x56, b=0x5cb, c=0x1dab83
a=0X56, b=0X5CB, c=0X1DAB83

6、C 语言中的正负数及其输出

C 语言规定,把内存的最高位作为符号位
C 语言规定,在符号位中,用 0 表示正数,用 1 表示负数
C 语言允许我们这样做,如果不希望设置符号位,可以在数据类型前面加上 unsigned 关键字。不加 unsigned 的数字称为有符号数,能表示正数和负数,加了unsigned 的数字称为无符号数能表示正数

unsigned short a = 12;
unsigned int b = 1002;
unsigned long c = 9892320;

short、 int、 long 中就没有符号位了,所有的位都用来表示数值,正数的取值范围更大了。

无符号数的输出:无符号数可以以八进制、十进制和十六进制的形式输出,它们对应的格式控制符分别为:

 

short

int

long

unsigned short

unsigned int

unsigned long

八进制

--

--

--

%ho

%o

%lo

十进制

%hd

%d

%ld

%hu

%u

%lu

十六进制

--

--

--

%hx 或者 %hX

%x 或者 %X

%lx 或者 %lX

  • 当以有符号数的形式输出时, printf 会读取数字所占用的内存,并把最高位作为符号位,把剩下的内存作为数值位;
  • 当以无符号数的形式输出时, printf 也会读取数字所占用的内存,并把所有的内存都作为数值位对待。

7、C 语言中的小数(float,double)

C 语言中常用的小数有两种类型,分别是 float 或 double; float 称为单精度浮点型, double 称为双精度浮点型。

小数也可以使用 printf 函数输出,包括十进制形式和指数形式,它们对应的格式控制符分别是:

  • %f 以十进制形式输出 float 类型;
  • %lf 以十进制形式输出 double 类型;
  • %e 以指数形式输出 float 类型,输出结果中的 e 小写;
  • %E 以指数形式输出 float 类型,输出结果中的 E 大写;
  • %le 以指数形式输出 double 类型,输出结果中的 e 小写;
  • %lE 以指数形式输出 double 类型,输出结果中的 E 大写。
  • %g 会对比小数的十进制形式和指数形式,以最短的方式来输出小数。所谓最短,就是输出结果占用最少的字符

读者需要注意的两点是:

  • %g 默认最多保留六位有效数字,包括整数部分和小数部分; %f 和 %e 默认保留六位小数,只包括小数部分。
  • %g不会在最后强加 0来凑够有效数字的位数,而 %f 和 %e 会在最后强加 0 来凑够小数部分的位数。
  • 除了 %g,还有 %lg、 %G、 %lG:
    ① %g 和 %lg 分别用来输出 float 类型和 double 类型,并且当以指数形式输出时, e 小写。
    ② %G 和 %lG 分别用来输出 float 类型和 double 类型,只是当以指数形式输出时, E 大写。

8、在 C 语言中使用英文字符

经常用到的字符类型是 char,它的长度是 1只能容纳 ASCII 码表中的字符,也就是英文字符。
② 字符类型由单引号' '包围,字符串由双引号" "包围。
③ 字符的输出:输出 char 类型的字符有两种方法,分别是:

  • 使用专门的字符输出函数 putchar;
  • 使用通用的格式化输出函数 printf, char 对应的格式控制符是%

9、C 语言转义字符

转义字符

意义

ASCII 码值(十进制)

\a

响铃(BEL)

007

\b

退格(BS) ,将当前位置移到前一列

008

\f

换页(FF),将当前位置移到下页开头

012

\n

换行(LF) ,将当前位置移到下一行开头

010

\r

回车(CR) ,将当前位置移到本行开头

013

\t

水平制表(HT)

009

\v

垂直制表(VT)

011

\'

单引号

039

\"

双引号

034

\\

反斜杠

092

二、运算符、表达式和语句

1、对取余运算的说明

余数可以是正数也可以是负数,由 % 左边的整数决定

  • 如果 % 左边是正数,那么余数也是正数;

printf(
"100%%12=%d \n100%%-12=%d \n-100%%12=%d \n-100%%-12=%d \n",
100 % 12, 100 % -12, -100 % 12, -100 % -12
);

运行结果:
100%12=4
100%-12=4
-100%12=-4
-100%-12=-4

2、C 语言自增(++)和自减(--)运算符

++--分别称为自增运算符自减运算符。
 

int a = 10, b = 20;
printf("a=%d, b=%d\n", a, b);
++a;
--b;
printf("a=%d, b=%d\n", a, b);
a++;
b--;
printf("a=%d, b=%d\n", a, b);

运行结果:
a=10, b=20
a=11, b=19
a=12, b=18

需要重点说明的是, ++ 在变量前面后面是有区别的:

  • ++ 在前面叫做前自增(例如 ++a)。前自增先进行自增运算,再进行其他操作。
  • ++ 在后面叫做后自增(例如 a++)。后自增先进行其他操作,再进行自增运算。

自减(--)也一样,有前自减和后自减之分。
 

int a = 10, b = 20, c = 30, d = 40;
int a1 = ++a, b1 = b++, c1 = --c, d1 = d--;

printf("a=%d, a1=%d\n", a, a1);
printf("b=%d, b1=%d\n", b, b1);
printf("c=%d, c1=%d\n", c, c1);
printf("d=%d, d1=%d\n", d, d1);

输出结果:
a=11, a1=11
b=21, b1=20
c=29, c1=29
d=39, d1=40

a1=++a;会先进行自增操作,再进行赋值操作;而 b1=b++;会先进行赋值操作,再进行自增操作。

int a = 12, b = 1;
int c = a - (b--);
int d = (++a) - (--b);

printf("c=%d, d=%d\n", c, d);

输出结果:
c=11, d=14

  • 执行语句①时,因为是后自减,会先进行 a-b 运算,结果是 11,然后 b 再自减,就变成了 0;最后再将 a-b 的结果(也就是 11)交给 c,所以 c 的值是 11。
  • 执行语句②之前, b 的值已经变成 0。对于 d=(++a)-(--b), a 会先自增,变成 13,然后 b 再自减,变成 -1,最后再计算 13-(-1),结果是 14,交给 d,所以 d 最终是 14。

3、C 语言运算符的优先级和结合性

 

优先级

运算符

名称或含义

使用形式

结合方向

说明

1

[]

数组下标

数组名[常量表达式]

左到右

 

()

圆括号

(表达式)
函数名(形参表)

 

.

成员选择(对象)

对象.成员名

 

->

成员选择(指针)

对象指针->成员名

 

2

-

负号运算符

-表达式

右到左

单目运算符

(类型)

强制类型转换

(数据类型)表达式

 

++

自增运算符

++变量名
变量名++

单目运算符

--

自减运算符

--变量名
变量名--

单目运算符

*

取值运算符

*指针变量

单目运算符

&

取地址运算符

&变量名

单目运算符

!

逻辑非运算符

!表达式

单目运算符

~

按位取反运算符

~表达式

单目运算符

sizeof

长度运算符

sizeof(表达式)

 

3

/

表达式 / 表达式

左到右

双目运算符

*

表达式*表达式

双目运算符

%

余数(取模)

整型表达式%整型表达式

双目运算符

4

+

表达式+表达式

左到右

双目运算符

-

表达式-表达式

双目运算符

5

<<

左移

变量<<表达式

左到右

双目运算符

>>

右移

变量>>表达式

双目运算符

6

>

大于

表达式>表达式

左到右

双目运算符

>=

大于等于

表达式>=表达式

双目运算符

<

小于

表达式<表达式

双目运算符

<=

小于等于

表达式<=表达式

双目运算符

7

==

等于

表达式==表达式

左到右

双目运算符

!=

不等于

表达式!= 表达式

双目运算符

8

&

按位与

表达式&表达式

左到右

双目运算符

9

^

按位异或

表达式^表达式

左到右

双目运算符

10

|

按位或

表达式|表达式

左到右

双目运算符

11

&&

逻辑与

表达式&&表达式

左到右

双目运算符

12

||

逻辑或

表达式||表达式

左到右

双目运算符

13

?:

条件运算符

表达式1? 表达式2: 表达式3

右到左

三目运算符

14

=

赋值运算符

变量=表达式

右到左

 

/=

除后赋值

变量/=表达式

 

*=

乘后赋值

变量*=表达式

 

%=

取模后赋值

变量%=表达式

 

+=

加后赋值

变量+=表达式

 

-=

减后赋值

变量-=表达式

 

<<=

左移后赋值

变量<<=表达式

 

>>=

右移后赋值

变量>>=表达式

 

&=

按位与后赋值

变量&=表达式

 

^=

按位异或后赋值

变量^=表达式

 

|=

按位或后赋值

变量|=表达式

 

15

,

逗号运算符

表达式,表达式,…

左到右

 

容易出错的优先级

优先级问题

表达式

经常误认为的结果

实际结果

. 的优先级高于 *(-> 操作符用于消除这个问题)

*p.f

p 所指对象的字段 f,等价于:

(*p).f

对 p 取 f 偏移,作为指针,然后进行解除引用操作,等价于:

*(p.f)

[] 高于 *

int *ap[]

ap 是个指向 int 数组的指针,等价于:

int (*ap)[]

ap 是个元素为 int 指针的数组,等价于:

int *(ap [])

函数 () 高于 *

int *fp()

fp 是个函数指针,所指函数返回 int,等价于:

int (*fp)()

fp 是个函数,返回 int*,等价于:

int* ( fp() )

== 和 != 高于位操作

(val & mask != 0)

(val &mask) != 0

val & (mask != 0)

== 和 != 高于赋值符

c = getchar() != EOF

(c = getchar()) != EOF

c = (getchar() != EOF)

算术运算符高于位移 运算符

msb << 4 + lsb

(msb << 4) + lsb

msb << (4 + lsb)

逗号运算符在所有运 算符中优先级最低

i = 1, 2

i = (1,2)

(i = 1), 2

4、C 语言数据类型转换(自动转换+强制转换)

数据类型转换就是将数据(变量、数值、表达式的结果等)从一种类型转换为另一种类型。

1、自动类型转换

自动类型转换就是编译器默默地、隐式地、偷偷地进行的数据类型转换,这种转换不需要程序员干预,会自动发生。
不建议这种事情发生,因为会导致数据失真
2、强制类型转换
在代码中明确地提出要进行类型转换,这称为强制类型转换。

(float)a;       将变量 a 转换为 float 类型
(int)(x + y); 把表达式 x+y 的结果转换为 int 整型
(float)100; 将数值 100(默认为int类型)转换为 float 类型

5、sizeof和size_t类型

深入浅出C语言:(六)基础部分 NO.1 数据类型和运算符、表达式和语句_链接

6、自动算出数组的个数

深入浅出C语言:(六)基础部分 NO.1 数据类型和运算符、表达式和语句_链接_02

 

举报

相关推荐

0 条评论