C语言中的指针相关知识汇总
一、引子
在进行我们这个话题之前,我们首先想一个问题,就是我们之前在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); int main() { 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) { int temp; temp = *u; *u = *v; *v = temp; }