滴水逆向三期笔记与作业——02C语言——11 指针(1)

接着水。

一、指针的宽度

1.1 基础类型宽度

void Function()
{
	char x;
	short y;
	int z;
	 
	x = (char)1;
	y = (short)2;
	z = (int)3;
}
int main(int argc, char* argv[]){
	Function();
    return 0;
}

在这里插入图片描述

char类型1字节
short类型2字节
int类型4字节

1.2 一级指针宽度

void Function()
{
	char* x;
	short* y;
	int* z;
	 
	x = (char*)1;
	y = (short*)2;
	z = (int*)3;
}
int main(int argc, char* argv[]){
	Function();
    return 0;
}

在这里插入图片描述

一级指针全都为8字节长度(系统位长),即64位系统8字节长度,32位系统4字节长度

1.3 二级指针宽度

void Function()
{
	char** x;
	short** y;
	int** z;
	 
	x = (char**)1;
	y = (short**)2;
	z = (int**)3;
}
int main(int argc, char* argv[]){
	Function();
    return 0;
}

在这里插入图片描述

二级指针也为操作系统位宽

1.4 四级指针宽度

void Function()
{
	char**** x;
	short**** y;
	int**** z;
	 
	x = (char****)1;
	y = (short****)2;
	z = (int****)3;
}
int main(int argc, char* argv[]){
	Function();
    return 0;
}

在这里插入图片描述

四级指针也为操作系统位宽

1.5 总结

带*类型的变量赋值时只能使用“完整写法”
带*类型的变量宽度永远是8字节(x64)/ 4字节(x86)、无论类型是什么,无论有几个*

二、指针声明

指针声明的推荐方式与不推荐方式

推荐方式不推荐方式
char* x;char *x;
short* y;short *y
int* z;int *z
float* f;float *f
double* d;double *d
Student* st;Student *st

三、指针赋值

char* x;
short* y;
int* z;
 
x = (char*)1;
y = (short*)2;
z = (int*)3;	
/**************************************/
char** x;
short** y;
int** z;
 
x = (char**)1;
y = (short**)2;
z = (int**)3;	
/**************************************/
char***** x;
short***** y;
int***** z;
 
x = (char*****)1;
y = (short*****)2;
z = (int*****)3;	
/**************************************/
char********** x;
short********** y;
int********** z;
 
x = (char**********)1;
y = (short**********)2;
z = (int**********)3;

四、指针的运算

4.1 ++或–运算

char a ;
short b ;
int c ;
 
a = 100;
b = 100;
c = 100;
 
a++;
b++;
c++;
 
printf("%d %d %d",a,b,c);	//输出:101 101 101

/**********************************************************************************/

char* a ;
short* b ;
int* c ;
 
a = (char*)100;
b = (short*)100;
c = (int*)100;
 
a++;
b++;
c++;
 
printf("%d %d %d",a,b,c);	//输出:101 102 104


/**********************************************************************************/

char** a ;
short** b ;
int** c ;
 
a = (char**)100;
b = (short**)100;
c = (int**)100;
 
a++;
b++;
c++;
 
printf("%d %d %d",a,b,c);	//输出:108 108 108


/**********************************************************************************/

char*** a ;
short*** b ;
int*** c ;
 
a = (char***)100;
b = (short***)100;
c = (int***)100;
 
a++;
b++;
c++;
 
printf("%d %d %d",a,b,c);	//输出:108 108 108


/**********************************************************************************/

char**** a ;
short**** b ;
int**** c ;
 
a = (char****)100;
b = (short****)100;
c = (int****)100;
 
a++;
b++;
c++;
 
printf("%d %d %d",a,b,c);	//输出:108 108 108

总结:

  • 不带*类型的变量,++或者-- 都是加1 或者减1
  • 带*类型的变量,可以进行++ 或者 --的操作
  • 带*类型的变量,++ 或者 – 新增(减少)的数量是去掉一个后变量(带的变量依然是变量,宽度为寻址宽度,若不带*,则为原变量的宽度)的宽度

4.2 加减一个整数

测试环境为x64
char* a ;
short* b ;
int* c ;
 
a = (char*)100;
b = (short*)100;
c = (int*)100;
 
a = a + 5;
b = b + 5;
c = c + 5;
 
printf("%d %d %d",a,b,c);
//输出105 110 120	

/**********************************************************************************/

char** a ;
short** b ;
int** c ;
 
a = (char**)100;
b = (short**)100;
c = (int**)100;
 
a = a + 5;
b = b + 5;
c = c + 5;
 
printf("%d %d %d",a,b,c);
//输出140 140 140	

/**********************************************************************************/

char*** a ;
short*** b ;
int*** c ;
 
a = (char***)100;
b = (short***)100;
c = (int***)100;
 
a = a + 5;
b = b + 5;
c = c + 5;
 
printf("%d %d %d",a,b,c);
//输出140 140 140	

/**********************************************************************************/

char**** a ;
short**** b ;
int**** c ;
 
a = (char****)100;
b = (short****)100;
c = (int****)100;
 
a = a + 5;
b = b + 5;
c = c + 5;
 
printf("%d %d %d",a,b,c);
//输出140 140 140

/**********************************************************************************/

char* a ;
short* b ;
int* c ;
 
a = (char*)100;
b = (short*)100;
c = (int*)100;
 
a = a - 5;
b = b - 5;
c = c - 5;
 
printf("%d %d %d",a,b,c);
//输出95 90 80	

/**********************************************************************************/

char** a ;
short** b ;
int** c ;
 
a = (char**)100;
b = (short**)100;
c = (int**)100;
 
a = a - 5;
b = b - 5;
c = c - 5;
 
printf("%d %d %d",a,b,c);
//输出60 60 60	

/**********************************************************************************/

char*** a ;
short*** b ;
int*** c ;
 
a = (char***)100;
b = (short***)100;
c = (int***)100;
 
a = a - 5;
b = b - 5;
c = c - 5;
 
printf("%d %d %d",a,b,c);
//输出60 60 60	

/**********************************************************************************/

char**** a ;
short**** b ;
int**** c ;
 
a = (char****)100;
b = (short****)100;
c = (int****)100;
 
a = a - 5;
b = b - 5;
c = c - 5;
 
printf("%d %d %d",a,b,c);
//输出60 60 60

总结:

  • 带*类型的变量可以加、减一个整数,但不能乘或者除.
  • 带*类型变量与其他整数相加或者相减时:
    • 带*类型变量 + N = 带类型变量 + N(去掉一个*后类型的宽度)
    • 带*类型变量 - N = 带类型变量 - N(去掉一个*后类型的宽度)

4.3 求差值

char* a ;
char* b ;
 
a = (char*)200;
b = (char*)100;
 
int x = a - b;
 
printf("%d\n",x);
//输出100(100/1)	

short* a ;
short* b ;
 
a = (short*)200;
b = (short*)100;
 
int x = a - b;
 
printf("%d\n",x);
//输出50(100/2)	

int* a ;
int* b ;
 
a = (int*)200;
b = (int*)100;
 
int x = a - b;
 
printf("%d\n",x);
//输出25(100/4)	

char**** a ;
char**** b ;
 
a = (char****)200;
b = (char****)100;
 
int x = a - b;
 
printf("%d\n",x);
//输出12(100/8取整)

总结:

  • 两个类型相同的带*类型的变量可以进行减法操作,减法后是int型变量
  • 相减的结果要除以去掉一个*的数据的宽度

4.4 比较

char**** a;
char**** b;
a = (char****)200;
b = (char****)100;
if(a>b)
{
	printf("1");
}
else        
{
	printf("2");
}
//输出1

总结:

  • 带*的变量,如果类型相同,可以做大小的比较。

五、作业

1、char类型占几字节?char*类型占几字节?int*****占几字节?

答:char类型占1个字节,int*****占4(x86)/8(x64)字节。

2、char** arr[10] 占多少个字节?

答:arr[10]占40(x86)/80(x64)字节。

3、自定义结构体如下(以下结果以x64环境为例):

struct Student
{
	int x;
	int y;
};

第一步:

Student**** s;
 
s = (Student****)100;

s++; //s的值是多少?
答:s的值是100,s++的值是100+8=108。

s = s+2; //s的值是多少?
答:s+2的值是100+2*8=116。

s = s-3; //s的值是多少?
答:s-3的值是100-3*8=76。

第二步:

Student**** s1;
Student**** s2;
int x;
 
s1 = (Student****)200;        
 
s2 = (Student****)100;        

x = s1-s2; //x的值是多少?
答:s1-s2的值是(200-100)/8=12。

第三步:

Student* s;
 
s = (Student*)100;

s++; //s的值是多少?
答:s++的值是100+8=108。

s = s+2; //s的值是多少?
答:s+2的值是100+2*8=116。

s = s-3; //s的值是多少?
答:s-3的值是100-3*8=76。

第四步:

Student* s1;
Student* s2;
int x;
 
s1 = (Student*)200;
 
s2 = (Student*)100;

x = s1-s2; //x的值是多少?
答:x的值是(200-100)/8=12。

  • 30
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值