03数据与基本数据类型
数据
计算机就是帮助人们处理数据的,数据就是承载信息的数字与字符。
变量
数据在程序运行过程中可能变化或被赋值,这称为变量。
变量必须先定义,后使用。
- 声明变量
①定义变量时指定该变量的名字和类型
②尽量使用有意义的变量名,变量名尽量英文
③变量名最多63个字符(C99),可供使用的字符有小写字母,大写字母,数字,下划线。第一个字符必须是字母或下划线。字母区分大小写。
④变量名实际上是以一个名字代表的一个存储地址,从变量中取值,实际上是通过变量名找到相应的内存地址,从该存储单元中读取数据。
⑤每个变量必须有一个类型,如整型、浮点型等,它指明给这个变量分配多大量的存储空间;一般,一个变量还要有值,值放在变量的存储空间内。
⑥声明多个变量时,用逗号隔开。
❗注意:有的编译器只支持在代码最前边声明,否则会报警告(
未加;
)。但C99标准要求在一个代码块的开始处声明变量
int i;
int j = 1;
int a, b, c;
- 变量赋值(初始化变量)
int num = 2;//num是一个变量,可以对num随意赋值
前边的 int num 语句在计算机内存中为变量num分配了空间,该赋值语句在那个地方为变量存储了一个值。
赋值的顺序是从右到左
- 变量的输出:
printf(格式控制,输出表列)
①括号中大致分两部分,第一部分用双引号,并用英文逗号隔开,第二部分写变量名(一个或多个)或者具有合适类型的某个式子(a * fathoms)
②引号中的%d的位置就是变量要待的位置,然而%d并不是固定,写什么取决于变量的数据类型。
③输出多个值时,第二部分的每一项都要用逗号隔开
int num = 2; printf("%d \n", num);
- 变量的输入:
scanf(格式控制,地址表列)
格式:scanf(%d,&a);
注意点:
①输出格式符(%d)要与变量名a的类型一致
②一定要加&号,表示变量地址,不加会演示异常
③在需要输入多个变量时,一定要注意分隔符是什么(空格?逗号?还是字母?)这样用户在输入时,在多个变量之间选择正确的分隔符
④消除警告:当出现如下警告:
文件地址: warning C4996: 'scanf': This function or variable may be unsafe.
则:方案①将
scanf
换成scanf_s
方案②文档最最前边加上一行(这是宏):
#define _CRT_SECURE_NO_WARNINGS
方案③文件前边加上:
#pragma warning(disable:4996)
注:scanf是标准C的。scanf_s是微软的。该警告可以忽略,但并不是所有警告都可以忽略。
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#pragma warning(disable:4996)
int main(void)
{
int a = 12;
printf("前:%d \n", a);
scanf("%d",&a);
printf("后:%d \n", a);
system("pause");
return 0;
}
//输入多个变量
scanf("%d%d",&a);//表示分隔符是空格
scanf("%d,%d",&a);//表示分隔符是逗号
scanf("%da%d",&a);//表示分隔符是字母a
- 取变量地址:
&变量名
输出格式符:
%p
(十六进制)int bd = 12; printf("%p \n", &bd);//0014FF20
加前缀#:
int bd = 12; printf("%#p \n", &bd);//0X0014FF20
常量
有些数据可以在程序使用之前预先设定并在整个运行过程中没有变化,这称为常量,比如1,4.2等。
符号常量:可以使用一个标识符表示常量。如:PI 表示 3.14159,C 语言中使用宏定义命令#define来定义。
格式:#define 标识符 常量串
例如:
#define PI 3.14159
#define BEEP '\a'
#define OOPS "Now you have done it! "
符号常量使程序易于阅读和修改。例如,一个程序中多处用到学生人数60,当有学生人数改变为65,修改这个程序很困难。而使用符号常量,只要将
#define NUM 60
改为#define NUM 65
,就可以了。说明:1)符号常量名常常用大写字母、变量名用小写字母。
2)符号常量不能在其作用域范围内重新赋值。
#define PRICE 30
#include <stdio.h>
int main()
{ int num,total;
num=10;
total=num*PRICE;
printf("total=%d\n",total);
}
常变量
其实也是符号常量。
const int a = 3;
其实C还有第三种办法创建符号变量,就是枚举(enum)功能。
转义序列
序列 | 意义 |
---|---|
\a | 警报(ASCLL C) |
\b | 退格 |
\f | 走纸 |
\n | 换行 |
\r | 回车 |
\t | 水平制表符 |
\v | 垂直制表符 |
\\ | 反斜杠(\) |
\' | 单引号(‘) |
\" | 双引号(“) |
? | 问号(?) |
\0oo | 八进制值(o表示一个八进制数字) |
\xhh | 十六进制值(h表示一个十六进制数字) |
例如我们想打印下边这行内容
Gramp sez,"a \ is a backslash."
可以使用下边代码:
printf("Gramp sez,\"a \\ is a backslash.\" \n")
数据类型
❓什么是类型?
是对数据分配存储单元的安排,包括存储单元的长度(占多少字节)以及数据的存储形式。不同的类型分配不同的长度和存储形式
❓计算机为什么要分类型?
计算机要对数据进行分类处理,使更有条理,计算更加清晰,从而增加效率。
把一个变量声明为整数类型或字符类型是计算机正确地存储、获取和解释该数据地基本前提。
作用:编译器预算对象(变量)分配的内存空间大小。
sizeof()
:查看数据类型字节大小
unsigned int c = 2;
printf("%u \n",sizeof(unsigned int));//4
位、字节、字:
- 术语位、字节、字用于描述计算机数据单位或计算机存储单位。
- 最小的存储单位称为位(bit)。它可以容纳两个值(0或1)之一,是计算机存储的基本单位。
- 字节(byte)是常用的计算机存储单位。几乎对于所有的机器,1个字节均为8位。由于每个位或者是0或者是1,所以一个8位的字节包含256(2的8次方)种可能的0,1组合,这些组合可用于表示0到255的整数或者一组字符。
- 字(word)是自然的存储单位。
基本数据类型
整型
声明一个int类型变量就是声明一个存储int类型数据的容器;4个字节大小,至少16位长
格式说明符:%d
//声明了一个int类型的变量 int a; //变量b是一个整数类型,被赋值为187234(初始化) int b = 187234;
数的范围:-2的31次方到2的31次方-1(-2147483648-2147483647)
格式说明符:%d
数的范围:02的32次方-1(04294967295)
用
%u
输出无符号整型signed int x = -1; unsigned int c = 2; printf("%u \n", c);//2
数的范围:-2的15次方到2的15次方-1(-32768~-32767),至少16位长,2字节大小
输出格式符:
%hd
short s = 12; short int si =12;
数的范围:-2的31次方到2的31次方-1(-2147483648-2147483647),至少32位长
window占4字节,Linux 4字节(32位),8字节(64位)
输出格式符:
%ld
C99标准新类型(现大多用的C89编译库)
8字节数,范围:-2的63次方到2的64次方-1,至少64位长
输出格式符:
%lld
- 字符型char
char类型用于存储字母和标点符号之类的字符。但是在技术实现上,char却是整数类型,这是因为char类型实际上存储的是整数而不是字符(本质上是存储1个字节大小的整数 )。
为了处理字符,计算机使用一种数字编码,用特定的整数表示特定的字符。常用的是ASCLL码。
①声明:
char response;
char itable, latan;
②字符常量及其初始化:
char grade = 'A';//注意这里是单引号
char grade2 = 65;//65是字母A的ASCLL码,此语句将字符A赋予变量grade2
//推荐使用字符常量,而不是数值编码(因为不能保证系统使用的一定是ASCLL码)
值得注意的是:C将字符常量视为int类型,而不是char类型。
例如,在int类型为32位和char类型为8位的ASCLL系统中,下列代码:
char grade = 'B';
意味着’B’ 作为数值66存储在一个32位单元中,而赋值后的grade则把66存储在一个8位单元中。
利用字符常量的这个特性,可以定义一个字符常量‘FATE’,这将把4个独立的8位ASCII码存储在一个32位单元中。然而,如果把这个字符常量赋给一个char变量,那么只有最后8位会起作用,因此变量的值为‘E’。
③打印字符
char ch;
printf("please enter a character.\n");
scanf("%c",&ch);
printf("The code for %c is %d.\n",ch,ch);
/*
please enter a character.
假如用户输入的C
The code for C is 67.
*/
④有符号还是无符号
一些C实现把char当作有符号类型。这意味着char类型值的典型范围为-128到127.
另一些C把char当作无符号类型,其取值范围为0到255.
编译器手册会指明char的类型,或者通过limits.h
头文件检查这一信息。
⑤字符’1’和整数1
字符’1’只是代表一个形状为’1’的符号,在需要时按原样输出,在内存中以ASCII码形式存储,占1个字节.
整数1是以整数存储方式(二进制补码方式)存储的,占2个或4个字节
- _Bool类型
_Bool
类型由C99引入,用于表示布尔值,即逻辑值true(真)与false(假)。因为C用值1表示true,用值0表示false,所以_Bool
类型实际上也是一种整数类型。只是原则上它仅仅需要1位来进行存储。因为对于0和1而言,1位的存储空间已经够用了。
浮点型
输出格式符:
%f
(默认输出六位小数)内存大小:4字节
输出格式符:
%lf
(默认输出六位小数)内存大小:8字节
输出格式符:
%lf
内存大小:大于8字节
📌其他格式说明符:
格式 | 说明 |
---|---|
%e | 用科学计数法输出(指数形式) |
%o | 以八进制输出 |
%X | 以十六进制输出 |
%#o | 以八进制输出,加上前缀0 |
%#x | 以十六进制输出,加上前缀0x |
%#X | 以十六进制输出,加上前缀0X |
%lx | 以十六进制格式打印长整数 |
%lo | 以八进制格式打印长整数 |
%ho | 以八进制显示short整数 |
%hd | 以十进制输出short整数 |
… | h和l前缀都可以和u组合使用表示无符号类型(%lu是unsigned long) |
举例:
include<stdio.h>
int main(void)
{
int a = 100;
printf("十进制:%d,八进制:%0,十六进制:%x\n",a,a,a);
//十进制:100,八进制:144,十六进制:64
printf("十进制:100,八进制:0144,十六进制:0x",a,a,a);
//十进制:100,八进制:0144,十六进制:0x64
}
📌问题总结:
📝0和0.0是不一样的:
printf("%e \n",0);//8.848045e-305
printf("%e \n",0.0);//0.000000e+000
- 浮点数与整数的存储方案不同。浮点数表示将一个数分为小数部分和指数部分并分别存储,例如:
以浮点格式存储实数(十进制版本) | ||
---|---|---|
+ | .314159 | 1 |
符号 | 小数部分 | 指数部分 |
-
浮点数与整数的精确度不同。浮点数会损失更多精度。浮点数往往是实际值的近似值,例如7.0可能以浮点值6.999999存储。
-
浮点数与整数的运算速度不同。浮点运算通常比整数运算慢。
📝查看最大最小值:
printf("%e, \n",FLT_MAX);
//选中FLT_MAX,点击鼠标右键,转到定义->float.h
printf("%e, \n",FLT_MIN);
printf("%e, \n",DBL_MAX);
📝何为精度
精度是指有效数位(从第一个非零数开始查)精确到哪里
单精度ANSI C规定最小值为6位,双精度ANSI C规定最小值为10位
例如:
float f = 2333.3456289;
printf("%f",f);//2333.345703
//输出和我们赋值的数值不相等,是因为精确度只有前7位【不同编译器位数不一定相同,这里用的是vs2010】
📝关于警告C4305:从double到float截断
8字节的到4字节,(大范围类型到小范围类型的转变)在C语言中,写小数默认是double类型,所以会报出警告,这是数值后边加上f(F)即可
float f = 12.23f;
float f = 12.23F;
long double ld = 12.34l;
📝如果位数超出float或double能显示的位数(6)则四舍五入
float a =12.2326345f;
printf("%f",f);//12.232635
📝控制输出位数
float a =12.2326f;
printf("%.2f",f);//12.23保留两位小数
📝控制数值占多少输出位:(数据宽度)
float a =12.2326f;
printf("%10.2f",f);// 12.23 占10个位置,此时右对齐
printf("%-10.2f",f);//加符号表示左对齐
可移植类型:inttypes.h
以上这些基本的名字不够明确。比如,知道一个变量是int类型并不能告诉您它有多少位,除非您查看系统文档。为解决这类问题,C99提供了一个可选的名字集合,以确切地描述有关信息。
例如:int16_t表示一个16位有符号整数类型,uint32_t表示一个32位无符号整数类型。
要使这些名字对于程序有效,应当在程序中包含inttypes.h头文件。这个文件使用typedef工具创建了新的类型名字。
inttypes.h头文件将定义串PRId16来表示打印16位有符号值所需的合适说明符。