进制转换:

为什么使用二进制、八进制、十六进制?

由于现在的CPU只能识别高低两种电平,只能使用二进制数据进行计算

二进制虽然能够被计算机直接计算,但是不方便书写、记录,因此将数据以八进制方式为了更方便记录在文件中

随着CPU位数不断增加,八进制不能满足需求,所以发展出了十六进制来表示数据,

由于历史原因八进制还不能退出历史舞台

十进制转二进制:(十进制转其他进制)

求余法: 用2对数据求余,然后再继续对商求余,知道商为0结束,过程中产生的余数就是该数据的二进制(逆序)

n %2 余数

商%2

...

127 %2 1

63 %2 1

31 %2 1

15 %2 1

7 %2 1

3 %2 1

1 %2 1

0 0

二进制:01111111

求权法: 数据- 2^(n-1) 如果可以减,则第n位为1,否则为0

137

128 64 32 16 8 4 2 1

1 0 0 0 1 0 0 1

手算: 79 28 63 119

10 A 11 B

二进制转十进制:(其他进制转十进制)

二进制数据每位 乘2^(n-1) 结果求和

10011101 128+16+8+4+1 157

二进制转八进制:

三个二进制位转为一位八进制位

二进制 10 011 001 101 110

八进制 2 3 1 5 6

二进制转十六进制:

四个二进制位转为一位十六进制位

二进制 10 0110 0110 1110

十六进制: 2 6 6 E

在C代码中,以0开头的数据是八进制数据,以0x开头的是十六进制数据

%o 以八进制形式显示数据

%x 以十六进制显示数据

%#o %#x 以对应的进制显示数据

原码、反码、补码:

原码: 数据的二进制

反码:

正数的原码就是它的反码

负数的反码是它的原码符号位不变,其它位按位求反

补码: 数据在内存中是以补码形式存储的

正数的原码就是它的补码

负数的补码是它的反码+1

负数的补码:

1、数据转换为二进制

2、二进制符号位不变,其余按位求反得到反码

3、反码+1得到补码

-127

1111 1111

1000 0000

1000 0001 补码

0000000000000000000000001000 0001 %d --127->129

补码转数据:

无符号的补码直接转成十进制数据

有符号看最高位是0,说明是正数,也直接转成十进制数据

有符号且最高位是1,说明是负数

1、补码-1得到反码

2、反码符号位不变,按位求反得到原码

3、原码转换成十进制

11111111 补码

11111110 反码

10000001 原码 -1

最大值+1 = 最小值

最小值-1 = 最大值

位运算符:& | ~ ^ << >>

A & B 按位相与

01101010 0x6A

01110110 0x76

01100010 0x62

A | B 按位相或

01101010 0x6A

01110110 0x76

01111110 0x7E

~A 按位求反

01101010 0x6A

10010101 0x95

A^B 按位异或 相同为0,相异为1

01101010 0x6A

01110110 0x76

00011100 0x1C

A<<n 把A的补码向左移动n位,左边丢弃,右边补0

01101010 0x6A << 4

10100000 0xA0

A>>n 把A的补码向右移动n位,右边丢弃,左边补符号位

11101010 0xEA >> 3

11111101 0xFD

4位先与0 ,再或1010

printf("%d\n",n & ~(0xf<<4) | (0xA << 4));

00000000 00001111

00000000 11110000

11111111 00001111

xxxxxxxx 0000xxxx

0xA << 4

00000000 10100000

xxxxxxxx 1010xxxx

函数:

是一段具有某项功能的代码,是C语言中管理代码的最小单位

把代码封装成一个个的函数,可以方便管理和调用代码

函数的分类:

标准库函数

C语言标准委员会为C语言以函数形式提供一些基础的功能,被封装在libc.so库,默认添加的,所以使用时需要包含头文件,以函数名(参数) 来调用函数

int isalnum(int c);

int isalpha(int c);

int isdigit(int c);

int islower(int c);

int isupper(int c);

int isxdigit(int c);

int toupper(int c);

int tolower(int c);

int abs(int j);

以下函数被封装在libm.so 数学库中,使用时需要在编译时加参数-lm

double sqrt(double x);

double pow(double x, double y);

double ceil(double x);

double floor(double x);

double fabs(double x);

time_t time(time_t *t);

功能:返回自1970-1-1 0:0:0 到运行时过了多少秒

int system(const char *command);

功能:调用系统命令 system("clear");

int rand(void);

功能:返回一个随机数

void srand(unsigned int seed);

功能:种随机种子,设置取随机数的位置

练习3:获取10个[100,1000]范围内的随机数

num = rand()%901+100

[a,b) rand()%(b-a)+a

练习4:随机出一注双色球中奖号码

红球6个:1-33,不能重复 rand()%33+1

蓝球1个:1-16 rand()%16+1

系统函数

系统函数不是函数,只是操作系统以函数接口的形式提供的一些功能

内存管理、信号处理、文件IO、文件管理、进程管理、进程通信、线程管理、线程同步、网络通信

第三方库函数

由第三方提供的收费、开源的库函数

github

MD5

XML

JSON

自定义函数:

为了更方便地管理代码、减少冗余把代码封装成函数

注意:一个函数尽量控制在50行左右,一个函数一个功能

函数声明:函数声明目的是为了告诉其他代码该函数的调用格式

返回值类型 函数名(类型1 变量名1,类型2 变量名2...);

1、C语言中函数名一般全部小写,用下划线分隔

2、如果不需要参数建议写void,不要空着

3、如果不需要返回值写void

4、如果在调用前有函数的定义,那么函数声明可以省略

隐式声明:

当调用函数时没有函数声明或定义,编译器会猜测函数的格式,参数列表会根据调用时的提供数据来猜测,返回值猜测为int类型

如何避免:在调用前,提供函数的声明或定义

函数定义:

返回值类型 函数名(类型1 变量名1,类型2 变量名2...)

{

函数体;

return val;

}

注意:return语句的作用:1、返回值给调用者 2、结束函数的执行

函数调用:

函数名(实参);

返回值会放在调用的位置,可以用变量记录下来,也可以直接显示,如果不记录就会丢失

函数传参

1、实参与形参之间是以赋值的形式传递数据的(单向值传递)

2、在函数内定义的参数,只属于它所在的函数,出了该函数就不能在使用了

3、return语句其实是把数据放置到一个公共区域(函数和调用者共用),如果不写return语句,调用者从该区域中获取的是一个随机的垃圾数据

4、当数组作为函数的参数时,长度会丢失,需要额外多加长度的参数来把长度传递过去

5、数组的传递是"址传递",函数和函数的调用者可以共享数组

练习5:实现一个函数,找出数组中的最大值

练习6:实现一个函数,对数组进行排序

练习7:实现一个函数,查找数组中是否存在某个值,如果存在则返回该数据在数组中的下标

int find_arr(int arr[],int len,int val);


设计函数的准则:

1、一个函数最好只解决一个问题,从而可以降低出错率

2、最好不要过分依赖其他函数,降低耦合度

3、数据由调用者提供,结果返回给调用者,以此提高函数的通用性

4、对于调用者提供的非法参数,可以通过返回值、注释等方式来告诉调用者数据非法,以此提高函数的健壮性

5、一个函数最多不要超过50行

进程映像:

程序:储存在磁盘中的可执行的文件(二进制文件、脚本文件)

进程:在系统中运行的程序

进程映像:进程的内存的分布情况

text 代码段: 存储的是二进制的指令、常量数据,权限是只读的,如果强行修改会产生段错误

data 数据段: 存储的是初始化过的全局变量、被初始化过的静态局部变量

bss 静态数据段:存储的是未初始化过的全局变量、未初始化过的静态局部变量,程序运行前会清零

stack 栈: 局部变量、块变量,会随着进程运行而申请、释放,由系统管理的,缺点:小

heap 堆: 由程序员手动管理的,手动申请、释放的,使用比较麻烦,特点是:足够大,理论上无限大

局部变量和全局变量:

全局变量: 定义在函数外的

存储位置: data(初始化过的)或者bss(未初始化过的)

生命周期: main函数运行开始前到程序结束才释放

作用范围: 程序中的任何位置

局部变量: 定义在函数内的

存储位置: stack栈内存

生命周期: 函数的定义语句开始,直到函数执行结束

作用范围:只能在本函数内使用

块变量: 定义在if\for\while等语句块内的变量

存储位置: stack栈内存

生命周期: 函数的定义语句开始,直到函数执行结束

作用范围:只能在语句块内使用

注意:局部变量和全局变量可以同名,但是会屏蔽同名的全局变量,同名块变量会屏蔽同名的局部变量和全局变量

建议:全局变量首字母大写

类型限定符:

auto

用于定义自动申请、自动释放的变量(局部变量),不加代表了加

不能用于修饰全局变量

const

显示地"保护"变量不被修改

但是,如果要强制修改还是可以修改的

如果对初始化过的全局变量,用const修饰后,存储位置从data变成了text

extern

声明外部的全局变量,声明的变量已在别处定义过,请放心使用

但是只能临时通过编译,如果没有定义,链接时依然会报错

只是声明变量,不能赋值

static

被static修饰过的变量称为静态局部变量,局部全局变量

改变存储位置:

改变局部变量的存储位置,由stack改data或者bss(由是否初始化决定)

延长生命周期:

延长局部变量的生命周期

限制作用范围:

限制全局变量、函数只能在本文件内使用

可以防止函数、全局变量重名、防止被别人调用

存储介质:

硬盘->内存->高速缓存->寄存器->CPU

register

申请把变量的存储介质由内存转移到寄存器存储,如果能成功,数据的读取速度会大幅提升,寄存器数量有限,申请可能失败

volatile

编译器的取值优化:

变量的值没有发生改变时,后续的取值会进行优化,不再去内存中读取,而是使用第一次读取的结果,可以节约时间

使用volatile修饰的变量不做取值优化

volatile int num = 10;

if(num == num)

{

//可能为假

}

一般硬件编程和驱动编程时使用

typedef

类型重定义,注意不是替换关系,定义变量时如果前面加上typedef,则变量名就变成了类型

typedef int num;

#define num int;

num num2;

uint8_t size_t time_t

typedef unsigned char uint8_t

函数递归:

分治:分而治之 循环、递归

函数自己调用自己的行为叫做递归,会产生死循环

递归可以实现分治算法,其实就是把一个大而复杂的问题,分解成若干个相同的小问题,解决小问题,直到全部问题解决

1、出口

2、分解成一个小问题

3、自己调用自己

斐波那契数列

1 0|1 1 2 3 5 8 13 21 ...

练习1:求前N项斐波那契数列

5

递归函数好处是容易理解,思路清晰

递归函数每次调用都会在栈内存产生一份自己的内存拷贝,直到到达出口,才会一层层地返回,因此递归非常地耗费内存资源,与循环相比,速度非常慢

递归的优缺点:

1、耗费内存、速度慢

2、好理解、思路清晰

3、能使用循环就用循环

C语言中进制转换与函数相关推荐

  1. python进制转换函数-Python中进制转换函数的使用

    Python中进制转换函数的使用 关于Python中几个进制转换的函数使用方法,做一个简单的使用方法的介绍,我们常用的进制转换函数常用的就是int()(其他进制转换到十进制).bin()(十进制转换到 ...

  2. c语言中10转8和16的转换,(C语言)10进制转换2,8,16进制

    (C语言)10进制转换2,8,16进制 作者:vinseven #include"stdio.h" #include"conio.h" #include&quo ...

  3. python进制转换#replace函数删除多余符号

    首先是在python中,将十进制转换为不同进制: print(bin(37)) #bin(n)是将十进制整数n转换为二进制 print(oct(37)) #oct(n)是将十进制整数n转换为八进制 p ...

  4. 【ZZULIOJ】1112: 进制转换(函数专题)

    ZZULIOJ题解 1112: 进制转换(函数专题) 题目描述 输入一个十进制整数n,输出对应的二进制整数.常用的转换方法为"除2取余,倒序排列".将一个十进制数除以2,得到余数和 ...

  5. 1112: 进制转换(函数专题)

    1112: 进制转换(函数专题) 时间限制: 1 Sec 内存限制: 128 MB 提交: 3448 解决: 2599 [提交] [状态] [讨论版] [命题人:admin] 题目描述 输入一个十进制 ...

  6. ZZULIOJ 1112: 进制转换(函数专题)

    进制转换(函数专题) 题目描述 输入一个十进制整数n,输出对应的二进制整数.常用的转换方法为"除2取余,倒序排列".将一个十进制数除以2,得到余数和商,将得到的商再除以2,依次类推 ...

  7. python中进制转换关系

    python中进制转换关系 标题整数之间的进制转换: hex(16) # 10进制转16进制 print(hex(16) ) >>'0x10' oct(8) # 10进制转8进制 prin ...

  8. 从0开始学习C语言————数组、进制转换、函数

    数组: 什么是数组: 变量的组合,是一种批量定义变量的方式 定义: 类型 数组名[数量]; int num1,num2,num3,num4,num5; int arr[5]; 使用:数组名[下标]; ...

  9. C语言笔记-进制转换

    一.进制转换     为什么要使用二进制.八进制.十进制.十六进制         因为现在的CPU只能识别高低电平,只能对二进制数据进行计算         虽然二进制的数据可以直接被CPU识别计算 ...

  10. 进制转换和函数的定义

    进制转换: ​ 为什么使用二进制.八进制.十六进制 ​ 因为现在的CPU只能识别高低两种电流,只能对二进制数据进行计算. ​ 二进制数据虽然可以直接被CPU计算识别,但是不方便书写.记录,把二进制数据 ...

最新文章

  1. 封装了一套WeCenter的IOS SDK
  2. ros安装orocos造成工作空间编译不通过
  3. Chapter 17 高级进程间通信
  4. angularjs 中的$digest和$apply区别
  5. 单片机指令周期、机器周期、状态周期、时钟周期
  6. android studio安装教程博客园独王,Android Studio安装与配置
  7. wpf 如何设置弹出窗口必须关闭才能打开其他软件_Mac忘记登录密码?以防万一,必须收藏。...
  8. C语言试题八十八之实现选冒泡排序算法
  9. 递归-计算字符串长度(代码、分析、汇编)
  10. 一道简单的编程题,不过您做对了吗?
  11. SQL Server:专业的DateTime范围
  12. 阿里云云原生一体化数仓入选 2022数博会“十佳大数据案例”
  13. 中兴软件测试过往面试题汇总
  14. java聊天室设计_JAVA网络聊天室的设计与实现
  15. One More Check: Making “Fake Background” Be Tracked Again
  16. VueSSR的一些理解和详细配置
  17. C++ SLT之map的用法总结
  18. devise 自定义手机号登录
  19. Android接收和发送短信
  20. UVM—virtual sequencer and virtual sequence详解

热门文章

  1. python网站上搜索答案_用python搭建百万赢家自动搜索答案
  2. system.gc()和system.runFinalization()区别作用
  3. 计算机与信息技术研究生,计算机与信息技术学院研究生必读经典文献.doc
  4. mysql 建表结构_MySQL学习系列之二——创建表及对表结构的基本操作
  5. C/C++遍历目录下的所有文件(Windows篇)
  6. centos8终端fish安装
  7. java君临天下单机游戏_君临天下java单机游戏
  8. 开源游戏java引擎_基于Java的开源3D游戏引擎jMonkeyEngine
  9. 【数据挖掘】基于密度的聚类方法 - OPTICS 方法 ( 算法流程 | 算法示例 )
  10. 谈谈可视化编程 (转)