指针
Posted lnterpreter
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了指针相关的知识,希望对你有一定的参考价值。
一、宽度
- 正常类型的宽度
点击查看代码
#include "stdafx.h"
void test()
{
char x;
short y;
int z;
x = 1;
y = 2;
z = 3;
}
int main(int argc, char* argv[])
{
test();
getchar();
return 0;
}
- 带类型的变量宽度永远是4字节、无论类型是什么,无论有几个.
点击查看代码
#include "stdafx.h"
void test()
{
char* x;
short* y;
int* z;
x = (char*)1;
y = (short*)2;
z = (int*)3;
}
int main(int argc, char* argv[])
{
test();
getchar();
return 0;
}
二、运算(只能做加减运算,+或者-得到的结果类型还是原来的类型)
- 运算时,先去掉一个,然后再加上去掉一个之后的宽度
#include "stdafx.h"
void test()
{
char* a ;
short* b ;
int* c ;
a = (char*)100;
b = (short*)100;
c = (int*)100;
a++;
b++;
c++;
//结果是101,102,104
printf("%d %d %d",a,b,c);
}
int main(int argc, char* argv[])
{
test();
getchar();
return 0;
}
#include "stdafx.h"
void test()
{
char** a ;
short** b ;
int** c ;
a = (char**)100;
b = (short**)100;
c = (int**)100;
a++;
b++;
c++;
//结果是104,104,104
printf("%d %d %d",a,b,c);
}
int main(int argc, char* argv[])
{
test();
getchar();
return 0;
}
三、同类型的加减(得到的结果是int型)
#include "stdafx.h"
void test()
{
short** a ;
short** b ;
a = (short**)200;
b = (short**)100;
int c = a - b;
//结果是25, 先是200-100=100,然后100/4(short*的宽度是4)
printf("%d",c);
}
int main(int argc, char* argv[])
{
test();
getchar();
return 0;
}
四、类型转换
#include "stdafx.h"
void test()
{
char* x;
int* y;
x = (char*)10;
y = (int*)x;
printf("%d",y);
}
int main(int argc, char* argv[])
{
test();
getchar();
return 0;
}
五、&
- &是地址符,类型是其后面的类型加一个“*”,任何变量都可以使用&来获取地址,但不能用在常量上。
#include "stdafx.h"
void test()
{
char a = 10;
int pa = &a;
// char* pa = &a;
}
int main(int argc, char* argv[])
{
test();
getchar();
return 0;
}
- 从汇编角度看
#include "stdafx.h"
void test()
{
char a = 10;
char* pa = &a;
}
int main(int argc, char* argv[])
{
test();
getchar();
return 0;
}
六、*
- 带类型的变量,可以通过在其变量前加来获取其指向内存中存储的值
- 在带类型的变量前面加,类型是其原来的类型减去一个*
#include "stdafx.h"
void test()
{
int a = 10;
int* pa = &a;
int a1 = *pa;
printf("%d",a1);
}
int main(int argc, char* argv[])
{
test();
getchar();
return 0;
}
七、遍历数组
#include "stdafx.h"
void test()
{
char arr[5] = {1,2,3,4,5};
char* px = arr;
for(int i=0;i<5;i++)
{
printf("%d\\n",*(px+i));
}
}
int main(int argc, char* argv[])
{
test();
getchar();
return 0;
}
八、学习ce搜索
#include "stdafx.h"
char data[100] = {
0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x07,0x09,
0x00,0x20,0x10,0x03,0x03,0x0C,0x00,0x00,0x44,0x00,
0x00,0x33,0x00,0x47,0x0C,0x0E,0x00,0x0D,0x00,0x11,
0x00,0x00,0x00,0x02,0x64,0x00,0x00,0x00,0xAA,0x00,
0x00,0x00,0x64,0x10,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x02,0x00,0x74,0x0F,0x41,0x00,0x00,0x00,
0x01,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x0A,0x00,
0x00,0x02,0x74,0x0F,0x41,0x00,0x06,0x08,0x00,0x00,
0x00,0x00,0x00,0x64,0x00,0x0F,0x00,0x00,0x0D,0x00,
0x00,0x00,0x23,0x00,0x00,0x64,0x00,0x00,0x64,0x00
};
void test()
{
int* p;
char* n;
p = (int*)data;
n = data;
for(int i=0;i<97;i++)
{
if(*(int*)(n+i) == 0x64)
{
printf("%x\\n",(int*)(n+i));
printf("%x\\n",*(int*)(n+i));
}
}
}
int main(int argc, char* argv[])
{
test();
getchar();
return 0;
}
九、字符数组
#include "stdafx.h"
char arr[6] = {\'A\',\'B\',\'C\',\'D\',\'E\',\'F\'};
int main(int argc, char* argv[])
{
char arr[6] = {\'A\',\'B\',\'C\',\'D\',\'E\',\'F\'};
getchar();
return 0;
}
十、字符串
#include "stdafx.h"
char arr[6] = {\'A\',\'B\',\'C\',\'D\',\'E\',\'F\'};
int main(int argc, char* argv[])
{
char names[] = "ABCDE";
getchar();
return 0;
}
十一、常量区
1、char* x = "china"
#include "stdafx.h"
char* x = "china";
void test()
{
//x存的是常量区的地址,常量区只允许读
*(x+1) = \'A\';
}
int main(int argc, char* argv[])
{
test();
getchar();
return 0;
}
2、char y[] = "china"
#include "stdafx.h"
void test()
{
char y[] = "china";
}
int main(int argc, char* argv[])
{
test();
getchar();
return 0;
}
十二、返回字符串长度
#include "stdafx.h"
int strlen(char* s)
{
int length = 0;
while(*s != 0)
{
s++;
length++;
}
return length;
}
int main(int argc, char* argv[])
{
char x[] = "abcde";
printf("%d",strlen(x));
getchar();
return 0;
}
十三、复制字符串src到dest中。返回指针为dest的值
#include "stdafx.h"
char* strcpy(char* dest, char* src)
{
char* ret = dest;
while(*src != 0)
{
*dest = *src;
dest++;
src++;
}
return ret;
}
int main(int argc, char* argv[])
{
char x[] = "abcde";
char y[] = "xyz";
printf("%x\\n",strcpy(x,y));
printf("%s\\n",strcpy(x,y));
getchar();
return 0;
}
十四、将字符串src添加到dest尾部。返回指针为dest的值
#include "stdafx.h"
void strcpy(char* dest, char* src)
{
char* ret = dest;
while(*src != 0)
{
*dest = *src;
dest++;
src++;
}
*dest = *src;
}
char* strcat(char* dest, char* src)
{
char* ret = dest;
while(*dest != 0)
{
dest++;
}
//while((*dest++) = (*src++))可以替代strcpy函数
//while((*dest++) = (*src++));
strcpy(dest,src);
return ret;
}
int main(int argc, char* argv[])
{
char x[] = "abcde";
char y[] = "xyz";
printf("%s\\n",strcat(x,y));
getchar();
return 0;
}
十五、一样返回0 不一样返回1
#include "stdafx.h"
int strcmp(char* s1, char* s2)
{
while(*s1 == *s2)
{
if(*s1 == \'\\0\')
{
return 0;//相等
}
s1++;
s2++;
}
return 1;
}
int main(int argc, char* argv[])
{
char x[] = "abcde";
char y[] = "abcde";
printf("%d\\n",strcmp(x,y));
getchar();
return 0;
}
十六、模拟实现CE的数据搜索功能
#include "stdafx.h"
char data[100] = {
0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x07,0x09,
0x00,0x20,0x10,0x03,0x03,0x0C,0x00,0x00,0x44,0x00,
0x00,0x33,0x00,0x47,0x0C,0x0E,0x00,0x0D,0x00,0x11,
0x00,0x00,0x00,0x02,0x64,0x00,0x00,0x00,0xAA,0x00,
0x00,0x00,0x64,0x10,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x02,0x00,0x74,0x0F,0x41,0x00,0x00,0x00,
0x01,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x0A,0x00,
0x00,0x02,0x57,0x4F,0x57,0x00,0x06,0x08,0x00,0x00,
0x00,0x00,0x00,0x64,0x00,0x0F,0x00,0x00,0x0D,0x00,
0x00,0x00,0x23,0x00,0x00,0x64,0x00,0x00,0x64,0x00
};
int strcmp(char* s1, char* s2)
{
while(*s1 == *s2)
{
if(*s1 == \'\\0\')
{
return 0;//相等
}
s1++;
s2++;
}
return 1;
}
int strlen(char* s)
{
int length = 0;
while(*s != 0)
{
s++;
length++;
}
return length;
}
char* FindRoleNameAddr(char* pData,char* pRoleName)
{
int length = strlen(pRoleName);
int all = sizeof(data)/sizeof(pData[0]);
int i=0;
while(i < all -length)
{
if(!strcmp(&pData[i],pRoleName))
{
return &pData[i];
}
i++;
}
return NULL;
}
int main(int argc, char* argv[])
{
char *result = FindRoleNameAddr(data,"WOW");
if(result != NULL)
{
printf("%p\\n", result);
printf("%s\\n", result);
}
else
{
printf("not found\\n");
}
getchar();
return 0;
}
十七、指针数组
1、声明
//占20个字节
char* arr[5] = {0};
2、赋值
char* arr[5] = {0};
arr[0] = (char*)1;
arr[1] = (char*)2;
arr[2] = (char*)3;
arr[3] = (char*)4;
arr[4] = (char*)5;
或者
char a1 = \'A\';
char a2 = \'B\';
char a3 = \'C\';
char a4 = \'D\';
char a5 = \'E\';
char* p1 = &a1;
char* p2 = &a2;
char* p3 = &a3;
char* p4 = &a4;
char* p5 = &a5;
char* arr[5] = {p1,p2,p3,p4,p5};
3、最常用的指针数组:
#include "stdafx.h"
int main(int argc, char* argv[])
{
char* p1 = "if";
char* p2 = "for";
char* p3 = "while";
char* p4 = "switch";
char* keyword[] = {p1,p2,p3,p4};
getchar();
return 0;
}
或者
char* keyword[] =
{
if,
for,
while,
switch
};
4、遇到的坑
//此时打印出错,原因是px1存储的是常量china的地址,打印地址一个字节,编译器不知道打印什么所以会出错,想要打印正确用%s或者*px1
#include "stdafx.h"
int main(int argc, char* argv[])
{
char* px1 = "china";
printf("%c\\n",px1);
getchar();
return 0;
}
十八、结构体指针
#include "stdafx.h"
struct Test
{
int a ;
int b ;
char c ;
};
int main(int argc, char* argv[])
{
Test s;
s.a = 10;
s.b = 20;
s.c = 30;
Test* px = &s;
printf("%d %d %d",px->a,px->b,px->c);
getchar();
return 0;
}
十九、*()与[]的互换表示
char* p1;
char** p2;
char*** p3;
char**** p4;
char***** p5;
char****** p6;
char******* p7;
//反汇编 了解*的反汇编
printf("%d\\n",*p1);
//反汇编:*p1 = *(p1+0)
printf("%d\\n",*(p1+0));
//反汇编:*(p1+0) = p1[0]
printf("%d %d\\n",*(p1+0),p1[0]);
printf("%d %d\\n",*(p1+2),p1[2]);
//反汇编:了解**的反汇编
//
printf("%d\\n",*p2);
printf("%d\\n",*(*p2));
printf("%d %d\\n",*(*(p2+0)),*(*(p2+0)+0));
printf("%d\\n",*(*(p2+1)));
printf("%d\\n",*(*(p2+1)+1));
printf("%d\\n",*(*(p2+2)+3));
printf("%d %d\\n",*(*(p2+0)+0),p2[0][0]);
//反汇编 了解***的反汇编
printf("%d\\n",*p3);
printf("%d\\n",*(*p3));
printf("%d\\n",*(*(*p3)));
printf("%d %d\\n",*(*(*p3)),*(*(*(p3+0)+0)+0));
printf("%d\\n",*(*(*(p3+1)+2)+3));
printf("%d %d\\n",*(*(*(p3+1)+2)+3),p3[1][2][3]);
二十、数组指针
#include "stdafx.h"
int main(int argc, char* argv[])
{
int arr[5] = {1,2,3,4,5};
//--取数组第一个数的地址,结果是int*类型
int* px = arr;
//--取数组的首地址,结果是int (*px)[5]类型
int (*px1)[5];
px1 = (int (*)[5])arr;
//探测++
printf("%d %d\\n",px,px1);
px++;
px1++;
printf("%d %d\\n",px,px1);//int (*)[5]的宽度:int宽度*5 = 20
getchar();
return 0;
}
#include "stdafx.h"
int main(int argc, char* argv[])
{
int arr[5] = {1,2,3,4,5};
//--取数组第一个数的地址,结果是int*类型
int* px = arr;
//--取数组的首地址,结果是int (*px)[5]类型
int (*px1)[5];
px1 = (int (*)[5])arr;
//px[0] = *(px+0) px为int*类型,*(px+0)为int类型
printf("%d %d\\n",px[0],px1[0][0]);
//px1[0][0] = *(*(px1+0)+0) px1为int (*)[5]类型,*(px1+0)为int [5]类型,*(*(px1+0)+0)为int类型
printf("%d %d\\n",px[0],px1[0][0]);
getchar();
return 0;
}
二十一、函数指针
1、函数指针的声明
返回类型(*函数名)(参数表)
如:int (*pFun)(int,int);
2、赋值
pFun = (int (*)(int,int))10;
pFun = 函数名(可以配合硬编码来运行)
#include "stdafx.h"
int test(int x,int y)
{
return x+y;
}
int main(int argc, char* argv[])
{
int (*pFun)(int,int);
pFun = test;
int x = pFun(1,2);
printf("%d",x);
getchar();
return 0;
}
3、配合硬编码使用
#include "stdafx.h"
unsigned char code[] =
{
0x55,
0x8B, 0xEC,
0x83, 0xEC, 0x40,
0x53,
0x56,
0x57,
0x8D, 0x7D, 0xC0,
0xB9, 0x10, 0x00, 0x00, 0x00,
0xB8, 0xCC, 0xCC, 0xCC, 0xCC,
0xF3, 0xAB,
0x8B, 0x45, 0x08,
0x03, 0x45, 0x0C,
0x5F,
0x5E,
0x5B,
0x8B, 0xE5,
0x5D,
0xC3
};
int main(int argc, char* argv[])
{
typedef int (*Fun)(int,int);
Fun p = (int (*)(int,int))&code;
int x = p(2,2);
printf("%d\\n",x);
getchar();
return 0;
}
二十二、习题
习题
- 数组大小
#include "stdafx.h"
void test()
{
char** arr[10];
}
int main(int argc, char* argv[])
{
test();
getchar();
return 0;
}
- Student****
#include "stdafx.h"
struct Student
{
int x;
int y;
};
void test()
{
Student**** s;
s = (Student****)100;
/*
s++; //s的值是多少? 104
s = s+2; //s的值是多少? 108
s = s-3; //s的值是多少? 88
*/
}
int main(int argc, char* argv[])
{
test();
getchar();
return 0;
}
- Student*
#include "stdafx.h"
struct Student
{
int x;
int y;
};
void test()
{
Student* s;
s = (Student*)100;
/*
s++; //s的值是多少? 108
s = s+2; //s的值是多少? 116
s = s-3; //s的值是多少? 76
*/
}
int main(int argc, char* argv[])
{
test();
getchar();
return 0;
}
- Student*
#include "stdafx.h"
struct Student
{
int x;
int y;
};
void test()
{
Student* s1;
Student* s2;
int x;
s1 = (Student*)200;
s2 = (Student*)100;
x = s1-s2; //x的值是多少?
printf("%d",x)
}
int main(int argc, char* argv[])
{
test();
getchar();
return 0;
}
以上是关于指针的主要内容,如果未能解决你的问题,请参考以下文章