简体   繁体   English

如何在C中通过引用将数组指针传递给函数?

[英]How to pass array pointer to a function by reference in C?

#include <stdio.h>
#include <stdlib.h>

void populateArray(char* line, char** cmd){
    printf("INPUT LINE: %s\n", line);
    char *  token    = strtok (line, " ");
    int n_spaces = 0, i;

    /* split string and append tokens to 'cmd' */

    while (token) {
      *cmd = realloc (*cmd, sizeof (char*) * ++n_spaces);

      if (*cmd == NULL)
        exit (-1); /* memory allocation failed */

     *cmd[n_spaces-1] = token;

      token = strtok (NULL, " ");
    }

    /* realloc one extra element for the last NULL */

    *cmd = realloc (*cmd, sizeof (char*) * (n_spaces+1));
    *cmd[n_spaces] = 0;

    /* print the cmd */

    for (i = 0; i < (n_spaces+1); ++i)
      printf ("cmd[%d] = %s\n", i, cmd[i]);
}    

int main (int argc, char* argv[])
{
    char *cmd1 = NULL;
    char * line = "ls -l";
    populateArray(line, &cmd1);
}

I know that C is pass by value but is there anyway to emulate it to pass by reference? 我知道C是按值传递的,但是有没有模仿它通过引用传递的呢? I need to pass cmd1 to populateArray(char* line, char** cmd) as a reference. 我需要将cmd1传递给populateArray(char * line,char ** cmd)作为参考。 I did some research and to pass by reference in C, it seem like I need to do something like this: I tried but still cant make it work for the array pointer. 我进行了一些研究,并通过C语言进行引用,似乎我需要执行以下操作:我尝试了但仍无法使它适用于数组指针。

void byreference_func(int* n){
    *n = 20;
}
int main(int argc, char *argv[])
{
    int i = 10;
    printf("before the call the value of i is %d\n", i);
    byreference_func(&i);
    printf("after the call the value of i is %d\n", i);
    return 0;
}

EDIT: Error code 编辑:错误代码

anon@turing:~/csce3613/assign3$ gcc gg.c
gg.c: In function âpopulateArrayâ:
gg.c:6:24: warning: initialization makes pointer from integer without a cast [enabled by default]
gg.c:17:23: warning: assignment makes integer from pointer without a cast [enabled by default]
gg.c:19:13: warning: assignment makes pointer from integer without a cast [enabled by default]
anon@turing:~/csce3613/assign3$ ./a.out
INPUT LINE: ls -l
Segmentation fault (core dumped)

cmd1 is an array. cmd1是一个数组。 Arrays cannot be reallocated. 数组无法重新分配。 You can only use realloc on a null pointer, or a pointer returned by a previous call to a malloc family function. 您只能在空指针或上一次调用malloc系列函数返回的指针上使用realloc

Instead you will need to do : 相反,您将需要执行以下操作:

int main() 
{
    char *cmd1 = NULL;
    populateArray( line, &cmd1 );
}

and then inside your function, change cmd to (*cmd) . 然后在函数内部,将cmd更改为(*cmd) It is exactly analogous to your int example, except everywhere you have int in that example you need to change it to char * . 它与您的int示例完全相似,除了在该示例中所有具有int地方之外,您都需要将其更改为char * You correctly write *n = 20; 您正确地写*n = 20; in your int example but then you forget to do that in your real code. 在您的int示例中,但随后您忘记了在实际代码中这样做。

BTW if you are always going to free before returning , then you are not really populating an array, and. 顺便说一句,如果您总是要在返回之前free ,那么您实际上并没有在填充数组,并且。

I cannot find the declaration of line in your code snippet. 我找不到宣言line在您的代码段。 May it be part of your troubles? 可能是您麻烦的一部分吗? Can you also add the error that you are getting? 您还可以添加您得到的错误吗?

When you do char * line = "ls -l -a"; 当你做char * line = "ls -l -a"; your line is actually a const char * , not a char * 您的line实际上是const char * ,而不是char *

You should do 你应该做

char *line = strdup("ls -l -a");

Or do 还是做

char line[] = "ls -l -a";

( this works, read here What is the difference between char s[] and char *s? ) (这可行,请在这里阅读char s []和char * s有什么区别?

strtok() tries to modify your line so it cannot be a const char* strtok()尝试修改您的line ,使其不能为const char*

And I don't do char *cmd1[64]; 而且我不做char *cmd1[64]; I do 我做

char **cmd1 = (char**)malloc(sizeof(char*));
cmd1[0] = (char*)malloc(sizeof(char) * 64);

Here is the working code : http://pastebin.com/TTsTpdgU 这是工作代码: http : //pastebin.com/TTsTpdgU

All strings in C are referenced by pointers (addresses), therefore you are passing the address of the string in every function call using char * as the parameter definition. C中的所有字符串都由指针(地址)引用,因此,您将在每个函数调用中使用char *作为参数定义来传递字符串的地址。 There is no need to pass it as char ** a simple char * will do. 无需传递它,因为char **实现简单的char * To return the value to main, simply declare populateArray as char * and return a pointer to cmd1 . 要将值返回给main,只需将populateArray声明为char *并返回一个指向cmd1的指针。

Next as indicated, you are declaring line as a constant string literal. 接下来,如图所示,您将line声明为常量字符串文字。 In order to make use of it in the way you are, it should be declared as an array of characters. 为了按照您的方式使用它,应该将其声明为字符数组。 (eg char line[] = "ls -al" ). (例如, char line[] = "ls -al" )。

As for your program logic, you are making things a bit difficult reallocating for every char you add. 至于程序逻辑,您很难为添加的每个字符重新分配内容。 It is far easier to use a couple of functions already providing in string.h , namely strcat . 使用string.h已经提供的几个函数(即strcat )要容易得多。 Here is an example. 这是一个例子。 (Note there are many, many different ways to do this, but allocating cmd with calloc instead of malloc initializes a string of NULL chars which makes strcat a snap and insures the resulting string is always null-terminated.) (请注意,有许多不同的方法可以执行此操作,但是用calloc而不是malloc分配cmd初始化NULL字符的字符串,这使strcat变得strcat并确保生成的字符串始终以null终止。)

Updated (I didn't like the first one) 更新(我不喜欢第一个)

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

#define CMDSZ 256

char *populateArray (char *line, char *cmd) /* declare as 'char *' and return pointer */
{
    printf ("\nINPUT LINE: %s\n\n", line);

    char *token = strtok (line, " ");
    int i = 0;

    cmd = calloc (CMDSZ, sizeof (cmd));  /* allocate command string to CMDSZ         */

    while (token)                        /* split string and append tokens to 'cmd'  */
    {
        if (strlen (cmd) > 0)            /* if not first command add space           */
            strcat (cmd, " ");

        strcat (cmd, token);             /* add token to cmd    */

        token = strtok (NULL, " ");      /* get next token      */
    }

    for (i = 0; i < (strlen (cmd)); ++i)        /* print each character in cmd */
        printf ("  cmd[%d] = %c\n", i, cmd[i]);

    printf ("\n  cmd: %s\n\n", cmd);            /* print final command         */

    return cmd;
}

int main () {

    char *cmd1 = NULL;
    char line[ ] = "ls -l -a -x -y -z";

    cmd1 = populateArray (line, cmd1);  /* return a pointer to cmd1                 */

    printf ("In main():\n\n  cmd1: %s\n\n", cmd1);

    if (cmd1) free (cmd1);              /* free memory allocated in populateArray   */

    return 0;
}

Note: int main(....) is an integer function -- it should return a value. 注意: int main(....)是一个整数函数-它应该返回一个值。

output: 输出:

$ ./bin/poparray

INPUT LINE: ls -l -a -x -y -z

  cmd[0] = l
  cmd[1] = s
  cmd[2] =
  cmd[3] = -
  cmd[4] = l
  cmd[5] =
  cmd[6] = -
  cmd[7] = a
  cmd[8] =
  cmd[9] = -
  cmd[10] = x
  cmd[11] =
  cmd[12] = -
  cmd[13] = y
  cmd[14] =
  cmd[15] = -
  cmd[16] = z

  cmd: ls -l -a -x -y -z

In main():

  cmd1: ls -l -a -x -y -z

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 C - 如何通过引用将结构指针数组传递给 function - C - How to pass struct pointer array to a function by reference 在C函数中通过指针传递结构数组以更新指针引用 - Pass array of struct by pointer in C function to update pointer reference 如何将 function 指针数组的 function 指针作为 function 参数传递给 Z0D61F8370CAD14D4E214F14F1421 - How to pass a function pointer of an function pointer array as function parameter in C? 在C中通过引用正确传递char数组和char指针 - Correctly pass a char array and char pointer to function by reference in C 如何在C中模仿C ++“通过引用传递数组(指针)”? - How to mimic C++ “pass array(pointer) by reference” in C? 如何在不衰减的情况下将指针传递到数组,并在野蛮人函数中使用“引用”? - How to pass a pointer to an array without decay, and use the 'reference' in a function for barbarrians? 如何在C中通过引用将结构数组传递给函数? - How to pass an array of structures to a function by reference in C? 如何通过引用C中的函数来传递数组? - How to pass an array by reference to a function in C? 将指针作为数组传递给C中的函数? - Pass a pointer as array in function in C? C - 为 malloc 传递指向 function 的指针的引用? - C - pass reference to pointer to function for malloc?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM