c语言:指针运算

目录

指针类型与整型进行加减

规律

同类型指针减法运算

其他类型的指针运算


一个数据对象的内存位置有两个重要信息:

  1. 数据对象的首地址
  2. 数据对象占用存储空间大小

指针类型的值存储的是内存地址。内存地址是从0开始,依次加1的整型数据。 


指针类型与整型进行加减

我们让指针变量从地址100开始加减,看看能不能成功。如果可以,计算后的结果是什么。

 c语言:指针运算_第1张图片

c语言:指针运算_第2张图片 

编译后,我们发现编译器提示我们,不能将int类型转换为指针类型。

这个错误应该是意料之中的,指针类型可以记录两种信息,一个是首地址,一个是目标数据空间大小。

而整型数据的值可以被当作首地址,但是目标数据空间大小却无法表示。赋值操作符两边提供的信息不统一,那么肯定无法成功赋值。

既然无法直接赋值,我们将整型转换为对应的指针类型后,再进行赋值。

c语言:指针运算_第3张图片

现在编译可以通过了,让我们仔细观察结果。

所有的指针内保存的首地址一开始均为100,加1后,现在变成了不同的值。与初始值相比,分别移动了:1244848

sizeof(char) = 1

sizeof(short) = 2

sizeof(int) = 4

sizeof(long) = 4 sizeof(long long) = 8 sizeof(float) = 4

sizeof(double)

指针类型加1后,将首地址向后移动了 sizeof(目标数据对象) 字节。我们再让指针加2试试看?

 c语言:指针运算_第4张图片

与初始值相比,分别移动了:248816816

指针类型加2后,将首地址向后移动了两个 sizeof(目标数据对象) 字节。

pc = pc - 1;

ps = ps - 1;

pn = pn - 1;

pl = pl - 1;

pll = pll - 1;

pf = pf - 1;

pd = pd - 1;

c语言:指针运算_第5张图片

指针类型与整型也可以进行减法运算。指针类型减1后,将首地址向前移动了 sizeof(目标数据对象) 字节。 


规律

sizeof(目标数据对象) 被称作步长。

指针类型加 n 后。其首地址向后移动 n * 步长 字节。

指针类型减 n 后。其首地址向前移动 n * 步长 字节。


n1n2n3n4之间的首地址刚好相差 sizeof(int)

那么我们是否可以通过指针与整型加减来访问它们呢?

c语言:指针运算_第6张图片

接着,我们使用取值运算符*,将指针指向的目标数据对象进行修改。

*p = 111 ,使得 p 指向的数据对象改为111

*(p - 1) = 222 ,使得 p - 1 指向的数据对象改为222

*(p - 2) = 333 ,使得 p - 2 指向的数据对象改为333

*(p - 3) = 444 ,使得 p - 3 指向的数据对象改为444

n1n4被修改为了111444

注意,表达式 p - 1 必须先被括号包裹,再使用取值运算符*。这是因为取值运算符*的优先级高于算术运算符。

我们需要先让首地址移动,再进行取值操作。

若不使用括号, *p 会先被取值,之后值再被加1

不使用括号:

*p 的值为111*p - 1 的结果为110

使用括号:

(p - 1) 使得首地址移动到n2*(p - 1) 得到结果为222

请格外注意,函数内声明的变量在内存中不一定是首尾相接的。受到内存对齐的影响,它们有可能不连续。这个例子仅仅是为了让读者理解指针与整型加减运算,请勿在实际使用中使用这种写法

另外,数组可以保证各元素在内存中首尾相接,各元素连续分布在内存上。所以,C语言中可以使用指针与整型加减运算访问和修改数组元素。我们将在下一节中讨论使用指针访问数组。

 


同类型指针减法运算

c语言:指针运算_第7张图片

c语言:指针运算_第8张图片 

第一个元素 arr[0] 的首地址为20970856。第六个元素 arr[5] 的首地址为20970876

&arr[5] - &arr[0] 进行减法运算后,结果居然是5

类比于指针类型与整型加减,这里肯定也受到了步长影响。步长为目标类型所占空间大小,步长为 sizeof(int)

arr[5] 的首地址减 arr[0] 的首地址为20970876 - 20970856 = 20。两首地址差值除以步长刚好为5。这里的5意义为:第一个元素与第六个元素之间相隔了5个元素。

规律

sizeof(目标数据对象) 被称作步长。

指针类型与指针类型相减后,其结果为两首地址差值除以步长。


其他类型的指针运算

上面我们介绍了两种有指针类型参数的运算:

  1. 指针类型与整型加减。
  2. 同类型的指针相减。

它们的运算结果都在内存上拥有实际的意义。还有另外几种运算:

  1. 指针类型与整型进行乘除运算。
  2. 同类型的指针相加。
  3. 同类型的指针乘除。

这些运算结果都没有实际意义,在C语言中无法通过编译。

 

 

你可能感兴趣的:(c语言,开发语言)