变量、常量、标准输入输出相关

变量类型

变量定义

C语言在使用变量前必须先定义,定义的方式是变量类型+标识符,如:

int a;

这样的定义相当于对编译器下了一个命令,要求它在内存中找一个四字节空间存储整数,并命名为 a 。 之后使用变量 a 就相当于在操作这片空间。

标识符命名原则

1、由字母、数字、下划线构成

2、数字不能开头

3、不能和关键字重复

整数的变量类型(整型)

整型是C语言的原生类型,它直接用若干二进制位表示整数。其中整型中可能存在负数,所以在定义时 存在有符号类型和无符号类型。

有符号类型和无符号类型

编译器在处理整型时会区分有无符号,在大多数环境中,默认定义的数据如 int i 是有符号的,如果要 定义无符号的数据,需要写成:

unsigned int i;

其实常规定义中是省略了关键字 signed ,表示将最高位看做符号位。

补码(以单字节整型为例)

补码是计算机存储负数的一种形式,用于有符号整型,这个存储方式会将这个整型中最高位的二进制位 取出作为符号位,0表示正,1表示负。

但如果这样表示,会导致类似: 10000001(-1) + 1 = 10000010(-2) 的问题,所以引入了补码来表示 负数,以避免多定义一种加法。

求补码的方式是在原码的基础上保持符号位不变,其他位取反加一:

10000001 -1的原码
11111110 取反
11111111 加一
得到补码

※补码回到原码的方式和原码到补码一致,也是保持符号位不变,其他位取反加一。

额外规定 10000000 是 -128 ,因为其为负数,且加上 128 后是0。

整型的类别

char

char 是单字节整型,其在有符号的情况下,取值范围为 [ − 2 7 , 2 7 − 1 ] [-2^7,2^7-1] [27,271],即 [ − 128 , 127 ] [-128,127] [128,127],在无符号的情 况下,取值范围为 [ 0 , 2 8 − 1 ] [0,2^8-1] [0,281] ,即 [ 0 , 255 ] [0,255] [0,255]

short

short 在大多数情况下是两字节整型,其在有符号的情况下,取值范围为 [ − 2 15 , 2 15 − 1 ] [-2^{15},2^{15}-1] [215,2151] ,即 [ − 32768 , 32767 ] [-32768,32767] [32768,32767],在无符号的情况下,取值范围为 [ 0 , 2 16 − 1 ] [0,2^{16}-1] [0,2161] ,即 [ 0 , 65535 ] [0,65535] [0,65535]

int

int 在大多数情况下是四字节整型,其在有符号的情况下,取值范围为 [ − 2 31 , 2 31 − 1 ] [-2^{31},2^{31}-1] [231,2311] ,即 [ − 2147483647 , 2147483648 ] [-2147483647,2147483648] [2147483647,2147483648] ,在无符号的情况下,取值范围为 [ 0 , 2 32 − 1 ] [0,2^{32}-1] [0,2321] ,即 [ 0 , 4294967295 ] [0,4294967295] [0,4294967295]

long

long 在MSVC环境下也是四字节整型,由于在不同的编译器间, long 容易产生长度变化,所以较少使 用。

long long

long long 是C99语法,但C++98也约定了 long long ,所以可以使用。它就是系统约定的 __int64 类型,是八字节整型。其在有符号的情况下,取值范围为 [ − 2 63 , 2 63 − 1 ] [-2^{63},2^{63}-1] [263,2631],即 [ − 9223372036854775808 , 9223372036854775807 ] [-9223372036854775808,9223372036854775807] [9223372036854775808,9223372036854775807],在无符号的情况下,取值范围为 [ 0 , 2 64 − 1 ] [0,2^{64}-1] [0,2641] ,即 [ 0 , 184674473709551615 ] [0,184674473709551615] [0,184674473709551615]

整型的截断与提升

当把位数较多的整型赋值给位数较少的整型时,会发生截断。截断时会将高位的数据直接截掉,只保留 低位的数据。

如:

int a =321;
char ch = a;

printf("%d",ch);

此时,a的数据用十六进制表示是 0x141 ,截断时,高位的1被截掉,剩下的0x41给了 ch 。所以打印结果是65。

当把位数较少的整型赋值给位数较多的整型时,会发生提升。提升时,会将多出来的位数填写为位数较 少的整型的符号位。如果是无符号类型,则直接补0。

浮点的数据类型(浮点型)

C语言的浮点型遵循IEEE754标准。

浮点型存储原理(了解)

以下以单精度浮点数(32位浮点数)为例,来说明一下二进制浮点数的存储方式:

0 00000000 00000000000000000000000
符号位:01负
	指数位:用于存储指数
				尾数位,用于存储小数的尾数

假如要存储885.875这个小数,则第一步是将它转换为二进制:

1101110101.111

然后将它用二进制的科学计数法表示出来:

1.101110101111 × 2^9

此时,这个9就是指数。将9转换为阶码存储到指数位,阶码也是一种可以存储负数的方式,这里可以直 接简化为加上127。即指数位存储的就是9+127,即 10001000 。

而小数点后的内容,即 101110101111 就是尾数,因为二进制的科学计数法最高位肯定是1,所以干脆省 略掉,只记录尾数,所以,对应的二进制就是

0 10001000 10111010111100000000000
浮点型的分类
float

指数范围是 [ − 126 , 127 ] [-126,127] [126,127] ,而由于尾数位只有23位,而加上隐含的一位也只有24位,能表示的有效数字大约是 2 23 2^{23} 223,即约7位十进制数字,所以float只能保证7位有效数字是精确的。

double

指数范围是 [ − 1022 , 1023 ] [-1022,1023] [1022,1023],拥有52位尾数位, 其能表示的有效数字大约是 2 52 2^{52} 252,换算成十进制就是15到16位左右。所以可以保留15位有效数字,甚至第16位也大概率是对的。

long double(C99专属语法)

指数范围是 [ − 16382 , 16383 ] [-16382,16383] [16382,16383] ,拥有64位尾数位,能保证19位有效数字。由于是C99专属语法,所以各 个编译器的实现方法不尽相同,最好不要使用。

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("long long : %d\n", sizeof(long long));
	printf("float : %d\n", sizeof(float));
	printf("double : %d\n", sizeof(double));
	return 0;
}

通过这个代码就可以看到每个类型占用多少字节。

混合类型的运算

如果在一个算数表达式中出现了多个不同的类型,则按照如下规则判断其结果的类型:

1、整型向浮点型看齐

2、短类型向长类型看齐

3、有符号向无符号看齐

※总结起来就是向右界更宽的类型看齐。

const关键字

const可以加在变量定义之前,表示定义出的变量是只读的。如:

const int i = 8;

此时,i不能再被赋值。即i = 10这样的操作不合法。

※const的变量必须在定义时初始化。

字符型

字符型是整型的子集,本质上字符型存储的也是数字,只是存储的这些数字可以按照下表转换为具体的 字符:

上表叫做ASCII码表,表中用不同的颜色分成了几类不同的字符:

1、ASCII码0~32和127叫做不可见字符,通常是一些打印格式或者控制字符。可见字符和不可见字符的分界线是空格,ASCII码值为32。

2、ASCII码48~57 叫做数字字符,就是阿拉伯数字0~9。在编程过程中经常会遇到将数字字符转换为对应的数字的场景,通常写成 ch - ‘0’ 的形式。

3、ASCII码66~90 和 97~ 112叫做字母字符,包括26个大写字母和26个小写字母。在编程过程中经常会遇到大小写转换的场景,通常写成 ch + (‘a’ - ‘A’) 或者 ch - (‘a’ - ‘A’) 的形式。

4、ASCII码34,39,63,92是可转义的可见字符。指的是这些字符在字符串中有着特殊的含义,所以需要使用 \ 转义后 才可以正常打印。其中 ? 属于历史遗留问题。

字符型有专门的输入输出:

char ch;
ch = getchar(); //等同于scanf("%c", &ch);
putchar(ch); //等同于printf("%c", ch);

常量

常见的常量类型
常量类型备注
1int
1llongl不区分大小写
1uunsignedu不区分大小写
1ullunsignedl和u可以混用
3.14double
3.14ffloatf不区分大小写
‘a’int在c语言下是int,在C++是char
“Hello”const char[]
跟进制相关的常量
八进制常量

以0开头的整型常量是八进制常量,如:

int a =010;

实际a的值为 8 ,因为这里的 10 是八进制。

十六进制常量

以 0x 开头的整型常量是十六进制常量,如:

int a =0X10;

实际a的值为 16 ,因为这里的 10 是十六进制。

其他的特殊常量
科学计数法常量

C语言允许使用如下方式定义一个 double 类型的常量:

double d = 1e5;

这表示 1 * 1 0 5 10^5 105

字符型的特殊表示

八进制转义字符,基本用法:

char ch = '\101';

用三位八进制表示一个任意ASCII码值的字符。其中数据的取值范围是 [ 0 , ( 377 ) 8 ] [0,(377)_8] [0,(377)8] ,所以如果数据超出了 这个范围或者出现了数字8、9,这个字符常量就不合法。

十六进制转义字符,基本用法:

char ch = '\x41';

用两位十六进制表示一个任意ASCII码值的字符。其中数据的取值范围是 [ 0 , ( F F ) 16 ] [0,(FF)_{16}] [0,(FF)16]

标准输入输出

printf

在标准输出 printf 中,采用了字符 % 作为占位符,每有一个占位符,后面就要有一个变量与之对应。 ※ printf 中如果想要打印 % ,则需要使用 %% 。

在 % 后紧跟一个类型描述符,表示将对应的变量以什么格式打印。类型描述符分为三个大类:

进制相关

d :十进制

o :八进制(无符号)

x/X :十六进制(无符号)

类型相关

i : int 类型

u : unsigned int 类型

l :是配置项,需要跟上面的5个连用,如 ld 、 llx 之类的,表示 long

h :是配置项,需要跟上面的5个连用,如 hd ,表示 short

f : float/double 类型

lf :等同于 f

c : char 类型

其他

s :字符串,即 string

p :指针,即 pointer

e/E :以科学计数法打印浮点型

g/G :智能决定是否用科学计数法打印浮点型

精度

精度主要用于控制小数的显示位数,具体写法是在占位符和类型描述符间添加一个小数点,后跟一个数 字,表示精度的具体数值,以下的类型描述符可以使用精度:

f 、 e/E 中,精度可以控制保留几位小数。

g/G 中,精度可以控制保留几位有效数字。

s 中,精度可以截取字符串的前几个字符。

宽度

宽度用于控制打印字符数,在占位符后、精度之前可以添加一个数字,表示至少要打印多少个字 符,如果已经输出的字符数大于这个数,则宽度失效,否则会在输出结果前补充空格

零宽度

在宽度前加上0,表示原本补的空格改为补0。

负宽度

在宽度前加上 - ,表示原本补在前面的空格改为补在后面。

※宽度允许传入,使用如下方式就可以传入宽度:

int a = 14;
printf("%*d"10,a); //*表示传入10的宽度

在宽度的位置放一个 * ,表示后面多传一个数来表示宽度。

scanf

※在现阶段不要向 scanf 的双引号内放除了占位符、类型描述符、宽度外的任何东西。

scanf 和 printf 类似,也需要占位符,也是每有一个占位符后面就要有一个对应的变量(注意取地址 & )与之对应。其类型描述符的种类和 printf 基本一致,差别有如下几点:

1、 scanf 严格区分 %f 和 %lf ,它们分别对应 float 和 double 。

2、 scanf 中没有 %g 和 %e 。

宽度

表示至多接收几个字符,如:

scanf("%4d%4d", &i, &j);
printf("%d %d", i, j);

输入 123456789 ,输出 1234 5678

※ scanf 也可以用 * 表示宽度,此时表示接受这个项,然后直接丢掉。即后面不需要有变量与之对应。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值