指针是什么?
在计算机科学中,指针(Pointer)是编程语言中的一个对象,利用地址,它的值直接指向(points to)存在电脑存储器中另一个地方的值。由于通过地址能找到所需要的变量单元,可以说,地址指向该变量单元。因此,将地址形象化地称为“指针”。意思是通过它能找到以它位地址的内存单元。
#include<stdio.h>
#include<stdlib.h>
int main() {
int a = 10;//在内存中开辟一块空间
int *p = &a;//用&取出a的地址并存放在变量p中,此时的p就是一个指针变量
system("pause");
return 0;
}
总结:指针是一个用来存放内存单元地址的变量(存放在指针中的值都被当成地址处理)。
指针的大小
- 在32位的机器上,地址是32个0或者1组成二进制序列,那地址就得用4个字节的空间来存储,所以一个指针变量的大小就应该是4个字节,即指针的大小在32位平台是4个字节。
- 如果在64位机器上,如果有64个地址线,那一个指针变量的大小是8个字节,才能存放一个地址。即在64位平台是8个字节。
指针类型
我们都知道变量有不同类型,比如整型,浮点型等,那么指针有没有类型呢?准确地说,是有的。
char *pc = NULL;
int *pi = NULL;
short *ps = NULL;
long *pl = NULL;
float *pf = NULL;
double *pd = NULL;
这里可以看到,指针的定义方式为:type + * 。其实:char* 类型的指针是为了存放 char 类型变量的地址;short* 类型的指针是为了存放 short 类型变量的地址。。。
指针类型的意义
指针±整数
#include<stdio.h>
#include<stdlib.h>
int main() {
int n = 10;
char *pc = (char*)&n;
int *pi = &n;
printf("%p\n", &n);//00FDF7FC
printf("%p\n", pc);//00FDF7FC
printf("%p\n", pc+1);//00FDF7FD
printf("%p\n", pi);//00FDF7FC
printf("%p\n", pi+1);//00FDF800
system("pause");
return 0;
}
总结:指针+1看似+1,实际上是指+其所指向类型大小。
指针的解引用
#include<stdio.h>
#include<stdlib.h>
int main() {
int n = 0x11223344;
char *pc = (char*)&n;
int *pi = &n;
*pc = 0;
*pi = 0;
system("pause");
return 0;
}
总结:指针类型决定了对指针解引用的时候有多大的权限(能操作几个字节)。比如:char* 的指针解引用就只能访问一个字节,而 int* 的指针的解引用就能访问四个字节。
指针运算
指针±整数
前面有提到。
#define N_VALUES 5
float values[N_VALUES];
float *vp;
for (vp = &values[0]; vp < &values[N_VALUES];)
{
*vp++ = 0;//清零,从前往后
}
总结:指针+1看似+1,实际上是指+其所指向类型大小。
指针-指针
int my_strlen(char *s) {
char *p = s;
while (*p != '\0')
p++;
return p - s;
}
总结:指针-指针代表两指针之间所经历的元素的个数。
指针的关系运算
for (vp = &values[N_VALUES]; vp > &values[0];)
{
*--vp = 0;//清零,从后往前
}
修改代码如下:
for (vp = &values[N_VALUES-1]; vp >= &values[0];vp--)
{
*vp = 0;
}
标准规定:允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针比较,但是不允许与指向第一个元素之前的那个内存位置的指针进行比较。
指针和数组
#include<stdio.h>
#include<stdlib.h>
int main() {
int arr[10] = { 1,2,3,4,5,6,7,8,9,0 };// 004FFE94
printf("%p\n", arr);// 004FFE94
printf("%p\n", &arr[0]);
system("pause");
return 0;
}
总结:数组名表示的是数组首元素的地址。
如下是直接通过指针来访问数组的例子:
#include<stdio.h>
#include<stdlib.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));
}
printf("\n");
system("pause");
return 0;
}
二级指针
指针变量也是变量,是变量就有地址,那么指针变量的地址存放在哪里?这就是二级指针。
指针数组
首先,我们应该知道指针数组是数组,是存放指针的数组。
如:
int* arr[5];
arr是一个数组,有五个元素,每个元素是一个整形指针。