2016-10-30 118 views
1

纠正我,如果我错了,但我本以为这行代码:为什么const char * foo =“Hello”;编译但不是const int * foo = 5;?

const char *foo = "Hello"; 

意味着充满了“你好”的地方创建堆栈上字符数组,和Foo是一个指向它。在这种情况下,我不明白为什么这行代码给出了从‘诠释’到‘const int的*’

const int *foo = 5; 

“无效的转换将不会只是在栈上创建5的整数某处并具有FOO指向它?

+0

'5'是一个整数文字,它的类型是'int'。 '“hello”'是一个字符串文字,它的类型是'const char *'。所以'int!= int *'。 – DeiDei

+0

像“Hello”这样的const char *字符串通常会放在堆上,而不是放在堆栈上。 –

+1

@squeamishossifrage像这样的字符串文字不会堆积在大多数编译器上(也不会堆叠)。它将作为只读数据嵌入到二进制文件中。 –

回答

5

由于"Hello"char [N]类型(C)和const char[N](在C++),它衰减到类型char*(在C)或const char*(在C++)的string literal,相同另一方面,5是一个右值,它的类型是int,所以你不能将它绑定到类型为的指针。

您可能会感兴趣this有用。

+0

为什么它衰变为const char *? – Goldname

+0

@Goldname因为这些是从C继承的规则。这就是为什么你可以将字符数组传递给带有字符指针的函数。原因在于C(以及随后的C++)没有数组的复制语义(出于效率的原因),并且在传递数组时,您将指针有效地传递给它的第一个元素。假如它有复制语义,那么所有的数组在被传递时被复制,这被认为是低效的。你可以使用['std :: array'](http://en.cppreference.com/w/cpp/container/array)(这是一个围绕C风格数组的薄包装)来按值传递数组。 – vsoftco

+0

它在C中是'char [6]'类型,在C++中是'const char [6]'。 (这个问题有两个标签。) –

0

首先,您正在使用字符串文字来初始化foo的值。

在第一,FOO本身是一个常量字符指针,其在某些方面的“特殊”相对于其他指针。

对于大多数指针,如在你的第二个例子,你声明富作为一个常量指针为int,你初始化它的地址您希望为指针来。

换句话说,下面的代码:

const int *foo = 5; 

是错误的,因为你是在告诉编译器foo的地址为5的时候你真的想为foo指向的5

您可以使用取消引用操作符访问存储在foo中的值;你想说的是:

const int *foo = malloc(sizeof(int)); 
*foo = 5; 

字符串文字是一种特殊情况:它们是经过特殊处理的,因为C表示字符串由“\ 0”终止字符数组。

const char *foo = "Hello"; 

在 “你好\ 0” 设置的foo在字母 'H' 为指向的地址。以这种方式使用的所有字符串文本都存储在特定的内存部分,这部分内容往往是只读的;试图像这样修改foo:

foo[0] = 'W'; 

将导致未定义的行为。

字符串文字在初始化上下文中的特殊行为与数组偶尔衰变为指针的方式有关;当一个数组被分配给一个指针时,你确实声明你想要指向指向给定数组的第一个元素。

最后一点:

你可以编译器使用强制解释5作为存储器地址:

// In C: 
const int *foo = (const int*) 5; 
// In C++: 
const int *foo = reinterpret_cast<const int *>(5); 

但是,你的程序可能会崩溃,因为无论是存储在内存位置5可能无法通过您的程序访问。

0
// const char* c = 5; 
// const char* c = '5'; 
// const int* i = 7; 

只要没有接受转换,上面的三行就会产生编译时错误。所以c需要一个文字字符串,并传递一个字符或整数值。

这就像传递给它当单个字符不是字符串的strcmp发生什么:

char* name = "name"; 
char c = 'a'; 

if(strcmp(c, name));// error cannot convert first parameter from char to const char* 
相关问题