指针表达式+1.对应的地址值却+4?/为什么两个数组元素的地址相减之差不为地址之差?

本文详细解释了C语言中指针加1运算为何实际上增加了4,以及两个指针相减的意义。根据C语言标准,指针加整数时,该整数会被乘以指针类型大小再进行加法运算;而两个指向同一数组的指针相减,则得到它们之间的元素数量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

C语言中,我们常常用到的一个运算是让某个变量的值+1.

例如 M = M + 1。

而在实际运用中,我们发现

对于指针进行+1运算,算出来的结果是+4。

如下图


图中我们定义的 变量M 和指针Matrix如下:

int M = 3;

int* Matrix = {1,2,3};


可以看到,对于M和 Matrix ,+1运算的效果是不同的。


这个差异是因为c语言的标准中规定了 加法与减法运算对于地址的操作和对于值的操作是不同的,如下文中粗体所示:


C89


3.3.6 Additive operators
Syntax


    additive-expression:
        multiplicative-expression
        additive-expression + multiplicative-expression
        additive-expression - multiplicative-expression


Constraints


For addition, either both operands shall have arithmetic type, or one operand shall be a pointer to an object type and the other shall have integral type. (Incrementing is equivalent to adding 1.)


For subtraction, one of the following shall hold:


    * both operands have arithmetic type;
    * both operands are pointers to qualified or unqualified versions of compatible object types; or
    * the left operand is a pointer to an object type and the right operand has integral type. (Decrementing is equivalent to subtracting 1.)


Semantics


If both operands have arithmetic type, the usual arithmetic conversions are performed on them.


The result of the binary + operator is the sum of the operands.


The result of the binary - operator is the difference resulting from the subtraction of the second operand from the first.


When an expression that has integral type is added to or subtracted from a pointer, the integral value is first multiplied by the size of the object pointed to. The result has the type of the pointer operand.
If the pointer operand points to a member of an array object, and the array object is large enough, the result points to a member of the same array object, appropriately offset from the original member. Thus if P points to a member of an array object, the expression P+1 points to the next member of the array object. Unless both the pointer operand and the result point to a member of the same array object, or one past the last member of the array object, the behavior is undefined. Unless both the pointer operand and the result point to a member of the same array object, or the pointer operand points one past the last member of an array object and the result points to a member of the same array object, the behavior is undefined if the result is used as the operand of a unary * operator.


当一个加法运算,加号左边的操作数是一个指针,而右边的操作数是一个整数时,这个整数值先乘以指针类型的大小(sizeof(int)),然后再加到左边的数上。


这就解答了标题所述的第一个问题。


而标准的描述中另外一个值得注意的点是,两个地址相减的值会是什么?

问题呈现如下:

同样答案在C标准当中,见下文粗体。


When two pointers to members of the same array object are subtracted, the difference is divided by the size of a member. The result represents the difference of the subscripts of the two array members.The size of the result is implementation-defined, and its type (a signed integral type) is ptrdiff_t defined in the <stddef.h> header. As with any other arithmetic overflow, if the result does not fit in the space provided, the behavior is undefined. If two pointers that do not point to members of the same array object are subtracted, the behavior is undefined. However, if P points either to a member of an array object or one past the last member of an array object, and Q points to the last member of the same array object, the expression (Q+1) - P has the same value as (Q-P) + 1, even though Q+1 does not point to a member of the array object.


当同一个数组的两个成员的指针相减时,其差值为:地址值的差,再除以一个数组成员的size。这个结果代表了两个指针对应元素的下标之差。


所以大家才遇到了上图中所遇到的问题。这是C语言标准所规定的。



原文地址:http://blog.youkuaiyun.com/a2806005024/article/details/36422987

第3关:字符串比较 100 学习内容 参考答案 记录 评论 任务描述 相关知识 指向数组元素指针 引用数组元素指针的运算 引用数组元素 字符指针作函数参数 编程要求 测试说明 任务描述 本关任务:编写一个函数,实现两个字符串的比较。 相关知识 指针数组虽然是同的东西,但有着千丝万缕的联系。本关我们就来学习和数组有关的指针。 指向数组元素指针 一个指针变量既可以指向变量,也可以指向数组元素(即把某一个元素地址放到一个指针变量中)。 例如: int a[5] = {1,3,5,7,9}; int *p; p = &a[0]; 以上是使指针变量 p 指向 a 数组的第0个元素。 引用数组元素指针的运算 当指针指向数组元素时,可以对指针进行加和运算。 如上例子 p 指向数组元素 a[0] , p+1 则表示指向下一个数组元素 a[1] 。 在指针指向数组元素时,可以对指针进行以下运算: 加一个整数,如p+1 一个整数,如p-1 自加运算,如p++++p 自运算,如p--,--p 两个指针相减,如p1-p2(只有当 p1 和 p2 都指向同一个数组中的元素才有意义) 注意:如果指针变量 p 指向数组中的一个元素,则 p+1 指向同一数组中的下一个元素, p-1 指向同一数组中的上一个元素。 引用数组元素 引用一个数组元素,可以有两种方法: 下标法:如 a[i] 的形式。 指针法:如*(a+i)或*(p+i),其中 a 是数组名, p 是指向数组元素指针变量,其初为 p = a 。 说明:因为 p+i 是指向 p 所指元素后第 i 个元素指针,所以在其前加上指针运算符后得到的*(p+i)就是该元素的别名。因此,如果 p 指向 a[0],那么表达式*(p+i)就表示 a[i] 本身。 字符指针作函数参数 如果想把一个字符串从一个函数“传递”到另一个函数,可以用地址传递的办法,即用字符数组名作为参数。 也可以用字符指针变量作为参数,在被调用的函数中可以改变字符串的内容,在主调函数(现在有 A、B 两个函数,A 函数调用了 B 函数,那么,A 函数就是主调函数,B 函数就是被调函数)中可以引用改变后的字符串。 编程要求 在右侧编辑器中的Begin-End之间补充代码,以实现字符串比较的功能。具体要求如下: 函数原型为:int stringCompared(char * p1,char * p2);,设p1指向字符串 s1,p2指向字符串 s2 ; 当 s1 == s2 时,返回为0; 当 s1 != s2 时,返回他们两者第一个同的字符的 ASCII 码。即如果 s1 > s2 ,则输出一个正,如果 s1 < s2 ,则输出一个负。 测试说明 平台会对你编写的代码进行测试,比对你输出的数与实际正确数,只有所有数据全部计算正确才能通过测试: 测试输入:asd123 asd123 预期输出:0 测试输入:123456 12356789 预期输出:-1#include <stdio.h> /********** Begin **********/ //在此编写函数,实现字符串比较 /********** End **********/ … printf("%d",m); return 0; }
最新发布
06-18
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值