C语言数据类型
说明:涉及到数据在计算机中的存储、计算、转换问题,所以不仅仅只是C语言知识,还涉及到了计算机的相关知识
一、整型(int:integer)
概念:表达整形类型的数据(正整数、负整数、0)全称:integer语法:
int num = 100; // 定义了一个专门存放整形数据的变量(variable)
(数据类型int) 变量 赋值号 常量(constant)(整型)
需要注意的地方:
int的本意是integer,即整数的意思int num代表在内存中开辟一块小区域,称为num,用来存放整数,num一般被称为变量变量num所占内存大小,在不同的系统中是不一样的,64位系统典型的大小是4个字节变量num有固定的大小,因此也有取值范围,典型的范围是:-2147483648到2147483648-1
(1)、变量的定义和初始化(从程序角度上去看待)
(3)、整型修饰符
char: 单字节的整型变量(典型尺寸:1字节(8位))
short int: 用来缩短整型的尺寸,减少取值范围并节省内存,称为短整型(典型尺寸:2字节(16位))
long int: 用来增长整型的尺寸,增大取值范围并占用更大的内存,称为长整型(典型尺寸:32位系统:4字节(32位)、 64位系统:8字节(64位))
long long int:用来用来增长整型的尺寸,增大取值范围并占用更大的内存,称为长长整形(典型尺寸:8字节(64位))
unsigned: 用来去除整型变量的符号位,使得整型变量只能表达非负整数
(4)、符号位
有符号(signed)的整型数据,首位为符号位,0表示正数,1表示负数无符号(unsigned)的整型数据,没有符号位
假设数值为10和-10,那么
有符号(signed)表示:
-10 == 1000 0000 0000 0000 0000 0000 0000 1010
+10 == 0000 0000 0000 0000 0000 0000 0000 1010
说明:左边的第一个位表示符号位,后面的31个位用来表示数据位
无符号(unsigned)表示:
10 == 0000 0000 0000 0000 0000 0000 0000 1010
说明:所有的位(32个位)都用来表示数据位
注意:程序中如果只写int型数据类型,则默认为有符号位signed int(前面的signed被省略不写了)
(5)、格式控制符
1、有符号格式控制符
%d int整型
%hd short整型,h代表half,表示一半的意思
%ld long整型
%lld long long整型
2、无符号格式控制符
%u 无符号int整型
%hu 无符号short整型,h代表half,表示一半的意思
%lu 无符号long整型
%llu 无符号long long整型
二、浮点型(float point、double float point)
概念:用来表达小数的数据类型全称:float point、double float point语法
单精度浮点型(float), 典型尺寸是4字节双精度浮点型(double), 典型尺寸是8字节长双精度浮点型(long double),典型尺寸是16字节
示例代码
float f1; // 单精度
double f2; // 双精度
long double f3; // 长双精度
说明:占用的内存越多,能表达的精度越高
(2)、格式控制符
%f // 单精度浮点型
%lf // 双精度浮点型
%Lf // 长双精度浮点型
%x.yf // 右对齐并占用宽度为x(-x左对齐并占用宽度为x),保留y位小数
示例代码:
#include
int main(int argc, char const *argv[])
{
// 1、单精度浮点型
printf("1、单精度浮点型\n");
float f1 = 3.14;
printf("f1 value == %f\n", f1);
printf("f1 value == %10.1f\n", f1); // 正数10表示右对齐(一共占用10个位置,数据靠右),反之亦然
// .1表示打印的小数位数只有1位
printf("f1 size == %lu\n", sizeof(f1));
// 2、双精度浮点型
printf("2、双精度浮点型\n");
double f2 = 6.28;
printf("f2 value == %lf\n", f2);
printf("f2 value == %10lf\n", f2);
printf("f2 size == %lu\n", sizeof(f2));
// 3、长双精度浮点型
printf("3、长双精度浮点型\n");
long double f3 = 12.42;
printf("f3 value == %Lf\n", f3);
printf("f3 value == %.2Lf\n", f3);
printf("f3 size == %lu\n", sizeof(f3));
}
三、字符型(char, character) --- 一个字节的整型
- 概念:用来描述字符的数据类型
- 全称:character
- 语法:
char ch1 = 'a'; // 'a'是字符常量(可见的),代表字符a,字符以单引号括住
char ch2 = '\n'; // '\n'不可见的字符串常量,代表回车
(1)、字符在内存中的表现形式
(2)、ASCII表
说明:字符以ascii码表设置的数值,存储到计算机中,可以在man手册、在线手册获取
(3)、格式控制符(不仅包含字符格式、还包含其它格式)
%c // 单个字符显示
%o // 八进制
%x // 十六进制
%#o // 输出带有0前缀的八进制数: 012
%#x // 输出带有0x前缀的十六进制数(小写): 0xab
%#X // 输出带有0x前缀的十六进制数(大写): 0xAB
示例代码:
#include
int main(int argc, char const *argv[])
{
// 1、打印字符(字符 == 单字节的整型)
char ch1 = 'a'; // 单引号表示字符
char ch2 = 105; // 可以直接给字符类型赋值整型数(因为字符类型本质上就是一个整型数)(单字节)
int ch3 = 10086;
printf("ch1 == %d\n", ch1); // 将这个字符变量ch1,以十进制的方式打印输出(数值:97)
printf("ch2 == %c\n", ch2); // 以字符的形式,打印这个ch2的变量的值(字符'i')
printf("ch3 == %c\n", ch3); // 以字符的形式,打印这个ch3的变量的值(字符'f')
/*
=》十进制:10086
=》二进制:0000 0000 0000 0000 0010 0111 0110 0110
=》格式要求打印%c,%c是一个字节(低8位)的:0110 0110
=》根据ascii码表转换成为字符:f
*/
/*
拓展一下:中文字符
如果你在程序中直接使用中文,会报错误
报错误现象:
003__字符型数据(character).c:19:4: error: stray ‘\344’ in program
世界那么大
^
003__字符型数据(character).c:19:4: error: stray ‘\270’ in program
003__字符型数据(character).c:19:4: error: stray ‘\226’ in program
003__字符型数据(character).c:19:4: error: stray ‘\347’ in program
003__字符型数据(character).c:19:4: error: stray ‘\225’ in program
说明一下:
你会发现\344,是一个字符的表达,但是在ASCII码表是没有这种字符的,所以会报错误
*/
// 2、字符打印其它格式
char ch4 = 127;
printf("ch4(字符) == %c\n", ch4);
printf("ch4(十进制) == %d\n", ch4);
printf("ch4(八进制) == %o\n", ch4);
printf("ch4(前缀八进制) == %#o\n", ch4);
printf("ch4(十六进制,小写) == %x\n", ch4);
printf("ch4(十六进制,大写) == %X\n", ch4);
printf("ch4(前缀十六进制,小写) == %#x\n", ch4);
printf("ch4(前缀十六进制,大写) == %#X\n", ch4);
return 0;
}
四、字符串型(character string)
- 概念:表达字符串类型的数据
- 全称:character string
(1)、在内存中的存储
1、 在内存中实际上是多个字符的组合
2、任何字符串都以一个'\0'作为结束标志,例如:"nihao"这个字符串的最后一个字符是'\0'
(2)、格式控制符
%s // 字符串类型
%-10s // 左对齐并占用宽度为10的字符串
%10s // 右对齐并占用宽度为10的字符串
图解:
示例代码
int main(int argc, char const *argv[])
{
// 1、定义字符串
char ch1 = 'a'; // 字符,单引号括住的表示字符
char buf1[16] = "a"; // 字符串1,双引号括住的表示字符串(这个buf1变量其实里面有两个字符.'a'和'\0')
char buf2[16] = "nihao"; // 字符串2,里面存放了"nihao"字符串(末尾还包括有'\0'的字符)
// buf1和buf2是数组,里面有16个char型内存大小的空间,一般用来存放字符串
char *p1 = "shijie"; // 字符串3,一个叫p1的指针变量指向了一个"shijie"这个字符串的首字符的地址(p1指针变量存放了一个"shijie"这个字符串的首字符的地址)
// 2、字符串的显示位置控制
printf("buf2 == %s\n", buf2); // 直接显示buf2里面的字符串(为什么能够刚好把字符串全部显示出来?因为字符串的最后的字符是一个结束标志符。printf函数遇到它就会停止打印了)
printf("p1 == %-10s\n", p1); // 左对齐并占用宽度为10的字符串
printf("p1 == %10s\n", p1); // 右对齐并占用宽度为10的字符串
}
五、布尔类型(bool)
概念:布尔类型数据只有真、假两种取值(非零为真(1、456、-2等)、零为假)注意:
逻辑真除了1之外,还有其它任何非零数值都表示逻辑真,等价于1使用布尔类型定义变量时,需要包含系统头文件 #include布尔类型数据常用于逻辑判断,循环控制等
示例代码:
#include
#include
// 官方定义的真和假
// #define true 1
// #define false 0
// 自己定义的真和假
#define TRUE 1
#define FALSE 0
int main(int argc, char const *argv[])
{
// 一般定义
bool flag = 100; // 非0为真,0为假
// 判断方法1
if (flag == TRUE) // 不推荐这种判断方法
{
printf("1111111111111\n");
}
else
{
printf("22222222222222\n");
}
// 判断方法2:笔试题(请写出bool flag 与零值比较的if语句)
if(flag) // 判断flag是真还是假(flag非0为真, 0为假)
{
printf("3333333333333\n");
}
if (!flag) // !为逻辑非(flag为真,遇到这个语句就会变为键, 反之亦然)
{
printf("444444444444\n");
}
return 0;
}
六、常量和变量
概念:不可改变的内存称为常量,可以改变的内存称为变量变量的类型:int型、浮点型、char型、字符串型、布尔型(还有它们的 无符号、短、长拓展型等)常量的类型:100、3.14、'a'、"nihao"等
示例代码
#include
#define YEAR 100 // 数值小(使用普通的整型常量的值范围即可)
#define LIVE_TIME (100*365*24*60*60ULL) // 数值大(使用更大的整型常量的值范围)
/*
如果这个常量的后面没有ULL的话,会出现的问题:
#define LIVE_TIME (100*365*24*60*60)
warning: integer overflow in expression [-Woverflow]
翻译:在表达式中,整型溢出了
*/
// 主函数
int main(int argc, char const *argv[])
{
// (1)、常量的类型
// 1、整型常量:100(整型int)、200L(长整型long int)、300LL(长长整型long long int)、400U(无符号的整型)、500UL(无符号长整型)、600ULL(无符号长长整型)
// 2、浮点型常量:3.14(双精度浮点型)、6.28L(长双精度浮点型)
// 3、字符常量:'a'、'1'
// 4、字符串常量:"nihao"
// 5、科学计数法常量:1.000e+03 == 1000
// (2)、变量的类型(左边为变量、右边为常量)
int num = 100;
double f = 3.14;
char ch = 'a';
char buf[128] = "nihao";
// 笔试题:用预处理语句#define顶一个常量,用以计算寿命(秒级)
printf("还能活LIVE_TIME == %llu秒\n", LIVE_TIME) ; // 常量的数据过大,超出格式控制符控制范围,会出现程序显示错误
return 0;
}
七、标准输入 -- 键盘设备(stdin)
概念:键盘是系统的标准输入设备,从键盘中输入数据被称为标准输入(stdin)相关函数:
scanf(); // 格式化输入函数(根据格式控制符输入相应的函数)(跟prinf函数相似并配套)
getchar(); // 从stdin读取出一个字符
注意1:
scanf()与printf()不同,scanf()的格式控制字符串不可乱写,尤其是结尾处的\n用户必须完全按照scanf()中描述的输入格式控制字符串来输入数据,否则将出错
注意2:
scanf()的返回值,代表成功从键盘读取的数据的个数无法匹配scanf()指定格式的数据,将被遗留在输入缓冲区中,不会消失,需要使用while(getchar()!='\n');清空
#include
int main(int argc, char const *argv[])
{
// (1)、scanf函数(格式化输入)和printf函数(和格式化输出函数是不一样的,尤其是\n)
int num1 = 0;
// scanf("%d", &num1); // 推荐
scanf(";%d=\n",&num1); // 不建议这么写,scanf函数的第一个参数(双引号),里面是什么格式,到时候键盘输入
// 时(输入到输入缓冲区中,并将输入缓冲区的数据和scanf函数的格式进行匹配), 就
// 应该是什么格式(并且会将其输入的数据通过变量num1的地方赋值给变量num1)
printf("num1 == %d\n", num1); // printf函数要根据第一个参数(双引号),里面是什么,那么输出到输出缓冲区的时候,就是什么样的形式
// 什么情况下,输出缓冲区的数据,才会输出到屏幕上
// 1、遇到\n(推荐)
// 2、程序/函数结束了
// 3、遇到fflush(stdout)函数冲刷了输出缓冲区的时候
// 4、输出缓冲区满了,溢出来的时候
// (2)、为了避免输入缓冲区有遗漏的数据存在,应该使用getchar函数,将里面的数据一个个的进行清空
while(getchar()!='\n'); // 为什么是以'\n'作为清空标志??(因为每次输入完数据后,都会敲enter键(\n)结束输入)
// 注意:如果上面的scanf函数的格式中有\n字符,那么此处的清空可能还是会遗留一个字符'\n',对下面的输入函数进行干扰
int num2 = 0;
scanf("%d", &num2);
printf("num2 == %d\n", num2);
// 笔试题: 需要输入空格到数组buf1中(注意:scanf函数遇到空格将会默认截至)
char buf1[128] = {0};
scanf("%s", buf1); // 此处不需要加取地址符号(因为buf1名字本身就是地址)
printf("buf1 == %s\n", buf1);
// 现象:
// 输入:shijienameda woxiangqukankan
// 输出:buf1 == shijienameda
// 原因:
// scanf函数遇到空格将会默认截至,不再获取后面的数据
// 解决:
// char buf1[128] = {0};
// scanf("%[^\n]", buf1); // 除了遇到\n符号外,否则不退出输入状态,一直读取数据
// // scanf("%[^#]", buf1); // 除了遇到'#'符号外,否则不退出输入状态,一直读取数据
// printf("buf1 == %s\n", buf1);
// (3)、用户必须完全按照scanf()函数中描述的输入格式控制符串来输入数据,否则将会出错
// 1、此处输入时,必须带;号#号
char ch1;
int n1;
float f1;
printf("请输入格式(字符;整型#浮点型):\n");
scanf("%c;%d#%f", &ch1, &n1, &f1);
printf("ch1 == %c, n1 == %d, f1 == %f\n", ch1, n1, f1);
// 2、此处输入时,必须带ch2==的符号
char ch2;
printf("请输入格式(ch2==字符型):\n");
scanf("ch2==%c", &ch2);
printf("ch2 == %c\n", ch2);
// 3、特殊情况
int num3 = 0;
scanf("num3==%d\n", &num3); // 输入的时候也必须要输入num3==和\n才可以
printf("num3==%d\n", num3);
// (4)、scanf函数的返回值
char ch3;
int n3;
float f3;
int ret = 0;
printf("请输入格式(浮点型,字符,整型):\n");
ret = scanf("%f,%c,%d", &f3, &ch3, &n3);
printf("ret == %d\n", ret);
}
本期内容到这里就结束了,有什么问题或者不懂的可以评论区留言.....