01C基础-02数据类型。

时间:2019-08-06
本文章向大家介绍01C基础-02数据类型。,主要包括01C基础-02数据类型。使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

声明和定义区别

声明变量不需要建立存储空间,如:extern int a;

定义变量需要建立存储空间,如:int b;

#include <stdio.h>

int main()

{

//extern 关键字只做声明,不能做任何定义,后面还会学习,这里先了解

//声明一个变量a,a在这里没有建立存储空间

extern int a;

a = 10; //err, 没有空间,就不可以赋值

int b = 10; //定义一个变量b,b的类型为int,b赋值为10

return 0;

}

从广义的角度来讲声明中包含着定义,即定义是声明的一个特例,所以并非所有的声明都是定义:

int b 它既是声明,同时又是定义

对于 extern b来讲它只是声明不是定义

一般的情况下,把建立存储空间的声明称之为“定义”,而把不需要建立存储空间的声明称之为“声明”。

使用示例

#include <stdio.h>

#define MAX 10 //声明了一个常量,名字叫MAX,值是10,常量的值一旦初始化不可改

int main()

{

int a; //定义了一个变量,其类型为int,名字叫a

const int b = 10; //定义一个const常量,名为叫b,值为10

//b = 11; //err,常量的值不能改变

//MAX = 100; //err,常量的值不能改变

a = MAX;//将a的值设置为MAX的值

a = 123;

printf("%d\n", a); //打印变量a的值

return 0;

}

常量的定义:

1、const 数据类型 常量名

2、【宏定义】#deifne 常量名 值

注意:

1、通过#define 定义的常量 是根据值来匹配数据类型的

2、const 修饰的常量是不安全 可以通过指针来修改

十进制转化二进制的方法:用十进制数除以2,分别取余数和商数,商数为0的时候,将余数倒着数就是转化后的结果。

十进制的小数转换成二进制:小数部分和2相乘,取整数,不足1取0,每次相乘都是小数部分,顺序看取整后的数就是转化后的结果。

八进制,Octal,缩写OCT或O,一种以8为基数的计数法,采用0,1,2,3,4,5,6,7八个数字,逢八进1。一些编程语言中常常以数字0开始表明该数字是八进制。

八进制的数和二进制数可以按位对应(八进制一位对应二进制三位),因此常应用在计算机语言中。

十六进制(英文名称:Hexadecimal),同我们日常生活中的表示法不一样,它由0-9,A-F组成,字母不区分大小写。与10进制的对应关系是:0-9对应0-9,A-F对应10-15。

十六进制的数和二进制数可以按位对应(十六进制一位对应二进制四位),因此常应用在计算机语言中。

8421法则:

将各个位数的二进制用十进制中的【数字 】来表示多位的二进制数 通过【数字 】相加就可以得到二进制数的数据

8 1000

4 100

2 10

1 1

1000

100

10

1

————

1 1 1 1

转化任意进制

进制在程序中打印:

int a=10;//十进制中的10

int b=010;//八进制中的10 在程序中定义一个八进制数需要在数前面加上0区分

int c=0x10;//十六进制中的10在程序中定义一个十六进制数需要在数前面加上0x区分

int d=0X10;//十六进制中的10在程序中定义一个十六进制数需要在数前面加上0X区分

注意:在程序中没有办法表示一个二进制数

%d 将数据按照十进制输出

%o将数据按照八进制输出

%x将数据按照十六进制小写输出

%X将数据按照十六进制大写输出

#include <stdio.h>

int main()

{

int a = 123; //十进制方式赋值

int b = 0123; //八进制方式赋值, 以数字0开头

int c = 0xABC; //十六进制方式赋值

//如果在printf中输出一个十进制数那么用%d,八进制用%o,十六进制是%x

printf("十进制:%d\n",a );

printf("八进制:%o\n", b); //%o,为字母o,不是数字

printf("十六进制:%x\n", c);

return 0;

}

原码、反码、补码

原码

一个数的原码(原始的二进制码)有如下特点:

  • 最高位做为符号位,0表示正,为1表示负
  • 其它数值部分就是数值本身绝对值的二进制数
  • 负数的原码是在其绝对值的基础上,最高位变为1

反码

  • 对于正数,反码与原码相同
  • 对于负数,符号位不变,其它部分取反(1变0,0变1)

补码

在计算机系统中,数值一律用补码来存储。

补码特点:

  • 对于正数,原码、反码、补码相同
  • 对于负数,其补码为它的反码加1
  • 补码符号位不动,其他位求反,最后整个数加1,得到原码

在计算机系统中,数值一律用补码来存储,主要原因是:

统一了零的编码

将符号位和其它位统一处理

将减法运算转变为加法运算

两个用补码表示的数相加时,如果最高位(符号位)有进位,则进位被舍弃

一个有符号的整型数据可以分为两部分一部分是符号位、一部分是数字位

无符号数据类型只包含数字位部分

signed int a= 1986(有符号标识 signed可以不用写)

二进制:11111000010

1986原码:0000 0000 0000 0000 0000 0111 1100 0010

-1986原码:1000 0000 0000 0000 0000 0111 1100 0010

1986反码: 0000 0000 0000 0000 0000 0111 1100 0010

-1986反码:1111 1111 1111 1111 1111 1000 0011 1101

1986补码: 0000 0000 0000 0000 0000 0111 1100 0010

-1986补码:1111 1111 1111 1111 1111 1000 0011 1110

结果: 1 0000 0000 0000 0000 0000 0000 0000 0000

溢出:在数据进行操作的时候会导致超出数据类型大小,会向前位进1,多于原始数据类型大小,会被系统自动舍弃 保留从后面开始数据类型大小的位数

10+20

0000 1010

0001 0100

0001 1110

-10+-20

原码:1000 1010

反码:1111 0101

补码:1111 0110

原码:1001 0100

反码:1110 1011

补码:1110 1100

计算

1111 0110

1110 1100

补码: 1110 0010

反码: 1110 0001

原码: 1001 1110 16+8+4+2=-30

补码符号位不动,其他位求反,最后整个数加1,得到原码

补码: 1110 0010

求反: 1001 1101 符号位不动,其他位求反

原码: 1001 1110 最后整个数加1

练习:用生辰年份年去生辰日期

1992

-326

1、将10进制转化为二进制

1992 :0000 0000 0000 0000 0000 0111 1100 1000

-326 :0000 0000 0000 0000 0000 0001 0100 0110

2、加符号位将数据变为原码

1992 :0000 0000 0000 0000 0000 0111 1100 1000

-326 :1000 0000 0000 0000 0000 0001 0100 0110

3、转化为反码

1992 :0000 0000 0000 0000 0000 0111 1100 1000

-326 :1111 1111 1111 1111 1111 1110 1011 1001

4、将反码+1转化为补码

1992 :0000 0000 0000 0000 0000 0111 1100 1000

-326 :1111 1111 1111 1111 1111 1110 1011 1010

5、计算补码

1992 :0000 0000 0000 0000 0000 0111 1100 1000

-326 :1111 1111 1111 1111 1111 1110 1011 1010

结果:1 0000 0000 0000 0000 0000 0110 1000 0010

6、将数据转化为10进制

110 1000 0010

2+128+512+1024 = 1666

无符号:

unsigned int a= 1986

无符号:1111 1111 1111 1111 1111 1111 1111 1111 =

0000 0000 0000 0000 0000 0000 0000 0000 =0

无符号整型取值:0-4294967295(2^32-1)

无符号的字符型:0-255

有符号:

int a= 1986

0111 1111 1111 1111 1111 1111 1111 1111 = 2147483647

0000 0000 0000 0000 0000 0000 0000 0001

原码: 1111 1111 1111 1111 1111 1111 1111 1111 = -2147483647

反码:1000 0000 0000 0000 0000 0000 0000 0000

补码:1000 0000 0000 0000 0000 0000 0000 0001=-2147483647

-0的补码

补码:1000 0000 0000 0000 0000 0000 0000 0000=-0 = -2147483648

sizeof关键字

sizeof不是函数,所以不需要包含任何头文件,它的功能是计算一个数据类型的大小,单位为字节

sizeof的返回值为size_t

size_t类型在32位操作系统下是unsigned int,是一个无符号的整数

#include <stdio.h>

int main()

{

int a;

int b = sizeof(a);//sizeof得到指定值占用内存的大小,单位:字节

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

size_t c = sizeof(a);

printf("c = %u\n", c);//用无符号数的方式输出c的值

return 0;

}

b = 4

c = 4

整型变量的定义和输出

打印格式

含义

%d

输出一个有符号的10进制int类型

%o(字母o)

输出8进制的int类型

%x

输出16进制的int类型,字母以小写输出

%X

输出16进制的int类型,字母以大写写输出

%u

输出一个10进制的无符号数

#include <stdio.h>

int main()

{

int a = 123; //定义变量a,以10进制方式赋值为123

int b = 0567; //定义变量b,以8进制方式赋值为0567

int c = 0xabc; //定义变量c,以16进制方式赋值为0xabc

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

printf("8进制:b = %o\n", b);

printf("10进制:b = %d\n", b);

printf("16进制:c = %x\n", c);

printf("16进制:c = %X\n", c);

printf("10进制:c = %d\n", c);

unsigned int d = 0xffffffff; //定义无符号int变量d,以16进制方式赋值

printf("有符号方式打印:d = %d\n", d);

printf("无符号方式打印:d = %u\n", d);

return 0;

}

a = 123

8进制:b = 567

10进制:b = 375

16进制:c = abc

16进制:c = ABC

10进制:c = 2748

有符号方式打印:d = -1

无符号方式打印:d = 4294967295

整型变量的输入

#include <stdio.h>

int main()

{

int a;

printf("请输入a的值:");

//不要加“\n”

scanf("%d", &a);

printf("a = %d\n", a); //打印a的值

return 0;

}

术语

含义

bit(比特)

一个二进制代表一位,一个位只能表示0或1两种状态。数据传输是习惯以“位”(bit)为单位。

Byte(字节)

一个字节为8个二进制,称为8位,计算机中存储的最小单位是字节。数据存储是习惯以“字节”(Byte)为单位。

WORD(双字节)

2个字节,16位

DWORD

两个WORD,4个字节,32位

1b

1bit,1位

1B

1Byte,1字节,8位

1k,1K

1024

1Kb(千位)

1024bit,1024位

1KB(千字节)

1024Byte,1024字节

数据类型

占用空间

short(短整型)

2字节

int(整型)

4字节

long(长整形)

Windows为4字节,Linux为4字节(32位),8字节(64位)

long long(长长整形)

8字节

整型常量

所需类型

10

代表int类型

10l, 10L

代表long类型

10ll, 10LL

代表long long类型

10u, 10U

代表unsigned int类型

10ul, 10UL

代表unsigned long类型

10ull, 10ULL

代表unsigned long long类型

打印格式

含义

%hd

输出short类型

%d

输出int类型

%l

输出long类型

%ll

输出long long类型

%hu

输出unsigned short类型

%u

输出unsigned int类型

%lu

输出unsigned long类型

%llu

输出unsigned long long类型

#include <stdio.h>

int main()

{

short a = 10;

int b = 10;

long c = 10l; //或者10L

long long d = 10ll; //或者10LL

printf("sizeof(a) = %u\n", sizeof(a));

printf("sizeof(b) = %u\n", sizeof(b));

printf("sizeof(c) = %u\n", sizeof(c));

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

printf("short a = %hd\n", a);

printf("int b = %d\n", b);

printf("long c = %ld\n", c);

printf("long long d = %lld\n", d);

unsigned short a2 = 20u;

unsigned int b2 = 20u;

unsigned long c2= 20ul; 

unsigned long long d2 = 20ull; 

printf("unsigned short a = %hu\n", a2);

printf("unsigned int b = %u\n", b2);

printf("unsigned long c = %lu\n", c2);

printf("unsigned long long d = %llu\n", d2);

return 0;

}

sizeof(a) = 2

sizeof(b) = 4

sizeof(c) = 8

sizeof(c) = 8

short a = 10

int b = 10

long c = 10

long long d = 10

unsigned short a = 20

unsigned int b = 20

unsigned long c = 20

unsigned long long d = 20

#include <stdio.h>

int main()

{

signed int a = -1089474374; //定义有符号整型变量a

printf("%X\n", a); //结果为 BF0FF0BA

//B    F    0    F    F    0    B    A

//1011 1111 0000 1111 1111 0000 1011 1010

return 0;

}

当我们写程序要处理一个不可能出现负值的时候,一般用无符号数,这样可以增大数的表达最大值。

有符号和无符号整型取值范围

数据类型

占用空间

取值范围

short

2字节

-32768 到 32767 (-2^15 ~ 2^15-1)

int

4字节

-2147483648 到 2147483647 (-2^31 ~ 2^31-1)

long

4字节

-2147483648 到 2147483647 (-2^31 ~ 2^31-1)

unsigned short

2字节

0 到 65535 (0 ~ 2^16-1)

unsigned int

4字节

0 到 4294967295 (0 ~ 2^32-1)

unsigned long

4字节

0 到 4294967295 (0 ~ 2^32-1)

一个有符号的整型数据可以分为两部分一部分是符号位、一部分是数字位

无符号数据类型只包含数字位部分

无符号:1111 1111 1111 1111 1111 1111 1111 1111 = 4294967295(2^32-1)

0000 0000 0000 0000 0000 0000 0000 0000 =0

无符号整型取值:0-4294967295(2^32-1)

有符号:0111 1111 1111 1111 1111 1111 1111 1111 = 2147483647 (2^31-1)

有符号:1111 1111 1111 1111 1111 1111 1111 1111 = -2147483647 (-2^31-1)

原码:1111 1111 1111 1111 1111 1111 1111 1111 = -2147483647

反码:1000 0000 0000 0000 0000 0000 0000 0000

补码:1000 0000 0000 0000 0000 0000 0000 0001 = -2147483647

-0的补码

补码:1000 0000 0000 0000 0000 0000 0000 0000 = -2147483648

#include <stdio.h>

int main(void)

{

int a = 2147483647;

a = a + 1;

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

return 0;

}

a=-2147483648

#include <stdio.h>

int main(void)

{

int a = 2147483647;

a = a + 2;

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

return 0;

}

a=-2147483647

#include <stdio.h>

int main(void)

{

unsigned int a = 0;

a = a - 1;

printf("a=%u\n", a); 

return 0;

}

a=4294967295

无符号整型取值:0-4294967295(2^32-1)

无符号的字符型:0-255

字符型:char

字符变量的定义和输出

字符型变量用于存储一个单一字符,在 C 语言中用 char 表示,其中每个字符变量都会占用 1 个字节。在给字符型变量赋值时,需要用一对英文半角格式的单引号(' ')把字符括起来。

字符变量实际上并不是把该字符本身放到变量的内存单元中去,而是将该字符对应的 ASCII 编码放到变量的存储单元中。char的本质就是一个1字节大小的整型。

输出和输入:

输出字符的两种方式:

1、printf("%c",变量)

2、putchar(字符)

输入字符的两种方式:

1、scanf("%c",&b变量)

2、变量=getchar()

#include <stdio.h>

int main(void)

{

char a;

printf("请输入a的值:");

scanf("%c",&a);

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

}

#include <stdio.h>

int main(void)

{

char b;

printf("请输入b的值:");

b = getchar();

putchar(b);

putchar('\n');

return 0;

}

ASCII值

控制字符

65

A

90

Z

97

a

122

z

48

0

57

9

转义字符

转义字符

含义

ASCII码值(十进制)

\n

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

10

\t

水平制表(HT) (跳到下一个TAB位置)

9

\a

警报

7

\b

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

8

\f

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

12

\r

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

13

\v

垂直制表(VT)

11

\

代表一个反斜线字符""

92

代表一个单引号(撇号)字符

39

"

代表一个双引号字符

34

?

代表一个问号

63

\0

数字0

0

\ddd

8进制转义字符,d范围0~7

3位8进制

\xhh

16进制转义字符,h范围0~9,a~f,A~F

3位16进制

%%可输出一个%

#include <stdio.h>

int main()

{

printf("abc");

printf("\refg\n"); //\r切换到句首, \n为换行键

printf("abc");

printf("\befg\n");//\b为退格键, \n为换行键

printf("%d\n", '\123');// '\123'为8进制转义字符,0123对应10进制数为83

printf("%d\n", '\x23');// '\x23'为16进制转义字符,0x23对应10进制数为35

return 0;

}

当超过一个数据类型能够存放最大的范围时,数值会溢出。

有符号位最高位溢出的区别:符号位溢出会导致数的正负发生改变,但最高位的溢出会导致最高位丢失。

数据类型

占用空间

取值范围

char

1字节

-128到 127(-2^7 ~ 2^7-1)

unsigned char

1字节

0 到 255(0 ~ 2^8-1)

char 1B=8bit

0x7f是127

0x7f+2

0111 1111

0000 0010

1000 0001 相加结果

1000 0000 求反码

1111 1111 -127 ,求原码

0xff

1111 1111

0000 0001

1 0000 0000

#include <stdio.h>

int main()

{

char ch;

//符号位溢出会导致数的正负发生改变

ch = 0x7f + 2; //127+2

printf("%d\n", ch);

// 0111 1111

//+2后 1000 0001,这是负数补码,其原码为 1111 1111,结果为-127

//最高位的溢出会导致最高位丢失

unsigned char ch2;

ch2 = 0xff+1; //255+1

printf("%u\n", ch2);

//   1111 1111

//+1后 10000 0000, char只有8位最高位的溢出,结果为0000 0000,十进制为0

ch2 = 0xff + 2; //255+1

printf("%u\n", ch2);

//   1111 1111

//+1后 10000 0001, char只有8位最高位的溢出,结果为0000 0001,十进制为1

return 0;

}

实型(浮点型):float、double

实型变量也可以称为浮点型变量,浮点型变量是用来存储小数数值的。在C语言中, 浮点型变量分为两种: 单精度浮点数(float)、 双精度浮点数(double), 但是double型变量所表示的浮点数比 float 型变量更精确。

数据类型

占用空间

有效数字范围

float

4字节

7位有效数字

double

8字节

15~16位有效数字

由于浮点型变量是由有限的存储单元组成的,因此只能提供有限的有效数字。在有效位以外的数字将被舍去,这样可能会产生一些误差。

不以f结尾的常量是double类型,以f结尾的常量(如3.14f)是float类型。

#include <stdio.h>

int main()

{

//传统方式赋值

float a = 3.14f; //或3.14F

double b = 3.14;

printf("a = %f\n", a);

printf("b = %lf\n", b);

//科学法赋值

a = 3.2e3f; //3.2*1000 = 3200,e可以写E

printf("a1 = %f\n", a);

a = 100e-3f; //100*0.001 = 0.1

printf("a2 = %f\n", a);

a = 3.1415926f;

printf("a3 = %f\n", a); //结果为3.141593

return 0;

}

a = 3.140000

b = 3.140000

a1 = 3200.000000

a2 = 0.100000

a3 = 3.141593

#include <stdio.h>

int main()

{

float r = 2;

float s = 3.14*r*r;

printf("s = %.2f\n", s); //s = 12.56

return 0;

}

格式控制符m.n,m表示输出数据宽度,n表示数据精度,具体因数据类型而不同。

"%m.nf"

1 m:总宽度,包括小数点

2 n:小数部分位数

3 m>n+1, 也可以小于, 但编译结果会按实际数据输出

4 如果m过大, 会在左边补空格

#include <stdio.h>

int main()

{

float r = 2;

float s = 3.14*r*r;

printf("s = %9.2f\n", s); //s = 12.56

return 0;

}

结果:

s =     12.56

浮点型:

float 用于存储带有小数的数据

在格式化输入printf("%f",变量)通过占位符%f来接收的

double 用于存储带有小数的数据 数据长度比float更长

注意:因为将小数转化为二进制时不是一个精确的值,所以浮点型都会有数据偏差

数据类型在内存的大小

#include <stdio.h>

int main()

{

int a=10;

//sizeof()求出数据类型在内存中占字节(Byte)大小

int len1 = sizeof(a);

//单精度浮点型

float b = 3.14;

//字符型

char c = 'A';

//双精度浮点型

double d = 5.12;

//短整形

short e = 10;

//长整型

long f = 10;

//长长整形

long long g=10;

int len2 = sizeof(b);

int len3 = sizeof(c);

int len4 = sizeof(d);

int len5 = sizeof(e);

int len6 = sizeof(f);

int len7 = sizeof(g);

printf("%d\n",a);

printf("int =%d\n",len1);

printf("float =%d\n",len2);

printf("char = %d\n",len3);

printf("double = %d\n",len4);

printf("short = %d\n",len5);

printf("long = %d\n",len6);

printf("long long = %d\n",len7);

return 0;

}

格式化输入输出

#include <stdio.h>

int main(void)

{

int a;

scanf("%d",&a);

printf("%d\n",a);

return 0;

}

练习

7f为127

#include <stdio.h>

int main(void)

{

char ch;

ch=0x7f+2;

printf("%d\n",ch);

return 0;

}

08浮点型数据操作

#include <stdio.h>

int main(void)

{

/*

单精度浮点型

float r=2;

float s = r*r*3.14;

printf("%1.2f\n",s);

*/

double a=2.0;

double s = a* a* 3.14;

printf("%f\n",s);

return 0;

}

思考任务(课后练习)

八进制必须以_____开头,十六进制必须以_______开头。

标识符只能由_______、__和_______组成。在计算机中的进制表现形式有三种,分别是、 _______、

C 语言提供了 sizeof 运算符,该运算符主要用于

二进制和八进制相互转换

111 010 101 011 转换为八进制后结果为?

76321 转换为二进制结果为?

二进制和十六进制相互转换

1111 1010 1101 1011 转换为十六进制后结果为?

a6b2f1 转换为二进制结果为?

请写出-8的原码、反码、补码

计算如下程序结果

short a = 0xfffe;

printf("%d\n", a); //结果为多少?

unsigned short a = 0xfffe;

printf("%u\n", a); //结果为多少?

short a = 0x7fff + 2;

printf("%d\n", a); //结果为多少?

unsigned short a = 0xffff + 5;

printf("%u\n", a); //结果为多少?

原文地址:https://www.cnblogs.com/wanglinjie/p/11311638.html