I have this code which is supposed to swap two values inside a_ptr and b_ptr:
// swaps two values inside two variables of any type
void swap(void *a_ptr, void *b_ptr)
{
size_t size = sizeof(void *);
void *tmp = malloc(size);
memcpy(tmp, a_ptr, size);
memcpy(a_ptr, b_ptr, size);
memcpy(b_ptr, tmp, size);
free(tmp);
// char wot0 = 0;
// char wot1 = 0;
// swap(&wot0, &wot1);
}
int main(){
long a = -7;
long b = 99999999;
printf("A: %ld, B: %ld\n", a, b);
swap(&a, &b);
printf("A: %ld, B: %ld\n", a, b);
printf("\n");
short c = -9;
short d = 11111;
printf("C: %hd, D: %hd\n", c, d);
swap(&c, &d);
printf("C: %hd, D: %hd\n", c, d);
printf("\n");
char ca = 'a';
char cx = 'x';
printf("CA: %c CX: %c\n", ca, cx);
swap(&ca, &cx);
printf("CA: %d CX: %c\n", ca, cx);
printf("\n");
char *str0 = "Hello, ";
char *str1 = "World!";
printf("STR0: %s STR1: %s\n", str0, str1);
swap(&str0, &str1);
printf("STR0: %s STR1: %s\n", str0, str1);
printf("\n");
return 0;
}
However the output is:
A: -7, B: 99999999
A: 99999999, B: -7
C: -9, D: 11111
C: -7, D: -9
CA: a CX: x
CA: -9 CX: a
STR0: Hello, STR1: World!
STR0: World! STR1: Hello,
It successfully swaps a and b, and then somehow replaces c with b, and ca with d, how's that even possible?
Also, uncommenting these lines:
// char wot0 = 0;
// char wot1 = 0;
// swap(&wot0, &wot1);
Leads to a segfault, why?
EDIT:
I think I didin't convey my intentions very well. That I basically want to do is swap pointers so that a_ptr points to value inside b, and b_ptr points to value inside a, I don't want to actually copy the values themselves and I think I achieved that somewhat successfully, strings of different lengths (for examples "Foo" and "Hello, World!") get swapped without any issues, I tested that, however I don't understand why some variables don't get swapped and actually point to values outside of that I passed into the function
sizeof(void *); is a constant (usually 4 or 8) and does not give you the size of the object it's pointing at. When you copy size bytes, you are not copying the correct amount for the types used.
You're probably better off by supplying the size of the type to the function:
// swaps two values inside two variables of any type
void swapper(void *a_ptr, void *b_ptr, size_t size)
{
void *tmp = malloc(size);
memcpy(tmp, a_ptr, size);
memcpy(a_ptr, b_ptr, size);
memcpy(b_ptr, tmp, size);
free(tmp);
}
// Generate compilation error if objects of different sizes are used.
// The false switch case (0) can only be defined once so if the sizes
// are not the same, it'll try to redefine "case 0" and fail compiling:
#define compile_assert(_expr) switch (_expr) { case 0: break; case _expr: break; }
#define swap(x,y) do { \
compile_assert(sizeof(*(x)) == sizeof(*(y))); \
swapper((x),(y),sizeof(*(x))); } while (0)
And call it like you aimed to do:
swap(&a, &b);
If you only need to swap fundamental types, you could make different implementations for all of them. This should also make it safer since it's harder to supply pointers to objects of different types this way:
#define SwapBuilder(name,type) \
void name(type *a, type *b) { type tmp = *a; *a = *b; *b = tmp; }
SwapBuilder(swap_char,char)
SwapBuilder(swap_schar,signed char)
SwapBuilder(swap_uchar,unsigned char)
SwapBuilder(swap_short,short)
SwapBuilder(swap_ushort,unsigned short)
SwapBuilder(swap_int,int)
SwapBuilder(swap_uint,unsigned int)
SwapBuilder(swap_long,long)
SwapBuilder(swap_ulong,unsigned long)
SwapBuilder(swap_longlong,long long)
SwapBuilder(swap_ulonglong,unsigned long long)
SwapBuilder(swap_float,float)
SwapBuilder(swap_double,double)
SwapBuilder(swap_longdouble,long double)
// A _Generic to call the correct function:
#define swap(x,y) _Generic((x), \
char* : swap_char, \
signed char* : swap_schar, \
unsigned char* : swap_uchar, \
short* : swap_short, \
unsigned short* : swap_ushort, \
int* : swap_int, \
unsigned int* : swap_uint, \
long* : swap_long, \
unsigned long* : swap_ulong, \
long long* : swap_longlong, \
unsigned long long* : swap_ulonglong, \
float* : swap_float, \
double* : swap_double, \
long double* : swap_longdouble \
)((x),(y))
And you'd still call it with swap(&a, &b);
Related
#include <stdio.h>
typedef unsigned char*pointer;
void show_bytes(pointer start, size_t len)
{
size_t i;
for (i = 0; i < len; i++)
printf("%p\t0x%04x\n",start+i, start[i]);
printf("\n");
}
int main()
{
double a = 4.75;
printf("Double demo by %s on %s %s\n", "Toan Tran", __DATE__, __TIME__);
printf("Double a = %.2f (0x%08x)\n", a, a);
show_bytes((pointer) &a, sizeof(double));
}
Output:
Double demo by Toan Tran on Nov 8 2018 11:07:07
Double a = 4.75 (0x00000100)
0x7ffeee7a0b38 0x0000
0x7ffeee7a0b39 0x0000
0x7ffeee7a0b3a 0x0000
0x7ffeee7a0b3b 0x0000
0x7ffeee7a0b3c 0x0000
0x7ffeee7a0b3d 0x0000
0x7ffeee7a0b3e 0x0013
0x7ffeee7a0b3f 0x0040
For this line:
printf("Double a = %.2f (0x%08x)\n", a, a);
I want it to print out the result of start[i]
The return hexadecimal is not the right value for double.
I want it to return 0x40130000000000...
Please help.
The %x format specifier is expecting an unsigned int argument, but you're passing in a double. Using the wrong format specifier invokes undefined behavior.
To print the representation of a double, you need to print each individual byte as hex using a character pointer. This is exactly what you're doing in show_bytes, and is the proper way to do this.
Also, when printing a pointer with the %p format specifier, you should cast the pointer to void *, which is what %p expects. This is one of the rare cases where a cast to void * is needed.
You might be tempted to do something like this:
printf("%llx", *((unsigned long long *)&a));
However this is a violation of the strict aliasing rule. You would need to use memcpy to copy the bytes to the other type:
static_assert(sizeof(unsigned long long) == sizeof(double));
unsigned long long b;
memcpy(&b, &a, sizeof(a));
printf("%llx", b);
You can also do this with a union:
union dval {
double d;
unsigned long long u;
};
union dval v;
v.d = d;
printf("%llx", v.u);
To allow printing a hex dump of any object, pass its address and length.
void show_bytes2(void *start, size_t size) {
int nibble_width_per_byte = (CHAR_BIT + 3) / 4; // Often 2
unsigned char *mem = start;
// Highest bytes first
for (size_t i = size; i>0; ) {
printf("%0*x", nibble_width_per_byte, mem[--i]);
}
printf("\n");
// Lowest bytes first
while (size--) {
printf("%0*x", nibble_width_per_byte, *mem++);
}
printf("\n");
}
Use "%a" to print the significand of the double in hexadecimal.
int main() {
double a = 4.75;
printf("Double a = %a %e %f %g\n", a, a, a, a);
show_bytes2(&a, sizeof a);
}
Output
Double a = 0x1.3p+2 4.750000e+00 4.750000 4.75
4013000000000000 // I want it to return 0x40130000000000...
0000000000001340
#include <stdio.h>
void swap( char* pA, char* pB, unsigned tam) {
for( unsigned i = 0; i < tam; i++) {
char tmp = *pA;
*pA = *pB;
*pB = tmp;
pA = pA + 1;
pB = pB + 1;
}
}
int main(int argc, char** argv) {
double a = 1.0;
double b = 2.0;
printf("linea: %d - antes a(%f) b(%f)\n", __LINE__, a, b);
swap(&a, &b, sizeof(double)); //This line gives the error
printf("linea: %d - despues a(%f) b(%f)\n", __LINE__, a, b);
}
When I call the swap method I get the error message in the title, any idea why? I saw many other posts with solutions but none of them fixed this problem
There are a number of ways of writing a generic swap function. If it will be used for only one type (so it doesn't need to be generic), the size argument is not needed and you can pass pointers of the relevant type (double * in the question) and swap using indirection.
extern void double_swap(double *d1, double *d2);
void double_swap(double *d1, double *d2)
{
double d = *d1;
*d1 = *d2;
*d2 = d;
}
There might well be advantages to making that into:
static inline void double_swap(double *d1, double *d2)
{
double d = *d1;
*d1 = *d2;
*d2 = d;
}
This could be placed in a header and used safely.
If it will be used for multiple types, you should use void * in the function arguments (and size_t for the size of the type).
/*
** This declaration belongs in a header if there is more than one
** source file that uses it. If there is only one file, then it
** should be declared and defined as a static function. If the
** header doesn't include any other headers that define size_t,
** it should #include <stddef.h> as that's the smallest header
** that does define size_t. You could make the function static
** inline instead of extern, even if it is in a header.
*/
extern void generic_swap(void *v1, void *v2, size_t size);
/* Implementation 1: Using VLA */
void generic_swap(void *v1, void *v2, size_t size)
{
char sp[size];
memmove(sp, v1, size);
memmove(v1, v2, size);
memmove(v2, sp, size);
}
You can use memcpy() if you don't mind living dangerously (you should probably add restrict to the v1 and v2 pointer types if you do that). Again, the function could probably be made static inline to good effect — that also applies to the other implementations below.
If you don't like the idea of large objects being allocated on the stack, you can copy the data in chunks, but you have to work quite a bit harder.
enum { CHUNK_SIZE = 64 };
static inline size_t min_size(size_t x, size_t y) { return (x < y) ? x : y; }
/* Implementation 2: Using a fixed size buffer */
void generic_swap(void *v1, void *v2, size_t size)
{
unsigned char sp[CHUNK_SIZE];
unsigned char *p1 = v1;
unsigned char *p2 = v2;
size_t chunk;
while ((chunk = min_size(size, CHUNK_SIZE)) != 0)
{
memmove(sp, p1, chunk);
memmove(p1, p2, chunk);
memmove(p2, sp, chunk);
p1 += chunk;
p2 += chunk;
size -= chunk;
}
}
Notwithstanding anything that GCC permits, the C standard says you can't increment a void * because there is no known size to increment it by. That's why the pointers are converted to unsigned char *. Clearly, you can tune the chunk size to suit your system. Any power of 2 in the range 16..1024 is probably usable, and other values than a power of 2 can be used if you prefer.
If you don't mind the overhead, you can dynamically allocate a buffer:
/* Implentation 3: Using dynamic memory allocation */
void generic_swap(void *v1, void *v2, size_t size)
{
char *sp = malloc(size);
if (sp != 0)
{
memmove(sp, v1, size);
memmove(v1, v2, size);
memmove(v2, sp, size);
free(sp);
}
}
If memory allocation fails, the swap doesn't occur. That's bad, so you might fall back on the 'fixed size buffer and swap in chunks', but that is probably quicker than this anyway.
I would use Implementation 2 in preference to Implementation 3; dynamic memory allocation is expensive. I would probably use Implementation 2 in preference to Implementation 1 as the extra cost of the looping is minimal and using a fixed amount of stack works well. I have not benchmarked any
of these to verify my assertions. (If you're swapping megabyte sized lumps of data, you should probably think again — use pointers instead. If you're only swapping smaller chunks, Implementation 1 is simple and safe.)
With any of the generic swap implementations, your main program becomes:
int main(void)
{
double a = 1.0;
double b = 2.0;
printf("linea: %d - antes a(%f) b(%f)\n", __LINE__, a, b);
generic_swap(&a, &b, sizeof(double));
printf("linea: %d - despues a(%f) b(%f)\n", __LINE__, a, b);
return 0;
}
I'm assuming that at least the declaration of generic_swap() is available before the start of main().
Note that using either double_swap() or generic_swap() means that no casts are necessary in the code. Minimizing casts is A Good Idea™.
See also Universal array element swap in C.
Well, your function is expecting a pointer to a character for the first two arguments
void swap( char* pA, char* pB, unsigned tam)
but you are passing in pointers to double
double a = 1.0;
double b = 2.0;
swap(&a, &b, sizeof(double)); //This line gives the error
The following would allow you to swap two doubles, unless there is a specific reason you are swapping one byte at a time:
void swap(double *pA, double *pB, unsigned int tam) {
double tmp = *pA;
*pA = *pB;
*pB = tmp;
}
I get the error message in the title ? Because you are passing double variable address and catching with char* so compiler is saying
expected ‘char *’ but argument is of type ‘double *’.
So you have two ways either typecast the address of double variable as char* or catch with double* itself.
Case 1:
void swap( double* pA, double* pB, unsigned int tam) {
double tmp = *pA;
*pA = *pB;
*pB = tmp;
}
int main(int argc, char** argv) {
double a = 1.0;
double b = 2.0;
printf("linea: %d - antes a(%f) b(%f)\n", __LINE__, a, b);
swap(&a, &b, sizeof(double)); //This line gives the error
printf("linea: %d - despues a(%f) b(%f)\n", __LINE__, a, b);
return 0;
}
Case 2 :-
Second way is typecast the address of double variable as char* send it to swap()
void swap( char *pA, char *pB, unsigned int tam) {
for( unsigned i = 0; i < tam; i++) {
char tmp = *pA;
*pA = *pB;
*pB = tmp;
pA = pA + 1;
pB = pB + 1;
}
}
int main(int argc, char** argv) {
double a = 1.0;
double b = 2.0;
printf("linea: %d - antes a(%f) b(%f)\n", __LINE__, a, b);
swap((char*)&a, (char*)&b, sizeof(double)); //typecast &a to (char*)&a
printf("linea: %d - despues a(%f) b(%f)\n", __LINE__, a, b);
return 0;
}
I need to write a function that replaces 2 "numeric numbers", of otherwise unknown type.
I don't know the exact type and I can only use 2 parameters.
So this is what I have tried:
void swap(void *p1, void *p2)
{
char p;
char * q1 = (char *)p1;
char * q2 = (char *)p2;
for (int i = 0; i < sizeof(long double); i++)
{
p = q1[i];
q1[i] = q2[i];
q2[i] = p;
}
}
Usage:
double a = 100123000000.2;
double b = 100065450000.3;
printf("a: %1f, b: %1f\n", a, b);
swap(&a, &b)
printf("a: %1f, b: %1f\n", a, b);
This works fine but my question is what if my number is bigger then long double (or there is no one..)
Is my solution OK?
This works fine but my question is what if my number is bigger (?)
Is my solution is OK ?
Code will have trouble unless it knows the exact size. So, no, OP's solution is not OK.
Somehow void swap() needs to know the size of the data to swap.
i can only use 2 parameters.
Code can cheat and put all the data into 1 argument as a compound literal, since C99.
typedef struct {
void *a;
void *b;
size_t sz;
} swap_T;
// Only 1 parameter!!
void swap(swap_T sw) {
unsigned char * q1 = sw.a;
unsigned char * q2 = sw.b;
while (sw.sz > 0) {
sw.sz--;
unsigned char p = q1[sw.sz];
q1[sw.sz] = q2[sw.sz];
q2[sw.sz] = p;
}
}
int main(void) {
double a = 100123000000.2;
double b = 100065450000.3;
printf("a: %g, b: %g\n", a, b);
swap(((swap_T ) { &a, &b, sizeof a } )); // Compound literal
printf("a: %g, b: %g\n", a, b);
return 0;
}
Output
a: 1.00123e+11, b: 1.00065e+11
a: 1.00065e+11, b: 1.00123e+11
Code could wrap the swap(((swap_T ) { &a, &b, sizeof a } )) in a macro that looks like a function call of 2
#define SWAP(a,b) (swap(((swap_T ) { &(a), &(b), sizeof (a) } )))
...
SWAP(a,b);
As long as a is not an expression with a variable logic array (VLA) and with side-effects, the macro should work fine.
Of course, best if a,b are the same type.
Your program should try to retrieve sizeof of its argument to know how many bytes to swap - perhaps as a third argument - you have no way of telling otherwise how big an argument is. With current function you will overwrite memory which will end up badly - especially in a bigger program. For example, consider a following program.
#include <stdio.h>
int main() {
int a[] = {1, 2, 3, 4, 5, 6, 7, 8};
swap(&a[0], &a[4]);
for (int i = 0; i < 8; i++) {
printf("%d\n", a[i]);
}
}
Which will return 5, 6, 7, 8, 1, 2, 3, 4 - which clearly isn't expected - only 0th and 4th array elements should have been swapped.
It's possible to hide getting size behind a macro if needed.
#define SWAP(a, b) swap(&(a), &(b), sizeof(a))
#define my_sizeof_one(type) (char *)(&type+1)-(char*)(&type)
int main(void)
{
int answer;
short x = 1;
long y = 2;
float u = 3.0;
double v = 4.4;
long double w = 5.54;
char c = 'p';
uint32_t e = 653;
uint16_t f = 44;
uint64_t g = 2323232;
typedef enum
{
kCountInvalid,
kCountOne,
kCountTwo,
kCountThree,
kCountFour,
}k_count_t;
/* __DATE__, __TIME__, __FILE__, __LINE__ are predefined symbols */
#if 1
printf("Date : %s\n", __DATE__);
printf("Time : %s\n", __TIME__);
printf("File : %s\n", __FILE__);
printf("Line : %d\n", __LINE__);
#endif
/* The size of various types */
printf("The size of int %zu\n", my_sizeof_one(answer));
printf("The size of short %zu\n", my_sizeof_one(x));
printf("The size of long %zu\n", my_sizeof_one(y));
printf("The size of float %zu\n", my_sizeof_one(u));
printf("The size of double %zu\n", my_sizeof_one(v));
printf("The size of long double %zu\n", my_sizeof_one(w));
printf("The size of char %zu\n", my_sizeof_one(c));
printf("The size of enum %zu\n", my_sizeof_one(k_count_t));
printf("The size of uint16_t %zu\n", my_sizeof_one(f));
printf("The size of uint32_t %zu\n", my_sizeof_one(e));
printf("The size of uint64_t %zu\n", my_sizeof_one(g));
return 0;
}
I get the following error:
error: expected expression before 'k_count_t'
error: expected expression before 'k_count_t'
For some reason my_sizeof doesn't seem to work for enumerated data type in C.Can someone explain the reason for this?
The problem is that you are passing a type to your macro, and the macro does not work for types. Because you cannot take the address of a type.
Although you've named the parameter of your macro type, that name is misleading. The macro accepts variables rather than types. Well, strictly it accepts anything for which you can take the address using the & operator. Notice that all your other uses of the macro are with variables. Supply a variable of type k_count_t to your macro and the compiler will be happy.
Of course, the real lesson to learn is to use sizeof like nature intended.
I am a Java programmer and recently play with C for fun. Now I am learning address and pointers which are a little bit confusing for me. Here is my question. See the below two blocks of the code.
void withinArray(int * a, int size, int * ptr) {
int x;
printf("ptr is %d\n", ptr);
printf("a is %d\n", a);
printf("difference in pointers is: %d\n", ptr - a);
x = ptr - intArray;
printf("x is %d\n", x);
}
void doubleSize() {
double doubArray[10];
double * doubPtr1;
double * doubPtr2;
doubPtr1 = doubArray;
doubPtr2= doubArray+1;
int p2 = doubPtr2;
int p1 = doubPtr1;
printf("p2-p1 is %d\n", p2-p1);
printf("doubPtr2-doubPtr1 is %d\n", doubPtr2-doubPtr1);
}
int main(void)
{
int a[10];
int *intarray = a;
int *p = intarray + 9;
printf(withinArray(a, 10, p));
return 0;
}
I am wondering for function withinArray(), why we could directly get the x value, which is 9? But for the other method, we have to convert doubPtr to int first and then we can get the difference between pointers in int?
From my understanding, in doubleSize(), doubPtr2-doubPtr1 = 1 means the difference in pointer address in memory is 1. But why the withinArray() doesn't need to do so?
A difference of 1 between two pointers means that the pointers point to adjacent units of memory of the size of the objects pointed at.
Thus, given:
int i[2];
int *ip0 = &i[0];
int *ip1 = &i[1];
double d[2];
double *dp0 = &d[0];
double *dp1 = &d[1];
we could safely write:
assert((ip1 - ip0) == (dp1 - dp0));
assert(ip1 - ip0 == 1);
assert(dp1 - dp0 == 1);
However, you could also safely write:
assert((char *)ip1 - (char *)ip0 == sizeof(int));
assert((char *)dp1 - (char *)dp0 == sizeof(double));
and usually you would find that it is safe to write:
assert(sizeof(double) != sizeof(int));
though that is not guaranteed by the standard.
Also, as Filipe Gonçalves correctly points out in his comment, the difference between two pointers is formally only defined if the pointers are of the same type and point to two elements of the same array, or point to one element beyond the end of the array. Note that standard C demands that given:
int a[100];
it is safe to generate the address int *ip = &array[100];, even though it is not safe to either read from or write to the location pointed at by ip. The value stored in ip can be used in comparisons.
You also formally cannot subtract two void * values because there is no size for the type void (which is why my example used casts to char *, not void *). Beware: GCC will not object to the subtraction of two void * values unless you include -pedantic in the options.
Do you know why the value of doubPtr2 - doubPtr1 (in my second method) is different from x = ptr - a (in my first method)?
Assuming that intArray is meant to be a, then this code:
#include <stdio.h>
static void withinArray(int *a, int *ptr)
{
int x;
printf("ptr is %p\n", (void *)ptr);
printf("a is %p\n", (void *)a);
printf("difference in pointers is: %td\n", ptr - a);
x = ptr - a;
printf("x is %d\n", x);
}
static void doubleSize(void)
{
double doubArray[10];
double *doubPtr1 = doubArray;
double *doubPtr2 = doubArray+1;
int p2 = doubPtr2;
int p1 = doubPtr1;
printf("p1 = 0x%.8X\n", p1);
printf("p2 = 0x%.8X\n", p2);
printf("p2-p1 is %d\n", p2-p1);
printf("doubPtr1 = %p\n", (void *)doubPtr1);
printf("doubPtr1 = %p\n", (void *)doubPtr2);
printf("doubPtr2-doubPtr1 is %td\n", doubPtr2-doubPtr1);
}
int main(void)
{
int a[10];
int *intarray = a;
int *p = intarray + 9;
withinArray(a, p);
doubleSize();
return 0;
}
compiles with warnings that I would ordinarily fix (change the type of p1 and p2 to uintptr_t, include <inttypes.h>, and format using "p1 = 0x%.8" PRIXPTR "\n" as the format string), and it generates the output:
ptr is 0x7fff5c5684a4
a is 0x7fff5c568480
difference in pointers is: 9
x is 9
p1 = 0x5C5684B0
p2 = 0x5C5684B8
p2-p1 is 8
doubPtr1 = 0x7fff5c5684b0
doubPtr1 = 0x7fff5c5684b8
doubPtr2-doubPtr1 is 1
Fixed code generates:
ptr is 0x7fff5594f4a4
a is 0x7fff5594f480
difference in pointers is: 9
x is 9
p1 = 0x7FFF5594F4B0
p2 = 0x7FFF5594F4B8
p2-p1 is 8
doubPtr1 = 0x7fff5594f4b0
doubPtr1 = 0x7fff5594f4b8
doubPtr2-doubPtr1 is 1
(The difference is in the number of hex digits printed for p1 and p2.)
I assume that your puzzlement is about why the int code prints 9 rather than, say, 36, whereas the double code prints 8 instead of 1.
The answer is that when you subtract two pointers, the result is given in units of the size of the objects pointed at (which I seem to remember saying in my opening sentence).
When you execute doubPtr2-doubPtr1, the distance returned is in units of the number of double values between the two addresses.
However, the conversion to integer loses the type information, so you effectively have the char * (or void *) addresses of the two pointers in the integer, and the byte addresses are indeed 8 apart.
If we make two symmetrical routines, the information is clearer:
#include <stdio.h>
#include <inttypes.h>
static void intSize(void)
{
int intArray[10];
int *intPtr1 = intArray;
int *intPtr2 = intArray+1;
uintptr_t p2 = (uintptr_t)intPtr2;
uintptr_t p1 = (uintptr_t)intPtr1;
printf("p1 = 0x%.8" PRIXPTR "\n", p1);
printf("p2 = 0x%.8" PRIXPTR "\n", p2);
printf("p2-p1 is %" PRIdPTR "\n", p2-p1);
printf("intPtr1 = %p\n", (void *)intPtr1);
printf("intPtr1 = %p\n", (void *)intPtr2);
printf("intPtr2-intPtr1 is %td\n", intPtr2-intPtr1);
}
static void doubleSize(void)
{
double doubArray[10];
double *doubPtr1 = doubArray;
double *doubPtr2 = doubArray+1;
uintptr_t p2 = (uintptr_t)doubPtr2;
uintptr_t p1 = (uintptr_t)doubPtr1;
printf("p1 = 0x%.8" PRIXPTR "\n", p1);
printf("p2 = 0x%.8" PRIXPTR "\n", p2);
printf("p2-p1 is %" PRIdPTR "\n", p2-p1);
printf("doubPtr1 = %p\n", (void *)doubPtr1);
printf("doubPtr1 = %p\n", (void *)doubPtr2);
printf("doubPtr2-doubPtr1 is %td\n", doubPtr2-doubPtr1);
}
int main(void)
{
doubleSize();
intSize();
return 0;
}
Output:
p1 = 0x7FFF5C93D4B0
p2 = 0x7FFF5C93D4B8
p2-p1 is 8
doubPtr1 = 0x7fff5c93d4b0
doubPtr1 = 0x7fff5c93d4b8
doubPtr2-doubPtr1 is 1
p1 = 0x7FFF5C93D4B0
p2 = 0x7FFF5C93D4B4
p2-p1 is 4
intPtr1 = 0x7fff5c93d4b0
intPtr1 = 0x7fff5c93d4b4
intPtr2-intPtr1 is 1
Remember Polya's advice in How to Solve It:
Try to treat symmetrically what is symmetrical and do not destroy wantonly any natural symmetry.