为什么使用long作为数据类型make'隐式转换会丢失整数精度'消失?

时间:2018-04-26 15:20:38

标签: c arrays pointers

我知道这个标题有很多问题,但我不是在寻找解决方案。我想知道为什么会这样。 我将此作为解决方案

int points[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

int *pos = points + 5;

int index = pos - points;

但当我使用该代码时,我得到警告隐式转换失去整数精度:' long' to' int'。现在当我使用long作为索引的数据类型

int points[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

int *pos = points + 5;

long index = pos - points;

它没有发出警告。我试着用很长时间,因为我记得一些关于指针和长期的东西。但指针没有数据类型(如果我错了请纠正我)。点和* pos都用int初始化。那么为什么long fit和int不会呢?

为什么他们在解决方案中使用int?解决方案是错误的还是关于xCode(我正在使用)?

感谢您的回答

2 个答案:

答案 0 :(得分:7)

  

但是当我使用该代码时,我得到警告隐式转换失去整数精度:'long'到'int'。

这意味着您平台上的 ,两个指针的差异属于long类型。

  

我尝试使用很长时间,因为我记得有关指针和长时间的东西。但指针没有数据类型(如果我错了请纠正我)。

你错了,一切都有C中的类型。指针有指针类型。两个指针之间的区别是有符号整数类型,但标准没有指定哪一个,不同的平台将使用不同的类型。

但是标准通过名称typedef(在ptrdiff_t中定义)指定stddef.h,必须将其定义为指针差异的有符号整数类型,所以这就是你的类型用于您展示的代码类型。

  

使用int初始化点和* pos。那么为什么long fit和int不会呢?

类型指针指向的是与指针本身不同的东西。指针是地址,在您的系统上,地址可能大于int值。

  

为什么他们在解决方案中使用int?解决方案是否错误

是的,这是错的。如上所述,表达式pos - points某些有符号整数类型,在某些平台上可能是int,但您不能认为。

当然,以下情况也可以:

int points[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

int *pos = points + 5;

int index = (int)(pos - points);

在此示例中,您知道结果可以在int中表示,因此您可以通过显式转换来转换它。但是不要那样做一般

答案 1 :(得分:6)

index = pos - points;是两个指针之间的减法,其类型必须为ptrdiff_t

以下是C11标准委员会草案N1570§6.5.6的描述:

  

9。当减去两个指针时,两个指针都指向   相同的数组对象,或者超过数组最后一个元素的数组   宾语;结果是两者下标的差异   数组元素。结果的大小是实现定义的,并且   其类型(有符号整数类型) ptrdiff_t 在   <stddef.h>标题。

在您的系统中,类型ptrdiff_t可能是typedeflong,就像@FelixPalmen在评论中提到的那样,这就是编译器在您声明{{{ 1}}为index