C 为什么这些变量显然改变了类型?

C 为什么这些变量显然改变了类型?,c,types,typedef,C,Types,Typedef,Python把我惯坏了,现在试图让我的思维围绕C是愚蠢错误的大屠杀。这个我不太明白 我想要Python的C等价物,但没有确切的等价物。看起来很相似,但需要一些按摩来简单使用 首先,我定义了我的路径类型:给定长度的字符串 #define MAX_PATH_LEN 200 /* sigh */ typedef char t_path[MAX_PATH_LEN]; 然后我写了一些代码来进行实际的按摩,试图避免副作用——只是为了让事情变得简单 typedef struct { t_path n

Python把我惯坏了,现在试图让我的思维围绕C是愚蠢错误的大屠杀。这个我不太明白

我想要Python的C等价物,但没有确切的等价物。看起来很相似,但需要一些按摩来简单使用

首先,我定义了我的路径类型:给定长度的字符串

#define MAX_PATH_LEN 200 /* sigh */
typedef char t_path[MAX_PATH_LEN];
然后我写了一些代码来进行实际的按摩,试图避免副作用——只是为了让事情变得简单

typedef struct {
    t_path next;
    t_path remainder;
} t_path_next

t_path_next path_walk_into(t_path path) {
    t_path_next output;

    t_path my_next, my_remainder = "/";
    strncpy(my_next, path, MAX_PATH_LEN);

    strsep(&my_next, my_remainder);

    output.remainder = my_remainder;
    output.next = my_next;
    return output;
}
然而,gcc并没有给人留下深刻印象

badp@delta:~/blah$ gcc path.c -Wall
path.c: In function ‘path_walk_into’:
path.c:39: warning: passing argument 1 of ‘strsep’ from incompatible pointer type
/usr/include/string.h:559: note: expected ‘char ** __restrict__’ but argument is of type ‘char (*)[200]’
path.c:41: error: incompatible types when assigning to type ‘t_path’ from type ‘char *’
path.c:42: error: incompatible types when assigning to type ‘t_path’ from type ‘char *’

我对这个注释感到困惑,
char**
char(*)[200]
到底有什么不同,但错误更为奇怪。我想在类型为
t\u path
的字段中分配一个我声明的变量
t\u path
,但我不能这样做

为什么呢


对于任何感兴趣的人,这里是该函数的正确工作版本:

t_path_next path_walk_into(t_path path) {
    t_path_next output;
    t_path my_path, delim = "/";
    char* my_path_ptr = my_path;    
    strncpy(my_path, path, MAX_PATH_LEN);

    strsep(&my_path_ptr, delim); //put a \0 on next slash and advance pointer there.

    if (my_path_ptr == NULL) //no more slashes.
        output.remainder[0] = 0;
    else
        strncpy(output.remainder, my_path_ptr, MAX_PATH_LEN);
    strncpy(output.next, my_path, MAX_PATH_LEN);

    return output;
}

错误:在C语言中,不能直接分配给数组(如字符串)。您需要逐个字符地复制字符,或者调用str(n)cpy,后者会为您执行此操作。

  • 警告:您可能已经意识到数组可能会衰减为指针。例如,这就是为什么数组可以作为一个函数的参数接受,而该函数需要指针。在您的例子中,您拥有的是一个指向数组的指针:没有理由将这样的东西转换为指向指针的指针

    为了记录在案,C99标准规定(6.3.2.1/3):

    除非它是sizeof运算符或一元&运算符的操作数,或者是 用于初始化数组的字符串文字,类型为“”的数组“”的表达式为 已转换为类型为“指向类型的指针”的表达式,该表达式指向 数组对象,并且不是左值

    您处于一元
    &
    的上下文中:您没有转换

  • 对于错误:它已经被回答了,但是数组分配不是直接可能的。您可能需要使用
    strcpy
    strncpy


问题的一部分在于,在C语言中,数组在各种情况下都会衰减为指针。如果您尝试使用
char*
而不是
char[…]
,则可能会得到更好的结果。不过,我还没有尝试过:)对数组类型使用
typedef
是一个确定的公式,或者会激怒所有读过你的代码并试图弄清楚它在干什么的人。不要这样做。如果前面的评论让你感到疑惑(它确实让我感到疑惑),这里是。在我看来,这并不是一个特别强的观点(代码仍然可以正常工作),但它仍然是一个有效的观点。“char**和char(*)[200]真的不同吗”-同样的
char*
int*
真的不同。它们指向不同的东西。第一个指向
char*
(并且
strep
被定义为将指针值存储到其第一个参数指示的位置),第二个指向
char[200]
。由于数组与指针不同,当需要指向指针的指针时,将指针传递给数组是没有好处的。多亏了这一点,所以显式转换是否足以将指向数组的指针更改为指向指针的指针?@badp:否。strep需要指向指针的指针,因此它可以更改(第二个)指针。您的变量my_next是一个t_路径,它是一个数组而不是指针,因此strep没有要更改的指针!