【发布时间】:2021-08-25 16:33:32
【问题描述】:
我有一个结构数组作为函数参数,并且数组的大小是动态的。我的同事说我必须使用双指针,因为结构数组中包含的值将被覆盖。
将成为双指针的参数如下:
xPIDConfig_t **pxPIDConfig
这是 xPIDConfig_t 的结构:
typedef struct
{
ePIDType_t ePIDType;
/* Common fields for the different types of PID */
float fLowerSaturationLimit;
float fUpperSaturationLimit;
float fOldInput;
float fIError;
uint32_t ulDeltaTime;
eBool_t bSaturationEnable;
eBool_t bAntiWindupEnable;
eBool_t bNegativeErrorEmptyIError;
union
{
/* Parallel PID fields */
struct
{
float fProportionalGain;
float fIntegralGain;
float fDerivativeGain;
}xParallelPID;
/* Non-interactive PID fields */
struct
{
float fControllerGain;
uint32_t ulIntegralTime;
uint32_t ulDerivativeTime;
}xNonInteractivePID;
}xUniqueFields;
}xPIDConfig_t;
pxPIDConfig 数组的大小会有所不同。
但我不确定如何分配双指针,甚至不知道如何使用包含双指针的函数。
我只是想知道是否有人有一个很好的代码示例,说明如何使用具有可变大小的双指针数组的函数?以及如何在函数内部正确更改数组本身包含的值?
现在这就是我在函数中更改值的方式:
pxPIDConfig->ePIDType = ePIDType;
pxPIDConfig->fOldInput = 0;
pxPIDConfig->fIError = 0;
pxPIDConfig->ulDeltaTime = ulDeltaTime;
pxPIDConfig->bSaturationEnable = bIsSaturationEnable;
pxPIDConfig->bAntiWindupEnable = bIsAntiWindupEnable;
pxPIDConfig->bNegativeErrorEmptyIError = bNegativeErrorEmptyIError;
当指针是双倍时,我必须使用双'->'吗?这让我很困惑。
谢谢大家的帮助
/********************** 编辑 **************************** ********
我的函数现在正在运行,但我被告知我需要使用内存分配,因为我的数组大小会根据我想要实现的循环数而变化。
这是我的函数的参数:
eError_t eControlCascadeInit( uint8_t ucNumberOfLoops, ePIDType_t *pePIDType, xPIDConfig_t **pxPIDConfig, float *pfLowerLimit, float *pfUpperLimit, uint32_t *pulDeltaTime, \
eBool_t *pbIsSaturationEnable, eBool_t *pbIsAntiWindupEnable, eBool_t *pbNegativeErrorEmptyIError, \
float *pfPGain, float *pfIGain, float *pfDGain, float *pfCGain, uint32_t *pulITime, uint32_t *pulDTime )
它们都是大小为 ucNumberOfLoops 的数组。它们都是只读数组,除了 pxPIDConfig 一个是只写的。该函数使用通过数组传递给函数的参数初始化数组中存在的所有xPIDConfig_t。
array[ 0 ] 包含正在初始化的第一个 PID 控制器的参数。
array[1] 包含正在初始化的第二个 PID 控制器的参数,依此类推...
函数中的所有参数都是这样的。
希望它能让我的问题更清楚吗?
【问题讨论】:
-
如果被调用函数将修改指针值,例如通过(重新)为数据结构分配内存或通过更改指针以指向结构的不同实例,您需要一个双指针。如果您只想修改结构中的值,则不需要它。请edit您的问题并解释您的函数应该对结构和指针做什么。您想在哪里分配/更改/释放结构或数组的内存,可能使用伪代码。
-
仅仅因为函数参数可能有一个双指针(即
**name)并不意味着该变量需要使用双指针分配内存,即如果函数 eg 是这样调用的:void funcChangeParam(&pxPIDConfig)它通常会被原型化为`void funcChangeParam(xPIDConfig_t **pxPIDConfig) -
对于
xPIDConfig_t **pxPIDConfig,那么如果pxPIDConfig指向一个有效的xPIDConfig_t *并且*pxPIDConfig指向一个有效的xPIDConfig_t,那么您可以使用pxPIDConfig来访问成员其中xPIDConfig_t像这样:(*pxPIDConfig)->ePIDType。 -
如果函数改变数组的大小(即重新分配),你只需要一个双指针。
-
@IanAbbott - OP 表示需要多个 struct 实例,因此必须定义为指向 struct 的指针,然后在函数原型中,需要一个双指针来允许更改对象。
标签: c pointers struct double structure