系列文章目录
前言
一、变量的申明
告诉计算机,我要用一块内存
int a,b,c //全局变量的声明
void Fun()
{
a = 10; //局部变量的声明
b = 20;
}
总结:
声明就是告诉计算机,我要用一块内存,宽度和存储格式有数据类型决定
计算机给一块内存,取决于变量作用范围,全局变量在编译完就已经分配了内存空间,局部变量所在程序被调用才会分配空间
全局变量不定义值默认是0,但局部变量使用前一定赋初值
二、类型转换
从C语言角度来说,我们需要一个容器存储数据,我们认为一个char足够,我们不断往里面存值,发现不够了,得用另外一个内存来存
#inclde"stdafx.h"
void Fun()
{
char c = 10;
int i = c;
}
先看几行汇编
mov al,ff
movsx cx,al
mov al,80
movsx cx,al
这个是先符号扩展,再传送,ecx前面不变,就后面al变
mov al,ff
movzx cx,al
mov al,80
movzx cx,al
先零扩展,再传送,ecx前面都变成0了
扩展
#inclde"stdafx.h"
void Fun()
{
char i = 0xff;
short k = i;
int h = i;
}
反汇编
如图,是movsx的形式,是有符号的
如果是undesigned,就是无符号
第二个例子
#inclde"stdafx.h"
void Fun()
{
int ni = 0x12345678;
short si = ni;
char ci = ni;
}
如图,int是四个字节的,我们想看看能不能存储到更短的short,可以存进去,只是只能存储相对应位的低位,比如si上存5678,ci上就是78
如果两个不同类型的变量,结果是比较类型比较大的那个类型
反汇编代码如下
#inclde"stdafx.h"
void Fun()
{
char b = 1;
unsigned int a = 0xFFFFFFFE;
printf("%d",a+b)
}
结果是-1,这里提个疑问,为什么是这样?
反汇编:
正常编程没有人这样写。。。。不管是怎么输入的,计算机都是存储一样的码
这里是printf%d就已经告诉他,这是有符号的了。。。。。
三.语句and程序块
void Fun()
{
int i;
int k;
if(x>y)
i = 100;
k = 100;
}
只执行一句i =100
,k不归if语句管
四.参数及返回值的运用
比如写一个函数,进行任意两位数的加法
#inclde"stdafx.h"
void Fun(int x,int y)
{
int z = x + y;
}
程序执行需要用到外边的值,就需要参数
两个数的和存在Z里面,这个程序一旦执行完,Z是局部变量,这里的值就变成垃圾了
如果想使用这个值怎么办?
#inclde"stdafx.h"
void Fun(int x,int y)
{
int z = x + y;
return z;
}
int main(int argc,char* argv[])
{
int x = Fun(1,2);
return 0;
}
反汇编
这里0401041行命令就是return的功劳,如果没有return,就没有这一行04010141,这一行的作用就是已经把局部变量储存到eax了
在main里面执行printf("%d\n",x),发现可以执行
五.关系运算符
== != >= <= > <
#inclde"stdafx.h"
void Fun(int x,int y)
{
int z = x == y;
return z;
}
反汇编
xor ecx,ecx清空ecx里面的值
sete cl:上面cmp,如果两个值一样,cl值为1,不相等就不改,就是0,然后把0或1传入到Z里面
六.逻辑运算符
&&:并且
||:或者
!:非
void Fun(int x,int y)
{
if(x>1 && y>1 && z>1)
{
printf("OK");
}
else
{
printf("error");
}
}
反汇编
cmp比较ebp+8(第一个参数)与1谁打,如果小于等于1,就跳转了,跳到C9,然后就执行printf了,观察,都跳到C9那
void Fun(int x,int y)
{
if(x>1 || y>1 || z||1)
{
printf("OK");
}
else
{
printf("error");
}
}
反汇编
只要一个成立,就直接打印。到第三个,如果满足大于1,就不跳,如果不满足,就跳到另一个C9执行printf(“error”)
七.单目运算符
void Fun(int x,int y)
{
int i = 10;
++i;
printf("%d\n",i);
int x = 10;
x++;
printf("%d",x);
}
都打印出11
++i:++在前面是先加,再参与运算
i++:++在后面是先运算,再加
void Fun(int x,int y)
{
int i = 10;
int k = i++;
printf("%d %d\n",k,i);
}
打印出来都是1011
因为i++那一栏,是先把i的值给k,然后i再++
反汇编
第一个局部变量先给到eax,把eax里的值给第二个局部变量,然后把第一个局部变量给到ecx,然后ecx里的值加1
void Fun(int x,int y)
{
int i = 10;
int k = ++i;
printf("%d %d\n",k,i);
}
打印11 11
反汇编
先把值给eax,eax加1,再把eax给到局部变量里,然后又取出放到ecx,把这个ecx给第二个局部变量
八.三目运算符
void Fun(int x,int y)
{
int r = x>y?x:y;
printf("%D"\n,r);
}
int main()
{
Fun(1,2);
return 0;
}
如果x>y是真的,返回x的值,如果是假的,就返回y的值
和if语句一样,写代码方便
九.循环语句
void Function()
{
int i =0;
while(i<=100)
{
printf("%d\n",i);
++i
}
}
int main(int argc[],char*argv[])
{
Function();
return 0;
}
如图为while循环,当i加到101停止循环
void Function()
{
int i =0;
for(表达式1;i<=100;++i)
{
printf("OK")
}
}
执行顺序:
第一次执行:1 2(判断执行条件,判断for是否停下来)3 4
第二次执行:2(判断是真)4 3
第三次执行 :2(不执行) 从for循环退出
void Function()
{
int i =0;
for(int i =0;表达式2;表达式3)
{
代码4
}
}
例子:倒序输出数组
void Function2()
{
int arr[5] = {
2,6,1,8,4}
int n = 4;
while(n>=0)
{
printf("%d\n",arr[n]);
n--;
}
}
例子:找出最大值
```c
void Function2()
{
int arr[5] = {
2,6,1,8,4}
int r = arr[0];
while(i<=4)
{
if(arr[i]>r)
{
r = arr[i];
}
i++;
}
}