一、引子
在进行我们这个话题之前,我们首先想一个问题,就是我们之前在scanf中用运算符&。这个运算符是用于获取变量的地址,他的操作数必须是变量,并且这个变量必须得有一个地址,我们才能进行取地址。
然后,我们这个时候自然而然地想到一个问题,既然我们能够将取得的变量的地址传递给一个函数,能否通过这个地址在那个函数内访问这个变量?
二、指针是什么?
指针就是一个保存地址的变量。这一点和普通变量区分开来,
普通变量的值就是实际的值,指针变量的值是具有实际值的变量的地址。
作为参数的指针。在被调用的时候得到了某个变量的地址,在函数里面可以通过指针访问外面的变量。如下:
void f(int* p);int i = 0;f(&i);
三、如何定义指针
首先我们得记得一个前提,指针就是一个变量,它是一个变量的话,那他就有一个变量类型。我们定义一个指针变量需要对他的类型进行说明:
int* ptr;
int nurse;
ptr = &nurse;
上面是定义了一个int类型的指针,让这个指针指向了nurse的地址。如果我们运行一下代码,会发现ptr和nurse的位置是相同的,它们的值也是相同的(注意这里我没有给nurse一个初始值,系统会自动分配发给他一个乱七八糟的值,这个是不推荐的。)
四、和指针相关的应用。
(一)空指针,也就是NULL
int* ptr = NULL;
printf("ptr的地址是%p\n", ptr);
(二)指针的算术运算(常用的就是++,--,-,+,还有大小)
int i = 100;int* ptr = &i;
printf("ptr的地址是%p\n", ptr);int* ptradd,*ptrdec,*ptrdadd,*ptrddec;
ptradd= ptr + 1;
printf("address of ptradd=%p\n", ptradd);
ptrdec= ptr - 1;
printf("address of ptrdec=%p\n", ptrdec);
ptrdadd= ptr++;
printf("address of ptrdadd=%p\n", ptrdadd);
ptrddec= ptr--;
printf("address of ptrddec=%p\n", ptrddec
if (ptrdec > ptr)
{
printf("ptrdec is great than ptr,they differ %d\n", ptrdec - ptr);
}
else
{
printf("ptrdec is less than ptr,they differ %d\n", ptr - ptrdec);
}
(三)指针数组
实际上指针数组没有什么,主要是记得数组名是该数组首元素的地址。然后将指针指向数组中的某一个元素,然后像操作数组一样操作就好了。下面这个例子:
int* ptr;
int arr[10] = { 12,15,16,8 };
ptr = &arr[5];
int s = *ptr + 2;
printf("the address of arr array is:%p\n", &arr);//result is 001BFDBC
printf("the address of arr[5] array is:%p\n", &arr[5]);//result is 001BFDD0
printf("the address of point ptr is:%p\n", ptr);//result is 001BFDD0
//the difference between *(ptr+2) and *ptr+2
printf("the address of ptr+2 is:%p and the result is %d\n", ptr + 2, *(ptr + 2));//RESULT IS 001BFDD8 0
printf("the address of s is:%p and the result is %d\n", &s, *ptr + 2);//result is 001BFDBO 2
return 0;
上面这个例子中指出了一个很容易混淆的地方,就是*ptr+2和*(ptr+2)的区别。注意*(ptr+2)是将ptr往后面移动了2位后的位置上面值,但是*ptr+2是将原本的ptr的值加了2.但是我们操作的时候,需要注意一个问题,就是*(ptr+n),这个n,加上n之后,不能超过数组大小,不然的话,系统会给你安排一个地址(类推),但是值会是一个任意值。
指针与多维数组的操作:
int zippo[4][2] = { {2,4},{6,8},{1,3},{5,7} };
printf("zippo=%p\n", zippo);
printf("zippo+2=%p\n", (zippo + 2));
printf("*(zippo+2)=%p\n", *(zippo + 2));
printf("*(zippo+2)+1=%p\n", *(zippo + 2) + 1);
printf("*(*(zippo+2)+1)=%p\n",&( *((*zippo + 2) + 1)));
printf("*(*(zippo+2)+1)=%d\n", *(*(zippo + 2) + 1));
printf("*(*zippo+2)+1)=%d\n", *(*zippo + 2) + 1);
The result is:
zippo=010FFB94
zippo+2=010FFBA4*(zippo+2)=010FFBA4*(zippo+2)+1=010FFBA8*(*(zippo+2)+1)=010FFBA0*(*(zippo+2)+1)=3
*(*zippo+2)+1)=7
(四)指针与函数的关系
如果在程序中定义了一个函数,在编译时,编译系统为函数代码分配一段存储空间,这段存储空间的起始地址称为这个函数的指针。
#include <stdio.h>
void interchange(int* u, int*v);intmain()
{int x = 5, y = 10;
printf("originally x=%d and y=%d\n", x, y);
interchange(&x, &y);
printf("now x=%d and y=%d.\n", x, y);return 0;
}void interchange(int* u, int*v)
{inttemp;
temp= *u;*u = *v;*v =temp;
}