1. 二进制基础

N进制转换十进制
计算机常用进制一般有二进制,八进制,十进制,十六进制,所谓进制,就是“逢N进一”。
二进制,逢二进一,数字中只有 0 和 1
例如数字1010对应十进制:12^3+02^2+121+0*0^0=10
八进制**,逢八进一,数字中**有0,1,2,3,4,5,6,7
例如八数字45转换十进制:48^1+58^0=37
十六进制,逢16进一,数字中有0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
例如十六进制数字45转换十进制:416^1+516^0=69
二进制与八进制互转
二进制转换成八进制的方法是,取三合一法
例如:10101001对应八进制:(010)(101)(001)=251
八进制转为二进制,方法是一分三
例如:345对应二进制:345=(011)(100)(101)
二进制与十六进制互转
二进制转换成十六进制的方法是,取四合一法
例如:10101001对应十六进制:(1010)(1001)=A9
十六进制转为二进制,方法是一分四
例如:1F02对应十六进制:1F02=(0001)(1111)(0000)(0010)
十进制转二进制
用2整除十进制整数,得到一个商和余数;再用2去除商,又会得到一个商和余数,如此重复,直到商为小于1时为止,每一位取余,最后倒叙.
例如:45对应二进制:
45/2=1,22/2=0,11/2=1,5/2=1,2/2=0,1/2=1 最后=101101
比较法:512,256,128,64,32,16,8,4,2,1 这个序是对应的二进制次方
例如:173对应为二进制:
从左至右依次开始,173比128大取1,(173-128)=45,45比64小取0,45比32大取1,(45-32)=13,13比16小取0,比8大取1,(13-8)=5,5比4大取1,(5-4)=1,1比2小取0,1比1取1,最后=10101101
小数部份转换
十进制的小数转换为二进制,主要是小数部分乘以2,取整数部分依次从左往右放在小数点后,直至小数点后为0
小数转二进制
0.125=0.1252=0.25取0,0.252=0.5取0,0.5*2=1取1=最终二进制为0.001
以下是0.3转成二进制的过程,
取8位小数的话0.3 =0.01001100,这是一个无限循环的数
内存中的位,字节,字
计算机中的内存是以位为最小存储单位的。通过对内存进行组织,可以引用特定的位集合。把计算机的内存起始位编号为1,每隔8位编号增1,也就是以字节为单位,每隔一个字节编号向上加一,可以对计算机所有内存进行编号。
2. 数据类型概述
C语言规定,在程序中使用的每一个数据,必须指定其数据类型。

不同类型,占用空间不同

sizeof是C语言的一种单目操作符,如C语言的其他操作符++、--等。
sizeof操作符以字节形式给出了其操作数的存储大小。操作数可以是一个表达式或括在括号内的类型名。
#include<stdio.h>
void main() {
printf("%d\n",sizeof(char));//1
printf("%d\n", sizeof(short));//1
printf("%d\n", sizeof(int));//4
printf("%d\n", sizeof(unsigned int));//4
printf("%d\n", sizeof(double));//8
getchar();
}
#include<stdio.h>
#include<limits.h>//极限头文件
void main() {
printf("%d,%d\n", INT_MAX,INT_MIN);
printf("%u,%u", UINT_MAX, 0);
getchar();
}

3. 原码反码补码
原码、反码、补码
原码:
最高位为符号位,其余各位为数值本身的绝对值
反码:
正数:反码与原码相同
负数:符号位为1,其余位对原码取反
补码:
正数:原码、反码、补码相同
负数:最高位为1,其余位为原码取反,再对整个数加1
原码例子:

对应十六进制:0000 0000 0000 0001

对应十六进制:0000 0000 0000 0010
补码例子:

这里会发现-1显示为ffffffff,由于int是32位
我们推理一下
-1的原码
1000 0000 0000 0000 0000 0000 0000 0001
取反
1111 1111 1111 1111 1111 1111 1111 1110
负数+1
1111 1111 1111 1111 1111 1111 1111 1111,这个就是-1的补码
|
原码 |
反码 |
补码 |
|
|
7 |
0000 0111 |
0000 0111 |
0000 0111 |
|
-7 |
1000 0111 |
1111 1000 |
1111 1001 |
从这里能发现,计算是用补码存储的
例子:
从这里能发现,计算是用补码存储的
例子:
#include<stdio.h>
void main() {
int x = -7;
printf("%p", &x);
getchar();
}

十六进制:ffff fff9
对应二进制:1111 1111 1111 1111 1111 1111 1111 1001
反码(减一): 1111 1111 1111 1111 1111 1111 1111 1000
原码(取反): 1000 0000 0000 0000 0000 0000 0000 0111
补码可以将符号位和数值域统一处理;同时,加法和减法也可以统一处理 。
#include<stdio.h>
void main() {
int x = -1;
printf("%p\n", &x);
printf("%d,%u", x,x);//d带符十进制,%u无符号
getchar();
}


切换无符号

4. 整型
整型常量的三种表示形式:
十进制整型常量的表示与数学上的表示相同,十进制整型常量前没有前缀,由0~9的数字组成。
八进制整型常量的表示形式是以数字0开头,即以0作为八进制数的前缀,由0~7的数字组成。
十六进制整型常量的表示形式以0x或0X作为前缀,由数字0~9、字母A~F或a~f组成。
|
类型 |
存储空间大小 |
值范围 |
|
char |
1 字节 |
-128 到 127 或 0 到 255 |
|
unsigned char |
1 字节 |
0 到 255 |
|
signed char |
1 字节 |
-128 到 127 |
|
int |
2 或 4 字节 |
-32,768 到 32,767 <br>-2,147,483,648 到 2,147,483,647 |
|
unsigned int |
2 或 4 字节 |
0 到 65,535 <br>0 到 4,294,967,295 |
|
short |
2 字节 |
-32,768 到 32,767 |
|
unsigned short |
2 字节 |
0 到 65,535 |
|
long |
4 字节 |
-2,147,483,648 到 2,147,483,647 |
|
unsigned long |
4 字节 |
0 到 4,294,967,295 |
#include<stdio.h>
void main() {
printf("你的编号:%d\n", 10);//十进制常量10
printf("一个负数:%d\n", -20);//十进制常量-20
printf("你的年纪%d\n", 044);//八进制的常量->36
printf("你有多少钱%d\n", -070);//八进制的常量->-56
printf("蜀国有%d多兵力\n", 0x7F);//八进制的常量->127
printf("蜀国有%d多兵力\n", -0x7F);//八进制的常量->-127
printf("这个长整数:%d\n", 10l);
printf("这个无符号长整数:%u", 12u);
unsigned int x = -20u;//这个会出错,加u后,不能带负号
getchar();
}

这里对就int对应二进制1010
再看一下-10

整形变量
整型变量用于存放整型数据。根据数值的表示范围整型可以为整型(int)、短整型(short)、长整型(long)三种。
这三种整型都默认为有符号型(signed),有符号型即可以是正数、负数和0。也可以根据需要,将整型指定为无符号型(unsigned),此时整型变量只能存放非负数。
short、long、signed、unsigned都是一些类型修饰符,用于补充说明变量的特性
#include<stdio.h>
void main() {
printf("short:%d,int:%d,long:%d\n", sizeof(short), sizeof(int), sizeof(long));
printf("ushort:%d,uint:%d,ulong:%d", sizeof(unsigned short), sizeof(unsigned int), sizeof(unsigned long));
getchar();
}
short 只占两个字节,2^16
long 占4个字节,2^32
int 在32位以下计算机与short一样,32位以上计算机与long等价
#include<stdio.h>
void main() {
short num = 900000;
printf("今天生产量:%d", num);//这时会溢出
getchar();
}
修改成int,就没问题了。
#include<stdio.h>
void main() {
int num = 900000;
printf("今天生产量:%d", num);
getchar();
}
使用无符号
#include<stdio.h>
void main() {
unsigned short unum = 32769;
printf("今天生产量:%d", unum);//这时不会出错,因为无符号的正数范围更大
getchar();
}
#include<stdio.h>
#include<limits.h>
void main() {
short smax = SHRT_MAX;//short 最大值
short smin = SHRT_MIN;//short 最小值
printf("%d,%d\n", smax, smin);
unsigned short usmax = USHRT_MAX;//unsigned short 最大值
unsigned short usmin = 0;//unsigned short 最小值
printf("%d,%d\n", usmax, usmin);
int imax = INT_MAX;//int 最大值
int imin = INT_MIN;//int 最小值
printf("%d,%d\n", imax, imin);
int lmax = LONG_MAX;//int 最大值
int lmin = LONG_MIN;//int 最小值
printf("%d,%d", lmax, lmin);
getchar();
}
5.浮点型
浮点型常量有两种表示形式:十进制小数形式和指数形式。
|
类型 |
存储大小 |
值范围 |
精度 |
|
float |
4 字节 |
1.2E-38 到 3.4E+38 |
6 位小数 |
|
double |
8 字节 |
2.3E-308 到 1.7E+308 |
15 位小数 |
|
long double |
16 字节 |
3.4E-4932 到 1.1E+4932 |
19 位小数 |
float.h 头文件定义了宏,在程序中可以使用这些值和其他有关实数二进制表示的细节。
#include<stdio.h>
void main() {
printf("工资有:%f元\n", 19800.34);
printf("还有%f零钱\n", 0.35);
printf("首富有:%f元\n", 1.58e9);//10^9
printf("手上没几个子:%f元\n", 1.58e-4);//10^-4
getchar();
}
实型常量的类型细分:
默认为double型,例如3.14就是double类型,
后面加f或F认为是float型,例如3.14f就是float类型
#include<stdio.h>
void main() {
printf("%d,%d\n", sizeof(1.0),sizeof(1.0f));
getchar();
}
浮点型变量:浮点型分为单精度型(float)和双精度型(double)两种。
float和double的区别:
float型数据占用4个字节(32bits)存储单元,提供的有效数字是6~7位;
double型数据占用8个字节(64bits)存储单元,提供的有效数字是15~16位。
#include<stdio.h>
void main() {
float x = 123.4;
double y = 123.4;
printf("%f,%f\n", x, y);
printf("%d,%d", sizeof(x), sizeof(y));
getchar();
}
#include<stdio.h>
#include <float.h>
void main() {
printf("float 存储最大字节数 : %lu \n", sizeof(float));
printf("float 最小值: %E\n", FLT_MIN);
printf("float 最大值: %E\n", FLT_MAX);
printf("精度值: %d\n", FLT_DIG);
printf("\n");
printf("double 存储最大字节数 : %lu \n", sizeof(double));
printf("double 最小值: %E\n", DBL_MIN);
printf("double 最大值: %E\n", DBL_MAX);
printf("精度值: %d\n", DBL_DIG);
}
海*公伦**式又译作希*公伦**式、海龙公式、希罗公式、海伦-秦九韶公式。它是利用三角形的三条边的边长直接求三角形面积的公式。表达式为:S=√p(p-a)(p-b)(p-c),它的特点是形式漂亮,便于记忆。

#include<stdio.h>
#include<math.h>
void main() {
float a = 5.0;
float b = 6.0;
float c = 7.0;
float s;
float p = (a + b + c) / 2;//公式里的p为半周长
s = sqrt(p * (p - a) * (p - b) * (p - c));
printf("面积:%f", s);
getchar();
}
6.字符
字符常量
定义:用单引号括起来的单个普通字符或转义字符.
字符常量的值:该字符的ASCII码值
转义字符:反斜线后面跟一个字符或一个代码值表示
|
转义序列 |
含义 |
|
\ |
\ 字符 |
|
' |
' 字符 |
|
" |
" 字符 |
|
? |
? 字符 |
|
\a |
警报铃声 |
|
\b |
退格键 |
|
\f |
换页符 |
|
\n |
换行符 |
|
\r |
回车 |
|
\t |
水平制表符 |
|
\v |
垂直制表符 |
C 库函数 int putchar(int char) 把参数 char 指定的字符(一个无符号字符)写入到标准输出 stdout 中。
#include<stdio.h>
void main() {
putchar('A');
putchar('\n');
putchar('B');
putchar('\n');
putchar('C');
getchar();
}

#include<stdio.h>
void main() {
putchar('\x45');//十六进制->十进制,对应69->E
putchar('\101');//八进制->十进制,对应65->A
getchar();
}
字符串常量
用双引号括起来的字符序列,每个字符串尾自动加个‘\0’作为字符串结束标志。

#include<stdio.h>
void main() {
printf("hello world\n");
printf("%d\n", sizeof(""));//空时也占了一个字节
printf("%d\n", sizeof("1"));
getchar();
}
字符常量是单引号引起来的一个字符,而字符串常量是双引号引起来的若干字符。
#include<stdio.h>
void main() {
char c = '1';
int x = 1;
printf("%p,%p", &c, &x);//在内存中观察区别
getchar();
}
char做加法
#include<stdio.h>
void main() {
char c = 'A';
printf("%c",c);//打印字符
c = c + 2;
printf("%c,%d", c,c);//打印字符与对应数字
getchar();
}
用char 存字符,这个在C编译器下不会出错,在C++下会出错,实际我们不能这么做。
#include<stdio.h>
void main() {
char c1 = 'A';
char c2 = "A";//这里会有问题
getchar();
}
7.ASCII码
ASCII 定义了 128 个字符。
- 0-31、127(删除键)是控制字符
- 空白字符:空格(32)、 制表符、 垂直制表符、 换行、 回车。
- 可显示字符:a-z、A-Z、0-9、~、!、@、、%、^、&、#、$、*、(、)、-、+、{、}、[、]、'、"、<、>、,、?、/、|、\、_、:、;、.,还有顿号、。
这个代码在vs中编译不过去。
#include<stdio.h>
void main() {
char c;
printf("请输入一个字符:\n");
scanf("%c", &c);
printf("%c的ASCII为%d", c, c);
getchar();
}
Severity Code Description Project File Line Suppression State Error C4996 'scanf': This function or variable may be unsafe. Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
我们可以scanf_s来替换,问题是scanf_s 不通用。由于 scanf_s 是VS编译器所提供的,所以在其他平台上并不通用,这就导致用 scanf_s 编写出来的代码不通用。
再就是在程序最上面加上
#define _CRT_SECURE_NO_WARNINGS 1
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
void main() {
char c;
printf("请输入一个字符:\n");
scanf("%c", &c);
printf("%c的ASCII为%d", c, c);//c%字符,%d数字
getchar();
}
来个大小写转换
#include<stdio.h>
//大写转小写
void main() {
char c;
c = getchar();//取得用户输入
printf("%c,%d\n", c,c);
c = c + 32;
printf("%c,%d", c,c);
}
getchar()函数实际上是int getchar(void),所以它返回的是ASCII码,所以只要是ASCII码表里有的字符它都能读取出来。在调用getchar()函数时,编译器会依次读取用户键入缓存区的一个字符。
注意:这里只读取一个字符,如果缓存区有多个字符,那么将会读取上一次被读取字符的下一个字
scanf() 是从标准输入流stdio (标准输入设备,一般指向键盘)中读内容的通用子程序,可以说明的格式读入多个字符,并保存在对应地址的变量中。
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
void main() {
int a, b, c;
printf("用空格分开输入:\n");
scanf("%d%d%d", &a, &b, &c);
printf("a=%d,b=%d,c=%d\n", a, b, c);
}