指针
关于C语言详解系列blog的目录:http://blog.csdn.net/snake_lp/article/details/78630717
一、概述
指针是C语言中使用非常广泛的一种数据类型。利用指针类型的变量可以表示各种类型的数据结构。但是指针也在C语言中比较难于掌握的一个知识点。
简单一点说,指针就是可以直接操作内存地址的一种数据类型。但是对于指针而言,也需要使用数据类型去进行修饰的。如果指针只是对内存空间进行操作,那么为什么还需要使用数据类型来进行修饰呢?
由于指针可以表示所有类型的变量,常量,函数等,所以指针的使用也非常的灵活。越灵活和好用的东西,越是难于掌握。可以这样说,如果真正的掌握了C指针,那你C语言的功底一定不会差。
二、什么是指针?
指针是一个变量,是存储变量地址的变量,这个值就是一个内存地址。由于指针也是一个变量,所以在使用指针之前,也需要对指针的类型进行声明。
其声明的方式如下所示:
type *name;
type为指针的类型,它是一个C语言中有效的数据类型即可;name为指针名,它只要符合C语言标识符的命名即可。*是用来指示name的类型为指针类型的。
例如:
int *i;
char *c;
对于指针变量来说,不管指向的变量类型是什么,指向的本质都是一致的,都是指向内存地址。但是指针的类型也是必要的。因为对于一个存储空间不一定是单个字节的,但是指针指向的地址都是变量的首地址,由于变量类型的存在,就可以确定指针指向内存空间的大小;同时由于即使相同的内存大小,存储的数据类型不同,数据在读取的时候对内存空间的解析也不一致,所以必须要指定指针的类型。由于以上的原因,指针的类型必须和指向变量的类型保持一致。
三、指针的使用
1. 指针和变量
主要的操作为:定义一个变量,把变量地址赋值给指针,通过操作指针变量来达到修改变量的值,之后还可以通过*运行符返回指定的变量值。
请欣赏下面代码:
#include<stdio.h>
int main()
{
int var = 10; /*变量声明*/
int *p =&var; /*声明指针,并初始化*/
printf("Addressof var is %p\n", &var);
printf("Addressstored in p is %p\n", p );
printf("Valueof *p is %d\n", *p );
*p = 30;
printf("Address of var is %p\n", &var );
printf("Address stored in p is %p\n", p );
printf("Value of *p is %d\n", *p );
}
运行结果为:
2. 指针和数组
实际的操作为:定义一个数组,定义一个指针并且将数组的首地址赋值给指针,通过指针的加操作来实现对数组角标的操作。
请欣赏下列代码:
#include<stdio.h>
int main()
{
intarray[10] = {0,1,2,3,4,5,6,7,8,9}; /*数组声明和赋初值*/
int*pa = array; /*声明指针,并初始化*/
inti = 0;
for(i= 0; i < 10; i++)
{
printf("array[%d]= %d\n",i,*(pa+i));
}
for(i= 0; i < 10; i++)
{
*(pa+i)= *(pa+i) + i;
}
for(i= 0; i < 10; i++)
{
printf("array[%d]= %d\n",i,*(pa+i));
}
}
运行结果如下:
3. 指针和函数
实际的操作为声明一个函数指针,定义一个函数(注意声明的函数指针和定义的函数需要保持原型一致),将函数地址赋值给函数指针,通过函数指针来调用函数。
请欣赏下面代码:
#include<stdio.h>
voidaddFunc(int x ,int y)
{
printf("x+ y = %d\n",x+y);
}
intmain()
{
void(*func)(int,int);
func= addFunc;
func(3,5);
}
运行结果为:
4. 作为值传递
实际操作就是函数的参数为指针类型。
请欣赏下面代码
void Copy(uint8_t *pDes, uint8_t *pSrc, uint16_t num)
{
uint8_ti = 0;
if(num== 0)
{
return;
}
for(i= 0;i<num;i++)
{
*pDes = *pSrc;
pDes++;
pSrc++;
}
}
以上为主要的使用方法,但是指针的使用场景不仅仅这么几个,只有在实际的使用过程中慢慢的体会。
四、NULL指针
NULL为空指针。空指针在很多编译器中就是指向0的指针。我觉得严谨来讲应该没有指定指向内存空间类型的指针,所以任何类型的指针都可以被赋值为NULL。我们在编程中尽量养成一个好的习惯:在指针声明之后,如果没有确切的地址可以赋值,建议为指针变量赋一个NULL类型的指针。NULL指针在标准库中的值就是为0.
请欣赏下面程序:
#include<stdio.h>
int main ()
{
int *ptr = NULL;
printf("ptr 的值是%p\n", ptr );
}
运行结果为:
五、指针的运算
指针能够支持的算术运算只有++,--,+,-四种。
这四种运算其实就是使得指针的地址进行向前或者向后移动。
这种所谓的一定不是单纯的一个字节的移动了,而是根据指针的类型来确定移动的字节数,每次移动的长度就是type类型所占用的长度。