C语言回顾day2
文章目录
- 不要直接不理会警告
- 数据类型关键字
- 浮点数类型
- 声明和赋值(很简单的东西,不过也值得注意一下)
- %d占位符
- ==%d这类占位符可能带来的陷阱==
- 其他占位符
- 八进制,十六进制
- short, long, unsigned三个用于修饰int的附属关键字
- 整型常量的数据类型
- char类型
- 字符常量(可以有多个字符组成的字符常量!)
- 非打印字符(警报,换行等)用转义序列来打印
今天回顾了C语言的数据类型,字符串,预处理器,输入输出,运算符等知识,是在看C primer plus的3-5章时,看到有值得注意的点就记录一下,没有什么其他的特定组织结构哈
不要直接不理会警告
按下enter会发送一个换行符诶
数据类型关键字
1972年int, long, short ,float就有了,90年加入了signed和void,99年加入了复数虚数和布尔类型的,看看历史感受标准制定者的用心,感受C语言的发现需要新的特性新的元素来补充
突然发现char是个很厉害的角色却一直被忽略,C语言的字符,字符串全靠char一人挑起大梁,而同时char还可以表示一些小的整数(0-255,or -128-127),确实很厉害
字长原来是这个意思??那现在的电脑基本都是64位字长了
浮点数类型
整数类型很好理解,但是浮点数类型一直让人觉得晕晕的,特地好好回顾,梳理一番
- 任意两个整数之间比如1和2之间都有无数个浮点数,所以计算机是不可能精确表示每一个浮点数的,每个浮点数都是被存储为它的计算机能表示的那个近似值!!!!
声明和赋值(很简单的东西,不过也值得注意一下)
声明只会创建内存空间
赋值会在那个内存空间放上正确的值
声明和赋值可以一起出现,初始化
%d占位符
占位符就是占位置
%d这类占位符可能带来的陷阱
试一下:
#include <stdio.h>
int main()
{
printf("%d minus %d is %d.\n", 10);
printf("%d minus %d is %d.\n", 10, 3, 7);
return 0;
}
果然编译器没检查出错误,没写的两个位置的参数不知道用了哪里的内存里的数据
10 minus 2129920 is 4194432.
10 minus 3 is 7.
我还是觉得这个检测编译器还是应该做到,不难吧,看看有几个占位符,再看看双引号后面有几个参数不就好了??或者是我还有什么没考虑到的导致我简化了问题?
其他占位符
注意虽然常量的后缀可以大写,但是在占位符这种转换说明里面只可以小写
打印int %d
short %hd
long %ld
long long %lld
unsigned int % u
unsigned short %hu
unsigned long % lu
unsigned long long %llu
#include <stdio.h>
int main()
{
short x1 = -1000;
int x2 = -100000;
long x3 = -100000000;
unsigned short y1 = 10000;
unsigned int y2 = 1000000;
unsigned long y3 = 100000000;
printf("%hd, %d, %ld\n", x1, x2, x3);
printf("%hu, %u, %lu\n", y1, y2, y3);
return 0;
}
-1000, -100000, -100000000
10000, 1000000, 100000000
注意不可以写%ul,%uh,字母u和d要写在l和h的后面,否则就会输出这样的结果
#include <stdio.h>
#include <limits.h>
int main()
{
short x1 = -1000;
int x2 = -100000;
long x3 = -100000000;
unsigned short y1 = 10000;
unsigned int y2 = 1000000;
unsigned long y3 = 100000000;
printf("%dh, %d, %dl\n", x1, x2, x3);
printf("%uh, %u, %ul\n", y1, y2, y3);
return 0;
}
-1000h, -100000, -100000000l
10000h, 1000000, 100000000l
八进制,十六进制
一个十六进制的数正好由四位二进制数表示
十六进制的3对应二进制 0011
十六进制的5对应二进制 0101
十六进制的35对应二进制的0011 0101
十六进制的53对应二进制的0101 0011
非常简便!
但是要知道,八进制十六进制只是为了表示上简便简短一点,计算机的内部还是二进制表示的
// 以三种计数系统显示同一个值
#include <stdio.h>
int main()
{
int x = 20;
printf("decimal=%d, octal=%o, hex=%x\n", x, x, x);
//加上前缀(在转换说明中加个#就行),十进制没有前缀,八进制的前缀是数字0,十六进制的前缀是数字0和字母x,小写大写都可以
printf("decimal=%d, octal=%#o, hex=%#x\n", x, x, x);
return 0;
}
decimal=20, octal=24, hex=14
decimal=20, octal=024, hex=0x14
short, long, unsigned三个用于修饰int的附属关键字
我们说的short, long整型实际上都是short int, long int的简写
short, int long, long long都是有符号的整型,加不加signed都一样,加signed只是强调一下用的是有符号整型,要用unsigned修饰才是无符号的,无符号的整型表示的范围大点
long long 在1999年加入,看来那时候人们感受到整型的范围不够用了
所以总结来说,先不管char:
- 有符号整型:short, int, long, long long 或者 signed short, signed int, signed long, signed long long
- 无符号整型: unsigned short, unsigned int, unsigned long, unsigned long long
整型常量的数据类型
一般对于没显式说明类型的数字,比如直接输入2,45,或者八进制十六进制的数,038, 0x89a,那么编译器都会默认存储为int类型,如果不够大则会尝试无符号int,如果还是不行则依次尝试long, long long。
但是除了可以用const限定符指定数据类型以外,还可以用后缀去告诉编译器用什么数据类型,比如45L,367LL, 234LU,687LLU,大写的L表示long整型(不要用小写的L否则看起来像1),而U表示unsigned,可以用小写的u.
char类型
虽然char类型用于存储字符,但是从技术层面上看实际上他还是在存整数,所以它实际上本质上还是一种整型
标准ASCII码用的是0-127,所以8位绰绰有余。
字符常量(可以有多个字符组成的字符常量!)
但是也有例外!!!可以有多个字符组成的字符常量!!!
#include <stdio.h>
int main()
{
char x = "A";//实际上"A"是字符串"A"的内存地址!!!,字符串就是指针!
char y = 'A';//提倡这种字符初始化,不管什么编码都不会错,不需要记住ASCII码的具体数值
char z = 65; //这是不好的编程风格,但是对于ASCII码是没错的,最好不要这样;
//注意65会被编译器默认为int类型,但是由于65在char的表示范围以内,所以可以赋给char类型
char w = 'FATE';//字符常量‘a’,‘ask’等也会被编译器识别为int类型!!!所以‘FATE’的四个字符分别占了int的一个字节,但是赋值给表示范围更小的char,就只把最后一个字节给char,于是只会打印最后一个字符
printf("%c, %c, %c, %c\n", x, y, z, w);
return 0;
}
D, A, A, E
字符常量‘a’,‘ask’等也会被编译器识别为int类型!!!所以‘FATE’的四个字符分别占了int的一个字节,但是赋值给表示范围更小的char,就只把最后一个字节给char,于是只会打印最后一个字符,下面的程序可以验证:
把字符常量赋值给int变量,并用十六进制打印其数值,把这四个数值作为ascii码打印为字符,确实就是F, A,T, E
这个实验也说明了用双引号给字符常量赋值是错误的,”A”的代码根本不是65.实际上”A”是字符串”A”的内存地址!!!,字符串就是指针!
#include <stdio.h>
int main()
{
char x = "A";
char y = 'A';
printf("%d, %d\n", x, y);
char w = 'FATE';
int s = 'FATE';
printf("%c, %c, %#0x, %#0x\n", x, w, w, s);
printf("%c, %c, %c, %c", 0x46, 0x41, 0x54, 0x45);
return 0;
}
68, 65
D, E, 0x45, 0x46415445
F, A, T, E
如果把超过四个字符赋值给int,自然int也只会记录后面4个字符,说明当字符常量超过四个字符时,编译器会识别为long等更大的数据类型,当然,实际中一般不会用超过一个字符的字符常量
#include <stdio.h>
int main()
{
int s = 'FATEL';
printf("%#0x\n", s);
printf("%c, %c, %c, %c\n", 0x41, 0x54, 0x45, 0x4c);
return 0;
}
0x4154454c
A, T, E, L
非打印字符(警报,换行等)用转义序列来打印
这些操作也是被定义为字符的,很神奇呢。打印这个字符,就可以执行这个操作,但是并不改变光标位置(也叫活跃位置,即下一个字符要出现的位置)
打印这些表示操作的字符可以用两种方法,一是赋值时用ASCII码值,二是用转义序列,当然还是更推荐第二种,不用记忆
#include <stdio.h>
int main()
{
char x = '\r';
printf("%c\n", x);
return 0;
}
打印\a,响一声警报
打印\b,backspace,退格
打印\r,回车,enter
打印\f,换页
水平制表符,相当于4个空格
#include <stdio.h>
int main()
{
char x = '\t';
printf("aaa%caaa\n", x);
return 0;
}
aaa aaa
垂直制表符
#include <stdio.h>
int main()
{
char x = '\v';
printf("aaa%caaa\n", x);
printf("%c", x);
return 0;
}
aaaaaa
反斜杠,单引号, 双引号,问号
aaa\aaa'aaa"aaa?
另外,八进制十六进制也是用转义序列来打印的哦
char类型不像short, int, long, long long 那样,默认有符号类型,char到底是有符号还是无符号要看你用的编译器怎么规定的,不同编译器的规定可能不同,但是用unsigned 和signed修饰一下就好啦
还没有评论,来说两句吧...