指针:有效的表示复杂的数据结构;能动态分配内存;方便地使用字符;有效而方便的使用数组;在调用函数时能获得一个以上的结果;能直接处理内存单元地址等。
指针:一种存放地址的数据类型;
地址:内存中存储单元的位置编号;
存储单元:大小固定,1Byte;
x86:sizeof(指针) == 4;(默认)
x64: sizeof(指针) == 8;
指针变量的定义
类型名 * 指针变量名;
类型名:可以是任意类型(包括void), 也称基类型;
p = &i;读作:p指向i;
如果: p指向i,那么*p就是i;
*p:以p中所存储的内容作为起始地址,
以p的基类型所占字节数作为偏移量,访问此空间。
指针传参:
在被调函数中,通过对形参指针的间接访问,
可以改变主调函数中实参指针所指向的变量的值。
例子:
void swap(int* pa, int* pb)
{
int* t;
t = pa;
pa = pb;
pb = t;
}
//
//void swapcpp(int& a, int&b)
//{
// int t = a;
// a = b;
// b = t;
//}
int main()
{
int a=3, b=8;
swap(&a, &b);
printf("a=%d, b=%d\n", a, b);
return 0;
}
数组与指针
a == &a[0];
数组名代表数组首元素的地址;
如果
int a[10];
int* p = a;
则
a[i] == *(a + i) == p[i] == *(p + i);
3[a] == a[3];
数组名取地址 + 1,跳过整个数组;
&a + 1
p = a;
p + n跳过几个字节(sizeof(p的基类型))*n;
例如:
int main2()
{
int a[3][4];
printf("%p\n", a);
puts("-----------------");
printf("%p\n", &a+1); //48
printf("%p\n", a+1); //16
printf("%p\n", &a[0]+1); //16
printf("%p\n", a[0]+1); //4
printf("%p\n", &a[0][0]+1); //4
return 0;
数组指针
类型名(*指针变量名)[数组长度];
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];
字符串与指针
可以用两种方法访问一个字符串:
char s[] = “hello world !”;
char* ps = “hello world !”;
const所在位置代表的含义:
//const int* p1 = &i;
//p1 = &j; //ok
//*p1 = 55; //error
//int* const p2 = &i;
//p2 = &j; //error
//*p2 = 66; //ok
//const int* const p3 = &i;
//p3 = &j; //error
//*p3 = 33; //error
//int const * p4 = &i;
//p4 = &j; //ok
//*p4 = 77; //error
函数指针的定义:
把函数声明中的函数名,换成(*指针变量名);
int Add(int a, int b)
{
return a + b;
}
int (*p)(int, int);
函数名即函数入口地址;
p = Add;
p(4, 5) == 9;
函数指针
函数指针用途:
主要作为其他函数的参数,将一个可变的功能传递给被调函数,
以提高被调函数的通用性。
返回指针的函数
类型名* 函数名(形参列表);
下面是错误示例:
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;
}
野(疯)指针:如果一个指针所指向的空间是无效空间,
那么他就是一个野指针.
函数返回指针变量时,我们要保证所返回的地址所对应的空间,
在主调函数中依然是有效的(依旧在其生存周期中)。
可行示例:
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;
}
指针数组:是个数组,数组每个元素是个指针。
int* a[10];