Exercise 3-20 (StructArrayAddresses for 3d points)

Chapter_3     Exercise_3-19 ArrayIdentifier     Exercise_3-21







Exercise 3-20     TCP1, p. 229


Exercise 3-20. Apply the technique in ArrayAddresses.cpp (see ch3-ArrayAddresses) to print out the size of the struct and the addresses of the array elements in StructArray.cpp.




CONTENTS:     struct_array_addresses.c     StructArrayAddresses.cpp




struct_array_addresses.c         download


#include <stdio.h> // for printf(), putchar()
#include <string.h> // for strcat(), strcpy()

typedef struct
{
int i, j, k;
} ThreeDpoint;

void print3d(ThreeDpoint);
void print3dAddresses(ThreeDpoint*, char*);

void reverse(char* s, int len);// reverse `s', knowing its length
int itoa (int , char*); // int to string of chars

int main()
{
char name[20], index[10]; // p[i]
ThreeDpoint p[2];
printf("sizeof(int) = %lu\n", sizeof(int));
printf("sizeof(ThreeDpoint) = %lu\n", sizeof(ThreeDpoint));
printf("sizeof(p) = %lu\n", sizeof(p));
printf("&p = %p (hex) = %ld (dec)\n", &p, (long)&p);
putchar('\n');
for(int i = 0; i < 2; i++) // local i
{
printf("sizeof(p[%d]) = %lu\n", i, sizeof(p[i])); // local i
print3d(p[i]); // local i
p[i].i = i + 1; // local i, struct i, local i
p[i].j = i + 2; // local i, struct j, local i
p[i].k = i + 3; // local i, struct k, local i
print3d(p[i]); // local i
putchar('\n');
strcpy(name, "p["); // (re)set name
itoa(i, index); // int to string
strcat(name, index); // concatenation
strcat(name, "]"); // concatenation
print3dAddresses(&p[i], name); // pass `p[i]' by address
putchar('\n');
}

return 0;
}

void print3d(ThreeDpoint p)
{ // struct i, j, k:
printf("(%d, %d, %d), ", p.i, p.j, p.k);
}

void print3dAddresses(ThreeDpoint* p, char* name)
{ // struct i, j, k:
printf("&%s = %p (hex) = %ld (dec)\n", name, &(*p), (long)&(*p));
printf("&%s.i = %p (hex) = %ld (dec)\n", name, &p->i, (long)&p->i);
printf("&%s.j = %p (hex) = %ld (dec)\n", name, &p->j, (long)&p->j);
printf("&%s.k = %p (hex) = %ld (dec)\n", name, &p->k, (long)&p->k);
}

void reverse(char* s, int len)// reverse `s', knowing its length
{
int i = 0, j = len-1;
char temp;

while (i < j)
{
temp = s[i];
s[i] = s[j];
s[j] = temp;
i++;
j--;
}
}
// get the digits of n into `s' (convert n to a string of characters),
// return the length of `s' (no of digits, plus an eventual sign):
int itoa (int n, char* s)
{
int i = 0, sign = 1;

if (n < 0)
{
sign = -1;
}

do
{ // get the digits in reverse order:
s[i++] = (n % 10)*sign + '0'; // get next (last read) digit
// if n < 0, (n /= 10) <= 0, (n % 10) < 0
} while (n /= 10); // while ((n /= 10) != 0); // delete last digit

if (sign < 0) {s[i++] = '-';} // first char after reverse

s[i] = '\0'; // end the string

reverse(s, i);

return i;
}
/*
gcc struct_array_addresses.c -o struct_array_addresses
./struct_array_addresses
sizeof(int) = 4
sizeof(ThreeDpoint) = 12
sizeof(p) = 24
&p = 0x7ffca9810e40 (hex) = 140723152293440 (dec)

sizeof(p[0]) = 12
(194, 0, -1451159945), (1, 2, 3),
&p[0] = 0x7ffca9810e40 (hex) = 140723152293440 (dec)
&p[0].i = 0x7ffca9810e40 (hex) = 140723152293440 (dec)
&p[0].j = 0x7ffca9810e44 (hex) = 140723152293444 (dec)
&p[0].k = 0x7ffca9810e48 (hex) = 140723152293448 (dec)

sizeof(p[1]) = 12
(32764, -1451159946, 32764), (2, 3, 4),
&p[1] = 0x7ffca9810e4c (hex) = 140723152293452 (dec)
&p[1].i = 0x7ffca9810e4c (hex) = 140723152293452 (dec)
&p[1].j = 0x7ffca9810e50 (hex) = 140723152293456 (dec)
&p[1].k = 0x7ffca9810e54 (hex) = 140723152293460 (dec)

*/





Notes:  See Exercise_3-4 on the blog Kernighan_and_Ritchie, Chapter_3, Sec. 3.6 for itoa(), as well as Hex_to_Decimal and Decimal_to_Hex on RapidTables, Numeric_conversions.
In function print3dAddresses() we have to pass p[i] by address (a pointer) to be able to print addresses (by default a struct is passed by value, see Kernighan_and_Ritchie, Chapter_6).











StructArrayAddresses.cpp         download


#include <iostream>
#include <string>
using std::string;
using std::to_string;
using std::cout;
using std::endl;

typedef struct
{
int i, j, k;
} ThreeDpoint;

void print3d(ThreeDpoint);
void print3dAddresses(ThreeDpoint&, string);

int main()
{
ThreeDpoint p[2];
cout << "sizeof(int) = " << sizeof(int) << endl;
cout << "sizeof(ThreeDpoint) = " << sizeof(ThreeDpoint) << endl;
cout << "sizeof(p) = " << sizeof(p) << endl;
cout << "&p = " << &p << " (hex) = " << (long)&p << " (dec)" << endl;
cout << endl;
for(int i = 0; i < 2; i++) // local i
{
cout << "sizeof(p[" << i << "]) = " << sizeof(p[i]) << endl; // local i
print3d(p[i]); // local i
p[i].i = i + 1; // local i, struct i, local i
p[i].j = i + 2; // local i, struct j, local i
p[i].k = i + 3; // local i, struct k, local i
print3d(p[i]); // local i
cout << endl;
string name = "p[" + to_string(i) + "]"; // concatenation
print3dAddresses(p[i], name); // pass `p[i]' by reference
cout << endl;
}

return 0;
}

void print3d(ThreeDpoint p)
{ // struct i, j, k:
cout << "(" << p.i << ", " << p.j << ", " << p.k << "), ";
}

void print3dAddresses(ThreeDpoint& p, string name)
{ // struct i, j, k:
cout << "&" << name << " = " << &p << " (hex) = "
<< (long)&p << " (dec)" << endl;
cout << "&" << name << ".i = " << &p.i << " (hex) = "
<< (long)&p.i << " (dec)" << endl;
cout << "&" << name << ".j = " << &p.j << " (hex) = "
<< (long)&p.j << " (dec)" << endl;
cout << "&" << name << ".k = " << &p.k << " (hex) = "
<< (long)&p.k << " (dec)" << endl;
}
/*
g++ StructArrayAddresses.cpp -o StructArrayAddresses
./StructArrayAddresses
sizeof(int) = 4
sizeof(ThreeDpoint) = 12
sizeof(p) = 24
&p = 0x7ffd3e0cc350 (hex) = 140725644477264 (dec)

sizeof(p[0]) = 12
(893293288, 32550, 891547175), (1, 2, 3),
&p[0] = 0x7ffd3e0cc350 (hex) = 140725644477264 (dec)
&p[0].i = 0x7ffd3e0cc350 (hex) = 140725644477264 (dec)
&p[0].j = 0x7ffd3e0cc354 (hex) = 140725644477268 (dec)
&p[0].k = 0x7ffd3e0cc358 (hex) = 140725644477272 (dec)

sizeof(p[1]) = 12
(32550, -907271855, 21939), (2, 3, 4),
&p[1] = 0x7ffd3e0cc35c (hex) = 140725644477276 (dec)
&p[1].i = 0x7ffd3e0cc35c (hex) = 140725644477276 (dec)
&p[1].j = 0x7ffd3e0cc360 (hex) = 140725644477280 (dec)
&p[1].k = 0x7ffd3e0cc364 (hex) = 140725644477284 (dec)

*/





Notes:  See GeeksForGeeks for the int_to_string conversion and ch3-Function_call in Section ch3-Data_Types for passing by reference (PassReference.cpp). This is used in function print3dAddresses(), where we pass p[i] by reference. Note that we could also pass p[i] by address, as in struct_array_addresses.c above.









Chapter_3     Exercise_3-19 BACK_TO_TOP ArrayIdentifier     Exercise_3-21



Comments

Popular posts from this blog

Contents