C中字符串的字符指针
因此,出于某种原因,当我调用GameGetCurretRomTitle()函数时,它无法正确打印roomData.title的内容,它会打印NULL。但是当我打印出函数本身内部的'title'变量时,它就工作了。。。我已经在完整的代码中包含了所有正确的文件、标题和所有语法都是正确的…C中字符串的字符指针,c,function,pointers,parameters,parameter-passing,C,Function,Pointers,Parameters,Parameter Passing,因此,出于某种原因,当我调用GameGetCurretRomTitle()函数时,它无法正确打印roomData.title的内容,它会打印NULL。但是当我打印出函数本身内部的'title'变量时,它就工作了。。。我已经在完整的代码中包含了所有正确的文件、标题和所有语法都是正确的…C使用传递值传递函数参数。如果要从GameGetCurrentRoomTitle()函数更改roomData.title变量本身的值,则必须传递指向roomData.title的指针。然后,您可以使用strdup()
C
使用传递值传递函数参数。如果要从GameGetCurrentRoomTitle()
函数更改roomData.title
变量本身的值,则必须传递指向roomData.title
的指针。然后,您可以使用strdup()
将gameData.title[0]
的内容复制到GameGetCurrentRoomTitle()内部的title
。您需要记住在之后释放指针
否则,您可以先将内存分配给title
,然后再将其传递给GameGetCurrentRoomTitle()
,然后在GameGetCurrentRoomTitle()中使用strcpy()
从gameData.title[0]
复制字符串
您需要相应地更改GameGetCurrentRoomTitle()
函数。在函数中设置变量的值不会更改调用者中变量的值
您需要使用strcpy将标题复制到传递到函数中的缓冲区。不要只更改局部指针。函数的参数是其局部变量。您可以想象这个函数定义
typedef struct {
char *title;
char *desc;
} RoomData;
RoomData roomData;
GameGetCurrentRoomTitle(roomData.title);
//INSIDE THE GAME.C FILE
int GameGetCurrentRoomTitle(char *title) {
title = &gameData.title[0];
return strlen(title);
}
以及它的号召
int GameGetCurrentRoomTitle(char *title) {
title = &gameData.title[0];
return strlen(title);
}
像
退出函数后,其局部变量标题将被销毁
如果要更改原始指针,必须传递其地址。在本例中,函数定义及其调用如下所示
GameGetCurrentRoomTitle(roomData.title);
//...
int GameGetCurrentRoomTitle() {
char *title = roomData.title;
title = &gameData.title[0];
return strlen(title);
}
假设gameData.title
是指向char
数组的指针数组
然后gameData.title[0]
持有指向内存中“某处”存在的char
数组的指针。假设标题是“Foobar”,这就是它在内存中的位置:
GameGetCurrentRoomTitle( &roomData.title );
//...
int GameGetCurrentRoomTitle( char **title ) {
*title = &gameData.title[0];
return strlen( *title );
}
假设标题前后的字节(或char
s)在此时此刻未设置且未被程序使用,而上面的空槽就意味着这一点
现在,让我们调用指向p1
的gameData.title[0]
中的char
数组的指针。它指向“Foobar”char
数组,如下所示:
[ ][ ][ ][ ][F][o][o][b][a][r][\0][ ][ ][ ][ ]
指针p2-p4是gameData.title
数组中char
指针的其余部分
现在,在您的场景中还有两个有趣的指针。首先是roomData.title
char
指针。为了简单起见,我们将其命名为pA
。当您将其传递给GameGetCurrentRoomTitle
时,它处于未设置状态,并指向内存空间中未定义的char
:
[ ][ ][ ][ ][F][o][o][b][a][r][\0][ ][ ][ ][ ]
^
|
+-----------+
|
[ ][ ][ ][ ][ ][ ][ ][p1][p2][p3][p4][ ]
其次是GameGetCurrentRoomTitle
titlechar
pointer参数。为了简单起见,我们称之为pB
。当您将pA
作为参数传递给GameGetCurrentRoomTitle
时,其值将复制到pB
。它的值不是它指向的内存的内容,而是它指向的地址。这意味着pB
将指向内存空间中与pA
相同的未定义char
:
[ ][ ][ ][ ][F][o][o][b][a][r][\0][ ][ ][ ][ ]
^
|
+------------+
|
[ ][pA][ ][ ][ ][ ][ ][p1][p2][p3][p4][ ]
|
+---------+
|
v
[ ][ ][ ][ ]
接下来,在GameGetCurrentRoomTitle
的主体中,您重新分配pB
(本地标题char
指针)以指向与p1
相同的内存位置(指向gameData.title[0]
中的char
数组的指针):
而且,当GameGetCurrentRoomTitle
最终返回到其调用者时,pA
仍指向相同的未定义内存位置
您错过的修复方法是将指向pA
的指针传递到GameGetCurrentRoomTitle
而不仅仅是pA
本身,而不是将pB
重新分配到与p1
相同的内存位置,您应该取消引用pB
并将p1
分配到该内存位置,这是存储pA
变量值的存储位置。这样,当GameGetCurrentRoomTitle
返回时,pA
将看到您期望的字符串
对于“图形”,新的情况是pB
不指向char
数组,而是指向char
数组的指针。我们知道pA
是指向char
数组的指针:
[ ][ ][ ][ ][F][o][o][b][a][r][\0][ ][ ][ ][ ]
^
|
+------+------+
| |
[ ][pA][ ][ ][ ][pB][ ][p1][p2][p3][p4][ ]
|
+---------+
|
v
[ ][ ][ ][ ]
通过将某些内容分配给被解除引用的pB
,可以有效地分配给它所指向的内存位置,而不是pB
本身。因此,在这种情况下,将p1
分配给延迟的pB
与将其分配给pA
是相同的:
[ ][ ][ ][ ][F][o][o][b][a][r][\0][ ][ ][ ][ ]
^
|
+-------------+
|
[ ][pA][ ][ ][ ][pB][ ][p1][p2][p3][p4][ ]
^ |
| |
+------------+
在代码中:
[ ][ ][ ][ ][F][o][o][b][a][r][\0][ ][ ][ ][ ]
^
|
+-----+-------------+
| |
[ ][pA][ ][ ][ ][pB][ ][p1][p2][p3][p4][ ]
[ ][ ][ ][ ][F][o][o][b][a][r][\0][ ][ ][ ][ ]
^
|
+-------------+
|
[ ][pA][ ][ ][ ][pB][ ][p1][p2][p3][p4][ ]
^ |
| |
+------------+
[ ][ ][ ][ ][F][o][o][b][a][r][\0][ ][ ][ ][ ]
^
|
+-----+-------------+
| |
[ ][pA][ ][ ][ ][pB][ ][p1][p2][p3][p4][ ]
GameGetCurrentRoomTitle(&roomData.title); // pass pointer to 'pA'
int GameGetCurrentRoomTitle(char **title) // 'pB' is a pointer to pointer
{
*title = &gameData.title[0]; // assign 'p1' to dereferenced 'pB'
return strlen(*title); // measure dereferenced 'pB'
}