C语言 使用指针访问嵌套结构中的数据



我正在做一个分配,这需要我写一个包含嵌套结构的代码。这个问题其实很简单。只是为了得到一个矩形的角的坐标。我一直在网上研究,但大多数例子都没有typedef结构。我的问题主要是不确定访问和存储数据的正确语法是什么。我有结构模板如下:

typedef struct
{
double x;
double y;
} Point; // Create a Point datatype;
typedef struct // nested structure
{
Point topLeft; // topLeft is the variable name for "Point" structure with x&y property
Point botRight; // botRight is the variable name for "Point" structure with x&y property
} Rectangle; // Create a Rectangle datatype with Point structure within
void getRect(Rectangle *r); // function prototype
int main()
{
Rectangle r; // initializing rectangle;
getRect(&r); // call function to get inputs using call by reference
}
void getRect(Rectangle *r)
{
printf("Enter top left points:n");
scanf("%lf %lf", r->topLeft.x,r->topLeft.y); // Not sure if this is correct as my program can compile and run up till this point and crashes.
printf("Enter bottom right points:n");
scanf("%lf %lf", r->botRight.x,r->botRight.y);
}

征求大家对这件事的善意指导!

问题是scanf调用的实参必须是指针。例如

scanf("%lf %lf", &r->topLeft.x, &r->topLeft.y);

scanf("%lf %lf", &r->botRight.x, &r->botRight.y);

也就是说,你需要通过引用传递对象x和y,函数scanf可以处理原始对象,而不是它们值的副本。

在C语言中,引用传递是指通过指向对象的指针间接传递对象。在这种情况下,被调用的函数可以通过使用指针的解引用操作直接访问对象。

scanf()不分配内存,因此您必须始终传递函数可以为每个说明符放置数据的地址,例如%d%lf。因此,在您的情况下,您必须使用操作符&

的地址传递每个double

字段的地址。总是测试scanf()的返回。如果不能得到

点之一,则没有理由继续读取数据。避免这种类型的注释:

void getRect(Rectangle *r); // function prototype

很明显这是一个原型。在您的代码中有一些这样的注释。更喜欢使用注释来描述用法、形参、实参、算法…

一个例子下面的小程序以一些常用的方式声明结构,包括一个函数为每次调用返回一个Rectangle,以及一个函数输出数据。通常用于测试。这只是一个例子。我不是说它是好的或最好的或其他什么。

:我总是将指针强制转换为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)nn");
showR( &R2);
// using a 'factory function gets a new one
printf( "nn(Using factory function)nn");
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
ntTop Left point: ");
res = scanf("%lf %lf", &one->tL.x,&one->tL.y);
if ( res != 2 )
{
free(one);
return NULL;
};  // if()
printf("
ntBottom 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( "nt[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:srcbases> gcc -o tst -std=c17 -Wall sh.c
PS C:srcbases> ./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:srcbases>

最新更新