1.C语言中的指针表达式,请大家根据图详细讲下,谢谢
先教你一个区分左值和右值的方法:
你可以试着对表达式进行取址操作,如果表达式不能进行取址的话,那么就可以看做右值。如果可以取址,就有可能是左值也有可能是右值。
举个例子 int a = 0; 这里对a进行取址操作,&a,是合法的,所以a可以是左值也可以是右值;
再来,&0,这样肯定不行的,所以0是个右值。同样的像"a"、a+b这类的都属于右值。
然后说你发的图:
第一个图:cp是个指向char的指针。
char c = 'a';
char *cp = &c;
图一简单描述如上,首先他是一个指针,他指向的内存里放的是char型的'a'。
那么按照我给你的技巧试一下,对cp进行取址操作,即&cp,这是合法的,也就是说cp可能是左值也可能是右值。
cp是左值的例子:char temp = 'd'; cp = &temp; //这里cp是左值(图一的右边)
cp是右值的例子:char *cp2 = cp; //这里cp是右值(图一左边)
第二张图:&cp,还是按照我给你的方法,&(&cp)这是不合法的,所以&cp只能当做右值。
&cp做右值的例子:char **cpp = &cp; //这里实际上是用一个临时的地址存放了&cp的值并附给cpp。
从上面的例子可以看出&cp实际上是临时的一个值,你并不知道他的内存地址,所以不能给他赋值,也就是不能把&cp当左值。
第三张图还是用那方法。&(*cp)是合法的所以可以是左值也可以是右值。
左值例子:*cp = 's'; //图三右边;
右值例子:char s = *cp; //图三左边;
第四张图:&(*cp+1)是不合法的。所以*cp+1只能是右值;
右值例子:int n = (int)(*cp+1); //这里跟第二张图情况一样,实际上*cp+1的结果是个临时的值,所以不能对这个临时的值进行赋值,也就是说他不可以当左值。
2.vb中指针的表达式
vb指针是有的,只不过被隐藏起来了,因为vb官方不鼓励用户使用指针。
VarPtr 得到的内存地址
ObjPtr 是得到对象入口地址
StrPtr 字符串地址
示例:
Private Sub Form_Load()
Dim Test As Long
Test = "123"
Debug.Print VarPtr(Test)
Debug.Print StrPtr(Test)
End Sub
VarPtr(Test)可以得到变量“Test”的内存地址。
StrPtr(Test)可以得到变量“Test”中值的内存地址,也就是储存“123”这块内存的地址。
这三个函数配合CopyMemory这个API函数可以达到和C语言的指针差不多的效果。
&H---------是表示十六进制。
3.指针的类型表达式是int(*)[3]
楼主你好。首先学习指针是有好多概念容易混淆。下面我来帮你区别一下:
1、int(*ptr)[3];------ptr为指向含3个元素的一维整形数组的指针变量(是指针)
2、int *ptr[3];-------定义指针数组ptr,它由3个指向整型数据的指针元素组成(是数组)
3、int(*)[3];--------实际上可以看作是一种数据类型。也就是第一个(int(*ptr)[3];)中定义的ptr的数据类型
其实你要看这种到底是什么,就是要看他最先和谁结合。 比如1中ptr先与*结合,那就说明ptr本质是一个指针;而2中ptr先与后面的[3]结合,说明他本质是一个数组。再慢慢理解。希望能帮到你。如有疑问可以再问我。
4.用指针作if语句的条件表达式意味著什么
当把一个指针作为条件表达式时,所要判断的条件实际上就是“该指针是否为一空指针”。在if,while,for或do/while等语句中,或者在条件表达式中,都可以使用指针。请看下例:
if(p)
{
/*dO something*/
}
else
{
/* dOsomethingelse */
}
当条件表达式的值不等于零时,if语句就执行“then”子句(即第一个子句),即“if(/*something*/)”和“if(/*something*/!=0)”是完全相同的。因此,上例和下例也完全相同:
if(p !=0)
{
/* dO something(not anull pointer)*/
}
else
{
/* dOsomethingelse(a null pointer)*/
}
以上两例中的代码不易读,但经常出现在许多C程序中,你不必编写这样的代码,但要理解这些代码的作用。
5.指针
指针是一个特殊的变量,它里面存储的数值被解释成为内存里的一个地址。
指针也是一种数据类型,并且也是有值的。要搞清一个指针需要搞清指针的四方面的内容:指针的类型,指针所指向的类型,指针的值或者叫指针所指向的内存区,还有指针本身所占据的内存区。
让我们分别说明。 先声明几个指针放着做例子: 例一: (1)int *ptr; (2)char *ptr; (3)int **ptr; (4)int (*ptr)[3]; (5)int *(*ptr)[4]; 1。
指针的类型。 从语法的角度看,你只要把指针声明语句里的指针名字去掉,剩下的部分就是这个指针的类型。
这是指针本身所具有的类型。让我们看看例一中各个指针的类型: (1)int *ptr; //指针的类型是int * (2)char *ptr; //指针的类型是char * (3)int **ptr; //指针的类型是 int ** (4)int (*ptr)[3]; //指针的类型是 int(*)[3] (5)int *(*ptr)[4]; //指针的类型是 int *(*)[4] 怎么样?找出指针的类型的方法是不是很简单? 2。
指针所指向的类型。 当你通过指针来访问指针所指向的内存区时,指针所指向的类型决定了编译器将把那片内存区里的内容当做什么来看待。
从语法上看,你只须把指针声明语句中的指针名字和名字左边的指针声明符*去掉, 剩下的就是指针所指向的类型。例如: (1)int *ptr; //指针所指向的类型是int (2)char *ptr; //指针所指向的的类型是char (3)int **ptr; //指针所指向的的类型是 int * (4)int (*ptr)[3]; //指针所指向的的类型是 int()[3] (5)int *(*ptr)[4]; //指针所指向的的类型是 int *()[4] 在指针的算术运算中,指针所指向的类型有很大的作用。
指针的类型(即指针本身的类型)和指针所指向的类型是两个概念。当你对C越来越熟悉时,你会发现,把与指针搅和在一起的"类型"这个概念分成"指针的类型"和"指针所指向的类型"两个概念,是精通指针的关键点之一。
我看了不少书,发现有些写得差的书中,就把指针的这两个概念搅在一起了,所以看起书来前后矛盾,越看越糊涂。3。
指针的值,或者叫指针所指向的内存区或地址。 指针的值是指针本身存储的数值,这个值将被编译器当作一个地址,而不是一个一般的数值。
在32位程序里,所有类型的指针的值都是一个32位整数,因为32位程序里内存地址全都是32位长。 所以不管任何类型的指针,它占据的存储空间都是4个字节。
指针所指向的内存区就是从指针的值所代表的那个内存地址开始,长度为sizeof(指针所指向的类型)的一片内存区。以后,我们说一个指针的值是XX,就相当于说该指针指向了以XX为首地址的一片内存区域;我们说一个指针指向了某块内存区域,就相当于说该指针的值是这块内存区域的首地址。
指针所指向的内存区和指针所指向的类型是两个完全不同的概念。在例一中,指针所指向的类型已经有了,但由于指针还未初始化,所以它所指向的内存区是不存在的,或者说是无意义的。
以后,每遇到一个指针,都应该问问:这个指针的类型是什么?指针指向的类型是什么?该指针指向了哪里? 4。 指针本身所占据的内存区。
指针本身占了多大的内存?你只要用函数sizeof(指针的类型)测一下就知道了。在32位平台里,指针本身占据了4个字节的长度。
指针本身占据的内存这个概念在判断一个指针表达式是否是左值时很有用。补充:何为32位机器和字长?32位系统指机内 数据长度,指令长度,地址长度是二进制32位。
64位系统指机内 数据长度,指令长度,地址长度是二进制64位。 64位系统速度快。
32位系统系统要寻高于32位的地址就要用到复杂一点的运算,用两个32位单元组合成(好几步才能到位)。64位系统直接寻址(一步到位)。
32位的寄存器和指令集不能及时进行相应的处理运算。32位处理器一次只能处理32位,也就是4个字节的数据;而64位处理器一次就能处理64位,即8个字节的数据。
字长:电脑技术中对CPU在单位时间内(同一时间)能一次处理的二进制数的位数叫字长。所以能处理字长为8位数据的CPU通常就叫8位的CPU。
同理32位的CPU就能在单位时间内处理字长为32位的二进制数据。字节和字长的区别:由于常用的英文字符用8位二进制就可以表示,所以通常就将8位称为一个字节。
字长的长度是不固定的,对于不同的CPU、字长的长度也不一样。8位的CPU一次只能处理一个字节,而32位的CPU一次就能处理4个字节,同理字长为64位的CPU一次可以处理8个字节。