by-sa

#1  Run the following code

(a) What is the output result  when only one #define is activated (#define B1, or #define B2, or  #define B3,  or #define B4).

(b) What will be the outcome if two or more #define’s are activated. Try to explain.


#define B1 enabled
&a= 0x00007fffc6dc60df a= 0xcc 
&p= 0x00007fffc6dc60e0 p= 0x7fffc6dc60df 
sizeof(a)= 1 bytes
sizeof(p)= 8 bytes
-----------------------
(p-2)= 0x00007fffc6dc60dd 
(p-1)= 0x00007fffc6dc60de 
(p+0)= 0x00007fffc6dc60df 
(p+1)= 0x00007fffc6dc60e0 
(p+2)= 0x00007fffc6dc60e1 
-----------------------
#define B2 enabled
&a= 0x00007ffda6a14dae a= 0xddcc 
&p= 0x00007ffda6a14db0 p= 0x7ffda6a14dae 
sizeof(a)= 2 bytes
sizeof(p)= 8 bytes
-----------------------
(p-2)= 0x00007ffda6a14daa 
(p-1)= 0x00007ffda6a14dac 
(p+0)= 0x00007ffda6a14dae 
(p+1)= 0x00007ffda6a14db0 
(p+2)= 0x00007ffda6a14db2 
-----------------------
#define B4 enabled
&a= 0x00007ffc1cf255dc a= 0xffeeddcc 
&p= 0x00007ffc1cf255e0 p= 0x7ffc1cf255dc 
sizeof(a)= 4 bytes
sizeof(p)= 8 bytes
-----------------------
(p-2)= 0x00007ffc1cf255d4 
(p-1)= 0x00007ffc1cf255d8 
(p+0)= 0x00007ffc1cf255dc 
(p+1)= 0x00007ffc1cf255e0 
(p+2)= 0x00007ffc1cf255e4 
-----------------------
#define B8 enabled
&a= 0x00007ffc445a4f38 a= 0xffeeddccbbaa9988 
&p= 0x00007ffc445a4f40 p= 0x7ffc445a4f38 
sizeof(a)= 8 bytes
sizeof(p)= 8 bytes
-----------------------
(p-2)= 0x00007ffc445a4f28 
(p-1)= 0x00007ffc445a4f30 
(p+0)= 0x00007ffc445a4f38 
(p+1)= 0x00007ffc445a4f40 
(p+2)= 0x00007ffc445a4f48 
-----------------------
#define B8 and #define B4 are enabled
gcc t.c
t.c: In function ‘main’:
t.c:29:8: error: conflicting types for ‘a’
   int  a = 0xFFEEDDCC;
        ^
t.c:11:11: note: previous definition of ‘a’ was here
   double  a = 3.14;
           ^
t.c:30:8: error: conflicting types for ‘p’
   int *p = &a;
        ^
t.c:12:11: note: previous definition of ‘p’ was here
   double *p = &a;
           ^

#2 Explain the following fomat charatecters

(a) %x  (b) %lx  (c) %hx

(d) %#x (e) %#lx (f) %#hx

(g) 0x%08x  (h) 0x%016lx (i) 0x%040hx

(j) %#08x  (k) %#016lx (l) %#04hx


  • %x : hexadecimal representation for a default 4-byte integer
  • %lx : hexadecimal representation for an 8-byte long integer
  • %hx : hexadecimal representation for a 2-byte short integer
  • %#x : with the prefix 0x
  • %#lx : with the prefix 0x
  • %#hx : with the prefix 0x
  • 0x%08x :  manual 0x and zero filling to 8 hexadecimal digits
  • 0x%016lx : manual prefixing 0x and zero filling to 16 hexadecimal digits
  • 0x%040hx : manual prefixing 0x and zero filling to 4 hexadecimal digits
  • %#08x : no zero filling with #
  • %#016lx : no zero filling with #
  • %#040hx : no zero filling with #

to print 8-byte address in hexadecimal

  printf("&p= 0x%016lx p= %p \n", (unsigned long) &p, p);

#3 Explain the following pointer arithmetic results

(addition & subtraction) when the pointer types are

(double *), (int *), (short *), (unsigned char *), respectively.

  • (a) (p-2)
  • (b) (p-1)
  • (c) (p+0)
  • (d) (p+1)
  • (e) (p+2)

double * p; 
sizeof(double)=8bytes 
p-2 ==> the address where p point - 2*8 byte offset
p-1 ==> the address where p point - 1*8 byte offset
p+0 ==> the address where p point + 0*8 byte offset
p+1 ==> the address where p point + 1*8 byte offset
p+2 ==> the address where p point + 2*8 byte offset
int * p; 
sizeof(int)=4bytes 
p-2 ==> the address where p point - 2*4 byte offset
p-1 ==> the address where p point - 1*4 byte offset
p+0 ==> the address where p point + 0*4 byte offset
p+1 ==> the address where p point + 1*4 byte offset
p+2 ==> the address where p point + 2*4 byte offset
short * p; 
sizeof(double)=2bytes 
p-2 ==> the address where p point - 2*2 byte offset
p-1 ==> the address where p point - 1*2 byte offset
p+0 ==> the address where p point + 0*2 byte offset
p+1 ==> the address where p point + 1*2 byte offset
p+2 ==> the address where p point + 2*2 byte offset
unsigned char * p; 
sizeof(double)=1byte 
p-2 ==> the address where p point - 2*1 byte offset
p-1 ==> the address where p point - 1*1 byte offset
p+0 ==> the address where p point + 0*1 byte offset
p+1 ==> the address where p point + 1*1 byte offset
p+2 ==> the address where p point + 2*1 byte offset

#4 Explain the type cast (unsigned long) and format character %lx.  (On a 64-bit machine, an address has 8 bytes, but an integer can print only 4-byte number.)

  • GCC – (unsigned long) : 64-bit
  • Visual C++ – (unsigned long) : 32-bit, (unsigned long long) : 64-bit

  • the value of a pointer variable is an address (32-bit or 64-bit)
  • the default converter is %p
  • this does not fill zero to the full 32-bit or 64-bit value.
  • to zero fill, convert the address into the same size (8-byte, 64-bit) unsigned long type.
  •  and use 0x%016lx converter.

include 

// #define B1
// #define B2
// #define B4
#define B8

int main(void) {
#ifdef B8
  long int a = 0xFFEEDDCCBBAA9988;
  long int *p = &a;

  printf("&a= 0x%016lx a= 0x%016lx \n", (unsigned long) &a, a);
  printf("&p= 0x%016lx p= %p \n", (unsigned long) &p, p);
  printf("sizeof(a)= %ld bytes\n", sizeof(a) );
  printf("sizeof(p)= %ld bytes\n", sizeof(p) );

  printf("-----------------------\n");
  printf("(p-2)= 0x%016lx \n", (unsigned long) (p-2));
  printf("(p-1)= 0x%016lx \n", (unsigned long) (p-1));
  printf("(p+0)= 0x%016lx \n", (unsigned long) (p+0));
  printf("(p+1)= 0x%016lx \n", (unsigned long) (p+1));
  printf("(p+2)= 0x%016lx \n", (unsigned long) (p+2));
  printf("-----------------------\n");
#endif
#ifdef B4
  int  a = 0xFFEEDDCC;
  int *p = &a;

  printf("&a= 0x%016lx a= 0x%08x \n", (unsigned long) &a, a);
  printf("&p= 0x%016lx p= %p \n", (unsigned long) &p, p);
  printf("sizeof(a)= %ld bytes\n", sizeof(a) );
  printf("sizeof(p)= %ld bytes\n", sizeof(p) );

  printf("-----------------------\n");
  printf("(p-2)= 0x%016lx \n", (unsigned long) (p-2));
  printf("(p-1)= 0x%016lx \n", (unsigned long) (p-1));
  printf("(p+0)= 0x%016lx \n", (unsigned long) (p+0));
  printf("(p+1)= 0x%016lx \n", (unsigned long) (p+1));
  printf("(p+2)= 0x%016lx \n", (unsigned long) (p+2));
  printf("-----------------------\n");
#endif
#ifdef B2
  short  a = 0xDDCC;
  short *p = &a;

  printf("&a= 0x%016lx a= 0x%04hx \n", (unsigned long) &a, a);
  printf("&p= 0x%016lx p= %p \n", (unsigned long) &p, p);
  printf("sizeof(a)= %ld bytes\n", sizeof(a) );
  printf("sizeof(p)= %ld bytes\n", sizeof(p) );

  printf("-----------------------\n");
  printf("(p-2)= 0x%016lx \n", (unsigned long) (p-2));
  printf("(p-1)= 0x%016lx \n", (unsigned long) (p-1));
  printf("(p+0)= 0x%016lx \n", (unsigned long) (p+0));
  printf("(p+1)= 0x%016lx \n", (unsigned long) (p+1));
  printf("(p+2)= 0x%016lx \n", (unsigned long) (p+2));
  printf("-----------------------\n");
#endif
#ifdef B1
  unsigned char  a = 0xCC;
  unsigned char *p = &a;

  printf("&a= 0x%016lx a= 0x%02hx \n", (unsigned long) &a, a);
  printf("&p= 0x%016lx p= %p \n", (unsigned long) &p, p);
  printf("sizeof(a)= %ld bytes\n", sizeof(a) );
  printf("sizeof(p)= %ld bytes\n", sizeof(p) );

  printf("-----------------------\n");
  printf("(p-2)= 0x%016lx \n", (unsigned long) (p-2));
  printf("(p-1)= 0x%016lx \n", (unsigned long) (p-1));
  printf("(p+0)= 0x%016lx \n", (unsigned long) (p+0));
  printf("(p+1)= 0x%016lx \n", (unsigned long) (p+1));
  printf("(p+2)= 0x%016lx \n", (unsigned long) (p+2));
  printf("-----------------------\n");
;
#endif

}