关于指针的几个问题与解答

来源:互联网 发布:mysql insert 中文列 编辑:程序博客网 时间:2024/05/16 05:38

                                                  

这几天一直在理解这几个概念。

假如我声明了一个指针,它占用内存不,有没有地址。如果只声明,不初始化,值是没有还是值随机。普通变量也是。

利用指针在函数之间进行通信,应该怎样才能正常通信。

指针和数组名、字符串名能完全等价吗?

一、声明即有地址,指针的地址是什么类型

如果我声明了一个指针,那么他就是一个指针变量,是变量总是有地址的。但关键分配给这个指针变量的内存有多大。假如我声明了一个char *p变量。那么p占有多大的内存空间。我的理解是只有int型大小的空间,非char型大小的空间,而且无论你声明什么类型的指针变量,指针变量本身的内存大小都是int。而声明的类型,如char只是指这个指针将要指向的变量是一个char型,而非指针变量本身是char

通过设计一个程序即可验证,如下:

char *p[2];

     printf("%p/n",&p[0]);

     printf("%p/n",&p[1]);

上述语句是声明了两个指针,连续的指针(所以用指针数组来表示),打印出来的地址为:

0012FF68

0012FF6C

 

两个地址相差4个字节。

下面一条语句,将char型换成double型:

char *p[2];

     printf("%p/n",&p[0]);

     printf("%p/n",&p[1]);

结果依旧为:

0012FF68

0012FF6C

还是相差4个字节,也就是一个int型大小。这就充分证明了,指针变量本身只占有4个字节的空间。上述结论只适应于本机。其实指针占有多少空间是和计算机系统相关的,在32位机上就是4个字节。32位机的最大内存寻址空间为232次方个位,即4Gb

二、未初始化的变量不可随便用,除非是用在赋值语句中

但是如果我想在函数之间进行通信,传地址,改如何写?假如写成

调用函数内容

Int mian()

{

Char *p;

Swap(p);

}

被调用函数内容

Swap(char *p)

{

}

这样的形式是不行的。虽然在调用函数中p是指针变量。但并没有给p赋值,p的内容是随机的,有可能不指向char类型的变量,也就不能将地址传给swap中的char型指针。所以以这种方式进行传地址是错误的。在声明指针的时候,系统只分配了指针本身所占用的空间,并没有给这个指针的内容进行初始化。而指针的内容如果未知,那么它所指向的地址也就未知,也就达不到你想将一个变量的地址传递给另一个函数的目的。同样,如果一个普通变量只分配了内存但没进行初始化,那么它的值也是随机的。也就是说,在进行传地址之前你首先要确定一个地址。因此可以有如下两种改进方式

一个是:

 

Char *p;

Swap(&p)

另一个是:

Char p;

Swap(&p)

前一种其实是不可取的,虽然在某些条件下也是行得通,因为p的地址是整型,而且p的内容也是整型,虽然它是char类型的指针变量,但它只是指向一个char类型的变量,存储的只是char类型变量的地址,而地址是整型。所以如果被调用函数传递回来的不是整型,那么将出错。而第二种是正确的方法。定义了一个char型变量,虽然没有初始化,也就是p的值未确定,但是p的地址是定的,而且传递回来的还是char类型。

 

所以,综上:指针和普通变量在声明的时候都有地址,未经初始化时值都是随机的。随机的值本身并没有什么过错,随机的值是可以赋值的,但未赋值就不能拿来就用,除非是在赋值语句中用,所以,必须先确定值。上面这个例子就是这个理念的佐证,如果传了一个随机的地址,那么就是错误,但未初始化的变量仍然是可以传地址的,因为地址是确定的。

三、变量能赋值,常量不可

这个道理非常简单,不用多解释。但一定要分清什么是变量,什么是常量。

一个指针变量和数组名可以等价吗?

不可以,虽然他们都代表地址。

但指针是变量(没有用const限制),数组名是常量。这也解释了为什么可以将一个值赋给指针变量,但不可以将整个数组的值赋给一个数组名。

 

综上这个几个例子,确定一些基本观念。

声明即有地址。指针变量地址是不随其类型改变的,都是int型。

未初始化的变量内容是随机的,在引用之前一定要确定内容,除非是给其赋值。

变量能赋值,常量不可。

这几点虽然都是最基础的,但是具体到应用的时候根本就抛之脑后,规则不复杂,但由几个简单规则引申出来的应用就会让人眼花缭乱了,回归最根本的规则才是正道。

原创粉丝点击