Hi,
I have written a generic mergesort program which is as below:
---------------------------------------------------------
mergesort.h
-----------------------
void
MergeSort(void *array[],int p,int r,int elemSize,int(*C ompare)(const
void *keyA,const void *keyB));
void
Merge(void *array[],int p,int q, int r,int elemSize,int(*C ompare)(const
void *keyA,const void *keyB));
int
IntegerComp(con st void *keyA,const void *keyB);
mergesort.c
--------------------
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "mergesort. h"
void
MergeSort(void *array[],int p,int r,int elemSize,int(*C ompare)(const
void *keyA,const void *keyB))
{
int q;
if(p < r) {
q = (p + r)/2;
MergeSort(array ,p,q,elemSize,C ompare);
MergeSort(array ,q + 1,r,elemSize,Co mpare);
Merge(array,p,q ,r,elemSize,Com pare);
}
}
void
Merge(void *array[],int p,int q, int r,int elemSize,int(*C ompare)(const
void *keyA,const void *keyB))
{
void **out = (void **)malloc(elemS ize * r);
int i,k,j;
i = k = p;
j = q + 1;
while( i <= q && j <= r ) {
if( Compare( &array[i * elemSize],&array[j * elemSize] ) <= 0 ) {
out[k++] = array[i++];
} else {
out[k++] = array[j++];
}
}
while( i <= q ) out[k++] = array[i++];
while( j <= r ) out[k++] = array[j++];
for (i = p;i < r; i++) {
array[i] = out[i];
}
free(out);
}
int
IntegerComp(con st void *keyA,const void *keyB)
{
if( (const int *) keyA == (const int *) keyB ) return 0;
else if( (const int *) keyA < (const int *) keyB ) return -1;
else if( (const int *) keyA (const int *) keyB ) return 1;
}
----------------------------------------------
And the driver program is here:
test.c
---------
#include <stdio.h>
#include "mergesort. h"
int
main()
{
int idx,length;
int arr[] = { 2,21,1,48,15,31 ,26 };
length = sizeof arr/sizeof &arr[0];
printf("Before sorting array:\n");
for (idx = 0;idx < length;idx++)
{
printf("%d ",arr[idx]);
}
printf("\n");
MergeSort(&arr, 0,length,sizeof (int),IntegerCo mp);
printf("After sorting array:\n");
for (idx = 0;idx < length;idx++)
{
printf("%d ",arr[idx]);
}
printf("\n");
return 0;
}
----------------------------------------------------------
I compile the programs above as:
gcc -g -o mergesort mergesort.c test.c
The output is little surprising as the array looks unsorted after sort
algorithm is completed. I am not understanding what's going wrong here,
kindly help me.:
kalyan@proteus mergesort
Before sorting array:
2 21 1 48 15 31 26
After sorting array:
2 21 1 48 15 31 26
Thank you.
Regards
Kalyan 9 5620
rkk said:
Hi,
I have written a generic mergesort program which is as below:
I took a long hard look at it, and got rid of many obvious bugs, which left
a not-so-obvious bug that I couldn't dislodge.
My best advice to you would be:
1) remove all casts - I guessed they were *all* wrong, and my guess was
correct
2) use void *, not void *[]
3) in Merge, use an unsigned char * to point at the base of the array
4) do your own pointer arithmetic properly (your code currently ignores the
problem of object sizes)
5) protect against malloc failure (returning, say, 0 if all went well and 1
if a memory allocation failure occurred)
6) write your comparison routine so that it doesn't need casts
7) choose better identifier names, names that reflect what the identifier
represents (e.g. you might want to use left, mid, and right, rather than p,
q, and r)
Once you have fixed all that up, you'll still have a bug. I couldn't find
that one, and wasn't heavily motivated to try. After applying all the
obvious fixes (see above), I got an output of
1 2 15 21 26 26 26
which is in some ways better and in some ways worse than your output.
Clearly, it has done some sorting - which is good! - but equally clearly it
has smeared one of the values across part of the array - which is not good.
So at least one bug remains. If you would like me to make my changes
available to you, just yell - but, as you can see, more work is required.
--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999 http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Richard Heathfield wrote:
[snip]
Once you have fixed all that up, you'll still have a bug. I couldn't find
that one, and wasn't heavily motivated to try.
In addition to the issues you found, the convention on the end index for
an array partition seems suspect. In some places it appears that the
index for the last array element is being used while in other places it
seems that this top index refers to one element beyond the last element.
For example the line:
while( j <= r ) out[k++] = array[j++];
uses the array[r] element whereas the following line:
for (i = p; i < r; i++)
excludes this element.
It's quite possible that this is correct since I have not studied the
code in any detail. But it looks suspicious to me.
Brian Gladman
rkk schrieb:
Hi,
I have written a generic mergesort program which is as below:
---------------------------------------------------------
mergesort.h
-----------------------
void
MergeSort(void *array[],int p,int r,int elemSize,int(*C ompare)(const
void *keyA,const void *keyB));
void
Merge(void *array[],int p,int q, int r,int elemSize,int(*C ompare)(const
void *keyA,const void *keyB));
int
IntegerComp(con st void *keyA,const void *keyB);
mergesort.c
--------------------
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "mergesort. h"
void
MergeSort(void *array[],int p,int r,int elemSize,int(*C ompare)(const
void *keyA,const void *keyB))
Note: If you have an array of void*, then elemSize == sizeof (void*).
You probably want either an array of generic pointers which you
sort (an "index array") or an array of elements which you sort directly.
I will go for the latter even though it is not very efficient for
large elemSize.
{
int q;
if(p < r) {
q = (p + r)/2;
MergeSort(array ,p,q,elemSize,C ompare);
MergeSort(array ,q + 1,r,elemSize,Co mpare);
This suggests that p and r are valid indices.
Merge(array,p,q ,r,elemSize,Com pare);
}
}
void
Merge(void *array[],int p,int q, int r,int elemSize,int(*C ompare)(const
void *keyA,const void *keyB))
Same as above.
{
void **out = (void **)malloc(elemS ize * r);
No check whether this was successful.
You do not allocate the size you need which is
elemSize * (r- p + 1)
Note: One of the primary advantages of merge sort is that
you do not have to keep everything in memory. Allocating
a temp array leads that ad absurdum -- if a temp array is
allowed, then we can implement something more efficient...
int i,k,j;
i = k = p;
If you allocate only as much as you need, then k should start at 0.
j = q + 1;
while( i <= q && j <= r ) {
if( Compare( &array[i * elemSize],&array[j * elemSize] ) <= 0 ) {
You cannot calculate the address of the array members like this.
(unsigned char *)array + i * elemSize
is the correct way to do this.
out[k++] = array[i++];
} else {
out[k++] = array[j++];
}
}
while( i <= q ) out[k++] = array[i++];
while( j <= r ) out[k++] = array[j++];
for (i = p;i < r; i++) {
array[i] = out[i];
}
free(out);
}
int
IntegerComp(con st void *keyA,const void *keyB)
{
if( (const int *) keyA == (const int *) keyB ) return 0;
else if( (const int *) keyA < (const int *) keyB ) return -1;
else if( (const int *) keyA (const int *) keyB ) return 1;
}
----------------------------------------------
And the driver program is here:
test.c
---------
#include <stdio.h>
#include "mergesort. h"
int
main()
{
int idx,length;
int arr[] = { 2,21,1,48,15,31 ,26 };
length = sizeof arr/sizeof &arr[0];
sizeof arr / sizeof arr[0]
>
printf("Before sorting array:\n");
for (idx = 0;idx < length;idx++)
{
printf("%d ",arr[idx]);
}
printf("\n");
MergeSort(&arr, 0,length,sizeof (int),IntegerCo mp);
You have to pass "length - 1". If you write sizeof arr[0],
then you are on the safe side even if the type of arr changes.
>
printf("After sorting array:\n");
for (idx = 0;idx < length;idx++)
{
printf("%d ",arr[idx]);
}
printf("\n");
return 0;
}
----------------------------------------------------------
I compile the programs above as:
gcc -g -o mergesort mergesort.c test.c
gcc -std=c89 -pedantic -Wall -O test.c mergesort.c -o test
My changed version gives you some debug output; for this,
you need -DMY_DEBUG on the command line.
,-- mergesort.h --
#ifndef H_MERGE_SORT_H
#define H_MERGE_SORT_H
typedef int (*TCompareFcn) (const void *, const void *);
int
MergeSort (void *array,
int startIndex,
int endIndex,
int elemSize,
TCompareFcn Compare);
int
IntegerComp (const void *keyA,
const void *keyB);
#endif
`----
,-- test.c --
#include <stdio.h>
#include "mergesort. h"
int
main (void)
{
int idx, length;
int arr[] = { 2,21,1,48,15,31 ,26 };
length = sizeof arr / sizeof arr[0];
puts("Before sorting array:");
for (idx = 0; idx < length; idx++)
{
printf(" %d", arr[idx]);
}
putchar('\n');
if (!MergeSort(arr , 0, length - 1, sizeof arr[0], IntegerComp))
fputs("Merging not successful\n", stderr);
puts("After sorting array:");
for (idx = 0; idx < length; idx++)
{
printf(" %d", arr[idx]);
}
putchar('\n');
return 0;
}
`----
,-- mergesort.c --
#include "mergesort. h"
#include <string.h>
#include <stdlib.h>
#ifdef MY_DEBUG
# include <stdio.h>
# define DEBUG_PRINT(s) printf s
# define DEBUG_I_PRINT(s ) printf("%*s", indent, " "), DEBUG_PRINT(s)
static int indent = 0;
# define DEBUG_ENTER indent += 3
# define DEBUG_EXIT indent -= 3
#else
# define DEBUG_PRINT(s)
# define DEBUG_I_PRINT(s )
# define DEBUG_ENTER
# define DEBUG_EXIT
#endif
static int
Merge (void *array,
int p,
int q,
int r,
int elemSize,
TCompareFcn Compare);
int
MergeSort (void *array,
int startIndex,
int endIndex,
int elemSize,
TCompareFcn Compare)
{
if (startIndex < endIndex) {
int splitIndex;
DEBUG_ENTER;
splitIndex = (startIndex + endIndex) / 2;
DEBUG_I_PRINT(( "MergeSort: %d %d\n", startIndex, splitIndex));
if (!MergeSort(arr ay,startIndex,s plitIndex,elemS ize,Compare))
return 0;
DEBUG_I_PRINT(( "MergeSort: %d %d\n", splitIndex+1, endIndex));
if (!MergeSort(arr ay,splitIndex + 1,endIndex,elem Size,Compare))
return 0;
DEBUG_I_PRINT(( "Merge: %d %d %d\n", startIndex, splitIndex, endIndex));
if (!Merge(array,s tartIndex,split Index,endIndex, elemSize,Compar e))
return 0;
DEBUG_EXIT;
}
return 1;
}
static int
Merge (void *array,
int startIndex,
int splitIndex,
int endIndex,
int elemSize,
TCompareFcn Compare)
{
int numElems = endIndex - startIndex + 1;
unsigned char *pTemp, *pCurrTemp;
unsigned char *pArrBase = array;
int lowerCurr = startIndex;
int upperCurr = splitIndex + 1;
const unsigned char *pArrLower = pArrBase + lowerCurr*elemS ize;
const unsigned char *pArrUpper = pArrBase + upperCurr*elemS ize;
pTemp = malloc(elemSize * numElems);
if (NULL == pTemp)
return 0;
pCurrTemp = pTemp;
DEBUG_ENTER;
while (lowerCurr <= splitIndex && upperCurr <= endIndex) {
DEBUG_I_PRINT(( "[%d(%d) %d(%d) -", lowerCurr, *(int*)pArrLowe r,
upperCurr, *(int*)pArrUppe r));
if ((*Compare)(pAr rLower, pArrUpper) <= 0 ) {
DEBUG_PRINT(("% d]\n", lowerCurr));
memcpy(pCurrTem p, pArrLower, elemSize);
pArrLower += elemSize;
++lowerCurr;
} else {
DEBUG_PRINT(("% d]\n", upperCurr));
memcpy(pCurrTem p, pArrUpper, elemSize);
pArrUpper += elemSize;
++upperCurr;
}
pCurrTemp += elemSize;
}
while (lowerCurr <= splitIndex ) {
DEBUG_I_PRINT(( "[%d(%d)]\n", lowerCurr, *(int*)pArrLowe r));
memcpy(pCurrTem p, pArrLower, elemSize);
pArrLower += elemSize;
++lowerCurr;
pCurrTemp += elemSize;
}
while (upperCurr <= endIndex) {
DEBUG_I_PRINT(( "[%d(%d)]\n", upperCurr, *(int*)pArrUppe r));
memcpy(pCurrTem p, pArrUpper, elemSize);
pArrUpper += elemSize;
++upperCurr;
pCurrTemp += elemSize;
}
memcpy(pArrBase + startIndex*elem Size, pTemp, elemSize * numElems);
free(pTemp);
DEBUG_EXIT;
return 1;
}
int
IntegerComp(con st void *keyA, const void *keyB)
{
const int *pIntKeyA = keyA;
const int *pIntKeyB = keyB;
return (*pIntKeyA *pIntKeyB) - (*pIntKeyA < *pIntKeyB);
}
`----
Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
BRG said:
<snip>
For example the line:
while( j <= r ) out[k++] = array[j++];
uses the array[r] element whereas the following line:
for (i = p; i < r; i++)
excludes this element.
Ah, thank you, Brian. Good spot. Together with my other fixes, that is
sufficient that the OP's sample array is correctly sorted, as is a second
test array I tried.
All that remains is to see whether he is sufficiently interested in his own
problem to request me to post my fixes. :-)
--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999 http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Sorry for late response.
I do understand the mistakes I did in my version of program. Shortly I
will post my own corrected version.
Also Thanks to Michael for his mergesort code. It is really helpful.
Much appreciated.
One doubt I have is that to calculate the mem address of array why it
has to be casted to unsigned char * why cant char* instead? Sorry to
ask this very silly question here.
Many thanks for all of your help.
Regards
Kalyan
Richard Heathfield wrote:
BRG said:
<snip>
For example the line:
while( j <= r ) out[k++] = array[j++];
uses the array[r] element whereas the following line:
for (i = p; i < r; i++)
excludes this element.
Ah, thank you, Brian. Good spot. Together with my other fixes, that is
sufficient that the OP's sample array is correctly sorted, as is a second
test array I tried.
All that remains is to see whether he is sufficiently interested in his own
problem to request me to post my fixes. :-)
--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999 http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Michael, Many thanks for this piece of code.
Regards
Kalyan
Michael Mair wrote:
rkk schrieb:
Hi,
I have written a generic mergesort program which is as below:
---------------------------------------------------------
mergesort.h
-----------------------
void
MergeSort(void *array[],int p,int r,int elemSize,int(*C ompare)(const
void *keyA,const void *keyB));
void
Merge(void *array[],int p,int q, int r,int elemSize,int(*C ompare)(const
void *keyA,const void *keyB));
int
IntegerComp(con st void *keyA,const void *keyB);
mergesort.c
--------------------
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "mergesort. h"
void
MergeSort(void *array[],int p,int r,int elemSize,int(*C ompare)(const
void *keyA,const void *keyB))
Note: If you have an array of void*, then elemSize == sizeof (void*).
You probably want either an array of generic pointers which you
sort (an "index array") or an array of elements which you sort directly.
I will go for the latter even though it is not very efficient for
large elemSize.
{
int q;
if(p < r) {
q = (p + r)/2;
MergeSort(array ,p,q,elemSize,C ompare);
MergeSort(array ,q + 1,r,elemSize,Co mpare);
This suggests that p and r are valid indices.
Merge(array,p,q ,r,elemSize,Com pare);
}
}
void
Merge(void *array[],int p,int q, int r,int elemSize,int(*C ompare)(const
void *keyA,const void *keyB))
Same as above.
{
void **out = (void **)malloc(elemS ize * r);
No check whether this was successful.
You do not allocate the size you need which is
elemSize * (r- p + 1)
Note: One of the primary advantages of merge sort is that
you do not have to keep everything in memory. Allocating
a temp array leads that ad absurdum -- if a temp array is
allowed, then we can implement something more efficient...
int i,k,j;
i = k = p;
If you allocate only as much as you need, then k should start at 0.
j = q + 1;
while( i <= q && j <= r ) {
if( Compare( &array[i * elemSize],&array[j * elemSize] ) <= 0 ) {
You cannot calculate the address of the array members like this.
(unsigned char *)array + i * elemSize
is the correct way to do this.
out[k++] = array[i++];
} else {
out[k++] = array[j++];
}
}
while( i <= q ) out[k++] = array[i++];
while( j <= r ) out[k++] = array[j++];
for (i = p;i < r; i++) {
array[i] = out[i];
}
free(out);
}
int
IntegerComp(con st void *keyA,const void *keyB)
{
if( (const int *) keyA == (const int *) keyB ) return 0;
else if( (const int *) keyA < (const int *) keyB ) return -1;
else if( (const int *) keyA (const int *) keyB ) return 1;
}
----------------------------------------------
And the driver program is here:
test.c
---------
#include <stdio.h>
#include "mergesort. h"
int
main()
{
int idx,length;
int arr[] = { 2,21,1,48,15,31 ,26 };
length = sizeof arr/sizeof &arr[0];
sizeof arr / sizeof arr[0]
printf("Before sorting array:\n");
for (idx = 0;idx < length;idx++)
{
printf("%d ",arr[idx]);
}
printf("\n");
MergeSort(&arr, 0,length,sizeof (int),IntegerCo mp);
You have to pass "length - 1". If you write sizeof arr[0],
then you are on the safe side even if the type of arr changes.
printf("After sorting array:\n");
for (idx = 0;idx < length;idx++)
{
printf("%d ",arr[idx]);
}
printf("\n");
return 0;
}
----------------------------------------------------------
I compile the programs above as:
gcc -g -o mergesort mergesort.c test.c
gcc -std=c89 -pedantic -Wall -O test.c mergesort.c -o test
My changed version gives you some debug output; for this,
you need -DMY_DEBUG on the command line.
,-- mergesort.h --
#ifndef H_MERGE_SORT_H
#define H_MERGE_SORT_H
typedef int (*TCompareFcn) (const void *, const void *);
int
MergeSort (void *array,
int startIndex,
int endIndex,
int elemSize,
TCompareFcn Compare);
int
IntegerComp (const void *keyA,
const void *keyB);
#endif
`----
,-- test.c --
#include <stdio.h>
#include "mergesort. h"
int
main (void)
{
int idx, length;
int arr[] = { 2,21,1,48,15,31 ,26 };
length = sizeof arr / sizeof arr[0];
puts("Before sorting array:");
for (idx = 0; idx < length; idx++)
{
printf(" %d", arr[idx]);
}
putchar('\n');
if (!MergeSort(arr , 0, length - 1, sizeof arr[0], IntegerComp))
fputs("Merging not successful\n", stderr);
puts("After sorting array:");
for (idx = 0; idx < length; idx++)
{
printf(" %d", arr[idx]);
}
putchar('\n');
return 0;
}
`----
,-- mergesort.c --
#include "mergesort. h"
#include <string.h>
#include <stdlib.h>
#ifdef MY_DEBUG
# include <stdio.h>
# define DEBUG_PRINT(s) printf s
# define DEBUG_I_PRINT(s ) printf("%*s", indent, " "), DEBUG_PRINT(s)
static int indent = 0;
# define DEBUG_ENTER indent += 3
# define DEBUG_EXIT indent -= 3
#else
# define DEBUG_PRINT(s)
# define DEBUG_I_PRINT(s )
# define DEBUG_ENTER
# define DEBUG_EXIT
#endif
static int
Merge (void *array,
int p,
int q,
int r,
int elemSize,
TCompareFcn Compare);
int
MergeSort (void *array,
int startIndex,
int endIndex,
int elemSize,
TCompareFcn Compare)
{
if (startIndex < endIndex) {
int splitIndex;
DEBUG_ENTER;
splitIndex = (startIndex + endIndex) / 2;
DEBUG_I_PRINT(( "MergeSort: %d %d\n", startIndex, splitIndex));
if (!MergeSort(arr ay,startIndex,s plitIndex,elemS ize,Compare))
return 0;
DEBUG_I_PRINT(( "MergeSort: %d %d\n", splitIndex+1, endIndex));
if (!MergeSort(arr ay,splitIndex + 1,endIndex,elem Size,Compare))
return 0;
DEBUG_I_PRINT(( "Merge: %d %d %d\n", startIndex, splitIndex, endIndex));
if (!Merge(array,s tartIndex,split Index,endIndex, elemSize,Compar e))
return 0;
DEBUG_EXIT;
}
return 1;
}
static int
Merge (void *array,
int startIndex,
int splitIndex,
int endIndex,
int elemSize,
TCompareFcn Compare)
{
int numElems = endIndex - startIndex + 1;
unsigned char *pTemp, *pCurrTemp;
unsigned char *pArrBase = array;
int lowerCurr = startIndex;
int upperCurr = splitIndex + 1;
const unsigned char *pArrLower = pArrBase + lowerCurr*elemS ize;
const unsigned char *pArrUpper = pArrBase + upperCurr*elemS ize;
pTemp = malloc(elemSize * numElems);
if (NULL == pTemp)
return 0;
pCurrTemp = pTemp;
DEBUG_ENTER;
while (lowerCurr <= splitIndex && upperCurr <= endIndex) {
DEBUG_I_PRINT(( "[%d(%d) %d(%d) -", lowerCurr, *(int*)pArrLowe r,
upperCurr, *(int*)pArrUppe r));
if ((*Compare)(pAr rLower, pArrUpper) <= 0 ) {
DEBUG_PRINT(("% d]\n", lowerCurr));
memcpy(pCurrTem p, pArrLower, elemSize);
pArrLower += elemSize;
++lowerCurr;
} else {
DEBUG_PRINT(("% d]\n", upperCurr));
memcpy(pCurrTem p, pArrUpper, elemSize);
pArrUpper += elemSize;
++upperCurr;
}
pCurrTemp += elemSize;
}
while (lowerCurr <= splitIndex ) {
DEBUG_I_PRINT(( "[%d(%d)]\n", lowerCurr, *(int*)pArrLowe r));
memcpy(pCurrTem p, pArrLower, elemSize);
pArrLower += elemSize;
++lowerCurr;
pCurrTemp += elemSize;
}
while (upperCurr <= endIndex) {
DEBUG_I_PRINT(( "[%d(%d)]\n", upperCurr, *(int*)pArrUppe r));
memcpy(pCurrTem p, pArrUpper, elemSize);
pArrUpper += elemSize;
++upperCurr;
pCurrTemp += elemSize;
}
memcpy(pArrBase + startIndex*elem Size, pTemp, elemSize * numElems);
free(pTemp);
DEBUG_EXIT;
return 1;
}
int
IntegerComp(con st void *keyA, const void *keyB)
{
const int *pIntKeyA = keyA;
const int *pIntKeyB = keyB;
return (*pIntKeyA *pIntKeyB) - (*pIntKeyA < *pIntKeyB);
}
`----
Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Please do not top-post.
Your reply belongs below (or interspersed with) the text you
are replying to; you of course can and should snip whatever
you find not useful for the parts you want to discuss further.
rkk schrieb:
Richard Heathfield wrote:
>>BRG said:
<snip: inconsistent use of the top index (included/excluded)
>> Ah, thank you, Brian. Good spot. Together with my other fixes, that is sufficient that the OP's sample array is correctly sorted, as is a second test array I tried.
All that remains is to see whether he is sufficiently interested in his own problem to request me to post my fixes. :-)
Sorry for late response.
I do understand the mistakes I did in my version of program. Shortly I
will post my own corrected version.
Also Thanks to Michael for his mergesort code. It is really helpful.
Much appreciated.
I am happy to hear that :-)
Note that this was only an example implementation of one of the
two possible solutions and not the one I would actually implement.
One doubt I have is that to calculate the mem address of array why it
has to be casted to unsigned char * why cant char* instead? Sorry to
ask this very silly question here.
Not a silly question at all.
Even though void * has the same representation and alignment
requirements as a pointer to any of the three types of char,
you cannot do pointer arithmetic with it.
[Three types of char? char is special in that there is a difference
between signed char and "plain" char which is a type distinct from
both signed char and unsigned char but has the characteristics of
one of these.]
unsigned char * is the only type with which you can guaranteedly
access the representation (i.e. the underlying bit pattern) of any
object:
myType foo;
void *pFoo = &foo;
unsigned char *bar = pFoo;
int i;
/* assign value to foo */
....
for (i = 0; i < sizeof foo; ++i) {
printf("%x\t", (unsigned int) bar[i]);
}
putchar('\n');
will give you the bytes of foo.
Neither char * nor signed char * guaranteedly can give you that.
Thus, you use "char" for characters and "unsigned char" if you
mean bytes and want to calculate addresses.
The comp.lang.c FAQ tells you a little bit more about that: http://c-faq.com
Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
rkk wrote:
>
.... snip ...
>
One doubt I have is that to calculate the mem address of array why
it has to be casted to unsigned char * why cant char* instead?
Sorry to ask this very silly question here.
Please don't top-post. Your answer belongs after, or possibly
intermixed with, the material you quote, after snipping. See the
links in my sig. below.
You cast to unsigned char because your system may define char as
either signed or unsigned. Without the cast the code is not
portable. Many routines (e.g. toupper() etc.) require unsigned
chars.
--
Some informative links:
<news:news.anno unce.newusers
<http://www.geocities.c om/nnqweb/>
<http://www.catb.org/~esr/faqs/smart-questions.html>
<http://www.caliburn.nl/topposting.html >
<http://www.netmeister. org/news/learn2quote.htm l>
<http://cfaj.freeshell. org/google/> This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics |
by: Tim Mohler |
last post by:
All -
I have a script that provides a web page interface to various system
utilities. Once the user has selected the utility and input various
parameters, it calls itself with a different method and input value,
for instance ping.
During the initial call, the output is not buffered, but on the second
call, the actually executes the utility, output is buffered until the
command completes.
|
by: Mark A Framness |
last post by:
Greetings,
I am working on a project and we need to write a conversion script to
initialize a new field on a table. The number of records on this table
is on the order of millions so routine selection and update takes a
long time.
I am tasked with writing a pl/sql proc that utilizes array processing
to update the column.
|
by: Kevin King |
last post by:
I have a question about an assignment I have. I need to count the
number of comparisons in my merge sort. I know that the function is
roughly nlog(n), but I am definately coming up with too many
comparisons. It seems to me like I should just use a single counter in
the merge function's 'if' statement, but this can't be right because
an array of 50 takes about 100 comparisons this way. If anyone has any
suggestions I would greatly...
|
by: Michael R. Copeland |
last post by:
I'm writing an application that requires an "intelligent merge" of 2
files. That is, equal data has a "preferred source" that I want to
write out. What I have works, I believe, but it seems horribly
cumbersome (having to set the input variables to ""...). Is there a
better way? TIA
while ((!feof(wf3)) || (!feof(wf1)))
{
if (!feof(wf1))
{
|
by: Alex Chudnovsky |
last post by:
I have come across with what appears to be a significant performance bug in
..NET 2.0 ArrayList.Sort method when compared with Array.Sort on the same
data. Same data on the same CPU gets sorted a lot faster with both methods
using .NET 1.1, that's why I am pretty sure its a (rather serious) bug. Below
you can find C# test case that should allow you to reproduce this error, to
run it you will need to put 2 data files into current directory...
| |
by: tienlx |
last post by:
Hi all,
I want to sort an array of struct _line:
....
typedef struct _line
{
int x1;
int x2;
} line;
|
by: mqueene7 |
last post by:
below is my code for my merge sort but I can't get it to sort properly. I am trying generate random numbers based on input from the user and then sort those random numbers. Can you tell me what I am doing wrong?
void merge(int,int,int);
void merge_sort(int low, int high)
{
int mid, temp;
if (low==high)
return;
if (low+1==high)
|
by: Michel Esber |
last post by:
Hi all,
DB2 V8 LUW FP 15
There is a table T (ID varchar (24), ABC timestamp). ID is PK.
Our application needs to frequently update T with a new value for ABC.
update T set ABC=? where ID = ?
|
by: aRTx |
last post by:
I have try a couple of time but does not work for me
My files everytime are sortet by NAME.
I want to Sort my files by Date-desc.
Can anyone help me to do it?
The Script
<?
/*
ORIGJINALI
|
by: Hystou |
last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it.
First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
|
by: Oralloy |
last post by:
Hello folks,
I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>".
The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed.
This is as boiled down as I can make it.
Here is my compilation command:
g++-12 -std=c++20 -Wnarrowing bit_field.cpp
Here is the code in...
| |
by: jinu1996 |
last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth.
The Art of Business Website Design
Your website is...
|
by: tracyyun |
last post by:
Dear forum friends,
With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
|
by: isladogs |
last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM).
In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules.
He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms.
Adolph will...
|
by: TSSRALBI |
last post by:
Hello
I'm a network technician in training and I need your help.
I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs.
The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols.
I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
|
by: adsilva |
last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
|
by: 6302768590 |
last post by:
Hai team
i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
| |
by: muto222 |
last post by:
How can i add a mobile payment intergratation into php mysql website.
| |