[英]Pass by reference String array to function and modify content in C
我在做錯了,將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
謝謝,凱文
你將arr
聲明為char *arr[2]
。 然后傳入*arr
,其類型為char*
以進行測試。 但測試需要char *[]
。 這樣就行不通了。 你應該簡單地傳入arr
,即test(arr)
。
char * array
是指向字符的指針,通常用於指向字符數組中的第一個字符,即字符串。 char **array
是指向字符指針的指針。 通常用於表示字符串數組。 char *array[size]
大部分等同於上面的那個,但它不同,那個,頂級指針已經指向一個有效的數組,所以數組不需要被malloc
編輯。
順便說一句,您的test
功能可以簡化一點: strcopy
是不必要的。
void test(char *arr[])
{
int i;
for(i=0;i<2;i++)
{
arr[i] = malloc(80);
gets(arr[i]);
}
}
好的,在C聲明中,您只能獲得從聲明中讀取的第一個分配內容。
在您了解如何閱讀聲明之前,這有點模糊。
運算符具有優先權,該優先權適用於聲明。 為簡單起見,請:
() - Either raises precedence, or means "function taking parameters and returning..."
[] - Array of
* - Pointer to (right associative)
所以,聲明:
char *a[3];
是一個“三個指向char的數組”,而
char (*a)[3];
是一個“3個數組的指針”(一個指向行數為3的多調焦字符數組的行的指針)
編譯器在堆棧上分配第一個東西。 因此,在第一個示例中,您將獲得三個能夠指向(尚未分配的)字符的指針。
| ptr | --> (unallocated char)
| ptr | --> (unalloc char)
| ptr | --> (unalloc char)
在第二:
| ptr | --> (unallocated block of 3 char)
下一個規則是:如果你有一個指針,你有一個數組。 因此,在這兩種情況下,您最終都會得到多維數組。
在第一個中,行數是固定的(您已經分配了它),但每行可以有不同的大小,因為編譯器知道指針可以被char偏移以到達下一個char。
在第二種情況下,您有一個固定的行大小,但編譯器知道如何偏移您的基指針(每個3個字符),因此您有任意數量的行。
C也是一種按值調用的語言。 所以,如果你已經聲明了一個變量:
char *a[3];
那么'a'本身就是“一個3 ptr到char的數組”,但是[0]是“ptr到char”,而[0] [0]是char。
當你編寫一個期望的函數時:
void f(char *arg[]) {
...
}
你必須傳遞一個指向char的指針數組。 它並不關心有多少行(你必須跟蹤它)...它只關心類型是否正確。
所以,如果你在我們的第一個例子中聲明了'a',你必須調用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".
char *數組創建一個指向內存字節的指針。 char * array [size]創建一個指向長度為'size'的數組的指針。 char **數組只是指向內存字節的指針
正如您所看到的,代碼的問題在於您試圖將測試函數傳遞給它不期望的東西。 測試函數需要一個指向指針的指針,你只需給它一個指針。 正確的段落是:test(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指向的第一個字符串。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.