字符数组与字符串12345678910int main(int argc, char* argv[]){ char arr[6] = {'A','B','C','D','E','F'}; char names[] = "ABCDE"; getchar(); return 0;}
编译器在字符串的结尾添加\0作为结束标记
常见字符串操作1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768// Test.cpp : Defines the entry point for the console application.//#include "stdafx.h"//返回字符的长度int s ...
类型转化基本类型之间可以相互转换,结构体不可以和基本类型之间转换
&符号可以放到任何变量前面获取变量的地址,被称为取地址符,假设 char a变量,&a的类型就是char + *也就是char*类型
12345678910111213141516171819202122232425#include "stdafx.h"struct st{ int age; int name;};void fun(){ char x =10; char* y=&x;}int main(int argc, char* argv[]){ fun(); getchar(); return 0;}
求值*跟变量名那么这个变量本身必须是指针类型,*和&相反,星号作用是去掉一个星号
&取地址,*取值
123456789101112131415161718#include "stdafx.h"int main(int argc, char* argv[]){ in ...
声明与赋值指针也是一种数据类型,在任何基本数据类型后面加一个或多个*号,一个星号与多个星号是完全不同的概念
123456789101112131415161718#include "stdafx.h"void fun(){ char x =(char)1;//完整赋值语句 short y =(short)2; int z =(int)3;}int main(int argc, char* argv[]){ fun(); getchar(); return 0;}
宽度带星号的类型只能使用完整写法赋值,32位操作系统指针大小多数为四个字节,这并不是统一的,不同的操作系统或硬件平台可能会有不同的指针大小,指针指向的数据多大需要分析
1234567891011121314151617181920212223242526#include "stdafx.h"struct AA{ int a; int b; int c;};void fun(){ char* x =(char*)1; ...
switch1、switch表达式里面的结果必须是整数
2、同一个switch语句的case后面的常量表达式不能出现相同结果
12345678910111213141516171819202122232425262728#include "stdafx.h"int main(int argc, char* argv[]){ int x=1; switch(x) { case 1: printf("1"); break; case 2: printf("2"); break; case 3: printf("3"); break; default: printf("default"); break; } getchar(); return 0;}
反汇编大表1、分支少的时候(根据编译器自己的算法来)使用switch没有意义,编译器在这时候生成的汇编代码与if没有显著区别
2、case后跟的常量可以是无需的,不影响大表生成
那么 ...
sizeofC语言关键字,用于获取某个类型的大小,如果想获取数组元素个数需要用大小除以单个元素的宽度
int基本类型1234567891011121314#include "stdafx.h"int main(int argc, char* argv[]){ int a = 100; printf("The int para is %d",sizeof(a)); getchar(); return 0;}
整数类型数组12345678910111213141516171819#include "stdafx.h"int main(int argc, char* argv[]){ char arr1[10]={0}; short arr2[10]={0}; int arr3[10]={0}; printf("%d\n",sizeof(arr1[0])); printf("%d\n",sizeof ...
定义找到具体的机构体对象以后
偏移:加偏移可以访问结构体的属性,二级偏移就是结构体里面的结构体
基址:全局变量
12345678910111213141516171819202122232425#include "stdafx.h"struct AA//声明一个新的结构体类型AA,声明类型不会分配空间 { char x; int y; float a; int arr[2]; };int a;//全局变量,程序编译成exe的时候就分配好了内存空间void fun(){ AA xiu={'a',6,3.14,{0,1}};//声明一个AA类型的变量xiu并且为变量初始化值,在这一步才会分配空间 }int main(int argc, char* argv[]){ fun(); return 0;}
使用连续等宽很可能是数组
连续不等宽很可能是结构体
打印结构体属性1234567891011121314151617181920212223 ...
缓冲区溢出123456789101112131415161718192021222324#include "stdafx.h"void p(){ printf("hello world"); getchar();}void fun(){ int arr[5]={1,2,5,3,2};//数组长度为5,最大下标为4 arr[5]=0x12345678;//数组下标越界,强制赋予值 }int main(int argc, char* argv[]){ fun(); return 0;}
1234567891011121314151617181920212223#include "stdafx.h"void p(){ printf("hello world"); getchar();}void fun(){ int arr[5]={1,2,5,3,2}; arr[6]=(int) ...
二进制
未读返回值123456789101112131415#include "stdafx.h"char fun(){ char x=3; return x;}int main(int argc, char* argv[]){ int y=fun(); return 0;}
123456789101112131415#include "stdafx.h"__int64 fun(){ __int64 x=3; return x;}int main(int argc, char* argv[]){ __int64 y=fun(); return 0;}
局部变量函数调用的时候编译器会提升堆栈分配新的内存空间,栈顶ESP提升的空间就被称为缓冲区,不同的编译器会分配不同的默认空间
参数在函数调用前就已经分配了内存空间,局部变量只有当函数调用后才会分配空间
参数参数传递本质就是将上层函数的变量或者表达式的值复制一份传给下层函数
12345678910111213141516#i ...
循环do..while性能比其他循环好,缺点就是无论条件如何都会运行一次代码,三个循环实现的功能一样
12345678910111213141516171819#include "stdafx.h"void add(){ int i =0; do{ printf("%d\n",i); i++; }while(i<=100); }int main(int argc, char* argv[]){ add(); return 0;}
1234567891011121314151617181920212223242526272829303132333435360040B7B0 push ebp0040B7B1 mov ebp,esp0040B7B3 sub esp,44h0040B7B6 push ebx0040B7B7 push esi0040B7B8 push e ...
指令扩展movsx用于有符号数的类型转换
可以将大小不同的寄存器al的值传给cx,高位根据al的符号位是1,就全补1,是0就全补0
movsx cx,al
movzx用于无符号数的类型转换
可以将大小不同的寄存器al的值传给cx,高位直接补0
movzx cx,al
sete如果上一条表达式的判断结果为相等,会把cl设置为1,否则就不变,使用之前一般会把ecx整个寄存器异或自己置为0
sete cl
类型转换注意有符号数与无符号数的区别,使用的汇编指令不同
低宽度转高宽度12345678910111213141516#include "stdafx.h"void add(){ char x=0xf0; int y=x; }int main(int argc, char* argv[]){ add(); return 0;}
高宽度转低宽度直接截取低宽度相应大小的低位数据,高位数据会被丢弃
表达式1、只有一个结果
2、通常与流程控制语句或者赋值语句一起出现
3、当表达式存在不同宽度的变量时,结果将转换为宽度最大的那个
语句与 ...