前言
变量:在运行期间会改变和赋值,需要在声明时指定类型
常量:在运行期间没有变化
位:最小存储单元,存储0、1,是计算机内存的基本构建块
字节:计算机存储单位,1字节=8位
字:自然存储单位,1个字长可以有8,16,32位,现在计算机普遍64位
整数:无小数部分,以二进制数字存储整数
浮点数:有小数部分,表示的范围更大,损失的精度更多,浮点数通常只是实际值的近似值,eg:2.75、3.16E7=3.16*107、2e-8,在计算机中被分为小数部分和指数部分表示,且分开存储
C语言使用特定的前缀表示使用哪些进制
0x或0X表示16进制
0表示8进制
10进制16=0x10=020
基本数据类型
C通过识别一些基本数据类型来区分和使用不同的数据类型
int(short long unsigned修饰int)整数
float、double 、long double 浮点数
char 字符、较小的整数
_Bool 布尔 _Complex复数 _Imaginary 虚数
先声明在使用,使用有意义的变量名
初始化应该和类型匹配,类型不匹配时会损失精度
int
有符号整型,可以是正整数,负整数和0
一个int占一个机器字长,32位或64位
ISO C规定int最小取值范围为-32768~32787,c语言规定不小于16位
一个特殊位表示正负号
整型常量:编译器自行判断常量类型
整数溢出会出现结果错误
#include <stdio.h>
int main()
{
// 声明
int age; // 声明一个int类型变量、赋予名称、分配内存空间
int dogs, cows, goats; // 声明多个变量、逗号分隔
// 初始化:给变量赋初值
age = 10; // 直接赋值
scanf("%d", &age); // 键盘输入一个整数赋值给age
int erns = 10; // 声明创建内存空间同时初始化
int hogs = 10, cats = 14; // 同时对两个值声明赋值
// int ages,cats=10;//变量ages未初始化,不建议用
// int cost=12.99;用double类型的值初始化float类型的变量,直接丢弃小数部分不进行四舍五入
/* 打印int值
%d 以10进制格式打印int值,指明在一行中打印整数的位置
%x 16进制、显示前缀使用%#x、显示大写使用%X
%o 8进制、显示前缀使用%#o、显示大写使用%O
进制只是显示不同,都以二进制存储*/
int ten = 10, two = 2, x = 100;
printf("%d minus %d is %d\n", ten, 2, ten - two);
// 可以是int变量,int常量,或是值为int的表达式
printf("%d minus %d is %d\n", ten);
/*前后数目不对应,会打印出内存中的任意值,也可能编译报错
使用printf时,要确保转换数量和待打印值数量相等*/
printf("dec =%d;octal=%o;hex=%x\n", x, x, x);
printf("dec =%d;octal=%#o;hex=%#x\n", x, x, x);
getchar();
return 0;
}
其他整数类型
提供3个附属关键字修饰基本整数类型:short、long、unsigned、signed(C90);
short (short int),通常占16位
int,通常占32位
long (long int),通常占32位
long long (long long int),通常占64位,C99加入
以上均为有符号类型
unsigned int 用于非负的场合,可以表示更大的正数
同理,
unsigned short(unsigned short int),
unsinged(unsinged int),
unsigned long(unsigned long int),
unsigned long long(unsigned long long int)、C99加入
占用空间大会减慢运算速度,优先使用小类型节省存储空间
使用long代替int的原因:在系统中要表示的数超过了int可表示的范围;要使用一种在所有系统中都保证至少是32位的类型,提高程序的可移植性
通常取值范围
long>short,int可能和short相等(在旧DOS系统),也可能和long相等(在windows 95系统)
类型 | 通常取值范围 | 位数 | 字节 |
---|---|---|---|
short | -32768,32767 | 16 | 2 |
unsigned short | 0,65535 | 16 | 2 |
int | -21.4亿, 21.4亿 或 -32768,32767 | 32/16 | 4/2 |
unsigned int | 0,42.9亿 或 0,65535 | 32/16 | 4/2 |
long | -21.4亿, 21.4亿 | 32 | 4 |
unsigned long | 0,42.9亿 | 32 | 4 |
long long | -9223千万亿,9223千万亿 | 64 | 8 |
unsigned long long | 0,18446千万亿 | 64 | 8 |
#include<limits.h>//INT_MIN,INT_MAX
int max = (1<< (sizeof(int)*8-1))-1;//获取最大值
int min = 1 << (sizeof(int)*8-1);
printf("max %d min %d\n",max,min);
long常量
在数字末尾加上l(L)做后缀:需要编译器以long类型存储一个小数字,把一个较小的常量作为long类型对待;
可使用LL做后缀表示long long 类型的值
加u(U)做后缀表示无符号常量
eg:7L,3LL,5ull
打印
(signed)int %d
unsigned %u u不可省略,整数值有无符号在内存中表示完全相同,必须指定无符号值,才能正确打印
short类型 %hd、%hx 十六进制、%ho 八进制、%hu无符号
long类型 %ld、 %lx 十六进制、%lo 八进制、%lu无符号
long long 类型 %lld、 %llx 、%llo、 %llu
必须根据待打印值类型使用正确的转换说明
char
存储字符,整数类型,
使用数字编码处理字符:使用特定的整数表示特定的字符
标准ASCII是0-127,通常被定义为8位存储单元,C语言定义为1字节
单引号是字符
双引号是字符串,一个字符串是一个参数
声明
char response;
char itable,latan;
初始化
char grade = 'A';//用单引号引起来的单个字符是字符常量,声明grade且赋值'A'
char broiled;//声明
broiled ='A';//单引号赋值适用于字符,数字,标点符号
char a ='4';//表示字符4.对应ASCII值为52
char beep = 7;//表示ASCCI值为7,蜂鸣字符
//broiled =T;//错误,T是变量
//broiled ="A";//错误,双引号引起来的是字符串
//broiled =65;//正确,不建议
//char grade = 'ADFE';//溢出警告,char只有1字节8位,grade是E
其他字符
char beep = 7; // 蜂鸣字符的ASCII为7
char nerf = '\n'; // 转义字符
char beep1 = '\007'; // 8进制的7,ASCII值为7,可以省略为'\7','\07'
char beep2 = '\x7'; // 16进制的7
char beep3 = '7'; // 字符7 ASCII值为55
printf("Gramps sez,\"a \\ is a backslash\"\n"); // 双引号括起来的字符集合,无需用单引号括,\\打印出来\,\'打印出来',\"打印出来",\做转义,/直接打印
printf("Hello!\007\n"); // 打印出Hello!加一声蜂鸣
printf("Hello!7\n"); // 打印出Hello!7
printf("Hello!%d\n", beep1); // 打印出Hello!7
printf("Hello!%d\n", beep3); // 打印出Hello!55
使用 \f 比直接使用ASCII好记,好移植
使用 \032 可以嵌入字符串中
打印字符
char ch;
printf("Please enter a character.\n");
scanf("%c",&ch);
printf("The code for %c is %d.\n",ch,ch);//%d只决定显示方式
char 在不同编译器里可以是有符号和无符号类型
_BOOL
逻辑值true(1)和false(0),只占用1位存储空间
可移植类型
stdint.h
精确宽度整数类型
示例:
int32_t表示32位有符号整数类型
在int16位,long32位的系统中作为long的别名
最小宽度类型
示例:
int_least8_t是可容纳8位有符号整数值的类型中宽度最小的类型别名
最快最小宽度类型
示例:
int_fast8_t是系统对8位有符号值运算最快的整数类型的别名
最大有符号整数类型intmax_t
最大无符号整数类型unintmax_t
inttypes.h
PRId32代表打印32位有符号值的合适转换说明
#include<inttypes.h>//支持可移植类型
int32_t me32; // 32位有符号整型变量
me32 = 45933945;
printf("me32=%d\n", me32);
printf("me32=%" PRId32 "\n", me32);
//相当于printf("me32=%" "d" "\n", me32);
float、double、long double 浮点数
浮点能表示包括小数在内更大范围的数
float类型
至少精确到小数点后6位有效数字
最小取值范围是10-37~10+37,通常系统存储一个浮点数要32位,其中8位用于表示指数的值和符号,剩下24位用于表示非指数部分
不加后缀的浮点型常量默认double、加f\F后缀可覆盖默认设置
double类型
至少必须能表示10位有效数字,取值范围与float相同
一般占用64位,多出的32位全部用来表示非指数部分或者分配一部分给指数部分
精度高,运算速度减慢
不加后缀的浮点型常量默认double、加f\F后缀可覆盖默认设置
long double 只保证精度和double相同
加l\L后缀
声明
float noah,jonah;
double trouble;
float planck = 6.63e-34;
long double gnp;
//float pi=3.1415926536;用double类型的值初始化float类型的变量,只能保证前6位的精度,可能会报警告
浮点型常量
有符号的数字 +. +e/E +有符号数表示10的指数
浮点型常量中间没有空格
-1.56E+12
2.87e-3
.可省略 2e5 4e16
指数可省略 19.28 100.
小数部分可省略 3.E16
整数部分可省略 .45E-6 .2 .8E-5
点和指数不能同时省略
小数和整数部分不能同时省略
默认double类型
加f/F 后缀float
加l/L 后缀long double
打印浮点数
float aboat = 32000.0;
double abet = 2.14e9;
double dip = 5.32e-5; // long double dip = 5.32e-5;打印错误
printf("%f can be written %e\n", aboat, aboat);
printf("And it's %a in hexadecimal ,powers of 2 notation\n", aboat);
printf("%f can be written %e\n", abet, abet);
printf("%Lf can be written %Le\n", dip, dip);
/*
%f 打印十进制float 和 double
%e 打印指数计数法 E 大写
%a 打印16指数计数法 A
%LF %Le %La打印long double
%.2f 精确控制输出小数点后2位
*/
上溢下溢
上溢:计算导致数字过大超过当前类型能表达的范围;
下溢:在计算过程中损失原末尾有效位上的数字;
浮点数舍入错误:浮点数只存按比例缩小或放大的6/7位,如果发生变化的是7位之后的数字会发生错误,eg:2.0e20+1.0;需要变化的是第21位,所以错误,
2.0e4+1.0;需要变化的是第5位,在float精度内;
复数 _Complex 虚数 _Imaginary
complex.h
float_Complex
double_Complex
long double_Complex
float_Imaginary
double_Imaginary
long double_Imaginary
其他
类型大小
sizeof()内置运算符,以字节为单位给出指定类型大小
%zd (%u %lu可代替)
/*C99 为类型大小提供%zd 转换说明 */
printf("Type int has a size of %zd bytes,\n", sizeof(int));
printf("Type char has a size of %zd bytes,\n", sizeof(char));
printf("Type long has a size of %zd bytes.\n", sizeof(long));
printf("Type lonq long has a size of %zd bytes.\n", sizeof(long long));
printf("Type double has a size of %zd bytes.\n", sizeof(double));
printf("Type long double has a size of %zd bytes,\n"
,sizeof(long double)); // 只要不在引号内部或一个单次中间即可换行
参数和陷阱
双引号是一个字符串,一个字符串是一个参数
scanf(“%d”,&weight);包括两个参数
scanf和printf参数个数可变,用第一个字符串参数表明后续有多少个参数,转换说明的数量个数和类型需要匹配
参数太少,太多,值类型不匹配都会出问题
转义序列
部分转义序列不兼容
float salary;
printf("\aEnter your desired monthly salary:"); /* 1 \a警报*/
printf(" $_______\b\b\b\b\b\b\b"); /* 2 \b 光标左移一个位置*/
scanf("%f", &salary);
printf("\n\t$%.2f a month is $%.2f a year.", salary,
salary * 12.0); /* 3 \n下一行 \t 下一个制表点,一般是第9列 没有\n结束后光标停在本行末尾*/
printf("\rGee!\n"); /* 4 \r当前行起始位置*/
printf会把输出发送到缓冲区,当缓冲区满 或需要换行或需要输入时,会把数据发送到屏幕或文件,称为刷新缓冲区