------ Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
1.C语言中的进制
1>C语言标准中针对数值常量,规定了八进制、十进制和十六进制的规则,但是对于常用的二进制则没有规定。
一些编译器厂商,自行扩展了类似0b10001000这样的语法,用来表示二进制数值。
1>特点:只有0和1,逢2进1。2>书写格式:0b或者0b开头。3>n为二进制位所能表示的数据范围(不考虑负数):0~2的n次方-1。
八进制
1>特点:0~7,逢八进一。2>书写格式:0开头。
十六进制
1>特点:0~F,逢十六进一。2>书写格式:0x或者0X开头。
2>在C语言中默认的输出格式
1>%d\%i 十进制形式输出整数
2>%c 输出字符
3>%p 输出地址
4>%f 输出小数
5>%o 八进制形式输出整数
6>%x 十六进制形式输出整数
7>%o 不带符号输出八进制
8>%x 不带符号输出十六进制
9>%u 不带符号输出十进制
10>%e 以标准指数形式输出单、双精度,数字部分小数位数为6位
*/
#include
int main()
{
// 默认情况下,就是十进制
int number = 12;
// 二进制(0b或者0B开头)
int number2 = 0B1100;
// 八进制(0开头)
int number3 = 014;
// 十六进制(0x或者0X开头)
int number4 = 0xc;
// %d以10进制整数的形式输出一个数值
printf("%x\n", number);
return 0;
}
3>进制之间的转化
二进制转十进制
0b1100 = 0 * 2的0次方 + 0 * 2的1次方 + 1 * 2的2次方+ 1 * 2的3次方
= 0 + 0 + 4 + 8 = 12
0b1111 = 1 + 2 + 4 + 8 = 15
0b1010 = 10
十进制转二进制
67 = 64 + 2 + 1 = 2的6次方 + 2的1次方 + 2的0次方
= 0b1000000 + 0b10 + 0b1
= 0b1000011
n位二进制的取值范围
2位二进制位的取值范围:0~3 0~2的2次方-1
3位二进制位的取值范围:0~7 0~2的3次方-1
n位二进制位的取值范围:0~2的n次方-1
输出一个整数的二进制存储形式
#include
int main()
{
void putBinary(int);
putBinary(-12);
putBinary(13);
return 0;
}
// 输出一个整数的二进制存储形式
void putBinary(int n)
{
int bits = sizeof(n) * 8;
while (bits-->0) {
printf("%d", n>>bits&1);
if (bits%4==0) printf(" ");
}
printf("\n");
}
2.类型说明符
short 2个字节 %d
long 8个字节 %ld
long long 8个字节 %lld
(2)注意signed和unsigned的区别:
1>signed 最高位要当做符号位
2>unsigned 最高位不要当做符号位
3>signed == signed int
4>signed 有符号:正数、0、负数
5>unsigned int == unsigned
6>unsigned 无符号:0、正数
(3)各类符之间的等价关系long == long int
long long int == long long
short == short int
3.位运算
1) &按位与
只有对应的两个二进位均为1时,结果位才为1,否则为0。
二进制中,与1相&就保持原位,与0相&就为0可以用来获取精确某一位的二进制位
2) |按位或
只要对应的两个二进位有一个为1时,结果位就为1,否则为0。
当对应的二进位相异(不相同)时,结果为1,否则为0。
相同整数相^的结果是0。任何值与0^,结果为本身。多个整数相^的结果跟顺序无关。a^b^a = b
对整数a的各二进位进行取反,符号位也取反(0变1,1变0)
把整数a的各二进位全部左移n位,高位丢弃,低位补0。左移n位其实就是乘以2的n次方由于左移是丢弃最高位,0补最低位,所以符号位也会被丢弃,左移出来的结果值可能会改变正负性
把整数a的各二进位全部右移n位,保持符号位不变。右移n位其实就是除以2的n次方
为正数时,符号位为0,最高位补0为负数时,符号位为1,最高位是补0或是补1取决于编译系统的规定
4.char类型
当取值范围在-128—127是,可以作为整数用。
printf("%d", 'A'); 输出为65
转义字符 | 意义 | ASCII码值 |
\n | 将当前位置移到下一行开头(回车换行) | 10 |
\t | 跳到下一个TAB位置 | 9 |
\\ | 代表一个反斜线字符 | 92 |
\' | 代表一个单引号字符 | 39 |
\" | 代表一个双引号字符 | 34 |
\0 | 空字符 | 0 |
5.数组
1)用来存储一组数据,只能存放一种类型的数据,数组数据成为元素。
元素类型 数组名[元素个数]; 如:int ages[3]; 元素数据的访问a[i];
遍历:按照顺序查看数组的每一个元素
- for (int i = 0; i<5; i++)
- {
- printf("ages[%d]=%d\n", i, ages[i]);
- }
2).数组的定义和初始化
定义的同时进行初始化,元素个数只能放常量,或者不写
- int ages[5] = {10 , 11, 12, 67, 56};
- int ages[5] = {10, 11};
- int ages[5] = {[3] = 10, [4] = 11};
- int ages[] = {10, 11, 14};
- int count = 5;
- int ages[count];
- ages[0] = 10;
- ages[1] = 11;
- ages[2] = 18;
- int count = sizeof(ages)/sizeof(int);
3).内存存储细节
内存的分配是从高地址到低地址进行的,但一个数组内部元素又是从低到高进行的
数组的地址是首元素的值 a[0]
数组名就代表数组的地址,数组元素地址 &a[0]
4).数组和函数
数组作为函数参数,可以省略元素个数
数组作为函数参数,传递是整个数组的地址,修改函数形参数组元素的值,会影响到外面的实参数组
当把一个数组当作函数传递时候,会当做指针变量来使用,指针变量占据8个字节
5).练习
数组的逆序排列和元素和
- #include <stdio.h>
- int main()
- {
- int i;
- int sum=0;
- int a[4];
- printf("请输入四个数:\n");
- //输入数组元素
- for(i=0;i<4;i++)
- {
- scanf("%d", &a[i]);
- }
- //求数组元素和
- for(i=0;i<4;i++)
- {
- //累加
- sum=sum+a[i];
- }
- printf("数组和:%d\n", sum);
- //逆序存放
- int t;
- for(i=0;i<3;i++)
- {
- //元素调换
- t=a[i];
- a[i]=a[3-i];
- a[3-i]=t;
- }
- printf("数组逆序输出:\n");
- for(i=0;i<4;i++)
- {
- printf("%d\n", a[i]);
- }
- return 0;
- }
6).二维数组
int ages[3][10]; 三个班,每个班10个人
相当于3行10列
相当于装着3个一维数组
二维数组是一个特殊的一维数组:它的元素是一维数组。
内存存储细节参照一维数组
初始化
- int ages2[3][5]= {
- {10, 11, 90, 89, 70},
- {10, 11, 90, 89, 70},
都是正确写法
//int ages[5] = {10 , 11, 12, 67, 56};
//int ages[5] = {10, 11};
//int ages[5] = {[3] = 10, [4] = 11};
//int ages[] = {10, 11, 14};
// 错误写法
// int ages[];
// 错误写法
/* 只能在定义数组的同时进行初始化
int ages[5];
ages = {10, 11, 12, 14};
*/
// 正确写法
// int ages['A'-50] = {10, 11, 12, 14, 16};
//int size = sizeof(ages);
//printf("%d\n", size);
// 正确写法
/*
int count = 5;
int ages[count];
ages[0] = 10;
ages[1] = 11;
ages[2] = 18;
*/
//printf();
// 错误写法
// 如果想再定义数组的同事进行初始化,数组元素个数必须是常量,或者不写
//int ages[count] = {10, 11, 12};