それほど面倒ではない条件でそれを行うことができますが、それは一種のチートです.
add_element()
関数が新しい要素をリストの先頭ではなく末尾に追加する場合、およびリストに最初のノードが存在するように配置する場合は、ほぼそれを行うことができます。
証拠:
#include <assert.h>
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static void err_exit(const char *fmt, ...);
typedef struct node node;
typedef struct object object;
struct object
{
int id;
char *name;
node *list_head; //a pointer to the head of a linked list
};
struct node
{
node *next;
object *data;
};
static void add_element(node **list, int value)
{
assert(list != 0);
object *new_objt = calloc(sizeof(object), 1);
node *new_node = calloc(sizeof(node), 1);
if (new_objt == 0 || new_node == 0)
err_exit("Out of memory in %s\n", __func__);
node *next = *list;
while (next->next != 0)
next = next->next;
next->next = new_node;
new_node->data = new_objt;
new_objt->id = value;
}
static void print_list(const node *list)
{
assert(list != 0);
node *next = list->next;
printf("List: ");
while (next != 0)
{
if (next->data != 0)
printf("%d ", next->data->id);
next = next->next;
}
printf("EOL\n");
}
static void function_a(object obj)
{
int num = 1;
add_element(&obj.list_head, num);
}
int main(void)
{
node temp_node = { 0, 0 };
object temp_obj = { 0, 0, &temp_node }; // Key trick!
print_list(&temp_node);
function_a(temp_obj);
print_list(&temp_node);
function_a(temp_obj);
print_list(&temp_node);
return 0;
}
static void err_exit(const char *fmt, ...)
{
int errnum = errno;
va_list args;
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
if (errno != 0)
fprintf(stderr, " (%d: %s)", errnum, strerror(errnum));
putc('\n', stderr);
exit(EXIT_FAILURE);
}
コンパイル
gcc -O3 -g -std=c99 -Wall -Wextra node.c -o node
出力:
List: EOL
List: 1 EOL
List: 1 1 EOL
演習の目的が脳死状態のインターフェースを打ち負かすことである場合、これはそれを回避します。演習の目的が使用可能なインターフェイスを作成することである場合は、おそらくこの方法では行いません。に構造体へのポインターを渡すとfunction_a()
、list_head
.