C、关于指针(或指向指针的指针?)、***和malloc
正如在标题中所说,我有一个关于两次使用*的问题,就像在下面代码的主要函数中一样。它确实运行,但我不明白为什么在这里使用**。我想要的是一个大小为n的SPPoints数组,其中parr是基本地址。为什么在这种情况下**是对的*是错的?谢谢 点代码:C、关于指针(或指向指针的指针?)、***和malloc,c,memory,malloc,dynamic-memory-allocation,C,Memory,Malloc,Dynamic Memory Allocation,正如在标题中所说,我有一个关于两次使用*的问题,就像在下面代码的主要函数中一样。它确实运行,但我不明白为什么在这里使用**。我想要的是一个大小为n的SPPoints数组,其中parr是基本地址。为什么在这种情况下**是对的*是错的?谢谢 点代码: struct sp_point_t { double* data; int dim; int index; }; SPPoint* spPointCreate(double* data, int dim, int index)
struct sp_point_t
{
double* data;
int dim;
int index;
};
SPPoint* spPointCreate(double* data, int dim, int index)
{
if (data == NULL || dim <= 0 || index < 0)
{
return NULL;
}
SPPoint* point = malloc(sizeof(*point));
if (point == NULL)
{
return NULL;
}
point->data = (double*)malloc(dim * sizeof(*data));
for (int i = 0; i < dim; i++)
{
point->data[i] = data[i];
}
point->dim = dim;
point->index = index;
return point;
}
struct sp\u point\t
{
双*数据;
int-dim;
整数指数;
};
SPPoint*spPointCreate(双*数据、整型尺寸、整型索引)
{
如果(数据==NULL | |尺寸数据=(双*)malloc(尺寸*尺寸(*数据));
对于(int i=0;i数据[i]=数据[i];
}
点->尺寸=尺寸;
点->索引=索引;
返回点;
}
这是主要功能:
int main()
{
int n, d, k;
scanf("%d %d %d", &n, &d, &k);
double* darr = malloc(d * sizeof(double));
if (darr == NULL)
{
return 0;
}
SPPoint** parr = malloc(n * sizeof(SPPoint*));
if (parr == NULL)
{
return 0;
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < d; j++)
{
scanf(" %lf", &darr[j]);
}
parr[i] = spPointCreate(darr, d, i);
}
}
intmain()
{
int n,d,k;
scanf(“%d%d%d”、&n、&d、&k);
double*darr=malloc(d*sizeof(double));
如果(darr==NULL)
{
返回0;
}
SPPoint**parr=malloc(n*sizeof(SPPoint*));
if(parr==NULL)
{
返回0;
}
对于(int i=0;i
数组的行为可以类似于指针。例如,int a[]与int*a非常相似。SPPoint中的每个函数都返回指向SPPoint结构的指针。指向SPPoint的指针数组可以写成指向SPPoint的指针。使用malloc命令,可以指定一定量的内存(足以容纳n个指向SPPoint的指针)用于存储指向SPPoint结构的指针
但是,并非所有指针都是数组。SPPoint**parr充当一个数组,其中包含指向SPPoint类型的单个结构的指针
数组的行为可能与指针不同,尤其是用于字符串时
使用指向SPPoint的指针(就像现在这样)是有利的,因为您可以查看或修改单个元素,而不必复制整个结构。当使用动态分配的数组时,它通常是“处理”的通过有一个指向数组第一个元素的指针,并且还有一些知道长度的方法,比如显式存储长度,或者有一个结束哨兵 因此,对于代码中动态分配的
SPPoint*
数组,指向其中第一个数组的指针的类型为SPPoint**
现有代码创建一个SPPoint*
数组,即指针数组。每个指针指向一个动态分配的SPPoint
实例,即每个条目都有单独的分配
这是可行的,但您指出您需要一个SPPoint
数组,在这种情况下,指向第一个元素的指针的类型为SPPoint*
为了拥有这样一个数组,它是一个单一的内存分配。因此,您需要重新设计spPointCreate
函数。目前,该函数只为单个SPPoint
分配内存并进行初始化。相反,您希望将分配与初始化分开,因为您只需要一个分配,但需要mult多次初始化。您的程序逻辑将如下所示:
- 为
n
s分配一块足够大的内存SPPoint
- 初始化分配空间内的每个
SPPoint
如果您尝试了此方法但遇到了问题,请发布一个新问题,显示您的代码并解释您遇到问题的原因。
SPPoint**parr;
是指向(一组)指针的指针SPPoint*spPointCreate(…)<代码> BTW: SPONT不是TyPoffff.你使用C++编译器吗?它在头文件中,很抱歉没有包含它.它在哪里并不重要:在C中,结构定义不等同于TyffFED结构.我明白,这很有趣,因为我的课程工作人员给了我们下面的标题文件:(typedef struct sp_point_t SPPoint;),并告诉我们需要在C文件中有这样的结构定义。因此,如果它的类型定义在头文件中,它也必须在C文件中有这样的定义吗?数组不能被视为指针,就像int可以被视为double一样…实际上,将数组与指针混淆会导致各种误解和错误伴随而来的错误。@Rusty,你还是不明白。数组和指针是完全不同的东西。指针不是数组,指针也不是数组,或者数组的行为类似于指针。实际情况是,当计算数组类型的表达式时,结果是指向数组的第一个元素的指针当然,这样一个指针的行为和指针完全一样。这一点需要理解,因为如果你不理解的话,关于C的许多事情似乎是不一致的。@Rusty数组不存储内存地址(除非它是指针数组)。数组有地址,但int和任何其他object都有地址。@M.M.说,数组不存储内存地址,除非它们的元素是指针。您提出的反对意见围绕着我前面提到的一些误解。其中:(I)没有C函数接受数组作为参数;(ii)索引运算符([]
)从技术上讲,它是一个指针运算符,而不是数组运算符。您没有提出这个运算符,但我们在这里经常看到的另一个运算符是错误的期望,即2D数组对应于所谓的双指针。这也是C没有完整数组赋值的原因。