将int *转换为const short int *

时间:2013-02-04 14:27:04

标签: c++ pointers casting int

我正在使用库中的函数,其中最重要的函数接受类型为const short int*的参数。我所拥有的是int *,并且想知道是否有一种方法可以将int *转换为const short int*。以下代码段突出显示了我面临的问题:

/* simple program to convert int* to const short* */


    #include <stdio.h>
    #include <iostream>
    #include <stdlib.h>

    void disp(const short* arr, int len) {

      int i = 0;
      for(i = 0; i < len; i++) {
        printf("ith index = %hd\n", arr[i]);
      }
    }

    int main(int argc, char* argv[]) {

      int len = 10, i = 0;
      int *arr = (int *) malloc(sizeof(int) * len);

      for(i = 0; i < len; i++) {
        arr[i] = i;
      }

      disp(arr, len);

      return 0;
    }

上面的代码片段编译。 这是我到目前为止所尝试的:
试过c式演员。函数调用看起来像这样:
disp((const short*) arr, len)。结果输出很奇怪:

ith index = 0
ith index = 0
ith index = 1
ith index = 0
ith index = 2
ith index = 0
ith index = 3
ith index = 0
ith index = 4
ith index = 0 
  1. 尝试了常数演员。函数调用看起来像:
    disp(const_cast<const short*> arr, len);
    这导致编译时出错。
  2. 我的问题:
    1.为什么方法1中的输出如此奇怪?那边发生了什么事? 2.我看到了一些使用方法2中的const cast去除常量的示例。我不知道如何添加相同的内容 3.有没有办法将int*投射到const short int*

    P.S:如果之前有过这样的问题,请告诉我。我用Google搜索并没有发现任何具体内容。

4 个答案:

答案 0 :(得分:5)

通常,从int *转换为short *不会产生有用的行为(实际上,如果您尝试取消引用生成的指针,它可能会导致未定义的行为)。它们指向基本不同的类型。

如果你的函数需要指向一堆short的指针,那么你需要给它。您需要创建一个short数组,并从原始数组中填充它。

答案 1 :(得分:4)

演员表几乎总是设计问题的标志。如果您的某个功能需要short*const或其他),则需要使用short*进行调用。因此,不是分配int数组,而是分配一个short数组。

当您将int*转换为short*时,您告诉编译器假装int*实际上是指向short的指针。它会这样做,但是对编译器撒了谎,你要承担后果。

答案 2 :(得分:3)

是的,所以short的SIZE与许多环境中的int不同(它不一定是,并且肯定有编译器例如具有16位{{} 1}}和16位int)。

所以你以这种方式投射指针的方法是:a)未定义的行为,b)除非你确切地知道你在做什么,否则可能不是你想要的。

你的代码的输出看起来非常好,我所期待的很明显,你没有告诉我们你想要做什么!

编辑:请注意,由于指针是“与大小相关的”,如果将一个大小的指针强制转换为指向不同大小类型的指针,则数据的对齐将是错误的,这就是为什么每隔一个值在输出中为零 - 因为short是4个字节[通常]而int是2个字节,指针将“逐步”为每个索引2个字节,(所以short将原始arr[i] + i * 2个字节。其中arr的'step'为4个字节,所以int * arr个字节。根据你的整数值,你会得到一些“半个整数“这个值 - 因为你的数字很小,这是零。

所以,虽然编译器完全按照你的要求去做:把一个指向arr + i * 4的指针指向一个包含short的内存块,它不会做你想象的那样do,即将每个int翻译成int。要做到这一点,你要么必须这样做:

short

如果这给出了错误的一半,你可以这样做:

short **sarr = malloc(sizof(short *) * 10); 

for(i = 0; i < 10; i++)
{
    sarr[i] = (short *)(&arr[i]);       // This may well not work, since you get the "wrong half" of the int.
}

但它取决于“字节顺序”(大端或小端),因此它不可移植。在一般代码中执行此操作是非常糟糕的编码风格。

或者:     short * sarr = malloc(sizof(short *)* 10);

     sarr[i] = (short *)(&arr[i])+1;      // Get second half of int.

第二种方法的作用是将整数数组的副本复制成一个短数组。这也不依赖于内容的存储顺序或类似的内容。当然,如果for(i = 0; i < 10; i++) { sarr[i] = (short)(arr[i]); } 中的值大于arr[i]中的值,则short中的值不会与arr[i]的值相同!

在这两种情况下,不要忘记在不再需要时释放阵列。

答案 3 :(得分:2)

回答q.1
输出并不奇怪。显然,您的编译器分配每个int 4个字节和每个short 2个字节。因此,您的arr大小为10x4 = 40个字节。当你为它分配数字0..9时,你有内存(每个字节一个字符,按int分组):

  

0 0 0 0
  0 0 0 1
  0 0 0 2
  0 0 0 3
  0 0 0 4
  ......

当您将arr转换为short时,内存现已“分组”为2个字节:

  

0 0
  0 0
  0 0
  0 1
  0 0
  0 2
  0 0
  ......

我希望你能看到效果,以及为什么你突然在你指定的数字之间有0 - s。

回答q.2
函数const中的display声明仅表示在执行arr期间display的内容不会更改。您无需将参数显式转换为const数组,以便调用display

回答q.3
请查看@Pete和@Mats

的答案