指针02
1.类型的转换
1)基础类型之间可以进行转换
例如:下面的代码可以通过编译
int x = 1;
char y = 2;
x = y;
2)基础数据和结构类型之间不能转换
无法通过编译:
struct st{
int a;
int b;
};
void fun()
{
st t1 = {1, 2};
int x = (int) t1;
}
3)待*的类型的转换
带*的基础类型和带*的结构类型之间可以转换
例如:可以通过编译:
struct st{
int a;
int b;
};
void fun()
{
int* x = (int*)1;
st* y = (st*)x ;
}
2.&符号
&是地址符,类型是其后面的类型加一个“*”,任何变量都可以使用&来获取地址,但不能用在常量上。
获取变量a的地址:
int a = 1;
int* pa = &a;
&a的类型就是变量a的类型加上一个*;例如这里a是int,&a就是int*;
带*的类型通常赋值是必须用完整写法:
int* a = (int*)1;
和取地址符&一起使用时可以简写;
char a = 10;
short b = 20;
int c = 30;
char* pa = (char*)&a;
short* pb = (short*)&b;
int* pc = (int*)&c;
简写为:
char* pa = &a;
short* pb = &b;
int* pc = &c;
带更多*的类型也一样:
char a = 10;
short b = 20;
int c = 30;
char* pa = &a;
short* pb = &b;
int* pc = &c;
char** ppa = (char**)&pa;
short** ppb = (short**)&pb;
int** ppc = (int**)&pc;
简写为:
char** ppa = &pa;
short** ppb = &pb;
int** ppc = &pc;
反汇编分析:
代码:
void fun()
{
int x = 1;
int* y;
y = &x;
}
反汇编:
3.带*的类型求值(解引用)
1)*运算结果的类型
带*的类型的变量,面加*运算符后所得的值的类型:
int* px;
int** px2;
int*** px3;
int**** px4;
//*(px) 是什么类型? ->int
//*(px2) 是什么类型? ->int*
//*(px3) 是什么类型? ->int**
//*(px4) 是什么类型? ->int***
也就是说:*a的值的类型是a去掉一个*后的类型;
只有带*的类型才能用*运算;
2)*运算结果的值
例如:
void fun()
{
int x = 1;
int* y = &x;
int** z = &y;
int r = *(*(z));
}
反汇编:
可以看出来:*运算符的反汇编是用带*变量的值来寻址,找到的值即为结果;
总结:
1、带*类型的变量,可以通过在其变量前加*来获取其指向内存中存储的值.
2、在带*类型的变量前面加*,类型是其原来的类型减去一个*.
4.用指针操作数组
取数组第一个元素的地址:
char arr[10];
char* p = &arr[0]; //取数组第一个元素的地址
char* p2 = arr; //简写
也就是说,数组变量名就是数组第一个元素的地址;
因为带*类型变量 + N = 带*类型变量 + N*(去掉一个*后类型的宽度) ,
利用这一特点可以用来操作数组:
原理:
char* p = (char*)10;
p+1 = 11;
short* p = (short*)10;
p+1 = 12;
总结:
1、&arr[0]代表取数组中第一个元素的地址,可以省略为数组名.
2、*(p+i) = p[i]