# Thread: more with my 1st structure program

1. ## more with my 1st structure program

ok I am continuing on with my evolving program
I have 2 structures and
what the program is doing is first finding the area of a rectangle "r"
then we are to find the center of that rectangle.
I worked a bit , think I got the point that is the center.
Now I have code here, but it isn't compiling right. I am to return as a value from the point structure. But how? I figured I'd return the value of that point's x, y coordinates (x and y axis on graph, of course)
but my return value is wrong.

Please help.

PHP Code:
```     #include <stdio.h> struct point {     int x, y; }; struct rectangle {     struct point upper_left, lower_right; } r; int area_of_r(struct rectangle rect); int center_of_r(struct rectangle x,struct rectangle y); int main(void) {     printf( "input upper left corner of rectangle r "              "as 0 0, with space in between.\n\n");     scanf( "%d %d", &r.upper_left.x, &r.upper_left.y );     printf( "input lower right corner of rectangle r  "             "as 0 0, with space in between.\n\n");     scanf( "%d %d", &r.lower_right.x, &r.lower_right.y );    /* here we print the area of the rectangle */         printf( "\nThe area of rectangle r is "             "%d\n", area_of_r(r));    /* here we print the center of rectangle */     printf("\nThe center point of rectangle r is "            "%d %d",center_of_r(r));     return 0; } int area_of_r ( struct rectangle rect ) {     int area;     area = (r.lower_right.x - r.upper_left.x) *            (r.upper_left.y - r.lower_right.y);     return area; } int center_of_r(struct rectangle x, struct rectangle y) {     int center;     int new_x, new_y;    /* having problems with this part, don't know how to run        line of assignments to next line...is that possible  */     x = (r.lower_right.x -((r.lower_right.x -                   r.upper_left.x)/2);     y = (r.upper_left.y - ((r.upper_left.y -                   r.lower_right.y)/2);     /* here's the return call, but what is wrong here?? How         do I return the values of x and y which are the values        of the coordinates of a point on a graph  ???                */         return (x,y);                }  ```

2. You cannot return two values with a single return statement.
Try passing pointers, and assigning the values that way:

void centerCoords( int *x, int *y )
{
....blah blah
.... *x = mystruct.point.x;
.... *y = mystruct.point.y;
}

Call it like so:

int getX, getY;

centerCoords( &getX, &getY );

Quzah.

3. printf( "\nThe area of rectangle r is "
"%d\n", area_of_r(r));
Right now your instance of the rectangle object r is global so you do not have to pass it as an arguement, however it would be better to define an instance of the rectangle in main and remove the r created after the declaration of the rectangle structure.

Should look like this:
Code:
```struct point {
int x, y;
};

struct rectangle {
struct point upper_left, lower_right;
} ;```
Than in main define an instance:

Code:
```int main()
{
struct rectangle r;
...
return 0;```
Than passing arguements to functions makes sense now because the scope of the object is the function. It is no longer global. Just the declaration of the structures are global so that you can define instances of the objects in any function. If you want to return a point structure than declare one in the called function.

Code:
```struct point CalledFunction(struct rectangle r)
{
struct point p;
....
return p;
}```
You would have to make an lvalue in main: such as:
Code:
`struct point center = CalledFunction(r);`
There are numerous ways to do this. Just pick one.

4. The center of a rectangle is a point, not an int, so your
PHP Code:
``` int center_of_r(struct rectangle x,struct rectangle y);  ```
should be
PHP Code:
``` struct point center_of_r(struct rectangle x,struct rectangle y);  ```
And obviously the logic in the function itself will have to change very slightly.
Printing the x and y coordinates of this point shouldn't be too tough...
PHP Code:
``` printf("\nThe center point of rectangle r is "            "%d %d",center_of_r(r).x, center_of_r(r).y);  ```

5. int center_of_r(struct rectangle x, struct rectang le y)
{
int center;
int new_x, new_y;
/* having problems with this part, don't know how to run
line of assignments to next line...is that possible */
x = (r.lower_right.x -((r.lower_right.x -
r.upper_left.x)/2);
y = (r.upper_left.y - ((r.upper_left.y -
r.lower_right.y)/2);
/* here's the return call, but what is wrong here?? How
do I return the values of x and y which are the values
of the coordinates of a point on a graph ??? */

return (x,y);
}
You made the mistake of passing TWO structures instead of ONE into this function! You are seeking the center of one structure!

You also declared new_x, new_y, but never used them. And int center is meaningless since we will not represent the center with a single value!

Finally, you defined the parameter "struct rectangle rect" in defining the area function, but then tried to access the REAL struct "r" WITHIN the fuction definition, so : "r.lower_right.y....." should be: "rect.lower_right.y..."

Same mistake in the next function definition. your parameter reads: " struct rectangle x..." and yet try to access the real struct "r" , so "r.lower_right.y..." should read "x.lower_right.y..."

Again, when you are writing a function, you are not going to refer to real variables(such as "r"). You are building a (semi-)generic framework that will work with ANY "rectangle" type. So it is imperitive that you understand that in defining these functions they do not try to access real variables! So if your parameter list says: "struct rectangle rect..." then the code body will use the same name when accessing the struct. Do you get it? Match your parameters with the code within the function and forget that you will declare "struct rectangle r" in your program!!

So:
Since you only need the VALUES of the center points, 1) declare new_x, new_y in main just before calling center_of_r() and initialize them to zero. 2) We don't want struct r to be changed by accident within the function, so we will pass it by value( so not a pointer!). 3) pass also new_x, new_y into this function by reference(because we DO want these values to be changed within the function). You can pass by reference by A) declaring pointers to new_x, new_y, or B) you can use the much simpler method of passing the variables themselves into the function preceded by the & symbol (same functionality as a pointer!).

So the parameters for the function definition are:

void center_of_r( struct rectangle rect, int *x_ptr, int *y_ptr)
{....} /// Function will work with pointer or & reference

And the syntax for using the function would be:

center_of_r( r, &new_x, &new_y);

But don't try to place the function in "printf()" because we are not using any return value!

instead:

printf("Center Point At (x: %d , y: %d) ! \n\n", new_x, new_y);

Better yet:

You should consider the fact that although we now have the
MEANS for obtaining the coordinates and center points, the all important structure ( whose job it is to hold useful data on an object) is not being utilized to hold this new information! So now you can add variables to the structure to hold the new data, plus get rid of random variables such as new_x,new_y:

( And some renaming...)

Code:
```typedef struct rectangle
{

struct point upper_left, upper_right, center_points;
int area;

};

typedef struct point
{ int x,y;};

// The value of typedef'ing is now to create r, you simply say:

int main()
{

rectangle r;    // Now you can omit the "struct" keyword

//Now the ugly but EXTREMELY imperitive initializing !!!

r.upper_left.x = 0, r.upper_left.y = 0, r.lower_right.x = 0, r.lower_right.y = 0, r.center_points.x =0, r.center_points.y =0, r.area = 0;

//// code goes here to get user input for coordinates...

r.area = get_area( r );

get_center( r,  &r.center_points.x,  & r.center_points.y );

// alternate but "unsafe": -->            // get_center(&r);

/// code goes here for printing for user...

return 0;
}

/// define your functions here...GENERICALLY!!```
That's it! Now "r" has been safely filled and all of it's members replaced the random variables on assignment, which cleans up the code quite nicely.

Notice that I changed the names of your functions. That's because they were named after struct "r", which in the long run is no good because they have nothing specifically to do with "r" in order to function and everything to do with rectangles! Next, we make a direct assignment of r.area() because it returns an int. Finally In chose to require three parameters to get_center(). Why? Because for safeties sake, we want to protect other values in "r" from being changed, so pass r by value, but the center points by reference(because we WANT to change them.) If you feel more comfortable passing just the struct into the function( as I show commented out) you will have to pass "r" by reference(&r) but risk the chance that other "r" variables get changed. They probably WON'T but that is a worse case scenario that exists.

__________________________________________________ _
Sue B: After conquering this, write a function that calculates the diagonal of the rectangle!
__________________________________________________ _

Advanced Programmers: Might it be possible to apply a bit mask to a long int who's hi-order byte holds the x, and low-order byte holds the y, thus making it possible to pass the coordinates of a rectangle as a single value??

6. The initializing is most important since if any of the functions fail, you may end up with "garbage values " if you don't initialize.

A cleaner approach than the on I suggested would be to create a new function whose sole purpose is to initialize variables for you! So:

void init( struct rectangle *ricky )
{
ricky.upper_left.x = 0, ricky.upper_left.y = 0, ricky.lower_right.x = 0, ricky.lower_right.y = 0, ricky.center_points.x =0, ricky.center_points.y =0, ricky.area = 0;
}

call it like:

init(&r);

Notice the parameters and code body match. Also, you might have to change all of your functions when using the &reference and *pointers so that the "." becomes either "->"
"ricky->center_points.x..." or else enclose the struct like this: "(*ricky).center_points.x..."

But that kindof depends on how proper your compiler is! (Unfortunately, The two above conventions are really basically "mandatory". I just forgot it in my examples!)

Lastly, do not declare "r" before main! You do not want a global variable like this!

7. > I am to return as a value from the point structure.
You already have a struct point, so return one of them

Code:
```#include <stdio.h>

// a single point
struct point {
int x, y;
};

// opposite corners
struct rectangle {
struct point upper_left, lower_right;
};

// this is good
int area_of_r ( struct rectangle rect );

// int center_of_r(struct rectangle x,struct rectangle y);
// this is wrong
// 1. you only need to pass one rectangle
// 2. you need to return a point, not an int
struct point centre_of_r ( struct rectangle rect );

int main(void) {
struct rectangle r;  // note - local var
struct point     centre;
int              area;

printf( "input upper left corner of rectangle r "
"as 0 0, with space in between.\n\n");
scanf( "%d %d", &r.upper_left.x, &r.upper_left.y );
printf( "input lower right corner of rectangle r  "
"as 0 0, with space in between.\n\n");
scanf( "%d %d", &r.lower_right.x, &r.lower_right.y );

/* here we print the area of the rectangle */
area = area_of_r(r);
printf( "\nThe area of rectangle r is "
"%d\n", area);

/* here we print the center of rectangle */
centre = centre_of_r(r);
printf("\nThe center point of rectangle r is "
"%d %d",centre.x, centre.y);
return 0;
}
int area_of_r ( struct rectangle r )
{
int area;
area = (r.lower_right.x - r.upper_left.x) *
(r.lower_right.y - r.upper_left.y);
return area;
}

struct point centre_of_r ( struct rectangle r )
{
struct point centre;
centre.x = r.upper_left.x + ( r.lower_right.x - r.upper_left.x ) / 2;
centre.y = r.upper_left.x + ( r.lower_right.y - r.upper_left.y ) / 2;
return centre;
}```

8. A cleaner approach than the on I suggested would be to create a new function whose sole purpose is to initialize variables for you!
Know what this reminds me of?

9. (Somewhat less cryptically) "OK,What?"

10. This is the purpose of a C++ class constructor. The only thing is that a constructor is more flexible, in that it can be overloaded.

11. I don't know WHAT your talking about!!

12. How much C++ do you know? This is a real thing. Sounds cool heh.

13. Well, put it this way, I have been studying it for about 2 weeks now! But I so far have designed a simple class Employee which does simple things such as the IO embedded to interact with the user, some string parsing, and several overloaded functions, and, my personal favorite:

Employee operator=(Employee *A){...}

Which does the one- for -one member copy to an empty struct so that:
...
Employee New;

New = Old;

And it's a done deal!

14. With all the ranting and raving, and extreme comments, I am frustrated now.

I am totally confused about :

when to use struct and when not, when using a variable of a structure
how to reference a global variable with structures
how to reference a local variable
when to know to use a global vs a local

now taking each reply to my post separately, it shall take a day for it to sink in enough to decipher what I really need to do.
And my programs (there are more than this one itty bitty one ) are due Tuesday.

C language is hard.

It is hard because I am used to BASIC which I learned 20 years ago. BASIC had line numbers and made sense to me. I didn't do real complicated programs, but I HAD FUN doing what was asked. Things have greatly changed, and now it isn't fun. I only decided to get IT training last year, and the class I take now is so fast, I don't get the darn stuff as fast as you guys. And to make matters worse. I pay the stupid university \$600 for this course and the professor is as arrogant as some programmers I know. and says everything is SIMPLE. It is simple, to someone who's been doing it for a long time.

I DON'T GET IT FOLKS.

I learn by step by step instruction.
I learn without all the subjective comments.
I need a better book that shows many examples of whatever is being taught. Without jumping from one set of parameters to another.

Geez.

I give up. And I guess C++ and Java are just as bad, huh?

15. See Salem's post there? Use that one because it combines everything. You need to be slightly more clear about the problem because there are a few different ways to do it. And just for your information, I have been doing C for 2+ years.

Popular pages Recent additions