当采用__T

它会变成如下

修改成_T,进行宏替换,实际上解决了宏嵌套的问题。关于宏转换规则的问题。

实际上第二次才转换到了如下

指针
#include "stdafx.h"
#include <iostream>
#include <stdio.h>
using namespace std;
void exchange(int n, int m)
{
int temp = n;
n = m;
m = temp;
}
int main(int argc)
{
int a = 8;
int *pa = NULL;
pa = &a;
*pa = 999;
system("pause");
return 0;
}
如上有一段示例代码,我们单步看看
int a = 8;
令19ff2c为int的8

int *pa = NULL;
定义一个指针就在19ff2c旁边,也就是19ff28的位置。初始值为00 00 00 00。 定义的时候限制了指向的位置 等会的解释类型。

pa = &a;
让pa指向a的地址。这里有个取地址符,实际上就是把a的地址,也就是19ff2c,给到了pa的19ff28。

*pa = 999;
间接访问,和去内容是一件事。
定位刚刚19ff28的位置,因为有*,又要再一次解析,解析到19ff2c的位置。然后用刚刚的解释类型把999变成int,存进19ff2c的位置。

不管留多少空,*往右靠近,也就是,只定义一个int型指针pa和一个int数据pb

type *ptr = ...;
int n = ...;
ptr +n = (int)ptr + sizeof(type)*n //运算结果为同类指针的常量
= (type *const)((int)ptr + sizeof(type)*n)
数组名是数组第0个元素的指针常量
type ary[M] = ...;
ptr = ary;
ptr[n] = *(type *const)((int)ptr + sizeof(type)*n) //多个取下标,也就是多个读内容
ary[n] = *(type *const)((int)ary + sizeof(type)*n) //其实就变个 ary
红框内生成的汇编代码会多一些,因为实际上是先取指针指向的地址,再做下标运算,而下面的是直接进行下标运算。(两个是一样的)


条数如下

(未被优化版本)
强类型检查 不同类型指针之间不可以相互赋值。

第一个语句 是对同一地址更换解释方式,是告诉编译器flt的这个地址我要把它当作整型地址了,然后把他取出来,就是4048f5c3
而第二个只是数值进行转换 输出3


空类型指针只做函数地址传递。只有箭头指的可以运行。

ctf里面也很常见,对整个数据块进行复制,比较,等等。一般接受三个参数,目标指针 源指针 大小

返回来的是目标的地址
可以看到这里就是void指针 就是上面那个知识点的用处
这个其实是不实际改变内容的,因为没有间接访问,所以没有影响到实参

如下就可以


老生常谈的指针常量常量指针的东西了

所指向的内容是一个常量
const int *
int const *是一样的。只要const在 *左边
如图这样*pn1 = 888 是没有办法过的
如果是如下,那么这个常量只能指向null了,不能改变。

一段简单代码
#include "stdafx.h"
#include <iostream>
#include <stdio.h>
using namespace std;
void exchange(int n, int m)
{
int temp = n;
n = m;
m = temp;
}
int main(int argc)
{
char szTest[] = "Hello";
char *pszTest = "Hello";
szTest[0] = 'h';
pszTest[0] = 'h';
puts(szTest);
puts(pszTest);
system("pause");
return 0;
}
这个里面能过编译,但是运行会访问错误
因为szTest[] = “Hello”这个里面是写在栈里面,可以修改的状态,但是*pszTest = “Hello”,其实是指向一个常量字符串,在不可以写入的data区里面,所以pszTest[0] = ‘h’;也是不行的。会直接C05
一个方法

这个位置的值 1f0下面,根据wres 写入 读取 执行 分享
写成1100 也就是C0,这样就可以写入了