答案:关于指针必须清晰的理解,我结合相关的知识并且举一些示例来说吧,希望你能明白指针,数组,以及他们作为函数参数,或是返回值的异同.这些都是让初学C++的人很头痛的事.
首先我们要清楚尽管指针与数组在有些地方可以通用,但它们两个是不同的,这一点要切记.
先来看看它们声明时的区别,在32位系统中指针是一个4字节的变量或常量.其存放的内容为一个地址值,也就是其指向的地址值.
而数组是一个连续的存放相同数据类型的数据结构,我们通常所说的数组名就是指向其数组首地址的指针,
这句话没错,但就我的理解它还不是一个真正意义上的指针.因为并没有一块内存是用来单独存放这个地址
的.
我们可以用sizeof()操作符来证明这一点,sizeof一个指针和一个数组名得到的结果是不同的(除非你的数组长度和指针长度相同).
在作为函数参数传递的时候,指针与数组是相同的,这个我们众所周知.所谓的传值与传址,其实都是传值,
都是将原值的拷贝传给函数.只不过当传递指针的时候传递的是指针的值(就是其指向的地址).当传递数组
的时候同样是传递的数组的首地址(把首地址作为一个值传递给函数).这就是为什么在函数内部我们可以
像操作一个指针一样操作一个传进来的数组,而在外面却不能这样做,看下面的例子:void ArrayTest(int* a)
...{
a++;
}
int main()
...{
int array[10];
array++;//错误
ArrayTest(array);//在函数内部可以当作指针来操作
}到这里我们已经基本明白了指针与数组的区别,下面我们来看看让人比较迷惑的例子.
#include <stdio.h>
char *retstr()
{
char str[]="hello world! ";
printf(str);
return str;
}
int main()
{
char *ptr;
ptr=retstr();
printf(ptr);
return 0;
}上面的程序编译不会出错,而只是给出了一个[Warning] address of local variable `str' returned的
警告.显然它没有达到我们的目地,继续看下面:#include <stdio.h>
char *retstr()
{
char *str="hello world! ";//注意这里
printf(str);
return str;
}
int main()
{
char *ptr;
ptr=retstr();
printf(ptr);
return 0;
}这个程序能够很好的运行,也达到了我们返回一个指向字符串的指针并利用返回的指针显示字符串的目的.
但第一个程序为什么不行呢,这里就是它们作为返回值的不同地方了.严格来说,本地数组是不能作为函数
返回值的,其返回的值是指向系统栈的地址,这个地址的内容在函数返回的时候会被清楚,所以你不知道其
指向的内容到底是什么,这就是为什么在你执行第一个程序的时候会看到乱码了.而第二个程序声明了一个本地指针,其指向的内容是一个常量,当然常量肯定是存放在系统堆上的,在函数
返回的时候函数把这个指针指向的地址返回,并将指针本身销毁.这是我们还保留这系统堆上的这个字符串
的地址,当然我们就可以用这个地址对其操作了.还有一个比较有意思的关于指针作为参数的例子:
void GetMemory(char *p)
{
p = (char *)malloc(100);
}
void Test(void)
{
char *str = NULL;
GetMemory(str);
strcpy(str, "hello world");
printf(str);
}这个程序将会崩溃,我们先看下面程序然后解释
void GetMemory2(char **p)
{
*p = (char *)malloc(100);
}
void Test(void)
{
char *str = NULL;
GetMemory(&str);
strcpy(str, "hello world");
printf(str);
}这个程序执行没有问题输出hello world.细心的人不用说已经知道原因了,这就是我们前面说过的,当指针的值作为参数传递时,其只是简单的将
自己的值拷贝给函数,而且函数肯定不会改变这个值.但函数可以改变这个值指向的内容.第二个函数就是利用传递给它的一个指向指针的指针,来改变这个指针所指向的指针的内容的.
指针的概念
谈到指针,它的灵活性和难控制性让许多程序员谈虎色变;但它的直接操作内存,在数据
操作方面有着速度快,节约内存等优点,又使许多C++程序员的深爱不以.那么指针究竟是怎么样一个概念呢?
其实, 指针就是一类变量,是一类包含了其他变量或函数的地址的变量。与其他变量所不同的是,一般的变量包含的是实际的真实的数据,而指针是一个指示器,它告诉程序在内存的哪块区域可以找到数据。
好了,在这里我们可以这样定义指针:指针是一类包含了其他变量或函数的地址的变量,它里面存储的数值被解释成为内存的地址.
指针的内容
简单讲,指针有四个方面的内容:即指针的类型,指针所指向的类型,指针的值,指针本身所
占有的内存区.下面我们将分别阐述这些内容.
指针的类型从语法的角度看,指针的类型是指把指针声明语句中的指针名字去掉所剩下的部分。这是指针本身所具有的类型。例如:
int*ip; //指针的类型是int*
char*ip; //指针的类型是char*
int**ip; //指针的类型是int**
int(*ip)[5]; //指针的类型是int(*)[5]
指针所指向的类型当你通过指针来访问指针所指向的内存区时,指针所指向的类型决定了编译器将把那片内存区里的内容当做什么类型来看待。从语法的角度看,指针所指向的类型是指针声明语句中的指针名字和名字左边的指针声明符*去掉所剩下的部分。例如:
int*ip; //指针所指向的类型是int
char*ip; //指针所指向的类型是char
int**ip; //指针所指向的类型是int*
int(*ip)[5]; //指针所指向的类型是int()[5]
指针的值(或称指针所指向的内存区)指针的值或者叫指针所指向的内存区或地址,是指针本身存储的数值,这个值将被编译器当作一个地址,而不是一个一般的数值。在32位程序里,所有类型的指针的值都是一个32位整数,因为32位程序里内存地址全都是32位长。 指针所指向的内存区就是从指针的值所代表的那个内存地址开始,长度为sizeof(指针所指向的类型)的一片内存区。以后,我们说一个指针的值是XX,就相当于说该指针指向了以XX为首地址的一片内存区域;我们说一个指针指向了某块内存区域,就相当于说该指针的值是这块内存区域的首地址。
指针所指向的内存区和指针所指向的类型是两个完全不同的概念。在上例中,指针所指向的类型已经有了,但由于指针还未初始化,所以它所指向的内存区是不存在的,或者说是无意义的。
以后,每遇到一个指针,都应该问问:这个指针的类型是什么?指针指的类型是什么?该指针指向了哪里?
指针本身所占有的内存区指针本身所占有的内存区是指针本身占内存的大小,这个你只要用函数sizeof(指针的
类型)测一下就知道了。在32位平台里,指针本身占据了4个字节的长度。
指针本身占据的内存这个概念在判断一个指针表达式是否是左值时很有用。
上一个:C++的粒子群算法运行结果
下一个:用C++写的中缀表达式