好的,首先要记住的是,没有“指向数组”的指针之类的东西,尽管您会经常听到这种说法。太草率了。
(正如下面所指出的,术语“指向数组的指针”确实有严格的含义——但我坚持认为你已经被它弄糊涂了。真正发生的是每个指针都包含一个地址。根据声明,编译器可以识别它是否在上下文中正确使用,这就是您的错误消息真正告诉您的内容:您在函数中声明的是指向字符数组的指针,也就是说同样的事情作为char **,而不是char *,这就是你要传递的。但是char *,或char **,或char ******,重要的是你让它太复杂了——你已经有了你需要的由数组名称标识的地址。)
指针是指针,它们是地址。
C 中的数组只是一个分配的内存块,它的名称表示第一个元素的地址。所以
char a[42];
是一块42个字符长的内存块,a是它的地址。
你可以将你的第二个函数重写为
void foo(char* a, int num){ // (3)
// notice that you don't need the word function and
// for lots of reasons I wouldn't use it as a function name.
a[num] = 'A'; // (4)
}
int main(){
// Sadly "00000" IS a string no matter what your comment
// says. Use an array initializer instead.
char arry[5] = {'0','0','0','0','0' } ; // (1)
foo(arry,3); // (2)
}
这就是我相信您的代码所要做的事情。请注意
(1) 由于 "00000" 确实是一个字符串,它实际上是在创建一个数组 6 个元素长,该数组可以使用数组初始化器进行初始化
{'0','0','0','0','0', 0 }
(2) 数组(我将其命名为 'arry' 而不是 'this',因为 'this' 通常是类 C 语言中的关键字,为什么会有混淆的风险?)已经是一个地址(但 不是 一个指针。它可以在指针赋值的右侧,但不能在左侧。)
所以当我打电话时
foo(arry,3);
我用 arry 的第一个元素的地址和数字 3 调用 foo(您不需要为此声明变量。)
现在,我可以也写成
foo(&arry[0],3);
您可以将其理解为“找到 arry 的第 0 个元素,获取其地址。”它是 C 中任何数组的标识
char c[len];
表达式c 和&c[0] 指的是同一个地址。
(3) 也可以定义为foo(char arry[], int num)。这些是等价的。
(4) 当您引用a[num] 时,您直接引用了a 指向的内存的第num 个元素,它位于数组@987654340 的开头地址处@。你不需要所有的取消引用。
不要担心这有点难以理解——每个人开始 C 时都很难。