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

在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语言标准所规定的。

C语言中,为什么指针表达式的值+1.对应的地址值却+4?/为什么两个数组元素的地址相减之差不为地址之差?,布布扣,bubuko.com

时间: 2024-10-26 13:50:47

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

c语言中,指针加1的情况.指针变量详细介绍

指针是一个特殊的变量,它里面存储的数值被解释成为内存里的一个地址. 要搞清一个指针需要搞清指针的四方面的内容: 指针的类型, 指针所指向的 类型, 指针的值或者叫指针所指向的内存区, 还有指针本身所占据的内存区. 让我们分别说明. 先声明几个指针放着做例子:  例一:  (1)int *ptr;  (2)char *ptr;  (3)int **ptr;  (4)int(*ptr)[3];  (5)int*(*ptr)[4]; 指针的类型  从语法的角度看,你只要把指针声明语句里的指针名字去掉,

c语言中%p指针

%p与指针对应,是输出指针的地址 如: char * p="abc"; ...... printf("The address %p is %s", p, p); 输出就如同这样 The address 0FEA is abc

C语言中void *指针与空指针区别

void* 这不叫空指针,这叫无确切类型指针.这个指针指向一块内存,却没有告诉程序该用何种方式来解释这片内存.所以这种类型的指针不能直接进行取内容的操作.必须先转成别的类型的指针才可以把内容解释出来. 还有'\0',这也不是空指针所指的内容. '\0'是表示一个字符串的结尾而已,并不是NULL的意思. 真正的空指针是说,这个指针没有指向一块有意义的内存,比如说:char* k;这里这个k就叫空指针.我们并未让它指向任意地点.又或者char* k = NULL;这里这个k也叫空指针,因为它指向NU

Java 语言中 Enum 类型的使用介绍

Enum 类型的介绍 枚举类型(Enumerated Type) 很早就出现在编程语言中,它被用来将一组类似的值包含到一种类型当中.而这种枚举类型的名称则会被定义成独一无二的类型描述符,在这一点上和常量的定义相似.不过相比较常量类型,枚举类型可以为申明的变量提供更大的取值范围. 举个例子来说明一下,如果希望为彩虹描绘出七种颜色,你可以在 Java 程序中通过常量定义方式来实现. 清单 1. 常量定义 Public static class RainbowColor { // 红橙黄绿青蓝紫七种颜

【C语言】指向一维数组元素的指针

本文目录 一.用指针指向一维数组的元素 二.用指针遍历数组元素 三.指针与数组的总结 四.数组.指针与函数参数 前面我们已经学习了指针,如果指针存储了某个变量的地址,我们就可以说指针指向这个变量.数组及其数组元素都占有存储空间,都有自己的地址,因此指针变量可以指向整个数组,也可以指向数组元素. 回到顶部 一.用指针指向一维数组的元素 1 // 定义一个int类型的数组 2 int a[2]; 3 4 // 定义一个int类型的指针 5 int *p; 6 7 // 让指针指向数组的第0个元素 8

【C语言】-指向一维数组元素的指针

本文目录 一.用指针指向一维数组的元素 二.用指针遍历数组元素 三.指针与数组的总结 四.数组.指针与函数参数 说明:这个C语言专题,是学习iOS开发的前奏.也为了让有面向对象语言开发经验的程序员,能够快速上手C语言.如果你还没有编程经验,或者对C语言.iOS开发不感兴趣,请忽略 前面我们已经学习了指针,如果指针存储了某个变量的地址,我们就可以说指针指向这个变量.数组及其数组元素都占有存储空间,都有自己的地址,因此指针变量可以指向整个数组,也可以指向数组元素. 回到顶部 一.用指针指向一维数组的

C语言 12-指向一维数组元素的指针

本文目录 一.用指针指向一维数组的元素 二.用指针遍历数组元素 三.指针与数组的总结 四.数组.指针与函数参数 说明:这个C语言专题,是学习iOS开发的前奏.也为了让有面向对象语言开发经验的程序员,能够快速上手C语言.如果你还没有编程经验,或者对C语言.iOS开发不感兴趣,请忽略. 前面我们已经学习了指针,如果指针存储了某个变量的地址,我们就可以说指针指向这个变量.数组及其数组元素都占有存储空间,都有自己的地址,因此指针变量可以指向整个数组,也可以指向数组元素. 一.用指针指向一维数组的元素 1

[C++程序设计]指向数组元素的指针

如果先使p指向数组a的首元素(即p=a),则: (1) p++(或p+=1).使p指向下一元素,即a[1]. 如果用*p,得到下一个元素a[1]的值. (2) *p++.由于++和*同优先级,结合方向为自右而 左,因此它等价于*(p++).作用是: 先得到p指向 的变量的值(即*p),然后再使p的值加1.例6.5(3)程序中最后一个for语句: for(p=a;p<a+10;p++) cout<<*p;可以改写为for(p=a;p<a+10;) cout<<*p++;

C++中cout输出字符串和字符串型指针地址值的方法以及C语言中的printf用法比较

#include <iostream> using namespace std; #include <stdio.h> int main() { char *pstr = "china"; char *qstr = "america"; char *q = "adf"; char * s; s = "hello"; printf("pstr = %p\n", pstr); /*输出为