指针的C-Array不同的索引方式

时间:2014-07-11 16:30:33

标签: c arrays pointers

#include<stdio.h>
#include<string.h>

main () {
    char *line[5];
    int i;
    line[0] = "line 1";
    line[1] = "line 2";
    line[2] = "line 3";
    line[3] = "line 4";
    line[4] = "line 5";

    char *p;
    p=line[2];
    //*p = *(p+2);  //gives error as segmentation fault.
    printf("\n coming here : %s",*line); //works fine
    printf("\n coming here : %s",*line++); //gives error "invalid increment in main"
    printf("\n coming here : %s",*(line+2)++); //error, i assumed it will work as *(line+2) is also a pointer
    printf("%c",*(line[4]+1));//works, prints character 'i'
    printf("%c",**(line+4));//segmentation error, i assumed it to print character 'l'
}

我正在尝试这个程序并遇到一些错误,正如我在每行代码旁边的注释中提到的那样。

with char * line [5]我试图实现一个指针数组,每个指针元素指向一个字符串。

请帮助我澄清我在这里做错了什么。感谢。

编辑1:

我只包含了部分示例,请参阅writelines函数。这个例子的其余部分很简单,不包括它。

#define MAXLINES 5000 /* max #lines to be sorted */ 
char *lineptr[MAXLINES]; /* pointers to text lines */

int readlines(char *lineptr[], int maxlines)
{
    int len, nlines;
    char *p, line[MAXLEN];
    nlines = 0;
    while ((len = getline(line, MAXLEN)) > 0)
        if (nlines >= maxlines || p = alloc(len) == NULL) return -1;
        else {
            line[len-1] = '\0'; /* delete newline */ strcpy(p, line);
            lineptr[nlines++] = p;
        }
    return nlines;
}

/* writelines: write output lines */
void writelines(char *lineptr[], int nlines)
{
    while (nlines-- > 0)
        printf("%s\n", *lineptr++); // this is where they are incrementing array, which you said is incorrect.
}

编辑2:

main(int argc, char *argv[])
{
    char *line[] = {"linawee 1", "lipe 2", "lint 3", "linr 4"};
    while (--argc > 0) //command line input has same number of elements as 'line'
    {
        printf("%s%s", *++argv, (argc > 1) ? " " : ""); //works just fine.
        printf("%s", *++line); //error
    }
}

请解释上面的编程,为什么它适用于一个并为其他人提供错误。 感谢。

4 个答案:

答案 0 :(得分:4)

所以,让我们迭代错误:

第1行:

*p = *(p+2);

您正在修改字符串文字。这是不允许的。

第2行:

printf("\n coming here : %s", *line);

*line会产生与line[0]相同的值,所以这一切都有意义。

第3行:

printf("\n coming here : %s", *line++);

line是一个数组。您不允许增加数组。因此line++无效。

第4行:

printf("\n coming here : %s", *(line+2)++);

这实际上意味着:

printf("\n coming here : %s", *(line + 2);
(line + 2) = (line + 2) + 1;

哪个无效,因为您无法分配到line + 2

第5行:

printf("%c", *(line[4]+1));

是的,没关系。我们在索引4处获取字符串,然后在索引1处获取其中的字符。

第6行:

printf("%c", **(line+4));

这应该可以正常工作。不清楚你为什么会收到错误。

关于编辑1:

void func(char *lineptr[]) {
    *lineptr++;
}

无论出于何种原因,C允许您在函数调用期间使用数组表示法。在这种情况下,如果您的函数参数为:char *lineptr[],则会将其视为char **lineptr

因此,在这种情况下,你实际上是在增加指针而不是数组,这就是它被允许的原因。

但请注意,指针的增量仅在函数内可见。也就是说,如果我这样做:

int main() {
    char * arr[] = {"hi", "how", "are", "you"};
    inc(arr);
    // arr[0] still points to "hi"
}

void inc(char *arr[]) {
    // arr[0] points to "hi"
    arr++;
    // arr[0] now points to "how"
}

关于编辑2:

char *line[] = {"linawee 1", "lipe 2", "lint 3", "linr 4"};
printf("%s", *++line);

您正在递增数组。你不允许那样做。你当然可以这样做:

printf("%s", line[3]);
printf("%s", *(line + 3)

答案 1 :(得分:2)

请参阅:lvalue required as increment operand

line不是指向动态内存的指针,它是在堆栈上声明的数组。所以line ++无效。

答案 2 :(得分:1)

虽然在C语言中它们具有非const字符数组的类型,但可能不会更改字符串文字。在本声明中

//*p = *(p+2);  //gives error as segmentation fault

您正在尝试更改p。

指向的字符串文字

对于其他错误,表达式中的数组将转换为指向数组第一个元素的rvalue指针。您可能不会增加rvalue。因为很明显,例如表达式

(line+2)++

实际上相当于以下代码

int x = 0;

( x + 2 )++;

此处编译器将发出错误,因为表达式( x + 2 )不是lvalue

答案 3 :(得分:0)

这里有一个问题

您正在尝试分配一个右值(外行术语:应该在等式右边的值,以及不应该修改的常量)

#include<stdio.h>
#include<string.h>

int main () {
    char *line[5];
    line[0] = "line 1";
    line[1] = "line 2";
    line[2] = "line 3";
    line[3] = "line 4";
    line[4] = "line 5";
    char *p;
    p=line[2];
//  *p = *(p+2);  // *p is a gives you  a character, this means you are trying to assign character with character?
    p = p + 2; // correct way
    printf("%s\n", p); // outputs: "ine 3", expected
    printf("coming here : %s\n",*line); // this is fine
//    printf("\n coming here : %s",*line++); //  Same reason as above and below
//    printf("\n coming here : %s",*(line+2)++); //*(line + 2)++ means *(line + 2) = *(line + 2) + 1 => see the error?
    printf("%c\n",*(line[4]+1)); //works, prints character 'i'
    printf("%c\n",**(line+4));// this prints l on my machine and is valid.
    return 0;
}