逆向技能+1
2016-07-06 23:55
239 查看
下面是技能表:
android看完第一行代码后,有过一定基础了。
就从NDk开发开始学习。
因为NDk开发需要JNI 所以把c的基础又看了一遍。
C语法基础
HelloworldC的基本数据结构
输出函数
输入函数
内存地址的概念
指针
指针的联系
多级指针
指针和数组的关系
结构体
联合体 枚举 自定义类型
输出 helloworld
1.Target:pritnf–》 helloworld2.open the Calculator
include
main(){ //public static void main(String args[]){} printf("hello world!\n"); system("calc"); system("pause");//调用系统的命令 在这是调用windows的命令 }
C的基本数据类型
java的数据类型:四类八种 c的基本类型boolean 1
byte 1
char 2 char 1*
short 2 short 2
int 4 int 4
long 8 long 4*
float 4 float 4
double 8 double 8
c没用boolean 而是用0和非零表示 false 和 true
java一个byte是8位二进制数第一位是符号位 00010001
符号位为0 表示正数
符号位为1 表示负数
输出函数
c char
unsigned 只能用来修饰整形的变量 char short int long11111111 0~255
singed 最高位是符号位 可以表示负数,但是表示的最大值相对要小
//关键字:sizeof(类型名字) sizeof 变量名
//printf 需要一个占位符
main(){ //public static void main(String args[]){}
printf(“int4类型占%d个字节\n”,sizeof(int));
printf(“char2%d个字节\n”,sizeof(char));
printf(“float4%d个字节\n”,sizeof(float));
printf(“double8%d个字节\n”,sizeof(double));
printf(“lon8g%d个字节\n”,sizeof(long));
printf(“short4%d个字节\n”,sizeof(short));
unsigned char c1=255;
char c2=255;
printf(“c1=%d\n”,c1);
printf(“c2 = %d\n”,c2);
system(“pause”);//调用系统的命令 在这是调用windows的命令
}
占位符的选用
占位符要与输出的数据类型相匹配 不然会出现精度问题/*占位符
%d - int
%ld - long
%lld - long long
%hd - 短整型
%c –char
%f -float
%lf -double
%u -无符号位
%x -十六进制输出 int 或者long int 或者short int
%s -字符串
*/
//printf 需要一个占位符
main(){ //public static void main(String args[]){}
int a =10;
char b= ‘Z’;
long c=92890;
float f=1.34;
printf(“%d\n”,a);
printf(“%c\n”,b);
printf(“%ld\n”,c);
printf(“%.1f\n”,f);//控制输出小数的有效位数%.位数f/d
system(“pause”);//调用系统的命令 在这是调用windows的命令
}
数组的表示方法
main(){char array[]={‘a’,’b’,’c’,’\0’};//array位数数组需要手动添加结束符’\0’结束符也会占用一个字节
//array里面不能直接打印中文
char arraya[]=”abc啊啊啊”;
printf(“array为%s\n”,array);
printf(“arraya为%s\n”,arraya);
system(“pause”);//调用系统的命令 在这是调用windows的命令
}
输入函数
接受用户在控制台输入java 里面的system.in
c 里面获取用户输入的函数为scanf(“%d”,内存地址) &为取地址符 c里面取地址符不能越界 使用的时候请注意
//printf 需要一个占位符
main(){
printf(“请输入班级的人数\n”);
int count;
scanf(“%d”,&count);//&取地址符,通过&把count对应的内存地址取出来
printf(“班级的人数为:%d\n”,count);
char name[4];
printf(“count的内存的值为%d\n”,&count);
printf(“name的内存的值为%d\n”,&name);
printf(“请输入班的名字:\n”);
scanf(“%s”,&name);
printf(“班级的人数%d,和班级的名字%s\n”,count,name);
system(“pause”);//调用系统的命令 在这是调用windows的命令
}
内存地址的概念
计算机中一般习惯用16进制的整数表示内存地址当生命一个变量 就会为这个变量在内存中申请一块内存空间
这个内存一定对应着一个编号,也就是内存地址的内存是没办法使用的
内存与cpu的关系?
答:
32位操作系统 地址总线32位 2^32次方 最大支持4个g
*为什么买来的内存是16g,而实际却没有16g?
显卡等其他硬件会占用系统的内存编号资源,而且还有就是按1000计算
*内存地址有什么用?
玩RPG游戏时如仙剑三,用修改器修改地址
Cheat Engine显示正在运行的内存,
还有金山游侠等修改器。
指针
main(){int i=123;
printf(“i内存地址%#x \n”,&i);
//int*就是定义了类型的指针变量 用来保存int类型的变量的内存地址
//通过指针变量 可以和直接对内存地址保存的值 进行读写操作
//pointer pointer在等号右边 就是要读出它指向内存的值 *pointer在等号左边 就是要对它指向的内存的进行赋值的操作
int* pointer =&i;
printf(“pointer =%#x \n”,pointer);
//*pointer
printf(“*pointer==%d\n”,*pointer);
printf(“pointer =%#x \n”,&pointer);
system(“pause”);//调用系统的命令 在这是调用windows的命令
}
指针使用常见的错误
1.野指针,未初始化就直接通过指针进行赋值操作初始化 就是把自己程序中的变量的内存地址 赋值给指针
2.指针类型也要匹配
int类型的指针变量只能用来保存 int类型变量的内存地址
c语言交换两个值的实现
void swap(int *p1, int *p2){int tmp=*p1;
*p1=*p2;
*p2=tmp;
}
void main(){
int a=5;
int b=10;
//swap(i,j);引用传递
//值传递 传递的也是值,只不是传递的是变量的内存地址
swap(&a,&b);
printf(“%d\n”,a);
printf(“%d\n”,b);
}
C的优势是有指针 可以直接操作内存
在数据交换中有很大的优势
C中定义int 数组【】一定要在变量名之后
c语言看数组是否是连续的
//根据输出结果可得char的地址是连续的static char(){
char array[]={‘a’,’b’,’c’,’d’,’\0’};
printf(“array的地址%d\n”,&array[0]);
printf(“array的地址%d\n”,&array[1]);
printf(“array的地址%d\n”,&array[2]);
printf(“array的地址%d\n”,&array[3]);
}
//int类型的数组地址不是连续的
void main(){
int a[]={1,2,23,4,4};
printf(“array的地址%x\n”,&a[0]);
printf(“array的地址%x\n”,&a[1]);
printf(“array的地址%x\n”,&a[2]);
printf(“array的地址%x\n”,&a[3]);
printf(“array的地址%x\n”,&a);
}
指针类型要匹配数据类型
c中字符串和数组类似
char *str=”abcd”char array[]={‘a’,’b’,’c’,’d’,’\0’};
char *str=&array[];
多级指针
int i=23;//一级指针
int*p=&i;
//二级指针
int**p1=&p;
//不能这样定义二级指针
int*q=&p;
error:cannot convert int** to int *;
Main函数获取子函数的临时变量的地址
//这段程序的实质是把int变量i的地址给p1;void function(int** p){
int i=200;
*p=&i;
printf(“%d\n”,&i);
//打印变量i的地址
printf(“&i=%d\n”,p);
}
//多级指针
void main(){
int *p1;
function(&p1);
//打印p1指针的地址
printf(“p1=%d”,p1);
}
在java里面可以retrun出来,但是这样效率会低一些
指针类型变量的长度
指针类型的变量长度都是一致的void main(){
printf(“int*占%d个字节\n”,sizeof(int*));
printf(“double*占%d个字节\n”,sizeof(double*));
}
结果如下:
int*占4个字节
double*占4个字节
64位编译器为8个字节
静态内存分配和动态内存分配
静态内存分配:
系统统一分配 统一回收 占内存大小固定char * function
(){
char array[]={
‘a’,’b’,’c’,’d’};
//返回首地址
printf(“array的首地址%#x\n”,&array);
return &array[0];
}
char *function2(){
char array[]={‘d’,’b’,’c’,’a’};
printf(“%#x\n”,&array);
return &array[0];
}
void main(){
char*p=function();
//有返回值的函数不一定要写返回值;
function2();
printf(“%d,%d,%d\n”,p,(p+1),*(p+2));
printf(“%d,%d,%d\n”,p,(p+1),*(p+2));
}
定义一个方法会在栈内分配内存,使用完后会被回收。
动态内存分配:
include
include
结构体
大小:大于或者等于每一个元素大小的和 而且是最大的元素所占节数的整数倍//c中结构体不能直接定义函数
//要使用函数就用函数指针
函数指针 定义方式: 返回值(*函数指针名字)(形参){
函数指针指向的函数 要跟函数指针定义的返回值和形参类型保持一致
}
结构体的指针
/*struct 结构体
在java中相当于是class
*/
age=220; printf("%d",(*stup).age); //方法这里一直报错 //第一个错误是没有声明指针方法,第二个错误是没有加括号 stup->studyP(); }" data-snippet-id="ext.99d32e0e483e2424a2ff2d149caf36d1" data-snippet-saved="false" data-codota-status="done">[code]void study(){ printf("好好学习 天天向上"); } struct Student{ float score;//4 short age;//2 char sex;//1 //c中结构体不能直接定义函数 //要使用函数就用函数指针 //函数指针的定义方式:返回值()(形参) void (*studyP)(); } main(){ struct Student stu = {2.2f,22,'f',&study}; stu.age=20; //调用函数时编译器报错 stu.studyP(); printf("%d\n",stu.age); //看结构体的大小 printf("%d\n",sizeof stu); //采用结构体指针来调用结构体里面的方法和函数 /*通过结构体类型的定义 struct Student* A=结构体的地址 直接引用和间接引用 */ //直接引用 struct Student * stup =&stu; (*stup).age=110; printf("%d\n",(*stup).age); //间接引用 stup->age=220; printf("%d",(*stup).age); //方法这里一直报错 //第一个错误是没有声明指针方法,第二个错误是没有加括号 stup->studyP(); }
联合体
include
include
枚举
//声明枚举类 enum 定义枚举类 类型的取值范围只能从枚举值中取//typedef type define
enum WeekDay{
//设置a为1 则从一开始递增
a=1,b,c,d,e,f
};
main(){
//调用枚举类
enum WeekDay day1=a;
enum WeekDay day4=d;
printf(“%d\n”,day1);
printf(“%d\n”,day4);
}
(注意枚举类的声明形式)
自定义类型
在jni中 typedef void* jobject;给任意类型的指针void* 起别名为jobject
typedef jobject jclass;
typedef jobject jarray;
typedef jarray jobjectArray;
其实都是表示void* 实质上是为了增强代码的可读性表示在java那边处理的是那种的数据类型
c知识点复习完之后就可以做JNI了。
相关文章推荐
- SSL介绍与Java实例
- Java泛型解析
- Axis2基础入门
- Git使用教程
- 李洪强iOS开发之断点续传1
- 二维数组的列排序
- indy httpserver 接收URL包含中文参数乱码的问题
- Logcat 显示
- OpenCV坐标系与操作像素的四种方法
- Hibernate联合主键怎样在xml中配置
- Spring——AOP的相关通知及应用
- 创建httpd启动脚本并加入启动列表开机启动
- 计算机体系结构组成及软硬件工作原理
- Spring注解
- HDU-4651-Partition
- Windows驱动开发之获取系统时间
- 专题四 Problem S
- React Native指南汇集了各类react-native学习资源、开源App和组件
- protobuf vs java
- ubuntu-64bit中数据库MySql安装