scanf() 不分配内存,因此您必须始终传递函数可以为每个说明符放置数据的地址,例如%d 或%lf。因此,在您的情况下,您必须使用运算符的地址 & 传递每个 double 字段的地址
总是测试scanf()的返回。如果您无法获得其中一分,则没有理由继续读取数据
避免这种类型的评论:
void getRect(Rectangle *r); // function prototype
很明显这是一个原型。您的代码中有一些这样的 cmets。更喜欢使用描述用途、参数、参数、算法的 cmets...
一个例子
下面的小程序以一些常用的方式声明你的结构,包括一个为每次调用返回Rectangle 的函数和一个打印数据的函数。通常用于测试。这只是一个例子。我不是说它是好还是最好或任何东西。
为了 SO 警察:我总是将指针指向 malloc(),因为,嗯,我这样做了。
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
double x;
double y;
} Point;
typedef struct
{
Point tL; // top left
Point bR; // bottom right
} Rectangle;
Rectangle* rFactory();
int showR(Rectangle*);
int main(void)
{
Point A = { 2., 3. };
Point B =
{
.y = 3.4,
.x = 0.
};
Point* pP = &A;
printf( "Point is (%lf,%lf)\n", pP->x, pP->y ); // using pointer
printf( "Point is (%lf,%lf)\n", A.x, A.y ); // using data directly
Rectangle R0 = { A,B };
Rectangle R1 =
{
{
.x = 0.,
.y = 2.
}, // tL
{ 3.,4. } // bR
};
Rectangle R2 =
{
.bR = { 1.,2. },
.tL = { -4.,-5 }
};
Rectangle* pR = &R0;
pR = &R1;
pR = &R2; // :) just to get rid of the unused-var warnings
printf( "(via pointer) Rectangle is [(%lf,%lf), (%lf,%lf)]\n",
pR->tL.x, pR->tL.y,
pR->bR.x, pR->bR.y ); // using pointer
printf( "(via data) Rectangle is [(%lf,%lf), (%lf,%lf)]\n",
R2.tL.x, R2.tL.y,
R2.bR.x, R2.bR.y ); // using data directly
R2.bR.x = 0.;
R2.bR.y = 0.;
printf( "(Changed bR) Rectangle is [(%lf,%lf), (%lf,%lf)]\n",
pR->tL.x, pR->tL.y,
pR->bR.x, pR->bR.y ); // using pointer
printf( "(Using function)\n\n");
showR( &R2);
// using a 'factory function gets a new one
printf( "\n\n(Using factory function)\n\n");
Rectangle* other = rFactory();
showR( other );
free(other); // this one was allocated
return 0;
}
Rectangle* rFactory()
{
Rectangle* one = (Rectangle*) malloc(sizeof(Rectangle));
if ( one == NULL ) return NULL; // could not alloc
int res = 0;
printf("\
\tEnter points like '3., -2.3' separated by at least one space\
\n\tTop Left point: ");
res = scanf("%lf %lf", &one->tL.x,&one->tL.y);
if ( res != 2 )
{
free(one);
return NULL;
}; // if()
printf("\
\n\tBottom Right point: ");
res = scanf("%lf %lf", &one->bR.x,&one->bR.y);
if ( res != 2 )
{
free(one);
return NULL;
}; // if()
return one;
};
int showR( Rectangle* pR)
{
if ( pR == NULL ) return -1;
printf( "\n\t[using showR()] Rectangle is [(%lf,%lf), (%lf,%lf)]\n",
pR->tL.x, pR->tL.y,
pR->bR.x, pR->bR.y ); // using pointer
return 0;
}
输出
PS C:\src\bases> gcc -o tst -std=c17 -Wall sh.c
PS C:\src\bases> ./tst
Point is (2.000000,3.000000)
Point is (2.000000,3.000000)
(via pointer) Rectangle is [(-4.000000,-5.000000), (1.000000,2.000000)]
(via data) Rectangle is [(-4.000000,-5.000000), (1.000000,2.000000)]
(Changed bR) Rectangle is [(-4.000000,-5.000000), (0.000000,0.000000)]
(Using function)
[using showR()] Rectangle is [(-4.000000,-5.000000), (0.000000,0.000000)]
(Using factory function)
Enter points like '3., -2.3' separated by at least one space
Top Left point: 1. 2.
Bottom Right point: 3. 4.
[using showR()] Rectangle is [(1.000000,2.000000), (3.000000,4.000000)]
PS C:\src\bases>