C语言基础知识-数据类型
作者:尹正杰
版权声明:原创作品,谢绝转载!否则将追究法律责任。
一.常量与变量
1>.关键字
C的关键字共有32个。
>.数据类型关键字(12个)
char,short,int,long,float,double,unsigned,signed,struct,union,enum,viod
>.控制语句关键字(12个)
if,else,switch,case,default,for,do,while,break,contiue,goto,return >.存储类型关键字(5个)
auto,extern,register,static,const >.其他关键字(3个)
sizeof,typedef,volatile
2>.数据类型
数据类型的作用:编译器预算对象(变量)分配的内存空间大小。 1>.数据类型的定义
变量的定义:
数据类型 变量名[也叫标识符],如:"char Habby;"
变量的赋值:
变量名 = 值,如:“NAME=Jason Yin;”
数据类型 变量名称[标识符] = 值,如:"int AGE = 10;" 2>.标识符的命名规则
字母,数字,下划线组成;
不能以数字开头(第一个字符必须为字母或下划线);
见名知意;
不能和同一函数内其他标识符重复;
不能使用C语言内置的关键字;
标识符中字母区分大小写;
3>.常量
常量的作用:
在程序运行过程中,其值不能被改变的量;
常量一般出现在表达式或赋值语句中; 举几个例子:
整型常量 : ,,-, 等
实型常量 : 3.14,9.18,1.44 等
字符型常量 : 'a','b','','\n'
字符串常量 : "age","","jason" 常量的定义:
const 数据类型 常量名;
#deifne 常量名 值 注意:
通过“#deifne”定义的常量是根据值来匹配数据类型的,推荐使用这种方式定义常量。
const修饰的常量是不安全的,可以通过指针来修改
4>.变量
变量的作用:
在程序运行过程中,其值可以改变;
变量在使用前必须先定义,定义变量前必须有相应的数据类型; 变量特点:
变量在编译时为其分配相应的内存空间;
可以通过其名称和地址访问相应内存;
5>.类型限定符
extenrn:
声明一个变量,extern声明的变量没有建立存储空间。 const:
定义一个常量,常量的值不能修改。例如 const int MONTH = ; volatile:
防止编译器优化代码。 register:
定义寄存器变量,提高效率。register是建议型的指令,而不是命令型的指令,如果CPU有空闲寄存器,那么register就生效,如果没有空闲寄存器,那么register无效。
6>.使用案例
[[email protected] /yinzhengjie/code/day002]# cat variable_definitions.c
/*
@author :yinzhengjie
blog:http://www.cnblogs.com/yinzhengjie
EMAIL:[email protected]
*/ #include <stdio.h>
#define PI 3.1415926 int main(void)
{
//定义变量
int _age = ;
printf("Age={%d}\n",_age); //定义常量
const int MONTH = ;
printf("一年有{%d}个月\n",MONTH); //引用使用"#define"定义的变量
printf("圆周率为:{%f}\n",PI);
}
[[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]# gcc -o variable_definitions variable_definitions.c
[[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]# ./variable_definitions
Age={}
一年有{}个月
圆周率为:{3.141593}
[[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]#
二.进制
进制也就是进制位,是人们规定的一种进位方法。对于任何一种进制-X进制,就表示某一位置的数运算时逢x进一位。十进制是逢十进一,十六进制是逢十六进一,二进制就是逢二进一,依次类推,x进制就是逢x进位。
1>.二进制
二进制逢2进1,所有的数都是由0,1组成,如11+=。
十进制转二进制:
除二反序取余法(将十进制数每次除以2,取出余数,按照结果倒叙排序)。
二进制专十进制:
权值法(将二进制各个位数从0位开始乘以2的N次幂,将各个位数的结果相加)。 当前计算机系统使用的基本上都是二进制系统,数据在计算机中主要以补码的形式存储。以下一些术语大家可以了解一下:
bit(比特)
一个二进制代表以为,一个位只能表示0或1两种状态。数据传输是习惯以“位”(bit)为单位。
Byte(字节)
一个字节为8个二进制,称为8位,计算机中存储的最小单位是字节。数据存储是习惯以“字节”(Byte)为单位。
WORD(双字节)
2个字节,即16位。
DWORD
两个WORD,4个字节,即32位。
1b
1bit,1位。
1B
1Byte,1字节,8位。
1k,1K
1024B。
1M(1兆)
1024k,1024*1024。
1G
1024M。
1T
1024G。
1Kb(千位)
1024bit,1024位。
1Kb(千字节)
1024Byte,1024字节。
1Mb(兆位)
1024Kb = 1024 * 1024bit。
1MB(兆字节)
1024KB=1024 * 1024Byte
2>.八进制
八进制逢8进1,所有的数字是0到7组成。 十进制转八进制:
除八反序取余法(将十进制数每次除以8,取出余数,按照结果倒叙排序)。
二进制转化为八进制:
将二进制数字从右到左,每3个二进制数划分为一组,将每组数据的二进制转换成八进制对应的数字即可。
八进制转换为二进制:
八四二一法则(将八进制的每一个位数上的数字拆开,分别用二进制表示即可。)
3>.十进制
十进制逢10斤=,有数字0-9组成,也是咱们生活中默认使用的进制。 十进制转换成二进制,八进制,十六进制的方法我这里就不啰嗦了,过于简单我这里就不啰嗦了,我这里重点说一下十进制的小数转换成二进制的方式。
十进制小数转换成二进制:
小数部分和2相乘,取整数,不足1取0,每次相乘都是小数部分,顺序看取整后的数就是转化后的结果。为了方便说明,我们看一下十进制的0.521如何用二进制表示:
0.521
* 2
---------
1.042 ---->第一次计算结果,取整数部分1,然后把小数部分0.042继续和2相乘
0.042 ---->这里的0.042就是上面计算的1.042的小数部分
* 2
----------
0.084 ----->第二次计算结果,取整数部分0,然后把小数部分0.084机型和2相乘 0.084 ----->这里的0.084是上面计算的0.084的小数部分
* 2
----------
0.168 ------>第三次计算结果,取整数部分0,并终止计算,因为十进制0.521只有3位小数,顾我们只需要取3位二进制位即可,最终结果为0.100
如上所述,我们来总结一下十进制转换成二进制的几个要点:
(1)乘的时候只乘小数部分;
(2)0.521只有3位,因此我们只需要算出3位二进制位置即可;
(3)0.521的二进制数为:0.100
4>.十六进制
十六进制逢16进1,由数字0-9和字母A-F组成。
十进制转化为十六进制
除十六反序取余法(将十进制数每次除以16,取出余数,按照结果倒叙排序,需要注意的是大于10的数字应该由A-F来表示)
十六进制转化为十进制
权值法(将二进制各个位数从0位开始乘以16的N次幂,将各个位数的结果相加)。 十六进制转换为二进制
八四二一法则(将十六进制的每一个位数上的数字拆开,分别用二进制表示即可。) 二进制转换为十六进制
将二进制数字从右到左,每4个二进制数划分为一组,将每组数据的二进制转换成八进制对应的数字即可。 十六进制转换为八进制
思路就是先将十六进制转换成二进制,再将二进制转换成八进制。
八进制转换成十六进制
思路就是先将八进制换转成二进制,再将二进制转换成十六进制。
5>.进制转换表
6>.在C程序中进制打印案例
[[email protected] /yinzhengjie/code/day002]# cat binary_conversion.c
/*
@author :yinzhengjie
blog:http://www.cnblogs.com/yinzhengjie
EMAIL:[email protected]
*/ #include <stdio.h> int main(void)
{
//十进制数字10
int a = ;
printf("%d\n",a); //定义八进制
int b = ;
printf("%d\n",b); //定义十六进制
int c = 0x10;
printf("%d\n",c); return ;
}
[[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]# gcc -o binary_conversion binary_conversion.c
[[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]# ./binary_conversion [[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]# cat binary_conversion.c
/*
@author :yinzhengjie
blog:http://www.cnblogs.com/yinzhengjie
EMAIL:[email protected]
*/ #include <stdio.h> int main(void)
{
//十进制数字10
int a = ;
printf("%o\n",a); //定义八进制
int b = ;
printf("%o\n",b); //定义十六进制
int c = 0x10;
printf("%o\n",c); return ;
}
[[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]# gcc -o binary_conversion binary_conversion.c
[[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]# ./binary_conversion [[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]# cat binary_conversion.c #以八进制方式显示
[[email protected] /yinzhengjie/code/day002]# cat binary_conversion.c
/*
@author :yinzhengjie
blog:http://www.cnblogs.com/yinzhengjie
EMAIL:[email protected]
*/ #include <stdio.h> int main(void)
{
//十进制数字10
int a = ;
printf("%x\n",a); //定义八进制
int b = ;
printf("%x\n",b); //定义十六进制
int c = 0x10;
printf("%x\n",c); return ;
}
[[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]# gcc -o binary_conversion binary_conversion.c
[[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]# ./binary_conversion
a [[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]# cat binary_conversion.c #以十六进制方式显示
[[email protected] /yinzhengjie/code/day002]# cat binary_conversion.c
/*
@author :yinzhengjie
blog:http://www.cnblogs.com/yinzhengjie
EMAIL:[email protected]
*/ #include <stdio.h> int main(void)
{
//十进制数字10
int a = ;
printf("%X\n",a); //定义八进制
int b = ;
printf("%X\n",b); //定义十六进制
int c = 0x10;
printf("%X\n",c); return ;
}
[[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]# gcc -o binary_conversion binary_conversion.c
[[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]# ./binary_conversion
A [[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]# cat binary_conversion.c #以十六进制方式显示
三.sizeof关键字
sizeof不是函数,所以不需要包含任何头文件,它的功能是计算一个数据类型的大小,单位为字节;
sizeof的返回值为size_t; sizeof_t类型在32位操作系统下是unsigned int,是无符号的整数。
注意:下面结果是根据64位操作系统获取的数据类型大小,此时案例可参考下面的“使用sizeof查看各个数据类型占用内存大小案例”
char(字符型,1Byte) < short(短整型,2Byte) < int(整型,4Byte)|float(单精度浮点型,4Byte)|long(长整型,4Byte) < long long(长长整型,8Byte)|double(双精度浮点型,8Byte)
[[email protected] /yinzhengjie/code/day002]# cat sizeof_demo.c
/*
@author :yinzhengjie
blog:http://www.cnblogs.com/yinzhengjie
EMAIL:[email protected]
*/ #include <stdio.h> int main()
{
int a;
int b=sizeof(a); //sizeof得到指定值占用内存大小,单位为字节.
printf("b=%d\n",b); size_t c = sizeof(a); //用无符号的方式输出c的值
printf("c=%u\n",c); return ;
}
[[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]# gcc -o sizeof_demo sizeof_demo.c
[[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]# ./sizeof_demo
b=
c=
[[email protected] /yinzhengjie/code/day002]#
sizeof使用案例
[[email protected] /yinzhengjie/code/day002]# cat sizeof_demo2.c
/*
@author :yinzhengjie
blog:http://www.cnblogs.com/yinzhengjie
EMAIL:[email protected]
*/ #include <stdio.h> int main()
{
int a = ;
//sizeof()求出数据类型在内存占用字节(Byte)大小
int len1 = sizeof(a);
printf("%d\n",a);
printf("int = %d\n",len1); //单精度浮点型
float b = 3.14;
int len2 = sizeof(b);
printf("%d\n",b);
printf("float = %d\n",len2); //字符型
char c = 'A';
int len3 = sizeof(c);
printf("%d\n",c);
printf("char = %d\n",len3); //双精度浮点型
double d = 9.18;
int len4 = sizeof(d);
printf("%d\n",d);
printf("double = %d\n",len4); //短整型
short e = ;
int len5 = sizeof(e);
printf("%d\n",e);
printf("short = %d\n",len5); //长整型
long f = ;
int len6 = sizeof(f);
printf("%d\n",f);
printf("long = %d\n",len6); //长长整型
long long g = ;
int len7 = sizeof(g);
printf("%d\n",g);
printf("long long = %d\n",len7); }
[[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]# gcc -o sizeof_demo2 sizeof_demo2.c
[[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]# ./sizeof_demo2 int = float = char = double = short = long = long long =
[[email protected] /yinzhengjie/code/day002]#
使用sizeof查看各个数据类型占用内存大小案例
四.计算机内存数值存储方式
1>.原码
一个数的原码(原始的二进制码)有如下特点:
最高位作为符号位,0表示正,1表示负;
其它数值部分都是数值本身绝对值的二进制数;
负数的原码是在其绝对值的基础上,最高位变为1; 举个例子,我们用一个字节的原码来表示+,-,+,-
+ :
- :
+ :
- : 原码表示方法简单易懂,带有符号数本身转换方便,只要符号位还原即可,但当两个整数相减或不同符号相加时,必须比较两个数哪个绝对值大,才能决定谁减谁,才能确定结果是正还是负,所以原码不便于加减运算。
2>.反码
一个数的反码(原始的二进制码)有如下特点:
对于正数,反码与原码相同;
对于负数,符号位不变,其它部位去反; 举个例子,我们用一个字节的反码来表示+,-,+,-
+ :
- :
+ :
- : 1111 反码运算也不方便,通常用来作为求补码的中间过渡
3>.补码
在计算机中,数值一律用补码来存储。补码特点如下:
对于正数,原码,反码,补码相同;
对于负数,其补码为它的反码加1;
补码符号位不动,其他为求反,最后整个数加1,得到原码;
举个例子,我们用一个字节的补码来表示+,-,+,-0
+15 : 0000 1111
-15 : 1111 0001
+0 : 0000 0000
-0 : 0000 0000 如果对补码还迷糊的小伙伴,可参考博主推荐阅读:https://www.cnblogs.com/yinzhengjie/p/8666354.html。
[[email protected] /yinzhengjie/code/day002]# cat complement.c
/*
@author :yinzhengjie
blog:http://www.cnblogs.com/yinzhengjie
EMAIL:[email protected]
*/ #include <stdio.h> int main()
{
int a = -;
printf("%x\n",a); return ;
}
[[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]# gcc -o complement complement.c
[[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]# ./complement
fffffff1
[[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]# /*
如上所述,输出结果为“fffffff1”,改值用途二进制表示为:1111 1111 1111 1111 1111 1111 1111 0001 符号位不变,其他去反,我们查看该二进制的反码为:1000 0000 0000 0000 0000 0000 0000 1110 我们在反码的基础上加1,得到最终的补码为:1000 0000 0000 0000 0000 0000 0000 1111,即最高位是符号位,1代表负数,即改值二进制的补码表示的为-15.
*/
补码案例分析,使用C程序表示-15
4>.补码的意义
在计算机系统中,数值一律使用补码来存储,主要原因如下:
统一了0的编码;
将符号位和其他位统一处理;
将减法运算转变为加法运算;
两个用补码表示的数相加时,如果最高位(符号位)有进位,则进位被舍弃。
五.整型(int)
1>.整型变量的定义和输出
%d
输出一个有符号的10进制int类型 %o(字母o)
输出8进制的int类型 %x
输出16进制的int类型,字母以小写输出 %X
输出16进制的int类型,字母以大写输出 %u
输出一个10进制的无符号数
[[email protected] /yinzhengjie/code/day002]# cat int_dome1.c
/*
@author :yinzhengjie
blog:http://www.cnblogs.com/yinzhengjie
EMAIL:[email protected]
*/ #include <stdio.h> int main()
{
int a = ; //定义变量a,以10进制方式赋值为123.
int b = ; //定义变量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("16进制:c=%d\n",c); unsigned int d = 0xffffffff; //定义无符号int变量d,以16进制方式赋值
printf("有符号方式打印:d = %d\n",d);
printf("无符号方式打印:d = %u\n",d);
return ;
}
[[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]# gcc -o int_dome1 int_dome1.c
[[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]# ./int_dome1
a =
8进制:b=
10进制:b=
16进制:c=abc
16进制:c=ABC
16进制:c=
有符号方式打印:d = -
无符号方式打印:d =
[[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]# cat int_dome1.c #使劲戳我可参考实际案例
2>.整型变量的输入
[[email protected] /yinzhengjie/code/day002]# cat int_dome2.c
/*
@author :yinzhengjie
blog:http://www.cnblogs.com/yinzhengjie
EMAIL:[email protected]
*/ #include <stdio.h> int main()
{
int num;
printf("请输入a的值:>>> "); //不要加换行符"\n"
scanf("%d",&num); //打印输入的int类型的值
printf("num = %d\n",num); return ;
}
[[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]# gcc -o int_dome2 int_dome2.c
[[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]# ./int_dome2
请输入a的值:>>>
num =
[[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]#
3>.short,int,long,long long
short(短整型)
2字节 int(整型)
4字节 long(长整型)
windows为4字节,Linux为4自己(32位),8字节(64位) long long(长长整型)
8字节 温馨提示:
整型数据在内存中占用的字节数与所选择的操作系统有关。虽然C语言标准中没有明确规定整型数据的长度,但long类型整型的长度不能短于int类型,short类型整数的长度长于int类型。
当一个小的数据类型赋值给一个大的数据类型,不会出错,因为编译器会自动转化。但是当一个大的类型赋值给一个小的数据类型,那么就可能丢失高位。 以下是整型常量及其所需类型
10
代表int类型
10l,10L
代表long类型
10ll,10LL
代表long long类型
10u,10U
代表unsigned int类型
10ul,10UL
代表unsigned long类型
10ull,10ULL
代表unsigned long long类型 接下来我们查看一下打印格式及其含义
%d
输出int类型
%l
输出long类型
%ll
输出long long类型
%hu
输出unsigned short类型
%u
输出unsigned int类型
%lu
输出unsigned long类型
%llu
输出unsigned long long类型
[[email protected] /yinzhengjie/code/day002]# cat int_dome3.c
/*
@author :yinzhengjie
blog:http://www.cnblogs.com/yinzhengjie
EMAIL:[email protected]
*/ #include <stdio.h> int main()
{
short a = ;
int b = ;
long c = 10L;
long long d = 10LL; printf("sizeof(a) = %u\n",sizeof(a));
printf("sizeof(b) = %u\n",sizeof(b));
printf("sizeof(c) = %u\n",sizeof(c));
printf("sizeof(d) = %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 ;
}
[[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]# gcc -o int_dome3 int_dome3.c
[[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]# ./int_dome3
sizeof(a) =
sizeof(b) =
sizeof(c) =
sizeof(d) =
short a =
int b =
long c =
long long d =
unsigned short a =
unsigned int b =
unsigned long c =
unsigned long long d =
[[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]# cat int_dome3.c #使用案例
4>.有符号和无符号的区别
一个有符号的整型数据可以分为两部分:一部分是符号位,一部分是数字位。 无符号数据类型只包含数字位部分。 当我们写程序要处理一个不可能出现负数的时候,一般用无符号数,这样可以增大数的表达最大值。 有符号和无符号整型取值范围如下:
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的15次方减1)
unsigned int
占用4字节,取值范围在0到4294967295(0到2的32次方减1)
unsigned long
占用4字节,取值范围在0到4294967295(0到2的32次方减1)
六.字符型(char)
1>.字符变量的定义和输出
字符型变量用于存储一个单一字符,在C语言中用char表示,其中每个字符变量都会占用1个字节。在给字符型变量赋值时,需要用一对英文半角格式的单引号(' ')把字符括起来。 字符变量实际上并不是把该字符本身放到变量的内存单元中去,而是将该字符对应的ASCII编码放到变量中的存储单元中。char的本质就是一个1字节大小的整型。
[[email protected] /yinzhengjie/code/day002]# cat char_demo.c
/*
@author :yinzhengjie
blog:http://www.cnblogs.com/yinzhengjie
EMAIL:[email protected]
*/ #include <stdio.h> int main(void)
{
char ch = 'a'; printf("sizeof(ch) = %u\n",sizeof(ch)); printf("ch(%%c) = %c\n",ch); //输出字符串 putchar(ch); //该方法只能输出字符,该行及下面一行均是输出字符 putchar('\n'); printf("ch(%%d) = %d\n",ch); //打印'a'对应的ASSCII的值 return ;
}
[[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]# gcc -o char_demo char_demo.c
[[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]# ./char_demo
sizeof(ch) =
ch(%c) = a
a
ch(%d) =
[[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]# cat char_demo.c
2>.字符变量的输入
[[email protected] /yinzhengjie/code/day002]# cat char_demo2.c
/*
@author :yinzhengjie
blog:http://www.cnblogs.com/yinzhengjie
EMAIL:[email protected]
*/ #include <stdio.h> int main(void)
{
char input; //scanf("%c",&input); //接收用户输入的一个字符 input = getchar(); //除了使用上面的scanf方法获取用户输入,我们还可以用getchar来获取用户输入的字符 putchar(input); //将用户输入的字符打印出来 putchar('\n'); //上面打印出来并没有换行,我们可以人为的给它加一个换行符 return ;
}
[[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]# gcc -o char_demo2 char_demo2.c
[[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]# ./char_demo2
Y
Y
[[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]# cat char_demo2.c
3>.ASCII对照表
ASCII码大致有以下两部组成:
ASCII非打印控制字符:
ASCII表上的数字0-31分配了控制字符,用于控制像打印机等一些外围设备。 ASCII打印字符
数字32-126分配了能在键盘上找到的字符,当查看或打印文档时就会出现。数字127代表Del命令。
ASCII值 | 控制字符 | ASCII值 | 控制字符 | ASCII值 | 控制字符 | ASCII值 | 控制字符 |
---|---|---|---|---|---|---|---|
0 | NUT | 32 | (space) | 64 | @ | 96 | 、 |
1 | SOH | 33 | ! | 65 | A | 97 | a |
2 | STX | 34 | " | 66 | B | 98 | b |
3 | ETX | 35 | # | 67 | C | 99 | c |
4 | EOT | 36 | $ | 68 | D | 100 | d |
5 | ENQ | 37 | % | 69 | E | 101 | e |
6 | ACK | 38 | & | 70 | F | 102 | f |
7 | BEL | 39 | , | 71 | G | 103 | g |
8 | BS | 40 | ( | 72 | H | 104 | h |
9 | HT | 41 | ) | 73 | I | 105 | i |
10 | LF | 42 | * | 74 | J | 106 | j |
11 | VT | 43 | + | 75 | K | 107 | k |
12 | FF | 44 | , | 76 | L | 108 | l |
13 | CR | 45 | - | 77 | M | 109 | m |
14 | SO | 46 | . | 78 | N | 110 | n |
15 | SI | 47 | / | 79 | O | 111 | o |
16 | DLE | 48 | 0 | 80 | P | 112 | p |
17 | DCI | 49 | 1 | 81 | Q | 113 | q |
18 | DC2 | 50 | 2 | 82 | R | 114 | r |
19 | DC3 | 51 | 3 | 83 | S | 115 | s |
20 | DC4 | 52 | 4 | 84 | T | 116 | t |
21 | NAK | 53 | 5 | 85 | U | 117 | u |
22 | SYN | 54 | 6 | 86 | V | 118 | v |
23 | TB | 55 | 7 | 87 | W | 119 | w |
24 | CAN | 56 | 8 | 88 | X | 120 | x |
25 | EM | 57 | 9 | 89 | Y | 121 | y |
26 | SUB | 58 | : | 90 | Z | 122 | z |
27 | ESC | 59 | ; | 91 | [ | 123 | { |
28 | FS | 60 | < | 92 | / | 124 | | |
29 | GS | 61 | = | 93 | ] | 125 | } |
30 | RS | 62 | > | 94 | ^ | 126 | ` |
31 | US | 63 | ? | 95 | _ | 127 | DEL |
NUL空 | VT 垂直制表 | SYN 空转同步 |
---|---|---|
STX 正文开始 | CR 回车 | CAN 作废 |
ETX 正文结束 | SO 移位输出 | EM 纸尽 |
EOY 传输结束 | SI 移位输入 | SUB 换置 |
ENQ 询问字符 | DLE 空格 | ESC 换码 |
ACK 承认 | DC1 设备控制1 | FS 文字分隔符 |
BEL 报警 | DC2 设备控制2 | GS 组分隔符 |
BS 退一格 | DC3 设备控制3 | RS 记录分隔符 |
HT 横向列表 | DC4 设备控制4 | US 单元分隔符 |
LF 换行 | NAK 否定 | DEL 删除 |
4>.转义字符
所有的转义字符和所对应的意义:
转义字符 | 意义 | ASCII码值(十进制) |
\a | 响铃(BEL) | 007 |
\b | 退格(BS) ,将当前位置移到前一列 | 008 |
\f | 换页(FF),将当前位置移到下页开头 | 012 |
\n | 换行(LF) ,将当前位置移到下一行开头 | 010 |
\r | 回车(CR) ,将当前位置移到本行开头 | 013 |
\t | 水平制表(HT) (跳到下一个TAB位置) | 009 |
\v | 垂直制表(VT) | 011 |
\\ | 代表一个反斜线字符''\' | 092 |
\' | 代表一个单引号(撇号)字符 | 039 |
\" | 代表一个双引号字符 | 034 |
\? | 代表一个问号 | 063 |
\0 | 空字符(NUL) | 000 |
\ddd | 1到3位八进制数所代表的任意字符 | 三位八进制 |
\xhh | 1到2位十六进制所代表的任意字符 | 十六进制 |
5>.数值溢出
当超过了一个数据类型能够存放最大的范围时,数值会溢出。 有符号最高位溢出的区别:符号位溢出会导致数的正负发生改变,但最高位的溢出会导致最高位丢失。 char 占用1字节 取值范围在-128到127(负的2的7次方到2的7次方减1) unsigned char 占用1字节 取值范围0到255(0到2的8次方-)
[[email protected] /yinzhengjie/code/day002]# cat char_demo3.c
/*
@author :yinzhengjie
blog:http://www.cnblogs.com/yinzhengjie
EMAIL:[email protected]
*/ #include <stdio.h> int main(void)
{
char input; //符号位溢出会导致数的正负发生改变,0x7f(十六进制表示法)对应的二进制为:0111 1111,给其加2后为:1000 0001,这是负数的原码,其补码为:1111 1111,十进制为-127.
input = 0x7f + ; //127 + 2
printf("%d\n",input); //最高位的溢出会导致高位丢失,0xff(十六进制表示法)对应的二进制为:1111 1111,给其加1后变为:1 0000 0000,char只有8位最高位的溢出(有网友也喜欢说是高位截短),纠其原因是一个字节存取8个比特位,因此结果为:0000 0000,十进制为0.
unsigned char input2;
input2 = 0xff +; //255+1
printf("%u\n",input2); //和上面案例原理相同,0xff(十六进制表示法)对应的二进制为:1111 1111,给其加2后变为:1 0000 0001,高位截断后结果为:0000 0001,十进制为1.
input2 = 0xff + ;
printf("%u\n",input2); return ;
}
[[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]# gcc -o char_demo3 char_demo3.c
char_demo3.c: In function ‘main’:
char_demo3.c::: warning: large integer implicitly truncated to unsigned type [-Woverflow] #我们在编译成可执行文件时,发现有warning的提示信息,说是无符号类型数据溢出(-Woverflow)啦,此消息咱们忽略即可,因为这个溢出是咱们人为造成溢出的~
input2 = 0xff +; //255+1
^
char_demo3.c::: warning: large integer implicitly truncated to unsigned type [-Woverflow]
input2 = 0xff + ;
^
[[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]# ./char_demo3
- [[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]#
七.实型(浮点型)
实型变量也可以成为浮点型变量,浮点型变量是用来存储小数数值的。在C语言中,浮点型变量分为两种:单精度浮点数(float),双精度浮点数(double),但是double型变量所表示的浮点数比float型变量更精确。 float:占用4字节,7位有效数字。 double:占用8字节,15~16位有效数字。 由于浮点型变量是由有限的存储单元组成的,因此只能提供有限的有效数字。在有效位以外的数字将被舍去,这样可能会产生一些误差。
[[email protected] /yinzhengjie/code/day002]# cat float_demo.c
/*
@author :yinzhengjie
blog:http://www.cnblogs.com/yinzhengjie
EMAIL:[email protected]
*/ #include <stdio.h> int main(void)
{
float a = 3.14f; //或者3.14F,这是传统赋值 double b = 3.14; printf("a = %f\n",a);
printf("b = %f\n",b); a = 3.2e3f; //或者3.2E3f,科学法赋值,表示3.2 * 1000 = 3200
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,因为我们知道a是float类型,占用4字节,仅仅有7位有效数字,最后一位会进行四舍五入法得结果 float r = ; float s = r * r * 3.14; printf("%.2f\n",s); //注意,“%.2f"表示保留小数点后2位. return ;
}
[[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]# gcc -o float_demo float_demo.c
[[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]# ./float_demo
a = 3.140000
b = 3.140000
a1 = 3200.000000
a2 = 0.100000
a3 = 3.141593
12.56
[[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]#
八.字符串格式化输入和输出
1>.字符串常量
字符串是内存中一段连续的char空间,以'\0'(数字0)结尾。
字符串常量是由双引号括起来的字符序列,如"chaina","C parogram","$PATH"等都是合法的字符串常量。 字符串常量与字符常量的不同:
每个字符串的结尾,编译器会自动的添加一个结束标志位“\”,即"a"包含两个字符'a'和'\0'
2>.printf函数和putchar函数
printf是输出一个字符串,putchar输出一个char。 printf格式字符:
打印格式 对应数据类型 含义
%d int 接收整数值并将它表示为有符号的十进制整数
%hd short int 端整数
%hu unsigned short 无符号短整数
%o unsigned int 无符号8进制整数
%u unsigned int 无符号10进制整数
%x,%X unsigned int 无符号16进制整数,x对应的是abcdef,X对应的是ABCDEF
%f float 单精度浮点数
%lf double 双精度浮点型
%e,%E double 科学计数法表示的数,此处"e"的大小写代表输出时用"e"的大小写
%c char 字符型,可以把输入的数字按照ASCII对应转换为对应的字符
%s char * 字符串,输出字符串中的字符直至字符串的空字符(字符串以'\0'结尾,这个'\0'即空字符)
%p void 以16进制形式输出指针
%% % 输出一个百分号,即"%" printf附加格式:
字符 含义
l(这个是小写字母l) 附加在d,u,x,o前面,表示长整数
- 左对齐
m(代表一个整数) 数据最小宽度
(这个是数字0) 将输出的前面补上0知道满指定列环位置不可用搭配使用-
m.n(代表一个整数) m值域宽,即对应的输出项在输出设备上所占的字符数,n指进度,用户说明输出的实型数的小数位数。对数值型的来说,未指定n时,隐含的精度为n=6位。
[[email protected] /yinzhengjie/code/day002]# cat echo.c
/*
@author :yinzhengjie
blog:http://www.cnblogs.com/yinzhengjie
EMAIL:[email protected]
*/ #include <stdio.h> int main()
{
int a = ;
printf("a = %d\n",a); //格式化输出一个字符串
printf("%p\n",&a); //输出变量a在内存中的地址编码
printf("%%d\n"); char c = 'a';
putchar(c); //putchar只有一个参数,就是要输出的char long long a3 = ;
printf("%lld,%llx,%llo\n",a3,a3,a3); int abc = ;
printf("abc = '%6d'\n",abc);
printf("abc = '%-6d'\n",abc);
printf("abc = '%0d'\n",abc);
printf("abc = '%-06d'\n",abc); double d = 12.3;
printf("d = \'%-10.3lf'\n",d);
return ;
}
[[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]# gcc -o echo echo.c
[[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]# ./echo
a =
0x7fff18387bec
%d
a1000,3e8,
abc = ''
abc = '10 '
abc = ''
abc = '10 '
d = '12.300 '
[[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]# cat echo.c #printf和putchar使用案例
3>.scanf函数与getchar函数
getchar是从标准输入设备读取一个char
scanf通过%转义的方式可以得到用户通过标准输入设备输入的数据
[[email protected] /yinzhengjie/code/day002]# cat echo2.c
/*
@author :yinzhengjie
blog:http://www.cnblogs.com/yinzhengjie
EMAIL:[email protected]
*/ #include <stdio.h> int main()
{
char ch1;
char ch2;
char ch3;
int a;
int b; printf("请输入ch1的字符:>>> ");
ch1 = getchar();
printf("ch1 = %c\n",ch1); getchar(); //测试此处getchar()的作用 printf("请输入ch2的字符:>>> ");
ch2 = getchar();
printf("\'ch2 = %ctest\'\n",ch2); getchar(); //测试此处getchar()的作用
printf("请输入ch3的字符:>>> ");
scanf("%c",&ch3); //这里第二个参数一定是变量的地址,而不是变量名
printf("ch3 = %c\n",ch3); printf("请输入a的值:>>> ");
scanf("%d",&a);
printf("a = %d\n",a); printf("请输入b的值:>>> ");
scanf("%d",&b);
printf("b = %d\n",b); return ;
}
[[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]# gcc -o echo2 echo2.c
[[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]# ./echo2
请输入ch1的字符:>>> a
ch1 = a
请输入ch2的字符:>>> b
'ch2 = btest'
请输入ch3的字符:>>> c
ch3 = c
请输入a的值:>>>
a =
请输入b的值:>>>
b =
[[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]#
[[email protected] /yinzhengjie/code/day002]# cat echo2.c #printf和getchar使用案例