这个使用字符串的非常简单的C程序有什么问题?

时间:2014-02-23 17:30:53

标签: c c-strings

自90年代以来我没有使用过C,所以我可能有一个大脑放屁,但下面的程序有什么问题?使用gcc 4.8我会收到各种警告,然后在运行时出现分段错误。谢谢你的帮助。

#include <stdio.h>

void print_string(char **a, char **b)
{
    printf("a string: \"%s\"\n", a[5]);
    printf("another string: \"%s\"\n", b[9]);

    return;
}

int main(void)
{
    int i, j;
    char a[10][10];
    char b[10][10];

    for(i = 0; i < 10; ++i)
    {
        for(j = 0; j < 9; ++j)
        {
            a[i][j] = 'x';
            b[i][j] = 'y';
        }
        a[i][9] = '\0';
        b[i][9] = '\0';
    }

    printf("a string: \"%s\"\n", a[3]);
    printf("another string: \"%s\"\n", b[7]);
    print_string(a, b); 

    return 0;
}

4 个答案:

答案 0 :(得分:3)

编译器不知道多维数组ab的维度,因此您必须在函数声明中指定它们:

void print_string(char a[][10], char b[][10])

详细信息:

  • 在函数main中,声明一个数组char a[10][10],其中包含100个char s

  • 编译器正确a[i]翻译为(char*)((int)a+10*sizeof(char)*i)

  • 然后,您将其传递给函数print_string,其中它被声明为指针char** a

  • 编译器错误地a[i]翻译为(char*)((int)a+sizeof(char*)*i)

答案 1 :(得分:2)

您认为数组是指针。指向不是2D数组的指针的指针。衰减到指针后,ab的类型为char (*)[10],但您的函数需要char **类型的参数。永远记住数组不是指针 将您的功能更改为

void print_string(char (*a)[10], char (*b)[10]) {...}

答案 2 :(得分:0)

很高兴知道a[i]实际上是*(a+i)。众所周知,a+i的结果是a_as_number + i * sizeof(*a)。您可以告诉char** asizeof(*a)为8(在64位平台上),而对于char a[10][10]sizeof(*a)为10(10个字符)。

指针包含运行时地址编译时类型信息。这两个指针有不同的类型信息。要纠正这个问题,只需将main中的数组更改为指针数组,然后让它们指向某个地方。

答案 3 :(得分:0)

首先,您应该阅读并修复生成警告的代码。如果您仍然不明白为什么您的代码不起作用,下面是调试printfs的示例。

#include <stdio.h>

void print_string(char **a, char **b)
{
    printf("in print_string\n");
    printf("a = %p\n", a); // outputs pointer's value
    printf("a[5] = %p\n", a[5]); //outputs the value stored at (a + 5*sizeof(pointer)), which you pass to printf
    printf("a[5] = %p\n", *(a + 5)); //same as above
    printf("a[5] address = %p\n", &a[5]);
    printf("a[5] address = %p\n", (a + 5));
}

int main(void)
{
    int i, j;
    char a[10][10];
    char b[10][10];

    for(i = 0; i < 10; ++i)
    {
        for(j = 0; j < 9; ++j)
        {
            a[i][j] = 'x';
            b[i][j] = 'y';
        }
        a[i][9] = '\0';
        b[i][9] = '\0';
    }

    printf("a string: \"%s\"\n", a[3]);
    printf("another string: \"%s\"\n", b[7]);

    printf("a's address = %p\n", a);
    printf("a[0, 0]'s address = %p\n", &a[0][0]);
    printf("a[1, 0]'s address = %p\n", &a[1][0]);
    printf("a[5, 0]'s address = %p\n", &a[5][0]);
    print_string(a, b); 


    return 0;
}