请考虑以下代码:
void Increment(int *arr) {
arr++;
}
int main() {
int arr[] = {1,2,3,4,5};
// arr++ // illegal because its a const pointer
Increment(arr); // legal
}
我的问题是如果arr
是一个const指针,我怎么能把它发送到一个没有接收到const指针的函数?
代码编译时没有丢弃const限定符的警告。
答案 0 :(得分:10)
我的问题是如果arr是一个const指针,我怎么能把它发送给一个没有接收到const指针的函数?
arr
(在main()
内)不是const指针,它是一个数组。传递给函数时,数组类型会衰减为指针类型。
arr
内的 Increment
(参数)包含参数arr
的地址副本(通过main()
的值传递)。
// arr ++ // ileagal因为它是一个const指针
这是非法的,因为arr
是不可修改的lvalue
。
答案 1 :(得分:7)
不要被指针愚弄。同样适用于平原:
const int a = 42;
int b = a; // How can I assign a const int to a non-const int?
int c = 4; // Come to think of it, the literal 4 is a constant too
void foo (int x) { std::cout << x; }
foo(a); // How come I can call foo with a const int?
总之,const
分别适用于每个对象。 const对象的副本也不需要是const。
答案 2 :(得分:3)
您无法在int arr[]
中增加main
的原因是因为它不是可修改的左值。标准说:
可修改的左值是一个左值 没有数组类型,没有 有一个不完整的类型,没有 一个const限定类型,如果它是一个 结构或联合,没有任何 成员(包括,递归,任何 所有成员或元素 聚合或联合)与 const限定类型。
增量运算符++
需要一个可修改的左值(因为它修改)。但是Increment
函数中的指针是一个可修改的左值(它不是数组类型,它是一个指针),这就是为什么它在那里是合法的。
答案 3 :(得分:1)
你没有在main()中增加数组,你在Increment()中递增局部变量(参数)
答案 4 :(得分:1)
函数内部的'arr'与main中的'arr'不同。你给了他们相同的名字。
main是一个数组,我很惊讶它的声明编译。通常你会这样做:
int arr[] = {1,2,3,4,5};
但是函数中的'arr'只是一个普通的指针,所以它可以递增。
如果您在main中添加
int *arr2 = arr;
然后你有更好的运气增加arr2。或者,您可以添加一个可以递增并用于索引到arr数组的索引。
答案 5 :(得分:0)
我的问题是如果arr是一个常量指针
它不是const
指针。
这是你如何声明一个const指针。
const char constArray[] = { 'H', 'e', 'l', 'l', 'o', '\0' };
C标准(C99 6.3.2.1/3)说“除非它是sizeof运算符或一元&amp;运算符的操作数,或者是用于初始化数组的字符串文字,否则表达式具有类型''类型''的数组被转换为类型为''指向类型'的指针的表达式,指向数组对象的初始元素,而不是左值。
int b[100]; // b is an array of 100 ints.
int* p; // p is a pointer to an int.
p = b; // Assigns the address of first element of b to p.
p = &b[0]; // Exactly the same assignment as above.
p = b; // Legal -- p is not a constant.
b = p; // ILLEGAL because b is a constant, altho the correct type.
来源:http://www.fredosaurus.com/notes-cpp/arrayptr/26arraysaspointers.html
答案 6 :(得分:0)
arr是int类型的const指针,它保存第一个元素的地址,这里是值1的地址.const定义不能更改arr中包含的地址。 这个说法 增量(ARR); 传递arr中包含的地址,类型为int * 这就是为什么编译器不抱怨。
答案 7 :(得分:-1)
这是因为函数Increment
仅更改其本地版本的arr,而main()作用域中的arr实际上并未更改。因此,根据函数参数忽略变量上的const。
void func(void* param) {}
int main() {
void *a;
void *const b;
void const *c;
void const *const d;
func(a); // legal
func(b); // legal, constantness of variable doesn't matter, because the function can't change it anyway
func(c); // illegal
func(d); // illegal
}