将 int* 转换为 const short int*
Cast int* to const short 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 = %hdn", 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;
}
上面的代码片段编译。这是我到目前为止尝试过的:
1.尝试了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
- 尝试了恒定性演员表。函数调用如下所示:
disp(const_cast<const short*> arr, len);
这导致编译时出错。
我的问题:
1. 为什么方法 1 中的输出如此奇怪?那边是怎么回事?
2. 我看到一些示例,这些示例使用方法 2 中的常量转换来消除常量。我不知道如何添加相同的内容。
3. 有没有办法将int*
投射到const short int*
?
PS:如果以前有人问过此类问题,请告诉我。我用谷歌搜索了一下,没有找到任何具体的东西。
通常,从 int *
转换为 short *
不会提供有用的行为(事实上,如果您尝试取消引用生成的指针,可能会导致未定义的行为)。 它们是指向根本不同类型的指针。
如果你的函数需要一个指向一堆short
的指针,那么这就是你需要给它的。 您需要创建一个 short
数组,并从原始数组填充它。
铸件几乎总是设计问题的标志。如果你有一个接受short*
的函数(const
或其他),你需要用short*
调用它。因此,与其分配一个int
数组,不如分配一个short
数组。
当您将int*
强制转换为short*
时,您告诉编译器假装int*
实际上是指向short
的指针。它会这样做,但是对编译器撒谎后,您要对后果负责。
对,所以在许多环境中,short
的 SIZE 与int
不同(不一定是这样,而且肯定有编译器,例如具有 16 位int
和 16 位short
)。
因此,以这种方式投射指针的结果是,a)未定义的行为,以及b)除非你确切地知道自己在做什么,否则可能不是你想要的。
您的代码输出看起来与我的期望完全一致,所以很明显您没有告诉我们您正在尝试做什么!
编辑:请注意,由于指针是"大小相关的",如果您将一种大小的指针投射到指向不同大小类型的指针,则数据的对齐将是错误的,这就是为什么输出中所有其他值均为零的原因 - 因为int
是 4 个字节 [通常] 和一个short
是 2 个字节, 指针将为每个索引"步进"2 个字节,(因此arr[i]
将是原始arr
+ i * 2 字节。 其中int * arr
的"步长"为 4 个字节,因此 arr + i * 4
个字节。根据您的整数值,您将从中获得一些"半个整数"值 - 由于您的数字很小,因此为零。
因此,当编译器完全按照您的要求进行操作时:使指针指向short
指向包含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.
}
如果这给出了错误的一半,您可以这样做:
sarr[i] = (short *)(&arr[i])+1; // Get second half of int.
但它取决于"字节顺序"(大端序或小端序),因此它不可移植。在一般代码中执行此操作是非常糟糕的编码风格。
或: short *sarr = malloc(sizof(short *) * 10);
for(i = 0; i < 10; i++)
{
sarr[i] = (short)(arr[i]);
}
第二种方法的工作原理是将整数数组的副本复制到短数组中。这也不取决于内容的存储顺序或类似的东西。当然,如果arr[i]
中的值大于short
可以容纳的值,则不会获得与short
中的arr[i]
相同的值!
在这两种情况下,当不再需要阵列时,不要忘记释放阵列。
对 q.1
的回答输出一点也不奇怪。显然,您的编译器为每个int
分配 4 个字节,每个short
2 个字节。因此,您的arr
大小为 10x4 = 40 字节。当您为它分配数字 0..9 时,您在内存中(每个字节一个字符,按 int
分组):
0 00 0
0 0 0 1
0 0 0 2
0 0 0 3
0 0 0 4
...
当您将arr
转换为short
时,内存现在被"分组"为2个字节:
00
0 0
0 0
0 1
0 0
0 2
0 0
...
我希望你能看到效果,以及为什么你突然在你分配的数字之间有0
-s。
对问题2
的答复函数display
中const
的声明仅表示arr
的内容在执行display
过程中不会改变。您无需将参数显式转换为数组const
即可调用display
。
对问题3
的答复请按@Pete和@Mats查看答案
- 'short int'持有的值溢出,但"自动"不会溢出?
- 从“ int”到'int16_t {aka short int}'内部{}的“((int)a) -1)”的缩小转换
- 如果超过 short int(c++) 的最大值会发生什么
- C++ 中有符号 int 和无符号 short 的比较
- Short Int基掩码在C 库子弹中的工作方式
- 为什么C/C++会自动将char/wchar_t/short/bool/enum类型转换为int
- 为什么编译器将"char"与"int"匹配而不是"short"?
- 为什么 foo(short int *) 和 bar(signed short *) 认为 QT 的签名不同
- 错误:从 'short unsigned int*' 到"短无符号 int"的转换无效|(在 C++ 中)
- wchar_t*到short int的转换
- 将无符号short/int强制转换为char*
- 像javashort[]一样在c中创建short int数组
- C/C++:在32位机器上的sizeof(short)、sizeof(int)、sizeof(long)、size of
- 对'icu_56::UnicodeString::UnicodeString(signed char, unsigned short const*, int)' 的未定义引用
- 将无符号字符转换为 int 和 short
- gcc 奇怪的转换警告(<B>从"int"转换为"A::count_type {aka short unsigned int}"可能会改变其值)
- 对类中的整数成员变量使用short、int或long
- 让template通过指定bitsize在char/short/int之间进行选择
- 是实现定义的unsigned short + int类型
- 为什么在C和c++中进行算术运算之前必须将short类型转换为int类型?