简体   繁体   English

指针算术与c中的char数组

[英]Pointer Arithmetic with array of char in c

Why if I increment an array string I get an error while if I pass the value to a function I can make it work? 为什么我增加一个数组字符串我得到一个错误,而如果我将值传递给一个函数我可以使它工作? A string array object is not already a pointer to the array elements? 字符串数组对象还不是指向数组元素的指针?

eg 例如

void foo(char *a){
    printf("%c", *a);
    a++; // this works
    printf("%c", *a);
}

int main(){
    char a[] = "ciao";
    a++; // I get the error
    foo(a);
    return 1;
}

thanks! 谢谢!

Because arrays are not pointers. 因为数组不是指针。 They may decay into pointers under certain circumstances (such as passing to a function, as you can see in your code) but, while they remain an array, you cannot increment them. 在某些情况下它们可能会衰减为指针(例如传递给函数,正如您在代码中看到的那样)但是,虽然它们仍然是数组,但您无法递增它们。

What you can do it create a pointer from the array such as by changing: 可以做什么从数组创建一个指针,例如通过更改:

foo(a);

to: 至:

foo(&(a[1]));

which will pass an explicit pointer to the second character instead of an implicit pointer to the first character that happens with foo(a); 它将传递一个指向第二个字符的显式指针,而不是一个指向foo(a);的第一个字符的隐式指针foo(a); .

Section 6.3.2.1 of C99 ("Lvalues, arrays, and function designators"), paragraph 3 has the definitive reason why you can't do what you're trying to do: C99的第6.3.2.1节(“左值,数组和函数指示符”),第3段有明确的理由说明为什么你不能做你想做的事情:

Except when it is the operand of the sizeof operator or the unary & operator, or is a string literal used to initialize an array, an expression that has type "array of type" is converted to an expression with type "pointer to type" that points to the initial element of the array object and is not an lvalue. 除非它是sizeof运算符或一元&运算符的操作数,或者是用于初始化数组的字符串文字,否则将类型为“array of type”的表达式转换为类型为“指向类型的指针”的表达式指向数组对象的初始元素,而不是左值。

It's that "not an lvalue" that's stopping you. 这不是一个阻止你的“不是左撇子”。 You cannot change it if it's not an lvalue (so named because they typically appear on the left of assignment statements). 如果它不是左值,则无法更改它(因为它们通常出现在赋值语句的左侧,因此命名)。

The reason you can do in your first function is because of section 6.7.5.3 ("Function declarators"), paragraph 7: 您可以在第一个函数中执行的原因是因为第6.7.5.3节(“函数声明符”),第7段:

A declaration of a parameter as "array of type" shall be adjusted to "qualified pointer to type" 参数声明为“类型数组”应调整为“限定类型的指针”

In other words, the parameter in the function is an lvalue pointer, which can be changed. 换句话说,函数中的参数左值指针, 可以更改。

The type of your foo's a is a pointer, which you can increment. 你的foo的类型是一个指针,你可以递增。

The type of your main's a is an array, which you cannot increment. 主要的a的类型是一个数组,你不能增加。

When you call foo, the address of your array is passed as a new variable of pointer type. 调用foo时,数组的地址将作为指针类型的新变量传递。 You can increment this without the original a being affected. 您可以在不受原始影响的情况下增加此值。

你可以尝试定义a像这个:

char* a = "ciao";

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM