可以把指针理解为定义地址的数据类型吗?
1个回答
展开全部
在C语言中,定义一个普通的变量(如整型数),我们这样做:int i; 而定义一个指针变量(指针)我们需要这样做:int *p ; 还记得吗,一个矩形中的值是有类型的,可能是整型,可能是字符型……,它们原本是“清白”的,无类型的,是我们通过一些手段使它们有了类型。当我们做出int i; 这样一个定义时,编译器就会分配一个地址(例如200)并和i 关联起来,而int将限定编译器把这个区域中的内容作为整型数看待。
矩形内的值被视为int型
现在我们又有了int *p;这个定义,假设p是指向变量i的(见下图),p中存的是变量i的地址。* 表示p是一个指针,而int表示p中所存的地址对应的变量(即变量i)的类型是int。
p指向i , int *p;中的int是指针p所指向的变量的类型
我们将int称为指针p的基类型,或指针p所指向的变量的类型。
类似地,我们可以有: char *s ; ( s是指向char型变量的指针 )
float *f ; ( f是指向float型变量的指针 )
double *d ; ( d是指向double型变量的指针 )
由此得到声明一个指针变量(指针)的一般形式 : 基类型 * 指针名;
有一点要注意,在定义指针时,以下两种方式都是允许的,例如:
int *ptr1;
int* ptr2;
但一般比较倾向用第一种,因为可以避免以下的误解:
int* prt1, ptr2;
这样的定义方式,容易使人误以为ptr2也是一个指针,事实上并不是,prt2是一个int型变量,以下的定义方式中ptr1与ptr2才都是指针:
int* ptr1, *ptr2;
2.指针的运算
.&(address-of operator)取地址操作符:
究竟如何使一个指针指向一个变量呢?后面的语句给出了解答:int *p = &i;& 用于取一个对象的地址(本文说的对象是泛指的某一事物,如变量,数组等,和C++中的对象概念不同),这里用于将i的地址赋给p, 那么指针p就指向了变量i 。上述的语句也可以分开写,如:int *p; p = &i;
小扩展:(下面大括号中的内容,出涉指针的朋友可以跳过,当然也可以作为扩展知识)
{&的实质:当对一个T类型对象进行 & 操作时,返回的是一个“指向T的指针”类型的常量,即指针常量(pointer constant),在我们使用&运算符时我们并不关心它是如何实现的,因为有编译器帮我们隐藏了这些细节。
可当我们想要对一个指针赋一个绝对地址的时候,这个问题就体现出来了,而且我们不得不去关注,在C语言中没有一种内建(built-in)的方法去表示指针常量,所以当我们使用它的时候通常先写成整型常量的形式,然后再通过强制类型转换把它转换成相应的类型,如:int * , double * , char *等。 所以后面所示的做法是不行的: int *p = 0x12345678 ; 正确的方式应为:int *p = (int *) 0x12345678; 也许大家还记得我在第一讲中说的要注意指针中只能存放地址,不能将一个非0值整型常量表达式或者其他非地址类型的数据赋给一个指针,原因就在此。在大多数计算机中,内存地址确实是以无符号整型数来表示的,而且多以16进制表示,但我们在C语言中不能用整型数去表示地址,只能用指针常量来表示,因为它是被用来赋给一个指针的。
对于这个赋值问题还可以换一个角度去理解,在C语言中,使用赋值操作符时,赋值操作符左边和右边的表达式类型应该是相同的,如果不是,赋值操作符将试图把右边表达式的值转换为左边的类型。所以如果写出int *p = 0x12345678 ; 这条语句编译器会报错:'=' : cannot convert from ' const int ' to ' int* ' ,因为赋值操作符左边和右边的表达式的类型应该相同,而0x12345678是int型常量,p是一个指向int型的指针,两者类型不同,所以正确的方式是:int *p = (int *) 0x12345678 ; }
.* (Dereference operator) 解引用操作符
* 在定义时用来说明一个变量是指针,而在定义了一个指针之后,我们使用(引用)指针时,*p表示的是p所指向的对象(即i)。也就是说,对于一个已定义的指针使用 * 操作符,将访问这个指针所指向的对象,我们来看下面的程序:
#include
int main()
{
int i; /*定义一个int型变量i*/
int *p;
(logical,logical, )参数说明:Logical,Logical,Logical……
矩形内的值被视为int型
现在我们又有了int *p;这个定义,假设p是指向变量i的(见下图),p中存的是变量i的地址。* 表示p是一个指针,而int表示p中所存的地址对应的变量(即变量i)的类型是int。
p指向i , int *p;中的int是指针p所指向的变量的类型
我们将int称为指针p的基类型,或指针p所指向的变量的类型。
类似地,我们可以有: char *s ; ( s是指向char型变量的指针 )
float *f ; ( f是指向float型变量的指针 )
double *d ; ( d是指向double型变量的指针 )
由此得到声明一个指针变量(指针)的一般形式 : 基类型 * 指针名;
有一点要注意,在定义指针时,以下两种方式都是允许的,例如:
int *ptr1;
int* ptr2;
但一般比较倾向用第一种,因为可以避免以下的误解:
int* prt1, ptr2;
这样的定义方式,容易使人误以为ptr2也是一个指针,事实上并不是,prt2是一个int型变量,以下的定义方式中ptr1与ptr2才都是指针:
int* ptr1, *ptr2;
2.指针的运算
.&(address-of operator)取地址操作符:
究竟如何使一个指针指向一个变量呢?后面的语句给出了解答:int *p = &i;& 用于取一个对象的地址(本文说的对象是泛指的某一事物,如变量,数组等,和C++中的对象概念不同),这里用于将i的地址赋给p, 那么指针p就指向了变量i 。上述的语句也可以分开写,如:int *p; p = &i;
小扩展:(下面大括号中的内容,出涉指针的朋友可以跳过,当然也可以作为扩展知识)
{&的实质:当对一个T类型对象进行 & 操作时,返回的是一个“指向T的指针”类型的常量,即指针常量(pointer constant),在我们使用&运算符时我们并不关心它是如何实现的,因为有编译器帮我们隐藏了这些细节。
可当我们想要对一个指针赋一个绝对地址的时候,这个问题就体现出来了,而且我们不得不去关注,在C语言中没有一种内建(built-in)的方法去表示指针常量,所以当我们使用它的时候通常先写成整型常量的形式,然后再通过强制类型转换把它转换成相应的类型,如:int * , double * , char *等。 所以后面所示的做法是不行的: int *p = 0x12345678 ; 正确的方式应为:int *p = (int *) 0x12345678; 也许大家还记得我在第一讲中说的要注意指针中只能存放地址,不能将一个非0值整型常量表达式或者其他非地址类型的数据赋给一个指针,原因就在此。在大多数计算机中,内存地址确实是以无符号整型数来表示的,而且多以16进制表示,但我们在C语言中不能用整型数去表示地址,只能用指针常量来表示,因为它是被用来赋给一个指针的。
对于这个赋值问题还可以换一个角度去理解,在C语言中,使用赋值操作符时,赋值操作符左边和右边的表达式类型应该是相同的,如果不是,赋值操作符将试图把右边表达式的值转换为左边的类型。所以如果写出int *p = 0x12345678 ; 这条语句编译器会报错:'=' : cannot convert from ' const int ' to ' int* ' ,因为赋值操作符左边和右边的表达式的类型应该相同,而0x12345678是int型常量,p是一个指向int型的指针,两者类型不同,所以正确的方式是:int *p = (int *) 0x12345678 ; }
.* (Dereference operator) 解引用操作符
* 在定义时用来说明一个变量是指针,而在定义了一个指针之后,我们使用(引用)指针时,*p表示的是p所指向的对象(即i)。也就是说,对于一个已定义的指针使用 * 操作符,将访问这个指针所指向的对象,我们来看下面的程序:
#include
int main()
{
int i; /*定义一个int型变量i*/
int *p;
(logical,logical, )参数说明:Logical,Logical,Logical……
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询