我创建了一个包含字符串数组的结构,并在其中填充了单词。当我尝试将阵列填满一半以上时,我想创建一个更大的结构,将当前数据复制到那个更大的结构,然后让那个更大的结构“替换”从main调用的旧结构。尽管我已经成功创建了数据并将其复制到了新结构;我可以通过从函数内部打印出数据来证明这一点;我无法替换main中的旧结构。我尝试的下一个book_insert
插入旧的较小的结构,而不是新的较大的结构。
我在一个约束内操作,因此无法在main内进行大小调整/复制/替换;必须从main调用的book_insert
函数中调用它。另外,我无法编辑void book_insert(dic* s, char* v)
(即添加双指针),它必须保持这种格式。
#include <stdio.h>
#include <stdlib.h>
struct book {
int size;
int count;
char** words;
};
typedef struct book book;
/* Create empty book, specifying lenght of strings and how many of them */
book* book_init(int wordlen, int maxwords);
/* Add one element into the book */
void book_insert(book* s, char* v);
/* Creates and returns new, bigger book */
book* resize(book* s, book* new);
/* Prints book */
void prints(book* a);
int main(void)
{
book* test;
test = book_init(60, 10);
book_insert(test, "dog");
book_insert(test, "cat");
book_insert(test, "mouse");
book_insert(test, "elephant");
book_insert(test, "snake");
/*The next insert will cause the resize function to trigger*/
book_insert(test, "fish");
/*The resize funtion should cause 'test' to be replaced by a bigger book*/
/*But doesn't as this next print shows*/
printf("But printing from main function means I'm back to %d\n", test->size);
prints(test);
}
void book_insert(book* s, char* v)
{
int i = 0;
while (s->words[i] != NULL ) {
i++;
}
s->words[i] = v;
s->count++;
/*If the book is half full resize is triggered, and should pass back new, bigger book*/
if((s->count * 100 / s->size) > 50) {
book *new_book;
new_book = book_init(60, 20);
s = resize(s, new_book);
printf("Printing from resize function gives me new length of %d\n", s->size);
prints(s);
}
}
book* resize(book* s, book* new)
{
int i;
for (i = 0; i < s->size; i++) {
if (s->words[i] != NULL ) {
new->words[i] = s->words[i];
}
}
return new;
}
book* book_init(int wordlen, int maxwords)
{
int i;
book* new = malloc(sizeof(book));
new->size = maxwords;
new->count = 0;
new->words = (char**) calloc((size_t)new->size, sizeof(char*));
for (i=0; i<new->size; i++) {
new->words[i] = (char*) calloc(wordlen, sizeof(char));
new->words[i] = NULL;
}
return new;
}
void prints(book* a)
{
int i;
for (i = 0; i < a->size; i++) {
printf("Index: %d, word: %s\n", i, a->words[i]);
}
}
我也尝试过在单独的函数中使用指针交换进行此操作,但这似乎也不起作用。在此版本中,我将book_resize
设为无效,而在dic_insert
中使用dictionary_swap(&new_book, &s)
:
void dictionary_swap(book **new, book **old)
{
book *temp = *old;
*old = *new;
*new = temp;
}
这又使我可以在book_insert
函数中打印出较大的新结构,但对main中发生的事情没有影响。
编辑答案
这个问题被标记为重复,这意味着我自己无法回答,但是我找到了答案。我更改了上面的重复交换,以便在以下代码上调用dictionary_swap(new_book, s);
(无“&”号):
void dictionary_swap(book *new, book *old)
{
book temp;
temp = *old;
*old = *new;
*new = temp;
}
答案 0 :(得分:2)
为了在函数内部修改指针,您必须将指针的地址传递给该函数,例如:
void changePtr(char* test) {
test = "Hello";
}
上面的方法不起作用,因为无法将测试返回给调用者,但是:
void changePtr(char** test) {
if ( test != NULL ) {
*test = "Hello";
}
}
以上操作之所以有效,是因为传递了指针的地址,并且可以取消引用指针以更改其内容。
呼叫示例:
char* ptr;
changePtr(&ptr);
这是实现上述技术的代码的重写:
#include <stdio.h>
#include <stdlib.h>
typedef struct _book {
int size;
int count;
char** words; //Must allocate space for each pointer before copying to.
} book;
//No need for below, see above:
//typedef struct book book;
/* Create empty book, specifying lenght of strings and how many of them */
book* book_init(int wordlen, int maxwords);
/* Add one element into the book */
void book_insert(book** s, char* v);
/* Creates and returns new, bigger book */
book* resize(book* s, book* new);
/* Prints book */
void prints(book* a);
int main(void) {
book* test = book_init(60, 10);
book_insert(&test, "dog");
book_insert(&test, "cat");
book_insert(&test, "mouse");
book_insert(&test, "elephant");
book_insert(&test, "snake");
/*The next insert will cause the resize function to trigger*/
book_insert(&test, "fish");
/*The resize funtion should cause 'test' to be replaced by a bigger book*/
/*But doesn't as this next print shows*/
printf("But printing from main function means I'm back to %d\n", test->size);
prints(test);
}
void book_insert(book** s, char* v) {
if ( s == NULL || v == NULL ) {
return;
}
(*s)->words = realloc((*s)->words, sizeof(char*) * (++(*s)->count));
(*s)->words[(*s)->count - 1] = v;
/*If the book is half full resize is triggered, and should pass back new, bigger book*/
if((((*s)->count * 100) / s->size) > 50) {
book *new_book;
new_book = book_init(60, 20);
*s = resize(*s, new_book);
}
}
book* resize(book* s, book* new) {
int i;
for (i = 0; i < s->size; i++) {
if (s->words[i] != NULL ) {
new->words[i] = s->words[i];
}
}
printf("Printing from resize function gives me new length of %d\n", new->size);
prints(new);
return new;
}
book* book_init(int wordlen, int maxwords) {
int i;
book* new = calloc(1, sizeof(book));
new->size = maxwords;
return new;
}
void prints(book* a) {
int i;
for (i = 0; i < a->size; i++) {
printf("Index: %d, word: %s\n", i, a->words[i]);
}
}