3

I have a 1D array A[3] & a 2D array B[4][3]. I want to assign the array A[3] to one of the rows of array B[4][3]. How to do it correctly?

#include<stdio.h>

void main()
{
   int A[3]={1,2,3};
   int B[4][3]={0};
   int row_select=2;

   B[row_select][] = A;
}   

But this assignment doesn't work. I don't want to assign element by element using a for loop. I want to do it in one statement.

9
  • 1
    memcpy would be a good option. Commented Feb 11, 2019 at 5:27
  • 1
    You can't assign arrays directly. Since you don't want to assign element by element, you'll have to use assignment 'byte by byte' with memmove() or memcpy(). The functions probably won't do byte copying, but that's how they're specified. (You can assign arrays indirectly if they're part of a structure; that wouldn't help you in this case, though.) Commented Feb 11, 2019 at 5:31
  • @JonathanLeffler. You could define a throwaway structure containing an array of the right size and nothing else, do some pointer casting, and probably get away with it. Commented Feb 11, 2019 at 5:37
  • @MadPhysicist: Hmmm; not sure how you're going to get the last row of B into an appropriate structure, or union. Can you clarify? Commented Feb 11, 2019 at 5:39
  • 1
    @MadPhysicist — You could use *b = *a; in your examples to assign the structures without getting the assignment errors, but I think you're running into strict aliassing problems instead. It's certainly devious, and not the sort of thing to show to someone asking this question. Commented Feb 11, 2019 at 5:51

2 Answers 2

4

memcpy could be a good option, although it's very likely it uses a loop internally.

memcpy(B[row_select], A, sizeof(A));
Sign up to request clarification or add additional context in comments.

Comments

1

Don't Do This: Use memcpy

There is a way to do the assignment with a single statement, as long as you are willing to do some preliminary setup to render your code illegible. Your can use the fact that structures can (1) be assigned to each other in one step, and (2) contain fixed-size arrays. The compiler will probably run memcpy under the hood anyway, but it's a fun exercise in ridiculousness:

#include<stdio.h>

#define SZ 3 // this is just for convenience

// a pointer to an anonymous structure containing our array
typedef struct {
    int x[SZ];
} *pthrowaway;

int main(void)
{
    int A[SZ]={1,2,3};
    int B[4][SZ]={0};
    int row_select=2;

    pthrowaway a = (pthrowaway)&A;
    pthrowaway b = (pthrowaway)&B[row_select];

    *b = *a; // magic

    return 0;
}

The variables a and b are unnecessary. You can actually assign the arrays in a single statement:

*(pthrowaway)&B[row_select] = *(pthrowaway)&A;

Here is an IDEOne link showing the C99 version: https://ideone.com/IQ6ttg And here is a regular C one: https://ideone.com/pH1hS2

12 Comments

Which is 'regular C'? C11/C18? Or C90?
@JonathanLeffler. Whatever IDEOne uses. So GCC 6.3, which probably doesn't conform to any of those.
IIRC, you (the IDEOne site) uses GCC 6.x, and GCC 6.x treats C11 (effectively C18) as the default (and the change was at GCC 5.x; prior to that, the default was C90 — so poor old C99 never got to be the default version of the standard for GCC). (A quick check of the GCC releases confirms my memory isn't ailing too much — gcc.gnu.org/gcc-5/changes.html has the change to C11 as the top item, and GCC 5.1 was released in April 2015.)
Well, looking at stackoverflow.com/questions/98650/…, and en.cppreference.com/w/c/language/type, I don't think int[3] and pthrowaway are compatible types. Indeed, there seems to be no way an array and a struct can ever be compatible types.
Beware the example 3 in C11 §6.5.2.3 Structure and union members. I'm not entirely sure how to interpret that either — be cautious.
|

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.