指针

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;
}	

以上是关于指针的主要内容,如果未能解决你的问题,请参考以下文章

片段中的空指针异常

活动到片段通信:当我尝试从活动更新片段中的文本视图时,出现空指针异常

使用回收器适配器获取空指针

片段 getArguments() 空指针异常

访问片段的子视图时出现空指针异常

空指针异常 - 片段活动