指针的优点:
- 使程序更加简洁高效
- 有效的表示比较复杂的数据结构
- 动态内存分配
- 得到多于一个的返回值 概念
概念:
- 地址:内存中每个字节单位都有一个编号,这个编号就是地址
- 指针:指针就是地址
- 指针变量:用于存放地址的变量
-
定义格式:
- 存储类型 数据类型 *变量名
-
- int * p;
- int a=3;
- int * p = &a;
- char b='c';
- char * q = &b;
-
指针操作符:
&:取地址 取变量的地址
* :取内容 取地址里面的内容
初始化:
指针变量使用之前不仅要定义还要初始化,未初始化的指针变量不能随便使用,会产生野指针
1)将普通变量的地址赋值给指针变量
a) int a = 5;
int * p = &a;
*p = 10;// a==10,*p ==10 可以通过改变*p的值来改变指针指向空间的内容
b) int * p = NULL;
p = &a;
- 将数组的首地址赋值给指针变量
char s[10]="hello";
char * p = s;//p指向字符'h'
- 将指针变量里面保存的地址赋值给另一个指针变量
float a = 3.14;
float * p = &a;
float * q = p;
指针运算
int a[5]={12,34,56,78,92};
int * p = a;
1)算术运算
p++:指针向高地址方向移动一个数据单位的大小,指针的指向发生改变
p--:指针向低地址方向移动一个数据单位的大小,指针的指向发生改变
p+n:访问了高地址方向第n个数据的地址,指针的指向没有发生变化
p-n:访问了低地址方向第n个数据的地址,指针的指向没有发生变化
两个地址之间的差为两个地址之间相隔元素个数
2)关系运算(只有当指针指向同一个数组时,关系运算才有意义)
> < == !=
指针之间的关系运算比较的是指向地址的高低
指向高地址的指针大于指向低地址的指针
char s[10]="hello";
char * p = &s[1];
char *q = &s[3];
p < q
指针的大小
指针的大小只和地址有关系
总结:
1.32位操作系统,指针就是4字节,64位操作系统,指针就是8字节
总结:
- 内存地址是固定的,变量的地址是不固定的
- 指针的数据类型是根据指向空间的数据类型决定的
段错误
Segmentation fault (core dumped)
1)野指针,没有规定指向的指针。
产生原因:
- 指针变量没有初始化
- 指针p被free了没有置为NULL
解决办法:int * p = NULL;
2)对非法空间进行赋值。
总结
-
指针是一个变量,它存储了一个内存地址,指向内存中的数据。通过指针,可以间接地访问和修改内存中的数据。
-
指针的声明使用星号(*)符号。例如,int *ptr; 声明了一个指向整数的指针变量。
-
指针变量必须初始化,否则它将指向一个未知的内存地址,这可能导致不可预测的结果。可以使用“&”运算符获取变量的地址来初始化指针。
-
指针的运算符包括“*”和“&”。“*”用于访问指针指向的内存中的数据,“&”用于获取变量的地址。
-
指针可以与数组结合使用,可以通过指针对数组进行遍历和修改。
-
指针还可以用于动态内存分配,通过调用malloc函数可以动态分配内存,并返回一个指向新分配内存的指针。
-
指针可以作为函数参数传递。通过传递指针,可以在函数中修改调用方的变量。
-
指针还可以形成链表和树等数据结构,这些数据结构可以高效地存储和访问大量数据。
-
指针在C语言中是非常强大和灵活的,但也容易出错。指针悬空和指针越界是常见的指针错误。在使用指针时,需要小心和谨慎,避免出现这些错误。