Velvet Star Monitor

Standout celebrity highlights with iconic style.

general

Array slicing in C

Writer Sebastian Wright

In Python, if I wanted to assign the vector x=(1,2) to the first two elements of y=(0,0,0,0), I would do something like y[:1] = x. Is there an equivalent in C to assign a double x[2]={1.,2.} to the first two elements of an available double y[4] = {0.,0.,0.,0.}? Or will I have to loop?

2

4 Answers

Just try this

#include <string.h>
#include <stdio.h>
int main()
{ double x[2] = {1., 2.}; double y[4] = {0., 0., 0., 0.}; memcpy(y, x, 2 * sizeof(*x)); /* ^ 2 elements of size -> sizeof(double) */ return 0;
}

instead of writing sizeof(double) which is ok, i did sizeof(*x) because if I change the type of x I wouldn't need to fix the memcpy, but i would also have to change the type of y in that case.

2

You could write a function that passes in the pointer or array, an offset, and a length. The function then allocates space to a new pointer with malloc() and does a memcpy() operation or loop-and-copy, although memcpy() is probably better. The new pointer is returned to the caller.

Yes, it is possible using the function memcpy. But you have to be careful about data types. You can also copy data of one type to another. Again as I said, you need to be careful. Otherwise it may generate garbage value.

And second option is looping as mentioned in question.

1

Try this. A bit more low-level than your python method but welcome to C where sooner or later everything is block of raw memory to be shunted around!

The macro arraycopy applies some size checking. The function arraycopyunchecked is fairly raw.

The functions are overlap safe. Under the hood they use memcopy(,,) which may be slower but won't have surprise results if unexpected aliasing results in overlapping arrrays.

#include <stdio.h>
#include <stdlib.h>
#include <string.h> //includes mempcy. I know! I know!
#define arraycopy(dest,doffset,source,soffset,count) arraycopy_((dest),(doffset),(source),(soffset),(count),sizeof(*(dest)),sizeof(*(source)))
int arraycopy_(void*const dest,const size_t doffset,const void*const source, const size_t soffset,const size_t count,const size_t size,const size_t sizecheck){ if(size!=sizecheck){ return 1;//Incompatible types. } memcopy(((char*)dest)+doffset*size,((const char*)source)+soffset*size,count*size); return 0;
}
int arraycopyunchecked(void*const dest,const size_t doffset,const void*const source, const size_t soffset,const size_t count,const size_t size){ memcopy(((char*)dest)+doffset*size,((const char*)source)+soffset*size,count*size); return 0;
}
int main(void) { int errors=0; double dest[]={0.0,0.0,0.0,0.0}; double source[]={1.0,2.0}; arraycopy(dest,0,source,0,2); if(dest[0]!=1.0){ ++errors; } if(dest[1]!=2.0){ ++errors; } if(dest[2]!=0.0){ ++errors; } arraycopy(dest,1,source,0,2); if(dest[0]!=1.0){ ++errors; } if(dest[1]!=1.0){ ++errors; } if(dest[2]!=2.0){ ++errors; } if(errors!=0){ printf("Errors - %d\n",errors); }else{ printf("SUCCESS"); } double dest1[]={0.0,0.0,0.0,0.0,0.0}; double source1[]={1.0,2.0,3.0}; arraycopy(dest1,2,source1,1,2); if(dest[2]!=2.0){ ++errors; } if(dest[3]!=3.0){ ++errors; } return errors==0?EXIT_SUCCESS:EXIT_FAILURE;
}

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.