What is the point of pointers to arrays? - c

So, I was reading about pointers, and came across the concept of pointers to arrays. The thing is that a pointer to an array doesn't really seem useful at all, since instead of using a pointer to have an offset to access an array element, I could just get the element directly. However I feel as if I'm missing the reason why these can be useful.
So, in short, What is the point of pointers to arrays; How and why should they be used, and do they have any practical applications?
Edit: I meant this in the context of normal/simple arrays such as:
int array[5];
Edit: As Keith Pointed out, I'm specifically asking about pointers to arrays, for example char (*ptr)[42] which is a pointer to a 42-element array of char.

Unfortunately some answers you received show misbeliefs about pointers and arrays in C, in brief:
1) Pointer to array is not the same as pointer to first element.
2) Declaring array type is not the same as declaring pointer.
You can found full description in C faq part related to common confusion between pointers and arrays: http://c-faq.com/aryptr/index.html
Adressing your question - pointer to array is usefull to pass an entire array of compile-time known size and preserve information about its size during argument passing. It is also usefull when dealing with multi dimensional arrays when you what to operate on subarray of some array.

In most expressions, an object of type "array of T" will degrade to the address of the first array element, which will have the type "pointer to T". In this sense, a pointer type can be used to represent an array of items, and is used to do so when there is need to dynamically allocate an array.
// ptr used to dynamically allocate array [n] of T
T *ptr = malloc(n * sizeof(*ptr));
In the case of a pointer to an array, then, it can be used to represent an array of arrays, and/or dynamically allocate an array of arrays. So, a pointer to an array can be used to represent a 2-dimensional array.
// ptr used to dynamically allocate 2 dimensional array [n][10] of T
T (*ptr)[10] = malloc(n * sizeof(*ptr));

True pointers to arrays (which haven't really been addressed so far) are uncommon since arrays decay to a pointer to their first element in most contexts, and since arrays are contiguous in memory by definition that is usually all that is needed. They are also somewhat impractical compared to other pointer types since array types cannot be assigned to. They are similar to function pointers in that respect.
The biggest practical difference comes from the fact that they preserve the size of the array in situations where it would otherwise be lost to pointer decay, such as function calls and returns. Take the following code for example
void function(char (*array)[10]) {
for(size_t i = 0; i < sizeof(*a); i++);
(*a)[i] = i;
}
...
char a[10];
function(&a);
Besides allowing for this application of sizeof (which isn't terribly useful since the size is known as part of the parameter), this enforces the exact size of the passing argument as part of the type, which function(char array[10]) won't do, even with [static 10].
Returning has an unusual syntax:
char (*function(void))[10] {
static char array[10];
// do something with our static array
return &array;
}
char (*a)[10] = function();
// or even
char (*b)[sizeof(*function())] = function();
I don't think I've ever come across an application of this in the wild, but it is at least possible (and legal).

If you have an array of arrays a pointer to an array becomes useful, like in the following:
typedef float Point[3];
Point points[10];
Point *p;
for (p=points;p<points+10;++p) {
...
}

Here is real-world example of using pointers to arrays:
typedef double t_matrix33[3][3];
// Result = AB
// const double (* M1)[3], const double (* M2)[3], double (* Result)[3]
void Matrix33xMatrix33( const t_matrix33 M1, const t_matrix33 M2, t_matrix33 Result ) {
t_matrix33 copy;
const t_matrix33 * A = ( const t_matrix33 * )M1; // const double (* A)[3][3] = const double (* M1)[3]
const t_matrix33 * B = ( const t_matrix33 * )M2; // const double (* B)[3][3] = const double (* M2)[3]
int Raw;
int Col;
int i;
// !!! Make copies if Result is the same as M1 and/or M2!
//const double (* A)[3][3] == double (* Result)[3]
if( A == ( const t_matrix33 * )Result ) { // cast is must -- to get rid of gcc warnings
memcpy( copy, A, sizeof( t_matrix33 ) );
A = ( const t_matrix33 * )copy;
if( B == ( const t_matrix33 * )Result ) {
B = ( const t_matrix33 * )copy;
}
}
else if( B == ( const t_matrix33 * )Result ) {
memcpy( copy, B, sizeof( t_matrix33 ) );
B = ( const t_matrix33 * )copy;
}
for( Raw = 0; Raw < 3; ++Raw ) {
for( Col = 0; Col < 3; ++Col ) {
Result[ Raw ][ Col ] = 0;
for( i = 0; i < 3; ++i ) {
Result[ Raw ][ Col ] += (*A)[ Raw ][ i ] * (*B)[ i ][ Col ];
}
}
}
};
Thanks to A and B pointers we can avoid redundant memcopies in the case of M1 and/or M2 are not the same as Result

The one I can think of at the moment is (I am sure there are others as well), you want to make multidimensional array, however you don't have any data at the moment to save in the 2nd or 3rd dimension of the array. You don't want to waste the memory by conserving the space for 2nd and 3rd dimension of the array but you plan to allocate the memory later when you have data to store, thats when pointers to arrays come handy.
Eg.
for (int i=0; i<10; i++)
(*x)[i] = malloc(N * sizeof(*x));
// take input or put data in the array
Representation Of 2d Array In C:
This site explains it quite well. This should help you removing any confusions.

Related

Understanding-pointer to a structure

I want to understand how the pointer to the structure is passed to the function argument and implemented. How is avrg_stpc[idx_u16].sum_f32 array is working?
typedef struct
{
const float * input_f32p;
float avg_f32;
float sum_f32;
float factor_f32;
unsigned int rs_u16;
} avgminmax_avg_t;
void avgminmax_AvgCalculate_vd(
avgminmax_avg_t * const avrg_stpc,
const unsigned int numOfEntrys_u16c)
{
unsigned int idx_u16 = 0u;
do
{
avrg_stpc[idx_u16].sum_f32 += (*avrg_stpc[idx_u16].input_f32p
- avrg_stpc[idx_u16].avg_f32);
avrg_stpc[idx_u16].avg_f32 = (avrg_stpc[idx_u16].sum_f32 *
avrg_stpc[idx_u16].factor_f32);
idx_u16++;
}while(idx_u16 < numOfEntrys_u16c);
}
A few points that could help you understand arrays and pointers and their relationship:
A pointer really only points to one "object", but that object might be the first in an array.
Arrays naturally decays to pointers to their first element.
And array indexing is equivalent to pointers arithmetic (for any pointer or array a and index i, the expression a[i] is exactly equal to *(a + i)).
As for your specific example code, perhaps it would be easier if you thought of it similar to this:
avgminmax_avg_t *temp_ptr = &avrg_stpc[idx_u16];
temp_ptr->sum_f32 += ...;
temp_ptr->avg_f32 = ...;
Or perhaps like:
avgminmax_avg_t temp_object = avrg_stpc[idx_u16];
temp_object.sum_f32 += ...;
temp_object.avg_f32 = ...;
avrg_stpc[idx_u16] = temp_obj;
Both the snippets above will lead to the same result as your existing code, but requires an extra temporary variable, and in the latter snippet copying of the structure twice.
avrg_stpc is regarded as an array (possibly, allocated on heap via .*alloc); since its bounds can't be known, hence the second argument to the function. See here: https://en.cppreference.com/w/c/language/operator_member_access

Pass pointer of an array of multi-dimensional arrays to a function, specifying bounds

Let's say I have multiple (a variable number) of 2D arrays (which may even be variable-length):
int a[2][2] = {{1,2},{3,4}};
int b[2][2] = {{5,6},{7,8}};
...
which I now want to pass to a function. I do not want to copy the 2D arrays into 3D array. However, I want to specify the bounds so that the function knows the dimensions of the 2D arrays so that I can index them conveniently with [i][j]
How can I format the functions' signature so that it accepts a pointer to an array (of unknown length) which contains 2D arrays of which it does now the dimensions?
E.g. something like
void myfunc(int[][3] *test, int len)
though of course this is syntactically invalid. Is specifying the bounds of arrays inside an array (passed by pointer) impossible in C? Will I be forced to move a and b into pointers, or forced to copy them into a 3D array?
If your compiler supports a variable length arrays you can write
void myfunc( int rows, int cols, int a[rows][cols] );
Take into account that the third parameter is implicitly converted to the type int ( * )[cols], that is within a function you are dealing with a pointer to one dimensional array. Nevertheless you can use expressions like
for ( int i = 0; i < rows; i++ )
{
for ( int j = 0; j < cols; j++ ) a[i][j] = value;
}
Otherwise if the compiler does not support variable length arrays and the second dimension of all arrays is the same then the function can be declared like
void myfunc( int ( *a )[2], int rows );
Take into account that this declaration
int[][3] *test
in any case is incorrect.
If you want to pass several two-dimensional arrays then you can within main declare a one dimensional array like
int a[2][2] = {{1,2},{3,4}};
int b[2][2] = {{5,6},{7,8}};
//...
int ( *p[] )[2] = { a, b, /*...*/ };
and then pass it to a function.
In this case the function will look like
void myfunc( int ( **p )[2], size_t n );
Here is a demonstrative program
#include <stdio.h>
void myfunc( int ( **p )[2], size_t n )
{
for ( size_t i = 0; i < n; i++ )
{
for ( size_t j = 0; j < 2; j++ )
{
for ( size_t k = 0; k < 2; k++ ) printf( "%d ", p[i][j][k] );
putchar( '\n' );
}
putchar( '\n' );
}
}
int main(void)
{
int a[2][2] = {{1,2},{3,4}};
int b[2][2] = {{5,6},{7,8}};
int ( *p[] )[2] = { a, b };
myfunc( p, sizeof( p ) / sizeof( *p ) );
return 0;
}
Its output is
1 2
3 4
5 6
7 8
If the first dimension of the arrays is not fixed and varies then you could pass also to the function an array of first dimensions of the arrays
If you have two things you need to pass to a function, you either
pass two separate arguments; or
create some kind of data structure that contains (pointers to) said things, and pass (a pointer to) that.
It doesn't matter if your things are arrays or anything else.
The same thing holds when you have a variable number of things. You can pass a variable number of arguments to a function, but that's a separate topic, so let's concentrate in option 2. In this case your data structure should be an array of pointers to things.
OK so how do you create one when your thing has a complex type, like an array (of arrays of pointers to functions that return a pointer to an array, or whatever)? The answer is simple: use a typedef.
typedef int MyThing[2][2]; // could be anything
MyThing one = {{1,2},{3,4}};
MyThing two = ...; // etc
MyThing* manyPointersToThings[] = {&one, &two};
void myFunc(int nThings, MyThing things[nThings]) {
// in here, each things[i] is a *pointer* to MyThing
(*things[0])[1][2] = 42;
// whatever
}
This works for any kind of thing. If your thing is in fact an array, there is another option: your data structure could store pointers to first elements of your arrays, rather than pointers to arrays themselves.
typedef int MyThing[2]; // this type names an *element* of your array
MyThing one[2] = {{1,2},{3,4}};
MyThing two[2] = ...; // etc
MyThing* manyPointersToThings[] = {one, two}; // note no & here
void myFunc(int nThings, MyThing things[nThings]) {
// in here, each things[i] is a pointer to the first element of an array
things[0][1][2] = 42;
// whatever
}
With this option, you gain some flexibility, as your arrays need not all be of the same size. You also lose that ugly dereference in parentheses.
For completeness, here are prototypes of the same functions sans typedef:
void myFunc(int nThings, int (*things[nThings])[2][2]) // version 1
void myFunc(int nThings, int (*things[nThings])[2]) // version 2
These are a bit more flexible than typedef versions, because now you can use a variable (another parameter) instead of the hardcoded number 2.
If you have trouble writing down things like the above, try this.

C: Pointer to 2-dimensional array of pointers

I am trying to solve the following issue but could not succeed yet:
I have a two-diwmensional array of pointers:
int* a[16][128];
Now I want to make a pointer to this array in that way that I can use pointer arithmetic on it.
Thus, something like this:
ptr = a;
if( ptr[6][4] == NULL )
ptr[6][4] = another_ptr_to_int;
I tried already some variations but it either fails then on the first line or on the if condition.
So, how can it be solved? I would like to avoid template classes etc. Code is for a time critical part of an embedded application, and memory is very limited. Thus, I would like ptr to be only sizeof(int*) bytes long.
A pointer to the first element of the array (which is what you want) could be declared as
int* (*ptr)[128];
A pointer to the array itself would be
int* (*ptr)[16][128];
and is not what you're looking for.
Thing you seem to want:
int* (*ptr)[128] = a;
Actual pointer to the array:
int* (*ptr)[16][128] = &a;
To start with array pointer basics for a 1D array, [tutorialspoint][1] has a very easy to ready description. From their example:
#include <stdio.h>
int main () {
/* an array with 5 elements */
double balance[5] = {1000.0, 2.0, 3.4, 17.0, 50.0};
double *p;
int i;
p = balance; //Here the pointer is assign to the start of the array
/* output each array element's value */
printf( "Array values using pointer\n");
for ( i = 0; i < 5; i++ ) {
printf("*(p + %d) : %f\n", i, *(p + i) );
}
printf( "Array values using balance as address\n");
for ( i = 0; i < 5; i++ ) {
printf("*(balance + %d) : %f\n", i, *(balance + i) ); // Note the post increment
}
return 0;
}
There are a couple of relavent Stack overflow answers that describe 2D arrays:
How to use pointer expressions to access elements of a two-dimensional array in C?
Pointer-to-pointer dynamic two-dimensional array
how to assign two dimensional array to **pointer ?
Representing a two-dimensional array assignment as a pointer math?
[1]: https://www.tutorialspoint.com/cprogramming/c_pointer_to_an_array.htm

Acessing a 2D array inside a function

I have a function which accepts int* pInput[] as an argument.
void Process(int* pInput[], unsigned int num);
I have to call this function via 2 methods as
main()
{
int *pIn[2];
int input[2][100] = {0};
pIn[0] = ( int* )malloc( 100 * sizeof( int) );
pIn[1] = ( int* )malloc( 100 * sizeof( int) );
Process( pIn, 2 );
Process( ( int** )input, 2 );
}
Then how can i access each value of pInput inside function 'Process'?I cannot access it directly as pIn[0][0].
how can i access each value of pInput inside function 'Process'?I cannot access it directly as pIn[0][0].
No! You can access it exactly that way: pInput[0][0] if the input you pass is pIn. This is because pIn is an array of int*s I.e. it's of type int *[n] each of its element pointing to an array of ints. It would decay into int**.
However, if you want to pass input, a 2D array of ints, you've to do more since a 2D array doesn't decay into a double pointer, T** but into a pointer to an array, T (*) [n]. This is because array decay is not recursive, it happens only to the first level. Alternatively, you can do this (Live example)
pIn[0] = input[0];
pIn[1] = input[1];
and now pass pIn to Process. Here pIn is a surrogate for input and it needs to have as many elements as input, which is not a very elegant solution. A better way to pass input, when you know the dimensions during compile-time is
void Process(int (*pInput)[100], size_t rows) { }
void Process(int input [2][100], size_t rows) { }
/* These two are the same; the compiler never sees the `2`. input's type is int(*)[100] */
Read on array decay to understand the situation better.
Aside
Do I cast the result of malloc? No, you do not need to cast the return value of malloc in C.
What should main() return in C and C++? The return type of main should be int.
Related
C-FAQ: My compiler complained when I passed a two-dimensional array to a function expecting a pointer to a pointer.
What is array decaying?
Why can we omit the first dimension of a multidimensional array when we are passing it to a function
In your process() function you just need to access it normally like any 2d array as below. Calling both ways are same.
void Process( int * pInput[], unsigned int num)
{
printf(" %d", pInput[0][0]); //printing value of pInput[0]
printf(" %d", pInput[1][0]); //printing value of pInput[1]
pInput[0][0] = 8054; // changing its value.
pInput[1][0] = 8055; // changing its value.
}
int main()
{
int *pIn[2];
int input[2][100] = {0};
pIn[0] = ( int* )malloc( 100 * sizeof( int) );
pIn[1] = ( int* )malloc( 100 * sizeof( int) );
// assigning value to array.
pIn[0][0] = 23;
pIn[0][1] = 2;
pIn[1][0] = 5689;
pIn[1][1] = 5643;
Process( pIn, 2 ); //calling process funtion
printf(" %d", pIn[1][0]); //printing the changed value by process funtion.
}
You are getting confused because you are using different types when there's no need for such. Arrays follow the same rules of indirection as any other type. If you would allocate a plain int dynamically, you would write int* x = malloc(sizeof(*x));. Simply do the very same thing when it comes to arrays. Don't confuse things by mixing in the "arrays decay to pointers" rule.
So we have int input[2][100], very straight-forward, it is a plain 2D array. Now if you want to allocate that dynamically, you will need a pointer to such an array:
int (*pIn)[2][100]; // pointer to an array of int [2][100].
pIn = malloc(sizeof(*pIn));
And the whole program would then be:
#include <stdlib.h>
void Process (size_t num, int pInput[num][100])
{
}
int main (void)
{
int (*pIn)[2][100];
int input[2][100] = {0};
pIn = malloc(sizeof(*pIn));
if(pIn == NULL)
{
// error handling
return 0;
}
Process(2, *pIn);
Process(2, input);
free(pIn);
return 0;
}
Comments:
size_t is the most correct type to use for array sizes, as it is the type returned by the sizeof operator. So it is just an unsigned integer with a fancy name.
int pInput[num][100] in the function will actually decay into an array pointer to an array of 100 int. You don't need to know that to use it though, simply use pInput[x][y] and pretend it is a 2D array. The important thing here is to understand that the array is not passed by value.
The correct form of main is int main (void).
Casting the result of malloc is pointless.
Always check the result of malloc and remember to clean up allocated data.

Returning a two-dimensional array in C?

I recently started programming C just for fun. I'm a very skilled programmer in C# .NET and Java within the desktop realm, but this is turning out to be a bit too much of a challenge for me.
I am trying to do something as "simple" as returning a two-dimensional array from a function. I've tried researching on the web for this, but it was hard for me to find something that worked.
Here's what I have so far. It doesn't quite return the array, it just populates one. But even that won't compile (I am sure the reasons must be obvious to you, if you're a skilled C programmer).
void new_array (int x[n][n]) {
int i,o;
for (i=0; i<n; i++) {
for (o=0; o<n; o++) {
x[i][o]=(rand() % n)-n/2;
}
}
return x;
}
And usage:
int x[n][n];
new_array(x);
What am I doing wrong? It should be mentioned that n is a constant that has the value 3.
Edit: Here's a compiler error when trying to define the constant: http://i.imgur.com/sa4JkXs.png
C does not treat arrays like most languages; you'll need to understand the following concepts if you want to work with arrays in C.
Except when it is the operand of the sizeof or unary & operator, or is a string literal being used to initialize another array in a declaration, an expression of type "N-element array of T" will be converted ("decay") to an expression of type "pointer to T", and the value of the expression will be the address of the first element of the array. This result is not an lvalue; it cannot be the target of an assignment, nor can it be an operand to the ++ or -- operators.
This is why you can't define a function to return an array type; the array expression will be converted to a pointer type as part of the return statement, and besides, there's no way to assign the result to another array expression anyway.
Believe it or not, there's a solid technical reason for this; when he was initially developing C, Dennis Ritchie borrowed a lot of concepts from the B programming language. B was a "typeless" language; everything was stored as an unsigned word, or "cell". Memory was seen as a linear array of "cells". When you declared an array as
auto arr[N];
B would set aside N "cells" for the array contents, along with an additional cell bound to arr to store the offset to the first element (basically a pointer, but without any type semantics). Array accesses were defined as *(arr+i); you offset i cells from the address stored in a and dereferenced the result. This worked great for C, until Ritchie started adding struct types to the language. He wanted the contents of the struct to not only describe the data in abstract terms, but to physically represent the bits. The example he used was something like
struct {
int node;
char name[14];
};
He wanted to set aside 2 bytes for the node, immediately followed by 14 bytes for the name element. And he wanted an array of such structures to be laid out such that you had 2 bytes followed by 14 bytes followed by 2 bytes followed by 14 bytes, etc. He couldn't figure out a good way to deal with the array pointer, so he got rid of it entirely. Rather than setting aside storage for the pointer, C simply calculates it from the array expression itself. This is why you can't assign anything to an array expression; there's nothing to assign the value to.
So, how do you return a 2D array from a function?
You don't. You can return a pointer to a 2D array, such as:
T (*func1(int rows))[N]
{
T (*ap)[N] = malloc( sizeof *ap * rows );
return ap;
}
The downside to this approach is that N must be known at compile time.
If you're using a C99 compiler or a C2011 compiler that supports variable-length arrays, you could do something like the following:
void func2( size_t rows, size_t cols, int (**app)[cols] )
{
*app = malloc( sizeof **app * rows );
(*app)[i][j] = ...; // the parens are necessary
...
}
If you don't have variable-length arrays available, then at least the column dimension must be a compile-time constant:
#define COLS ...
...
void func3( size_t rows, int (**app)[COLS] )
{
*app = malloc( sizeof **app * rows );
(*app)[i][j] = ...;
}
You can allocate memory piecemeal into something that acts like a 2D array, but the rows won't necessarily be contiguous:
int **func4( size_t rows, size_t cols )
{
int **p = malloc( sizeof *p * rows );
if ( p )
{
for ( size_t i = 0; i < rows; i++ )
{
p[i] = malloc( sizeof *p[i] * cols );
}
}
return p;
}
p is not an array; it points to a series of pointers to int. For all practical purposes, you can use this as though it were a 2D array:
int **arr = foo( rows, cols );
...
arr[i][j] = ...;
printf( "value = %d\n", arr[k][l] );
Note that C doesn't have any garbage collection; you're responsible for cleaning up your own messes. In the first three cases, it's simple:
int (*arr1)[N] = func(rows);
// use arr[i][j];
...
free( arr1 );
int (*arr2)[cols];
func2( rows, cols, &arr2 );
...
free( arr2 );
int (*arr3)[N];
func3( rows, &arr3 );
...
free( arr3 );
In the last case, since you did a two-step allocation, you need to do a two-step deallocation:
int **arr4 = func4( rows, cols );
...
for (i = 0; i < rows; i++ )
free( arr4[i] )
free( arr4)
Your function return void, so the return x; line is superfluous. Aside from that, your code looks fine. That is, assuming you have #define n 3 someplace and not something like const int n = 3;.
You can't return an array in C, multidimensional or otherwise.
The main reason for this is that the language says you can't. Another reason would be that generally local arrays are allocated on the stack, and consequently deallocated when the function returns, so it wouldn't make sense to return them.
Passing a pointer to the array in and modifying it is generally the way to go.
To return (a pointer to) a newly-created array of dimensions known at compile time, you can do this:
#define n 10 // Or other size.
int (*new_array(void))[n]
{
int (*x)[n] = malloc(n * sizeof *x);
if (!result)
HandleErrorHere;
for (int i = 0; i < n; ++i)
for (int o = 0; i < n; ++o)
x[i][o] = InitialValues;
return x;
}
…
// In the calling function:
int (*x)[n] = new_array();
…
// When done with the array:
free(x);
If the size is not known at compile time, you cannot even return a pointer to an array. C does support variable-length arrays but not in the return types of functions. You could instead return a pointer to a variable-length array through a parameter. That requires using a parameter that is a pointer to a pointer to an array of variable length, so it gets somewhat messy.
Also, the preferred choices between allocating an array in the caller dynamically, allocating an array in the caller automatically, allocating an array in the called function dynamically and using variable-lengths arrays or fixed-length arrays or even one-dimensional arrays with manual indexing depend on context, including what how large the array might be, how long it will live, and what operations you intend to use it for. So you would need to provide additional guidance before a specific recommendation could be made.
In C there's only pass/return by value (no pass by reference). Thus the only way of passing the array (by value) is to pass its address to the function, so that it can manipulate it through a pointer.
However, returning by value an array's address isn't possible, since by the time control reaches the caller, the function goes out of scope and its automatic variables go down with it too. Hence if you really have to, you can dynamically allocate the array, populate and return it, but the preferred method is passing the array and leaving the onus of maintaining the array to the caller.
As for the error, the only warning I get in GCC for this is warning: 'return' with a value, in function returning void which is simply meaning that you shouldn't return anything from a void function.
void new_array (int x[n][n]); what you're really doing here is taking a pointer to an array of n integers; the decayed type is int (*x)[n]. This happens because arrays decay into pointers generally. If you know n at compile time, perhaps the best way to pass is:
#define n 3
void new_array (int (*x)[n][n]) {
int i,o;
for (i=0; i<n; i++) {
for (o=0; o<n; o++) {
x[i][o]=(rand() % n)-n/2;
}
}
}
And call it as
int arr[n][n];
new_array(&arr);
You can pass around arbitrarily dimensions arrays like any another variable if you wrap them up in a struct:
#include <stdio.h>
#define n 3
struct S {
int a[n][n];
};
static struct S make_s(void)
{
struct S s;
int i, j;
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++)
s.a[i][j] = i + j;
}
return s;
}
static void print_s(struct S s)
{
int i, j;
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++)
printf(" %d", s.a[i][j]);
printf("\n");
}
}
int main(void) {
struct S s;
s = make_s();
print_s(s);
return 0;
}
You are probably declaring n as a constant integer:
const int n = 3;
Instead, you should define n as a preprocessor definition:
#define n 3

Resources