It may be interesting to "see into" our computer's memory... of a sort.

 

(right-click to download)

/* CExplorer --  A glimpse into WHERE in memory varibles and functions (blocks of code */
/* reside. Every time this program is run, different memory locations may be shown. */
/* This is because the operating system will never allocate the same memory space */
/* for our programs */

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void do_nothing(void);
void do_little(void);
void dechexmap(void);
void p_line(int);
unsigned char pickchar(void);

struct pgmdata  {
     char achar;
     char astring[10];
     int anint;
     float afloat;
     double adouble;
     };

int main(void)
{
unsigned char uch;
struct pgmdata pd;

p_line(2);
dechexmap(); p_line(1);

uch = pickchar();
printf("pickchar() gives: %d (character: '%c')", uch, uch); p_line(2);

printf("sizeof pd: %ld bytes", sizeof(pd)); p_line(2);

printf("sizeof pd.achar: %ld bytes", sizeof(pd.achar)); p_line(1);
printf("sizeof pd.astring: %ld bytes", sizeof(pd.astring)); p_line(1);
printf("sizeof pd.anint: %ld bytes", sizeof(pd.anint)); p_line(1);
printf("sizeof pd.afloat: %ld bytes", sizeof(pd.afloat)); p_line(1);
printf("sizeof pd.adouble: %ld bytes", sizeof(pd.adouble)); p_line(2);

/* the '%p' printf() format is KEY to providing the hex-representation memory location */

printf("location of structure pd: %p", (void *) &pd); p_line(2);

printf("location of structure element pd.achar: %p", (void *) &pd.achar); p_line(1);
printf("location of structure element pd.astring: %p", (void *) &pd.astring); p_line(1);
printf("location of structure element pd.anint: %p", (void *) &pd.anint); p_line(1);
printf("location of structure element pd.afloat: %p", (void *) &pd.afloat); p_line(1);
printf("location of structure element pd.double; %p", (void *) &pd.adouble); p_line(2);

printf("location function main(): %p", (void *) main); p_line(1);
printf("location function pickchar(): %p", (void *) pickchar); p_line(1);
printf("location function dechexmap(): %p", (void *) dechexmap); p_line(1);
printf("location function do_nothing(): %p", (void *) do_nothing); p_line(1);
printf("location function do_little(): %p", (void *) do_little); p_line(1);
printf("location function p_line(): %p", (void *) p_line); p_line(3);

return (0);
}

unsigned char pickchar(void)  {
     unsigned char retval;

     srand(time(NULL)); // 'seed' the rand() function (next) so it is as random as possible
     retval = (unsigned char) (rand() % 255); // rand() can return a very large number; limit to 0 - 255

     return(retval); // note this function returns an "unsigned char"
     }

void dechexmap(void)   {
     char x;

     printf("Decimal & hexidecimal values"); p_line(1);

     for (x = 0; x < 16; x++)
          {
          printf("%d = %x\t", x, x);
          if (!((x + 9) % 8))
               p_line(1);
          }
     }

void p_line(int qnty)   {
     int x;

     for (x = 0; x < qnty; x++)
          printf("\n");
     }

/* the last two functions do_nothing() and do_little() */
/* will cause a warning for "unused variable", which is */
/* fine, we just need tiny functions for observation */

void do_nothing()   {
     char a;
     a = 'a';
     }

void do_little()   {
     char b;
     b = 'b';
     }