1.指针:
1.提供一种间接访问数据的方法
2.空间没有名字,只有一个地址编号
2.指针:
1.地址:区分不同内存空间的编号
2.指针:指针就是地址,地址就是指针
3.指针变量:存放指针的变量称为指针变量,简称为指针
3.指针的定义:
int *p = NULL;
int *q = NULL;
char *p = NULL;
double *p = NULL;
struct student *p = NULL;
野指针:指向随机空间的指针
空指针:指向内存地址为0x0的空间的指针
注意:定义指针一定要初始化,防止成为野指针
4.指针的运算符:
*: *p作为右值:获得指针指向空间中的值
*p作为左值:将右值放入指针指向的空间
&:获得一个变量在内存空间中的首地址
5.指针的算数运算:
+
-
++
--
p+1:向内存高地址偏移指向的数据类型大小个字节空间
p-q:两个地址中间差了多少个指向的数据类型
6.不同类型的指针操作上有哪些不同
char *p;
int *p;
double *p;
struct student *p;
==================================================================================================================================================
1.指针数组和数组指针:
数组指针:
int (*a)[5]
定义一个指针变量a,占8个字节空间,指向20个字节空间
int a[5] = {1, 2, 3, 4, 5};
a == &a[0] == int *
注意:
大部分情况下a可以理解为int*型,有2中特殊情况除外
1.sizeof运算时
sizeof(a): 20
sizeof(int *): 8
2.&运算符
&a:int (*)[5]
&int *: int **
数组指针特点:
1.对一维数组数组名&得到数组指针,值不变,类型升级为指向整个数组的指针
2.对数组指针*,值不变,类型降级为指向数组第一个元素的指针
指针数组:
int *a[5];
定义一个数组a,有5个元素,每个元素为int *型,占40个字节空间
char *pstr[5];
操作多个字符串时,通过将每个指针指向一个字符串开头,完成对所有字符串的操作,使用指针数组
指针数组和二维数组的区别:
存储字符串数组使用二维数组
操作字符串数组使用指针数组
指针和数组的关系:
1.指针和一维数组的关系:
int a[5] = {1, 2, 3, 4, 5};
int *p = NULL;
p = &a[0];
p = a;
数组的数组名是指向数组第一个元素的指针
a == a[0]
访问第n个元素:
a[n] == *(a+n) == *(p+n) == p[n]
2.指针和二维数组的关系:
int a[2][3] = {{1, 2, 3}, {4, 5, 6}};
int *p = NULL;
int (*q)[3] = NULL;
p = &a[0][0];
p = a[0];
p = *a;
q = a;
数组的数组名a是指向数组第一行元素的数组指针
访问第m行第n列元素方式(N是每行的列数):
a[m][n]
*(a[m]+n)
*(*(a+m)+n)
*(p+m*N+n)
*(*(q+m)+n)
*(q[m]+n)
q[m][n]
3.指针操作字符串(字符串的遍历)
char str[32] = {"hello world"};
char *p = NULL;
p = str;
while (*p != '\0')
{
p++;
}
函数指针和指针函数:
函数指针:
int (*p)(int, int) = NULL;
定义一个指针变量p,p是指向一个int返回值且有2个int参数的函数的指针
指针函数:
int *p(int a, int b)
{
}
定义一个函数,函数的返回值是指针
注意:
绝对不能返回局部变量的地址,否则函数调用结束后,会清除局部变量的空间(栈),应该返回例如数据区的地址,这样函数调用结束后,仍可通过返回的地址访问数据区的数据。