我在做错了,将char数组传递给函数,并在函数中给出每个索引内存(使用malloc()),然后使用gets()从键盘插入一些东西。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
void test(char *arr[]);
int main(){
char *arr[2];//2 is the rows
/* arr[0] = malloc(80);//This commented code works
arr[1] = malloc(80);
strcpy(arr[0], "hey");
strcpy(arr[1], "whats up");
*/
test(*arr);
printf("in array[0]: %s", arr[0]);
printf("in array[1]: %s", arr[1]);
return 0;
}
void test(char *arr[]){
int index;
char *input = malloc(80);
for(index = 0; index < 2; index++){
arr[index] = malloc(80);
gets(input);
strcpy(arr[index], input);
//arr[0] = input;
}
}
这是一个非常基本的程序,由于某些原因我遇到了麻烦。还有一个问题当我声明一个数组时这些形式之间有什么区别
char *array
反对
char *array[size]
或
char **array
谢谢, 凯文
答案 0 :(得分:3)
您将arr
声明为char *arr[2]
。然后,您传入*arr
,其类型为char*
进行测试。但测试需要char *[]
。这样就行不通了。您应该直接传递arr
,即test(arr)
。
char * array
是指向字符的指针,通常用于指向字符数组中的第一个字符,即字符串。
char **array
是指向字符指针的指针。通常用于表示字符串数组。
char *array[size]
大致相当于上面的那个,但它不同,那个,顶级指针已经指向一个有效的数组,所以数组不需要malloc
ed。
顺便说一句,您的test
函数可以简化一点:strcopy
是不必要的。
void test(char *arr[])
{
int i;
for(i=0;i<2;i++)
{
arr[i] = malloc(80);
gets(arr[i]);
}
}
答案 1 :(得分:1)
好的,在C声明中,您只能获得从声明中读取的第一个分配内容。
在您了解如何阅读声明之前,这有点模糊。
运算符具有优先权,该优先权适用于声明。为简单起见,请:
() - Either raises precedence, or means "function taking parameters and returning..."
[] - Array of
* - Pointer to (right associative)
所以,宣言:
char *a[3];
是&#34;指向char&#34;的3个指针的数组,而
char (*a)[3];
是一个&#34;指向3 char&#34;数组的指针。 (指向行数为3的多调焦字符数组的行的指针)
编译器在堆栈上分配第一个东西。因此,在第一个示例中,您将获得三个能够指向(尚未分配的)字符的指针。
| ptr | --> (unallocated char)
| ptr | --> (unalloc char)
| ptr | --> (unalloc char)
在第二个:
| ptr | --> (unallocated block of 3 char)
下一个规则是:如果你有一个指针,你有一个数组。因此,在这两种情况下,您最终都会得到多维数组。
在第一个中,行数是固定的(您已经分配了它),但每行可以有不同的大小,因为编译器知道指针可以被char偏移以到达下一个char。
在第二种情况下,你有一个固定的行大小,但编译器知道如何偏移你的基指针(每个3个字符),所以你有任意数量的行。
C也是一种按值调用的语言。所以,如果你宣布了一个变量:
char *a[3];
然后&#39; a&#39;本身是&#34;一个3 ptr到char&#34;的数组,但是[0]是&#34; ptr到#&#34;和[0] [0]是char。
当你编写一个期望的函数时:
void f(char *arg[]) {
...
}
你必须传递一个指向char的指针数组。它并不关心有多少行(你必须跟踪它)...它只关心类型是否正确。
所以,如果你有&#39;在我们的第一个例子中声明,你必须调用f(a)。函数调用对函数args执行类似赋值的操作:
f(a)表示用(arg = a)调用f。
优先规则特别重要,您应该继续处理这些规则,直到您可以阅读这样的声明:
int (*f(int (*a)[4], void (*f)()))[6];
which is "f is a function that takes:
- a pointer to arrays of 4 int
- a pointer to a function that takes nothing and returns nothing)
and (then f) returns a pointer to arrays of 6 int".
答案 2 :(得分:0)
char * array创建一个指向内存字节的指针。 char * array [size]创建一个指向长度为'size'的数组的指针。 char **数组只是一个指向内存字节指针的指针
正如您所看到的,代码的问题在于您试图将测试函数传递给它不期望的东西。测试函数需要一个指向指针的指针,你只需给它一个指针。正确的段落是: 试验(ARR);
将第二个视角置于透视图中:在制作命令行程序时会看到这种情况(等等)。
考虑以下代码:
#include<stdio.h>
int main(int argc, char *argv[]) {
printf("%s\n", argv[0]);
return 0;
}
argv指针指向命令行参数,每个参数都是一个字符串(只是一个指针或一个数组)。因此,假设您为Linux执行了以下操作:
./ some_program -option opt-input
每个都被视为自己的字符串。 char * argv []指向每个字符串。第一个printf将打印出./some_program,因为这是argv指向的第一个字符串。