指针的定义
地址:
内存单元的编号
从零开始的非负整数
范围:4G[0--4G-1](32位)
指针:
指针就是地址,地址就是指针
指针变量就是存放内存单元编号的变量,或者说指针变量就是存放地址的变量
指针和指针变量是两个不同的概念
但是要注意,通常我们叙述时会把指针变量简称为指针,实际上它们含义并不一样
指针的本质就是一个操作受限的非负整数
下面举一个简单的例子:
例1:
# include <stdio.h>
int main(void)
{
int * p; //p是变量的名字,int *表示p变量存放的事int类型变量的地址
int i = 3;
p = &i;
// p = i; //错误,因为类型不一致,p 只能存放 int 类型的地址,不能存放 int 类型变量的值
// p = 55;//错误,原因同上
return 0;
}
输出结果为:
例2(这个例子说明一下最上面的内容):
# include <stdio.h>
int main(void)
{
int * p; //5行
int i = 3;
int j;
p = &i; //9行
j = *p;
printf("i = %d j = %d\n", i, j);
return 0;
}
输出结果为:
在这个程序的第五行,p是变量的名字,int *表示p变量存放的是int类型变量的地址,该语句不表示定义了一个名字叫做*p的变量,对于这个语句,我们应该这样理解:p是变量名,p变量的数据类型是int * 类型,所谓int * 类型就是存放int变量地址的类型
对于第九行来说,
1、p保存了i的地址,因此p指向i
2、p不是i,i也不是p,更准确的说:修改p的值不影响i的值,修改i的值也不影响p的值
3、如果一个指针变量指向了一个普通变量,则
*指针变量 就完全等同于 普通变量
即
如果p是个指针变量,并且p存放了普通变量i的地址
则p指向了普通变量i
*p 就完全等同于 i
或者说:
在所有出现*p的地方都可以替换成i
在所有出现i的地方都可以替换成*p
*p 就是以p的内容为地址的变量
(这里需要好好想想)
指针的重要性
表示一些复杂的数据结构
快速的额传递数据
使函数返回一个以上的值
能直接访问硬件
能够方便的处理字符串
是面向对象语言中引用的基础
总结:指针是C语言的灵魂
例3(要明白这个程序为什么会出错):
# include <stdio.h>
int main(void)
{
int * p;
int i = 5;
*p = i; //要明白这儿为什么不对
printf("%d\n", *p);
return 0;
}
这个程序是错误的,*p的意思是“以p的内容为地址的变量”,*p是一个局部变量,里边是一个垃圾值,是以p里边的地址为单元的变量,是一个未知的,但是,我们总共分配了两个空间,一个是p的空间,一个是i的空间,。在程序运行中,程序将5这个值去修改了一个不属于它(分配)的空间,所以会出错,这个一般编译链接时都不会报错,但调试时会出错,总之是错误的
再看一个错误的例子
例4:
# include <stdio.h>
int main(void)
{
int i = 5;
int * p;
int * q;
p = &i;
//*q = p; //错误,语法编译会出错
//*q = *p; //错误
p = q; //q是垃圾值,q付给p,p也变成垃圾值
printf("%d\n", *q); //13行
return 0;
}
q的空间是属于本程序的,所以本程序可以读写q的内容,但是如果q内部是垃圾值,则本程序不能读写*q的内容,因为*q所代表的内存单元的控制权限并没有分配给本程序,所以本程序运行到13行时就会出错
【所有代码均在windows系统下VC++6.0下运行通过】
(如有错误,敬请指正)
前段时间看到一句话,觉得不错,现摘录如下:
1 算法的集合就是将指令组织成程序来解决某个特定的问题
2 数据的集合算法在这些数据上操作以提供问题的解决方案
纵观短暂的计算机发展史这两个主要方面算法和数据一直保持不变发展演化的
是它们之间的关系就是所谓的程序设计方法programming paradigm
——《C++primer》