一、指针和地址的概念
指针:一种存放地址的数据类型;
地址:内存中存储单元的位置编号;
存储单元:大小固定,1Byte;
x86:sizeof(指针) == 4;(默认)
x64:sizeof(指针) == 8;
指针变量的定义:
类型名 * 指针变量名;
类型名:可以是任意类型(包括void), 也称基类型;
p = &i;读作:p指向i;
如果: p指向i,那么*p就是i;
*p:以p中所存储的内容作为起始地址,
以p的基类型所占字节数作为偏移量,访问此空间。
指针传参:
在被调函数中,通过对形参指针的间接访问,
可以改变主调函数中实参指针所指向的变量的值。
二、数组与指针
1、a == &a[0]; 数组名代表数组首元素的地址;
p = a;
p + n跳过几个字节(sizeof(p的基类型))n;
2、如果 int a[10];
int p = a;
则
a[i] == *(a + i) p[i] *(p + i);
3[a] == (a+b)==(b+a)==a[3];
数组名取地址 + 1,跳过整个数组;
&a + 1
int a[3][4]
Printf(“%p”,&a+1) //跳过48个字节
Printf(“%p”,a+1) //跳过16个字节
Printf(“%p”,&a[0]+1) //跳过16个字节
Printf(“%p”,a[0]+1) //跳过4个字节
Printf(“%p”,&a[0][0]+1) //跳过4个字节
3、数组指针
定义:类型名(*指针变量名)[数组长度];
int(*p)[4];
定义了一个指针变量p,该指针指向一个长度为4、元素为int的数组;
int a[3][4];
a[i][j] == (a[i] + j) == ((a + i) + j) == ((a + i))[j]
int* p = (int*)a;
p[i * 4 + j];
三、字符串与指针
1、定义:
char s[] = “hello world !”;
char* ps = “hello world !”;
四、指向函数的指针
1、函数指针的定义:
把函数声明中的函数名,换成(*指针变量名);
例如:int Add(int a, int b)
{
return a + b;
}
int (*p)(int a, int b);
2、函数名即函数入口地址;
p = Add;
3、函数指针用途:
主要作为其他函数的参数,将一个可变的功能传递给被调函数,
以提高被调函数的通用性。
4、返回指针的函数
1)、定义:类型名* 函数名(形参列表);
下面是错误示例:
int* fn()
{
int i = 99;
return &i;
}
int* fn()
{
int a[10] = { 1,2,3,4,5,6,7,8,9,10 };
return a + 5;
}
2)、野(疯)指针:如果一个指针所指向的空间是无效空间,
那么他就是一个野指针.
3)、函数返回指针变量时,我们要保证所返回的地址所对应的空间,
在主调函数中依然是有效的(依旧在其生存周期中)。
可行示例:
int* fn()
{
static int i = 9;
return &i;
}
int g = 9;
int* fn()
{
return &g;
}
int* fn(int a[10])
{
return a + 3;
}
int* fn()
{
int* p = (int*)malloc(100);
return p;
}
5、指针数组:是个数组,数组每个元素是个指针。
定义:类型名 * 数组名[数组长度]
int* p[n];
6、void指针类型
作为不同指针类型转换的中转使用;
int i, 定义一个整型变量i;
int * p, 定义一个整型数据的指针变量:
int a[n], 定义一个整型数组a,它有n个元素;
int *p[n], 定义指针数组p,它由n个指向整型数据的指针元素组成;
int §[n],定义数组指针,p为指向含n个元素的一维数组的指针变量;
int f(), f 为返回整函数值的函数;
int * p(), p为返回一个指针的函数,该指针指向整型数据;
int ( p)(),p为指向函数的指针,该函数返回一个整型值;
int * * p, p是一个指针变量,它指向一个指向整型数据的指针变量;
指针运算小结:
1)指针变量可以加(减)一个整数
2)指针变量赋值
3)两个指针变量可以相减
4)两个指针变量比较
两个指针变量不能进行加法运算