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");
}