C初级指针复习

C初级指针复习:

内存:

内存中的每一个位置都由一个独一无二的地址标识

每一个内存位置都包含一个值

值和类型:

不能简单地通过检查一个值的位来判断它的类型,为了判断值的类型(以及它的值),必须观察程序中这个值的使用方式,值的类型并非值本身所固有的一种特性,而是取决于它的使用方式

NULL指针:

NULL指针提供了一种方法:可以通过NULL指针表示一个特定的指针目前并未指定任何内容,这一方法可以使得程序返回两个信息:是否存在指定元素?指定元素的位置?但是对NULL指针进行解引用是非法的

指针、间接访问和左值:

间接访问操作符所需要的操作数是个右值,但这个操作符所产生的结果是一个左值

指针常量:

*地址=值

这是非法的,因为地址的数据类型是整数,无法作为左值,需要将其为转为指向整型的指针类型,即int*强转类型,但这种做法是有缺陷的,

左值和右值:

左值标识了一个可以储存结果值的地点,它是指向内存区域的对象,右值则是指定了一个值,它则是内存区域中存储的值,左值意味着一个位置,而右值则意味着一个值,所以在需要使用右值的地方可以使用左值,但反之则不行,左值一般为基本数据类型、指针、数组下标访问成员、枚举类型、结构体类型,右值一般为常量、表达式、const修饰的数据成员、函数名(地址常量)

*操作符具有从右向左的结合性,

指针表达式:

char ch

char* cp

&ch:只能作为右值,作为右值时,表示ch的地址,不能作为左值的原因是ch的地址不确定,不能指定一个特定的位置,或者是不能访问该位置的区域,所以左值不合法

cp:左值和右值均可,左值指的是cp所指的内存位置,右值则是cp的值

&cp:只能作为右值,作为右值时,表示cp的地址值,其类型是指向字符的指针的指针,但是作为左值时,因为其指向的地址位置不确定,所以是非法的

*cp:左值和右值均可,左值指向的位置是cp所指遍历的内存区域,也就是ch,右值则是ch变量的值

*cp+1:解引用操作符优先级高于加号,因此先间接访问cp的值,然后加一得到字符b,因此该表达式的结果只能作为右值使用,而不能作为左值,因为是非法的

*(cp+1):该表达式的含义是间接访问cp指向地址加一的位置,其结果既可以作为左值,也可作为右值

cp++与++cp:只能作为右值使用,作为右值的结果是cp所指内存位置加一的区域,但是作为左值时,因为其结果是一个地址常量,并没有进行访问,所以是非法的

*cp++:解引用操作符和自增运算符结合性相同,都是从右向左,所以先执行后置自增,因此先拷贝cp后自增,结果可作为左值和右值使用

*++cp:与上一个内容同理,这个是先自增后拷贝,结果可作为左值和右值使用,但它访问的位置和内容与上一个不同

++*cp:先执行解引用运算符,访问内存内容,后自增,结果为字符常量,因此只能用于右值

(*p)++:与上一个同理

++*++cp:结合性自右向左,因此最终结果还是字符常量,只能作为右值使用

++*cp++:同理

指针运算:

指针与整数发生加法运算时,会根据指针所指数据类型调整大小,例如定义float*p,p+3其实是相当于加12个字节

(1)算术运算:

指针+(-)整数,这一表达式的结果仍然是指针形式

指针-指针:这一表达式只能应用于指向同一数组的两个指针之间,表达式结果为有符号整数,反映的是两指针之间的距离,因为其结果是通过两指针的差值除于所指向数据类型的大小得到的

(2)关系运算:

关系操作符可以对两个指针值进行比较,不过其前提依然是两个指针指向同一数组,这将用于表示指向数组更前或更后的元素,当然不指向同一数组也是可以的,那么其结果只能体现是否指向同一地址

下面举一例子:

 #define num  5
 #include<stdio.h>
 #include<stdlib.h>
 #include<string.h>
 int main() {
  int array[num];
  for (int* p = &array[0]; p < &array[5]; )
  {
  *p++ = 0;
  }
  return 0;
 }

此代码应用了for。for循环的判断条件是合法的,因为p和&array[5]指向同一数组,事实上&array[5]这一指针常量所指向的是数组最后一个元素后面的那一个内存位置,尽管p指针最终也会指向这一位置,但p并没有间接访问此地址,所以是安全合法的

总结:

计算机内存中的每个位置都由一个地址标识,通常邻近的内存位置合成一组,这样就可以存储更大范围的值

不能通过值的位模式来判断值的类型,类型是通过其使用方式来隐式确定的,编译器能够保证值的声明与使用方式是绑定的,从而保证可以通过值的使用方式来确定值的类型

指针变量的值并非是它所指向的内存位置所存储的值,必须通过间接访问来获得其所指向的内存位置所存储的值,一个指向整型的指针进行间接访问操作后得到的是整型值 声明一个指针变量并不会自动分配任何内存,在对指针进行间接访问时,要对指针进行初始化,要么指向现有内存,要么分配动态内存

NULL指针就是不指向任何东西的指针,赋值指针意味着此指针不指向任何值,对其间接访问结果因编译器而异

除了NULL指针,再也没有任何内建方法的记法来表示指针常量,因为程序员通常无法预知编译器会把变量放在内存中的什么位置,在极少见的情况,需要使用指针常量,这时要强制类型转换为指针类型来创建它

最后,指针可以进行算术和关系运算,不过是一般用于两个指针指向同一数组

 

 

 

·

 

 

 

 

posted @ 2023-05-20 19:56  alexlance  阅读(9)  评论(0编辑  收藏  举报