返回值顯然是傳出的而不是傳入的,如果返回值傳出的是指針,和上一節通過參數傳出指針類似,也分為兩種情況:第一種是傳出指向靜態內存或已分配的動態內存的指針,例如localtime(3)
和inet_ntoa(3)
,第二種是在函數中動態分配內存並傳出指向這塊內存的指針,例如malloc(3)
,這種情況通常還要實現一個釋放內存的函數,所以有和malloc(3)
對應的free(3)
。由於這兩種情況的函數介面相同,應該在文檔中說明是哪一種情況。
以下是一個完整的例子。
例 24.5. 返回指向已分配內存的指針
/* ret_ptr.h */ #ifndef RET_PTR_H #define RET_PTR_H extern char *get_a_day(int idx); #endif
/* ret_ptr.c */ #include <string.h> #include "ret_ptr.h" static const char *msg[] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}; char *get_a_day(int idx) { static char buf[20]; strcpy(buf, msg[idx]); return buf; }
/* main.c */ #include <stdio.h> #include "ret_ptr.h" int main(void) { printf("%s %s\n", get_a_day(0), get_a_day(1)); return 0; }
這個程序的運行結果是Sunday Monday
嗎?請讀者自己分析一下。
表 24.6. 動態分配內存並返回指針示例:unit_t *alloc_unit(void);
void free_unit(unit_t *p)
;
調用者 | 實現者 |
---|---|
|
|
以下是一個完整的例子。
例 24.6. 動態分配內存並返回指針
/* ret_allocator.h */ #ifndef RET_ALLOCATOR_H #define RET_ALLOCATOR_H typedef struct { int number; char *msg; } unit_t; extern unit_t *alloc_unit(void); extern void free_unit(unit_t *); #endif
/* ret_allocator.c */ #include <stdio.h> #include <string.h> #include <stdlib.h> #include "ret_allocator.h" unit_t *alloc_unit(void) { unit_t *p = malloc(sizeof(unit_t)); if(p == NULL) { printf("out of memory\n"); exit(1); } p->number = 3; p->msg = malloc(20); strcpy(p->msg, "Hello world!"); return p; } void free_unit(unit_t *p) { free(p->msg); free(p); }
/* main.c */ #include <stdio.h> #include "ret_allocator.h" int main(void) { unit_t *p = alloc_unit(); printf("number: %d\nmsg: %s\n", p->number, p->msg); free_unit(p); p = NULL; return 0; }
思考一下,通過參數分配內存需要兩層的指針,而通過返回值分配內存就只需要返回一層的指針,為什麼?