1.指针的定义
指针就是地址
2.指针的大小
#include"stdio.h"
#include"windows.h"
void main()
{
char* c;
int* a;
long* b;
long long* l;
printf("char*:%d\nint*:%d\nlong*:%d\nlong long*:%d\n", sizeof(c), sizeof(a), sizeof(b),sizeof(l));
}
指针的大小都是4字节
3.指针的运算
每种类型指针的加减对应其类型的长度
#include "stdio.h"
void function() {
char* a;
short* b;
int* c;
a = (char*)1;
b = (short*)2;
c = (int*)3;
a++;
b++;
c++;
printf("a:%d\t b:%d\tc:%d\n", a, b, c);
}
int main(int argc, char* argv[])
{
function();
return 0;
}
4.同类型指针的相减操作
#include"stdio.h"
void function() {
char* a;
char* b;
short* c;
short* d;
int* e;
int* f;
a = (char*)200;
b = (char*)100;
c = (short*)200;
d = (short*)100;
e = (int*)200;
f = (int*)100;
printf("%d\n", a - b);
printf("%d\n", c - d);
printf("%d\n", e - f);
}
int main()
{
function();
return 0;
}
不同类型的数据指针做完减法的的结果 不同,那减完的这个值代表的是中间有几个相同的数据类型
char*: (200-100)/1=100
short*:(200-100)/2=50
int*:(200-100)/4=25
5.获取变量的数据类型
头文件中需包含#include<typeinfo>
#include<stdio.h>
#include<typeinfo>
int main()
{
char*** a;
printf("%s\n", typeid(a).name());
return 0;
}
6.取变量地址
在变量前加一个&符号来取变量地址
取用全局变量的地址
#include "stdio.h"
#include <typeinfo>
//为了方便观察地址 先声明为全局变量
int a;
void function() {
a = 610;
int* b = &a;
printf("%x\n", b);
}
int main(int argc, char* argv[])
{
function();
return 0;
}
对应的汇编代码为
function();
00241040 push offset a (0243374h)
00241045 push offset string "%x\n" (0242100h)
0024104A mov dword ptr [a (0243374h)],262h
00241054 call printf (0241010h)
00241059 add esp,8
可以看到全局变量有固定的地址0x0243374h
取用局部变量的地址
#include "stdio.h"
#include <typeinfo>
void function() {
//这里a声明为局部变量
int a = 610;
int* b = &a;
printf("%x\n", b);
}
int main(int argc, char* argv[])
{
function();
return 0;
}
对应的汇编语句为
function();
00101050 lea eax,[ebp-8]
00101053 mov dword ptr [ebp-8],262h
0010105A push eax
0010105B push offset string "%x\n" (0102100h)
00101060 call printf (0101010h)
可以看到局部变量是在堆栈上进行传递的
7.取地址中存放的数据
在地址之前加上【*】符号,就能获取改地址处存储的数据
#include "stdafx.h"
#include <typeinfo>
int a;
void function(){
a=610;
int* b=&a;
int** c=&b;
int*** d=&c;
c=*d;
b=*c;
a=*b;
b=**d;
a=**c;
a=***d;
}
int main(int argc, char* argv[])
{
function();
return 0;
}
对应的反汇编代码
11: a=610;
00401038 mov dword ptr [a (00427c50)],262h
12: int* b=&a;
00401042 mov dword ptr [ebp-4],offset a (00427c50)
13: int** c=&b;
00401049 lea eax,[ebp-4]
0040104C mov dword ptr [ebp-8],eax
14: int*** d=&c;
0040104F lea ecx,[ebp-8]
00401052 mov dword ptr [ebp-0Ch],ecx
15: c=*d;
00401055 mov edx,dword ptr [ebp-0Ch]
00401058 mov eax,dword ptr [edx]
0040105A mov dword ptr [ebp-8],eax
16: b=*c;
0040105D mov ecx,dword ptr [ebp-8]
00401060 mov edx,dword ptr [ecx]
00401062 mov dword ptr [ebp-4],edx
17: a=*b;
00401065 mov eax,dword ptr [ebp-4]
00401068 mov ecx,dword ptr [eax]
0040106A mov dword ptr [a (00427c50)],ecx
18:
19: b=**d;
00401070 mov edx,dword ptr [ebp-0Ch]
00401073 mov eax,dword ptr [edx]
00401075 mov ecx,dword ptr [eax]
00401077 mov dword ptr [ebp-4],ecx
20: a=**c;
0040107A mov edx,dword ptr [ebp-8]
0040107D mov eax,dword ptr [edx]
0040107F mov ecx,dword ptr [eax]
00401081 mov dword ptr [a (00427c50)],ecx
21:
22: a=***d;
00401087 mov edx,dword ptr [ebp-0Ch]
0040108A mov eax,dword ptr [edx]
0040108C mov ecx,dword ptr [eax]
0040108E mov edx,dword ptr [ecx]
00401090 mov dword ptr [a (00427c50)],edx
8.结构体指针
1.结构体指针和普通的指针没有什么区别
2.在对结构体成员进行操作时,首先要进行初始化
3.结构体指针并不直接存储结构体成员,而是存储指向结构体成员的地址,该地址里存放着所有的结构体成员
9.数组指针
int (*px)[2]
数组指针变量为px,类型为int(*)2,该结构体指针指向的数组为int[2]
1.在数组指针前加上*就是只想数组的指针
2.数组指针和指针数组存储的内容都是数组的首地址
3.数组指针和指针数组的主要区别是在进行运算时的单位不同,
前者为数组类型宽度*数组成员数
后者为数据类型宽度