C09-跳转表函数调用

gets与scanf

scanf遇到 \0 空格都会中断读取
gets可以任意输入,直到遇到回车 所以要保证buff足够大

int main()
{
 char arry[10] = {};
 scanf("%s", arry);
 printf("%s", arry);
 return 0;
}

在这里插入图片描述

int main()
{
 char arry[100] = {};
 gets(arry);
 printf("%s", arry);
 return 0;
}

在这里插入图片描述

gets与gets_s是一样的

cmd文件及其bat

就是批处理文件
也就是脚本

del *.db \f \s
*是表示所有
.db是表示db后缀
\f \s 删掉文件不删除文件夹

switch…case跳转表

switch为什么只能是int char

查看汇编
调试状态下按下 alt+8
带j 全是jump跳
switch 汇编语言中有一行代码

 jmp dword ptr [ecx*4+413E64h]  
```c
将不重要的内容去掉,可以精简为:
```c
jmp [ecx*4+413E64h]  

jmp 直接接上表达式(没有中括号)
jmp 0x0040000000 表示直接跳转到0x00400000
有中括号
jmp [0x004000000] 取出0x00400000地址处所存的数据(A),并且将他(A)作为地址,跳转到该(A)地址处。

  • 那么ecx到底代表着什么
    事实上,0x413E64h 是编译器所做的“跳转表”的一个首地址,该跳转表中由若干个元素
    每个元素都是一个地址(4个字节)对应了各个case

ecx其实就是下标作用

随机地址的设置

工程里面属性中的链接器中的高级里面 将随机基地址改成否定
设置完后可以发现反汇编窗口代码所处地址均为 0x004xxxx;

VS中内存表示

0x4 表示是全局区(放字符串,放代码)
0x19xxx 0x18xxx表示是栈区(局部变量,参数)

函数

函数肩负着模块化的重任
C程序由众多的函数实现的

语法层次复习

函数的声明

<返回类型><函数名>(参数1,参数2);
int MyFun(double arg1,double arg2);

把函数声明,称为函数原型(prototype)

函数的实现

<返回类型><函数名称>(参数 1,参数 2{
实现的内容
}

比如

int MyFun(double x,double y)
{
return x+y;
}

函数的调用

只需要调用方 的函数名及传入的参数

MyFun(1,2);

可以将函数返回值存储到另外的变量中 去使用它

函数之间的配合

函数的入口是参数,出口是返回值,函数之间通过传送参数,接受返回参数进行配合
函数调用会产生流程转移:A函数跳到B函数;
return也会造成流程转移:从前的B函数

强调一下return:

  • 结束当前函数调用,返回上一层函数
  • 如果函数返回值不是void,那么return还可以带出一个复合型变量

变参函数

void MyValFun(int argc,...)  //点点表示 变参函数  就是参数可变,不能确定多少个参数
{
printf("%d",argc);
}
int main()
{
MyValFun(1,2,3,4,41,35,1);
MyValFun(12,123,1234,3,1244,234,88);
return 0;
}
  • 参数在函数的栈区
  • 所以,一个函数的所有变量,都在栈区并且相连

思考题

函数声明与函数实现,函数调用的关系
在调用函数之前,是否一定需要函数声明
答 不用 只要函数在调用方前面就可以

要调用某函数,被调用函数可否只有函数实现,没有函数声明?
答 可以

是不是所有的情况下,有了函数实现,都不需要函数声明,就可以调用该函数
不是,是指函数实现 在调用函数 的前面
以下不可调用

int main()
{
MyFun();
return 0;
}
void MyFun()
{
printf("hello");
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值