前言
这一讲的核心概念就是,类型随便转就行,C 语言就是用来玩的,带*类型可以相互转换!(强转)(逆向经常会用到)
课堂
类型转换
这个就像前言中所说的那样,除了一些特别离谱的类型转换不能强转,其他一般都是可以的,这里给个强转的代码例子,不能抱有强转是不对的这样的思想
#include "stdafx.h"
struct Student{
int x;
short y;
};
void Test(){
char* a; //声明
int* b;
short** c;
Student* s;
a = (char*)1; //赋值
b = (int*)2;
c = (short**)3;
s = (Student*)4;
a = (char*)b; //int*可以强转成char*
b = (int*)a; //char*可以强转成int*
c = (short**)a; //int*可以强转成short**
s = (Student*)b; //int*可以强转成Student*
//...
}
int main(int argc,char* argv[]){
Test();
return 0;
}
地址符&
&
是地址符,任何类型变量前面加上&
,就成了一个新的类型变量,类型是:&
后面的类型加上一个*
char a = 10;
short b = 20;
int c = 30;
int* d = (int*)40;
double**** e = (double****)50;
char* pa = &a; //a是char类型,在前面加上&,&a就变成了char*类型;此时pa中存的就是a变量的地址值
short* pb = &b; //b是short类型,在前面加上&,&b就变成了short*类型
int* pc = &c; //c是int类型,在前面加上&,&c就变成了int*类型;此时pc中存的就是c变量的内存地址值
int** pd = &d; //d是int*类型,在前面加上&,&d就变成了int**类型
double***** pe = &e; //e是double****类型,在前面加上&,&e就变成了double*****类型
其实本来完整的写法应该是:char* pa = (char*)&a
。但是我们知道了这是强转的意思,现在&a 本来就是char*
类型,编译器认得出来,所以不用再加这个强转,直接简写就可以
再来看看它的反汇编
所以&
就是将变量的地址取出来,光取出来没有意义,我们要把这个值赋给一个容器,用什么类型的容器存储呢?就是这个变量的数据类型加一个*
带*
类型变量前加*
-
类型:在带
*
类型的变量前面加*
,类型是其原来的类型减去一个*
-
作用:在带
*
类型的变量前加*
的作用:带*
类型的变量,可以通过在其变量前加*来获取其指向内存中存储的值
记住:只能在带*
类型的变量前面加*
,不能在一个普通类型的变量前面加*
,不然编译器会报错!
//定义并赋值4个带*类型的变量
int* pa = (int*)1;
char** pa2 = (char**)2;
int*** pa3 = (int***)3;
short**** pa4 = (short****)4;
//接着在这些带*类型变量前加*号:得到的新类型就是原来的类型减一个*
int newpa = *pa;
char* newpa2 = *pa2; //*pa2的值是一个char*类型的,所以现在把*pa2的值取出来赋给一个char*类型的变量 newpa2
int** newpa3 = *pa3;
short*** newpa4 = *pa4;
//不能在普通类型的变量前加*
//int a = 1; 不能出现*a
咱们来看一下*的反汇编
用*来操作数组
-
*(arr+i) = arr[i]
(arr 是数组名) -
arr = &arr[0]
数组名其实就是一个地址,然后就正常操作就行
char arr[5] = {1,2,3,4,5};
char* pa = &arr[0]; //获取arr数组的首地址,也就是arr数组中第一个元素的首地址,这个值的类型为char*
char* pa2 = arr; //可以直接简写为arr,同样也是获取arr数组第一个元素的首地址
然后刚刚在上面说了带星号类型可以进行的运算,现在把它们结合一下,那就可以用这个指针去 1 操作数组里面的数据了
int arr[5] = {1,2,3,4,5};
int n0 = *arr; //arr表示数组第一个元素地址值,那么加一个*号就表示取这个地址中存的值,即数组中第一 个元素的值1
int n1 = *(arr + 1); //2 这里其实就是取数组首地址+1*4,取这个新地址中存的数,类型为int*减一个 *,即int类型。即第二个元素的值
int n2 = *(arr + 2); //3 首地址+2*4,取这个地址中存的值,即第三个元素的值
int n3 = *(arr + 3); //4
int n4 = *(arr + 4); //5
//使用for循环加*号的方式遍历数组中的元素
for(int i = 0;i < 5;i++){
printf("%d ",*(arr + i));
}
作业
1.前面两个的答案在图片已经给出
2.这里给出我的代码
void reverse_arry()
{
int arry[5] = {1,2,3,4,5};
int* p = arry;
int i = 0;
for(i ;i < 5/2;i++){
int a = 4 - i;
int temp = 0;
temp = *(p + i);
*(p + i) = *(p + a);
*(p + a) = temp;
}
for(i = 0;i < 5;i++){
printf("%d ",arry[i]);
}
}