1. 指针是什么
在c语言中指针是什么呢,他又有什么作用呢?
我们要了解指针,那么首先也得了解一下地址是什么。
地址:在计算机内存,每个变量都是存储在一个特定的地址中,而地址十一个标识内存中位置的数字,通常使用十六进制来表示。
变量的地址可以通过取地址运算符 “&”来获取,如: ‘&value’ 表示变量value的地址
那么当我们知道了地址是什么后,再来了解一下指针。
指针:指针是一个变量,这个变量用来存储另外一个变量的地址。
指针的作用:我们知道指针存放的是另外一个变量的地址,而地址又是变量存储的位置,因此我们就可以通过指针来访问和修改这个变量。
指针的大小在32位平台是4个字节,在64位平台是8个字节
我们经常说的指针指的是指针变量,但是严格来说指针和指针变量是不同的,指针就是地址,指针变量是用来存储的地址的变量。因此,地址就是指针,指针就是地址。
2. 指针和指针类型
通过上文我们可以知道指针十一个变量,既然是变量,那么是不是有不同的类型呢?答案是有的。
指针类型的定义方法如下:
定义方式为:type+*
例如:
char *pc = NULL;
int *pi = NULL;
short *ps = NULL;
long *pl = NULL;
float *pf = NULL;
double *pd = NULL;
不同类型的指针是用来存放不同类型的变量的地址。
指针 + - 整数
#include <stdio.h>
//演示实例
int main()
{
int n = 10;
char *pc = (char*)&n;
int *pi = &n;
printf("%p\n", &n);
printf("%p\n", pc);
printf("%p\n", pc+1);
printf("%p\n", pi);
printf("%p\n", pi+1);
return 0;
}
总结:指针的类型决定指针往前或者往后走一步有多大(即距离多远)
指针的解引用:
//演示实例
#include <stdio.h>
int main()
{
int n = 0x11223344;
char *pc = (char *)&n;
int *pi = &n;
*pc = 0;
*pi = 0;
return 0;
}
3. 野指针
野指针的成因:
- 指针未初始化
2.指针越界访问
3.指针指向的空间释放
4. 指针运算
4.1 指针+-整数
#define N_VALUES 5
float values[N_VALUES];
float *vp;
//指针+-整数;指针的关系运算
for (vp = &values[0]; vp < &values[N_VALUES];)
{
*vp++ = 0;
}
4.2 指针-指针
int my_strlen(char *s)
{
char *p = s;
while(*p != '\0' )
p++;
return p-s;
}
4.3 指针的关系运算
for(vp = &values[N_VALUES]; vp > &values[0];)
{
*--vp = 0;
}
代码简化, 这将代码修改如下:
for(vp = &values[N_VALUES-1]; vp >= &values[0];vp--)
{
*vp = 0;
}
实际在绝大部分的编译器上是可以顺利完成任务的,然而我们还是应该避免这样写,因为标准并不保证 它可行。
标准规定: 允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针比较,但是不允许与 指向第一个元素之前的那个内存位置的指针进行比较。
5. 指针和数组
我们来看一个关于指针和数组的例子简单了解一下二者联系:
#include <stdio.h>
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9,0};
printf("%p\n", arr);
printf("%p\n", &arr[0]);
return 0;
}
结果:
可见数组名和数组首元素的地址是一样的,因此我们可以认为数组名就是数组首元素的地址因此我们可以写出如下代码:
int arr[10] = {1,2,3,4,5,6,7,8,9,0};
int *p = arr; //p存放的就是数组首元素的地址
那么我们是否可以通过指针来访问和遍历数组呢?
如下:
#include<stdio.h>
int main()
{
int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
int *p = arr; //指针存放数组首元素的地址
int sz = sizeof(arr) / sizeof(arr[0]);
int i = 0;
for (i = 0; i<sz; i++)
{
printf("%d ", *(p + i));
}
return 0;
}
6. 二级指针
指针变量也是变量,是变量就会有地址,那么指针变量的地址放在哪里呢?
这就是二级指针
对于二级指针的运算有:
*ppa 通过对ppa中的地址进行解引用,这样找到的是 pa , *ppa 其实访问的就是 pa .
int b = 20;
*ppa = &b;//等价于 pa = &b;
**ppa 先通过 *ppa 找到 pa ,然后对 pa 进行解引用操作: *pa ,那找到的是 a
**ppa = 30;
//等价于*pa = 30;
//等价于a = 30;
7. 指针数组
指针数组是指针还是数组?
答案:是数组。是存放指针的数组。
数组我们已经知道整形数组,字符数组。
int * arr[5];
arr是一个数组,其中有五个元素,而这五个元素都是一个整型指针