如何修改已在C中传递给函数的指针?
因此,我有一些代码,类似于下面的代码,用于将结构添加到结构列表中:如何修改已在C中传递给函数的指针?,c,function,pointers,parameters,pass-by-value,C,Function,Pointers,Parameters,Pass By Value,因此,我有一些代码,类似于下面的代码,用于将结构添加到结构列表中: void barPush(BarList * list,Bar * bar) { // if there is no move to add, then we are done if (bar == NULL) return;//EMPTY_LIST; // allocate space for the new node BarList * newNode = malloc(sizeof(Bar
void barPush(BarList * list,Bar * bar)
{
// if there is no move to add, then we are done
if (bar == NULL) return;//EMPTY_LIST;
// allocate space for the new node
BarList * newNode = malloc(sizeof(BarList));
// assign the right values
newNode->val = bar;
newNode->nextBar = list;
// and set list to be equal to the new head of the list
list = newNode; // This line works, but list only changes inside of this function
}
这些结构的定义如下:
typedef struct Bar
{
// this isn't too important
} Bar;
#define EMPTY_LIST NULL
typedef struct BarList
{
Bar * val;
struct BarList * nextBar;
} BarList;
然后在另一个文件中,我执行如下操作:
BarList * l;
l = EMPTY_LIST;
barPush(l,&b1); // b1 and b2 are just Bar's
barPush(l,&b2);
然而,在此之后,l仍然指向空的_列表,而不是在barPush内部创建的修改版本。如果我想修改列表,我是否必须将列表作为指针传递给指针,或者是否需要其他一些黑色咒语 是的,您必须传入指向该指针的指针。C按值传递参数,而不是按引用传递参数。记住,在C中,所有参数都是按值传递的 您传入一个指向指针的指针,如下所示
int myFunction(int** param1, int** param2) {
// now I can change the ACTUAL pointer - kind of like passing a pointer by reference
}
如果要执行此操作,需要传入指向指针的指针
void barPush(BarList ** list,Bar * bar)
{
if (list == NULL) return; // need to pass in the pointer to your pointer to your list.
// if there is no move to add, then we are done
if (bar == NULL) return;
// allocate space for the new node
BarList * newNode = malloc(sizeof(BarList));
// assign the right values
newNode->val = bar;
newNode->nextBar = *list;
// and set the contents of the pointer to the pointer to the head of the list
// (ie: the pointer the the head of the list) to the new node.
*list = newNode;
}
然后像这样使用它:
BarList * l;
l = EMPTY_LIST;
barPush(&l,&b1); // b1 and b2 are just Bar's
barPush(&l,&b2);
Jonathan Leffler建议在评论中返回新的名单负责人:
BarList *barPush(BarList *list,Bar *bar)
{
// if there is no move to add, then we are done - return unmodified list.
if (bar == NULL) return list;
// allocate space for the new node
BarList * newNode = malloc(sizeof(BarList));
// assign the right values
newNode->val = bar;
newNode->nextBar = list;
// return the new head of the list.
return newNode;
}
用法变为:
BarList * l;
l = EMPTY_LIST;
l = barPush(l,&b1); // b1 and b2 are just Bar's
l = barPush(l,&b2);
这是一个经典问题。返回分配的节点或使用指针的指针。在C语言中,应该将指向X的指针传递给希望修改X的函数。在这种情况下,由于您希望修改指针,因此应该将指针传递给指针。一般答案:将指针传递给要更改的对象
在本例中,它将是指向您要更改的指针的指针。在另一个函数中修改指针需要一个称为多重间接寻址的概念,我将在后面解释,给定@geofftnz的扰流板解决方案使用多重间接寻址。我想做的是尽力解释C语言中的多重间接寻址 考虑以下两个程序,我将浏览代码 以下程序不使用多个间接寻址,因此失败 有错误的程序:
// filename: noIndirection.c
#include <stdio.h>
#include <stdlib.h>
void allocater(int *ptrTempAllctr)
{
ptrTempAllctr = malloc(sizeof(int));
if (ptrTempAllctr == NULL) {
perror("in allocater() memory allocation error");
exit(EXIT_FAILURE);
}
}
int main()
{
int *ptrMain = NULL;
allocater(ptrMain);
if (ptrMain == NULL) {
printf("ptrMain is points to NULL\n");
return 1;
}
//free(ptrMain); // we don't have to free because it will be invalid free.
return 0;
}
我们使用(&
)运算符的地址分配它们
多个间接指针类型变量的作用是,允许我们
指向指针变量本身的指针,用于修复上述程序。
这允许我们将ptrMain的地址传递给allocator()
使用此呼叫
分配器(&ptrMain)代码>
因此,上面的程序noIndirection.c
不允许我们这样做,请参阅程序withIndirection.c
以实现此多重间接寻址
我们需要指向int指针(int**ptrMain
)的指针作为allocator()
函数的函数参数,在这种情况下,可以解决上述错误程序(noIndirection.c)
这在以下程序中使用
下面的程序使用多重间接来解决上一个程序中的错误
// filename: withIndirection.c
#include <stdio.h>
#include <stdlib.h>
void trueAllocater(int **ptrTrueAllocater)
{
*ptrTrueAllocater = (int *) malloc(sizeof(int));
if (ptrTrueAllocater == NULL) {
perror("in trueAllocater() memory allocation error");
exit(EXIT_FAILURE);
}
}
int main(void)
{
int *ptrMain = NULL;
trueAllocater(&ptrMain);
if (ptrMain == NULL) {
printf("memory not allocated\n");
return EXIT_FAILURE;
}
printf("memory allocated and assigned to ptrMain");
printf(" from trueAllocater\n");
free(ptrMain);
return EXIT_SUCCESS;
}
//文件名:withIndirection.c
#包括
#包括
void trueallocator(int**ptrtruelocator)
{
*ptrTrueAllocater=(int*)malloc(sizeof(int));
if(ptrTrueAllocater==NULL){
perror(“在TrueAllocator()内存分配错误中”);
退出(退出失败);
}
}
内部主(空)
{
int*ptrMain=NULL;
trueallocator(&ptrMain);
if(ptrMain==NULL){
printf(“未分配内存”);
返回退出失败;
}
printf(“分配给ptrMain的内存”);
printf(“来自TrueAllocator\n”);
免费(ptrMain);
返回退出成功;
}
请参阅程序with indirection.c
,以了解今后的参考信息
为了解决我们的问题,我们需要将指针变量ptrMain
(trueallocator(&ptrMain);
)的地址传递给trueallocator,以便更改ptrMain
后面需要在trueallocator()或其他函数中指向的位置,
为此,函数需要接受具有正确间接级别的间接指针,
这是为了在参数声明中添加另一个*以达到我目前对传递的变量的理解
通过这种方式,我们需要将trueallocator()
函数参数设置为int**
fromint*
inwith indirection.c
而不是noIndirection.c
因此,间接层将被统计
调用方的参数变量ptrMain
的实际地址传递给函数时。中的tempraryptrTrueAllocater
参数变量
函数指向指针变量ptrMain
在调用者中的地址(main
)函数不是指针变量ptrMain
(在程序中为NULL
)在函数中指向的地址(main
)
如果我们取消引用ptrRueAllocater
变量,将显示ptrMain
指向的地址,因为ptrRueAllocater
临时变量指向调用者(main
)ptrMain
变量本身,而不是它的内容
取消引用的ptrRueAllocater
变量的内容将是调用者(main
)的变量(ptrMain
)指向的数据的地址,
因此,我们必须进行一次额外的解引用以获得最终数据
因此,我们必须取消引用一次,以获得它所指向的ptrMain
的地址,从而更改ptrMain
需要指向和取消引用的位置
两次以获取ptrMain
指向的实际数据,该值为NULL
@PaulWicks您打算更改,因此您必须取消引用一次,以分配或更改其指向的位置
使用指针进行多个间接寻址的目的是创建多维数组并传递需要指向某个对象的指针参数
我们需要根据需要操作的类型更改变量,如下所示
声明中每增加一个*都会增加指针间接寻址级别
每次取消引用都会降低指针的间接寻址级别,从而接近数据
我们可以
// filename: withIndirection.c
#include <stdio.h>
#include <stdlib.h>
void trueAllocater(int **ptrTrueAllocater)
{
*ptrTrueAllocater = (int *) malloc(sizeof(int));
if (ptrTrueAllocater == NULL) {
perror("in trueAllocater() memory allocation error");
exit(EXIT_FAILURE);
}
}
int main(void)
{
int *ptrMain = NULL;
trueAllocater(&ptrMain);
if (ptrMain == NULL) {
printf("memory not allocated\n");
return EXIT_FAILURE;
}
printf("memory allocated and assigned to ptrMain");
printf(" from trueAllocater\n");
free(ptrMain);
return EXIT_SUCCESS;
}