我正在编写一个函数来接受unsigned char *和int *:
int foo(const int * a)
然而,当我将unsigned char * a传递给foo()时,它有这个编译错误。我以为unsigned char会自动转换为int吗? (较小的范围变量将被铸造成较大的变量)。它也适用于数组指针吗?
示例代码:
#include <iostream>
using namespace std;
int average(const int * array, int size)
{
int sum = 0;
for (int i = 0; i <size; i++)
sum+=*(array+i);
return sum/size;
}
int main() {
unsigned char array[5] = {0,1,2,3,4};
std::cout << average(array, 5);
return 0;
}
编写接受unsigned char *和int *?
的函数的最佳方法是什么?答案 0 :(得分:6)
我以为unsigned char会自动转换为int?
unsigned char
会自动投放到int
,但unsigned char*
不会自动投放到int*
。
unsigned char c = 'a';
unsigned char* cp = &a;
int i = c; // This is allowed
int* ip = cp; // This is not allowed
如果允许,你可以这样做:
*ip = INT_MAX;
但&c
没有足够的空间来容纳这个数字。您将最终访问未经授权的内存,这将立即导致未定义的行为。
答案 1 :(得分:3)
欢迎使用某种类型的安全性。 const int
和unsigned char
是完全不同的类型。两者之间的隐式转换将是类型系统中的一个巨大缺陷。
只有3种类型的有效指针转换,在标准的第4.10节中描述:
从空指针prvalue到指针类型。例如:
const int* ptr = nullptr;
具体而言:
空指针常量是值为零的整数文字(2.14.2)或类型为std :: nullptr_t的prvalue。空指针常量可以转换为指针类型;结果是该类型的空指针值,并且可以与对象指针或函数指针类型的每个其他值区分开。这种转换称为空指针转换。相同类型的两个空指针值应相等。将空指针常量转换为指向cv限定类型的指针是单个转换,而不是指针转换的序列,后跟限定转换(4.4)。可以将整数类型的空指针常量转换为std :: nullptr_t类型的prvalue。 [注意:生成的prvalue不是空指针值。 - 结束说明]
void*
我说“某种类型系统”的原因正是如此。 [const] void* [const]
可以表示任何指针类型,只要它是相同的常量限定符:
const int* x = ...;
const void* vx = x; // OK
const int* y = ...;
void* vy = y; // Nope
具体描述如下:
类型为“指向cv T的指针”的prvalue,其中T是对象类型,可以转换为类型为“指向cv void的指针”的prvalue。将指针的非空指针值转换为对象类型的结果为“指向cv void的指针”表示内存中与原始指针值相同的字节的地址。空指针值将转换为目标类型的空指针值。
最后,我们有多态指针:指向基类的指针:
class B { ... };
class C : public B { ... };
class D : public B { ... };
...
C* c = new C();
D* d = new D();
B* b1 = c; // Yup
B* b2 = d; // Yup
D* dw = b1; // Nope. If you really want this UB you need to use `dynamic_cast`
具体做法是:
类型为“指向cv D的指针”的prvalue,其中D是类类型,可以转换为类型为“指向cv B的指针”的prvalue,其中B是D的基类(第10节)。 B是D的不可访问(第11条)或模糊(10.2)基类,需要这种转换的程序是不正确的。转换的结果是指向派生类对象的基类子对象的指针。空指针值将转换为目标类型的空指针值。
答案 2 :(得分:1)
指针的范围相同,因为它们都是指针。问题是它们都可以被[]索引,但是int和char的字节步长是不同的,它们是4和1.
如果要传递一个数组,则必须将字符复制到一个int数组中,这样它们就像内存中的int一样。
void char_array_to_int_array(int *ints, char *chars, int length){
for(int i=0; i<length; i++){
ints[i]=chars[i]; //Here the cast will happen
}
}
或者,您可以再次为char *定义函数作为参数,以便可以正确计算索引。
实际上我刚刚意识到你的问题是多态,你想要一个像这样的模板函数:
template <class T>
int average(T *array, int size){
int sum = 0;
for (int i = 0; i <size; i++)
sum+=*(array+i);
return sum/size;
}
这里编译器将为程序中调用它的每个类型编译此函数。我应该尽快意识到实际问题,而不是谈论类型和演员。
这可以像平常一样调用。
char a[4] = {1,2,3,4};
int i[4] = {1,2,3,4};
cout << "The ints: " << average(i,4) << endl;
cout << "The chars: " << average(a,4) << endl;