#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
}