I want to scan a 2D array with the help of pointers and have written this code, could you tell me why the compiler gives errors?
#include<stdio.h>
#include<stdlib.h>
int main(void) {
int i,j,n,a,b;
int (*(*p)[])[];
printf("\n\tEnter the size of the matrix in the form aXb\t\n");
scanf("%dX%d",&a,&b);
p=(int (*(*p)[b])[a])malloc(b*sizeof(int (*p)[a]));
for(i=0;i<b;i++) {
p[i]=(int (*p)[a])malloc(a*sizeof(int));
printf("\t\bEnter Column %d\t\n");
for(j=0;j<a;j++)
scanf("%d",&p[i][j]);
}
return 0;
}
This statement has several problems:
p=(int (*(*p)[b])[a])malloc(b*sizeof(int (*p)[a]));
First, malloc returns a void*. You are casting that pointer using (int (*(*p)[b])[a]) which yields a value, not a data type. That isn't a valid cast, so that's one reason that the compiler is yelling at you. At this point, p hasn't been initialized so the de-referencing taking place here can crash your program if this statement was executed.
Inside your malloc call, you are using sizeof(int (*p)[a]). The statement int (*p)[a] isn't a valid C statement.
It seems that you are making this a bit more complex that it needs to be. There are two ways of building a 2D array. You can build an array using malloc(a * b * sizeof(int)) as Reinderien explains. You can also build a 1D array of pointers, each pointing to an array of type int. From your code, it seems you are trying to do the latter.
The easier way to do this would be something like this:
int **p;
... get input from user ...
// Declare an array of int pointers of length b
p = malloc(b * sizeof(int*));
// For each int* in 'p' ...
for (i = 0; i < b; ++i) {
// ... allocate an int array of length 'a' and store a pointer in 'p[i]' ..
p[i] = malloc(a * sizeof(int));
// ... and fill in that array using data from the user
printf("\t\bEnter Column %d\t\n");
for(j = 0; j < a; j++)
scanf("%d", &p[i][j]);
}
Using this method of building a 2D array allows you to use the syntax p[x][y]. Since p is a pointer-to-pointer, p[x] is a pointer to an array and p[x][y] is an item in the pointed-to array.
That's some pretty contorted syntax. Usually when you make a 2D array:
The declaration is simply int *p;
The allocation is simply p = malloc(a*b*sizeof(int));
You cannot write p[i][j]. You must do one of several things - either make a secondary array int **q that contains row pointers to be able to write q[i][j] (better performance and legibility), or write p[b*i + j] (fewer steps).
Additionally, note that:
Your printf will spew garbage due to the missing %d parameter.
Since C is not typesafe, using scanf will hide any errors in indirection that you may make.
About the closest thing I could think of that remotely resembles what you were trying to do:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i, j;
const int a = 3, b = 4;
int m[4][3];
int (*p[4])[3];
for (i = 0; i < b; i++)
{
p[i] = &m[i];
printf("\t\bEnter Column %d\t\n", i);
for (j = 0; j < a; j++)
{
int x;
scanf("%d", &x);
(*p[i])[j] = x;
}
}
return 0;
}
It compiles and functions as expected, but it's pointlessly complicated. p is an array of pointers to arrays.
Related
I wrote a simple code to create an array of pointers to integer and then fill it with scanf while I was using k&R book to do such things this time I tried to use malloc function but encountered a weird problem
here is the code:
#include<stdio.h>
#include<stdlib.h>
#pragma warning(disable:4996)
int getArr(int **myArr);
void print(int *myArr, int n);
int main() {
int *myArr, n;
n = getArr(&myArr);
print(myArr, n);
return 0;
}
int getArr(int **myArr) {
int n;
scanf("%d", &n);
*myArr = (int *)malloc(n * sizeof(int));
for (int i = 0; i < n; i++)
scanf("%d", myArr+i); /* here if i put &(*myArr)[i] will work correctly */
return n;
}
void print(int *myArr, int n) {
while (n-- != 0) {
printf("%d\t", *myArr);
myArr += 1;
}
return;
}
but what is the difference between this two types of reading input?
The %d format specifier to scanf expects a int *.
The expression myArr+i has type int ** which doesn't match what is expected, while &(*myArr)[i] (or alternately *myArr+i) has the correct type int *.
since you need the value of the pointer to be updated out of the procedure you rightfully did:
*myArr = (int *)malloc(n * sizeof(int));
(except that you shouldn't cast the return value of malloc in C)
But after that *myArr is the pointer to scan from. myArr is a pointer on the pointer. So you need to keep dereferencing myArr
scanf("%d", (*myArr)+i);
The problem is in getArr() function as myArr is double pointer & while scanning data you should use (*myArr) + i) instead of just myArr + i. Also myArr is not initialized in main() function.
Here is the modified one
int getArr(int **myArr) {
int n;
scanf("%d", &n);
for (int i = 0; i < n; i++) {
myArr[i] = malloc(sizeof(int));/*allocate memroy here */
scanf("%d", (*myArr) + i);
}
return n;
}
Your code:
int getArr(int **myArr) {
int n;
scanf("%d", &n);
*myArr = (int *)malloc(n * sizeof(int));
for (int i = 0; i < n; i++)
scanf("%d", myArr+i); /* here if i put &(*myArr)[i] will work correctly */
return n;
}
Your memory layout looks something like this:
myArr (a pointer who lives on the stack in main()
|
| (points to)
V
[XXXX XXXX XXXX XXXX] (allocated by malloc)
The 4 X's together represent an integer, so this is an array of some sequence of them. When you dereference myArr, you get the pointer to the beginning of the array. When you index THAT pointer, you get elements in the array.
Your code is not doing that:
myArr+i
This is treating myArr as a pointer to array, not a pointer to a pointer. When you provide myArr + i, you're effectively doing this:
myArr --------------------> [WRITE HERE]
|
|
V
[XXXX XXXX XXXX XXXX]
(Imagine memory goes left to right, row by row, so that the array is "far" from myArr, and [WRITE HERE] is closer to it. By adding to the myArr pointer, you're moving into invalid memory areas. myArr literally holds an address in main (since that's where you originally declared it, and passed its address to this function.) When you add to it, you are computing an address somewhere in the main stack frame, and scanf treats it as a pointer to an int, and scribbles some bytes somewhere into your stack.
Your alternate syntax is doing something different:
&(*myArr)[i]
This dereferences myArr, fetching the beginning of your malloc'd array, then indexes into the array for the i'th offset int, then takes the address of that int and passes it to scanf.
The reason this works this way is that [] has higher precedence than &, and so it's equivalent to this:
&((*myArr)[i])
This is the correct way to access your memory given this scheme.
It is good to learn this, but the days of K&R C-style coding are fading, especially in c++ code bases, as the danger and error-prone nature of working with raw pointers like this (as you've discovered) have fortunately been superseded by c++ idioms to help encapsulate memory access and reduce hard to comprehend bugs.
Here is my code:
int dim_y, dim_x;
int **map_boundaries;
int **map;
int main( int argc, char* args[] ){
int i;
scanf("%d",&dim_x);
scanf("%d",&dim_y);
map_boundaries = (int **)calloc(dim_y + 40,sizeof(int*));
for(i = 0; i < dim_y + 40; i++){
map_boundaries[i] = (int *)calloc(dim_x + 40,sizeof(int));
}
(*map)[dim_x+40] = (int(*)[dim_x+40])&map_boundaries[20][20];
}
The warning is for the last line, how should the last line be?
When I have it like this it works fine:
#define dim_y 500
#define dim_x 600
int map_boundaries[dim_y+40][dim_x+40];
int (*map)[dim_x+40] = (int(*)[dim_x+40])&map_boundaries[20][20];
But I want the values of "dim_x" and "dim_y" to be provided by the user and "map" to be global.
First, we need to know what do you want to achieve. There is something obviously wrong with the last line, but without knowing your intent we will only guess how to fix it. Let's analyze your code.
Currently you are dereferencing (uninitialized) (int**) variable ((int*)) and then using it like array - this suggest that you intend map to be pointer to array of ints.
You are dynamically allocate 2-dimensional map_boundaries array with size of (dim_x+40) x (dim_y+40) - note that valid indexes will be respectively 0...dim_x+40-1 and 0...dim_y+40-1.
From your edit I understand that you want to use map_boundaries as helper to dynamically allocate global map.
Indeed you can allocate table like like you did. To assign whole array of map_boundaries to map you only need to do map = map_boundaries; like #BLUEPIXY suggested. Then You can make map_boundaries local.
int dim_y, dim_x;
int **map;
int main( int argc, char* args[] ){
int **map_boundaries;
scanf("%d",&dim_x);
scanf("%d",&dim_y);
map_boundaries = (int**) calloc(dim_y+40, sizeof(int*));
for(int i = 0; i < dim_y+40; i++){
map_boundaries[i] = (int*) calloc(dim_x+40, sizeof(int));
}
map = map_boundaries;
}
Warning occurs because:
(*map)[dim_x+40] is type of int (and you obtain it by dereferencing unallocated memory but compiler cannot know that).
(int(*)[dim_x+40]) is (if I'm not mistaken) of type array of pointers to int ((int*)[]) - compiler implicitly cast it to int since you jest cast data into invalid type.
If that's not what you wanted to do, please elaborate on what you actually were trying to achieve, since it is not obvious.
EDIT:
Trimming map_boundaries to map (one way to do it):
int trimmed_dim_y_start = 0;
int trimmed_dim_y_size = 20;
int trimmed_dim_x_start = 0;
int trimmed_dim_x_size = 20;
// ...
map = (int**) calloc(trimmed_dim_y_size, sizeof(int*));
for (int i = 0; i < trimmed_dim_y_size; i++) {
map[i] = map_boundaries[ trimmed_dim_y_start + i ] + trimmed_dim_x_start;
}
Note that in this variant you'll have to make map_boundaries global again since if you don't free all that calloc's you'll get memory leak. Maybe not so bad in this particular program but it's still an important practice to clean up things.
Remove bracket from int(*) and place all int* in brackets.
(*map)[dim_x+40] = ((int*)[dim_x+40])&map_boundaries[20][20];
Suppose we want to construct an array of structs, where the definition of the struct cannot be known at compile time.
Here is a SSCCE:
#include <stdlib.h>
int main(int argc, char *argv[]){
if (argc < 3) return 1;
int n = atoi(argv[1]);
int k = atoi(argv[2]);
if ((n < 1) || (k < 1)) return 2;
// define struct dynamically
typedef struct{
int a[n];
short b[k];
}data_point_t;
int m = 10;
// construct array of `m` elements
data_point_t *p = malloc(sizeof(data_point_t)*m);
// do something with the array
for(int i = 0; i < m; ++i) p[i].a[0] = p[i].b[0] = i;
free(p);
return 0;
}
This works fine with gcc (C99), however it doesn't with clang, which yields:
error: fields must have a constant size:
'variable length array in structure' extension will never be supported
So I'm obviously relying on a gcc extension. My question is, how to deal with this kind of problem in standard conform C99? (Bonus question: how to do this in C++11?)
Note: Performance matters, when iterating p there should be aligned memory access. Dereferencing pointers in the loop, yielding random memory access, is not an option.
I think your best bet is to drop the idea of wrapping the array in a structure, bite the bullet and allocate a 2D array yourself.
This will mean that you need to do explicit indexing, but that would have to happen under the hood anyway.
When it comes to alignment, if you're going to visit every n array elements in each of the m arrays, it probably doesn't matter, it's better to make them compact to maximize use of cache.
Something like:
int *array = malloc(m * n * sizeof *array);
Then to index, just do:
// do something with the array
for(int i = 0; i < m; ++i)
{
for(int j = 0; j < n; ++j)
array[i * n + j] = j;
}
If you're very worried about that multiplication, use a temporary pointer. After profiling it, of course.
Sometimes you see this done with a helper macro to do the indexing:
#define INDEX(a, n, i, j) (a)[(i) * (n) + (j)]
then you can write the final line as:
INDEX(array, n, i, j) = j;
it's a bit clumsy since the n needs to go in there all the time, of course.
First of all, it only makes sense to wrap the array inside a struct in the case there are other struct members present. If there are no other struct members, simply allocate an array.
If there are other struct members, then use a flexible array member to achieve what you want. Flexible array members are well-defined in the C standard and will work on every C99 compiler.
// define struct dynamically
typedef struct{
type_t the_reason_you_need_this_to_be_a_struct_and_not_an_array;
int a[]; // flexible array member
}data_point_t;
// construct array of `m` elements
int m = 10;
size_t obj_size = sizeof(data_point_t) + n*sizeof(int);
data_point_t *p = malloc(m * obj_size);
In C++ you can of course use pointers much like you do now, but for a "proper" C++ solution the only viable solution is to use std::vector:
struct data_point_t
{
explicit data_point_t(const size_t sz)
: a(sz) // Construct the vector `a` with `sz` entries,
// each element will be zero initialized (`int()`)
{}
std::vector<int> a;
};
int main(int argc, char *argv[]){
// Read `n`...
int n = 10; // Just example
// Read `m`...
int m = 10; // Just example
// Construct vector of `m` elements
std::vector<data_point_t> p(m, data_point_t(n));
// Here the vector `p` contains `m` elements, where each instance
// have been initialized with a vector `a` with `n` elements
// All fully allocated and initialized
// Do something with the array
// ...
}
This is valid C++03 code, so unless you use something ancient (like Turbo C++) any compiler today should support it.
I have been learning arrays, but theres one thing that I cant figure out.
I borrowed two books for C and looked online, but found no solution.
My function timesTen multiplies every array elemenet that I have by 10,
then returns pointer of that array back function main()
How can I copy array a[2] directly in array x[2]?
I would usually use for loop, but I cant, because arguments are in two different functions.
Solution has probably got something to do with pointers, so feel free to post sollution here, but is there any way around them aswell?
Heres the source code:
#include <stdio.h>
int timesTen(int a[])
{
int i;
for (i=0;i<2;i++)
{
printf("%d\t", a[i]);
a[i]*=10;
printf("%d\n", a[i]);
}
return a;
}
int main()
{
int i;
int x[2];
int a[2]={10,50};
// i know here's an error, but how do I fix it? I cant put x[0]=timesTen(a[0])
x[2] = timesTen(a);
//also what if there is array a[10], and I want to copy it in x[5]
for (i=0;i<2;i++)
printf("%d\n", x[i]);
return 0;
}
Thanks!
What you need to understand is the distinction between arrays and pointers. When you declare your two arrays in main(), you allocate two times memory for two integers. That's fine. But in C, you simply cannot pass arrays around (as in: implicitly allocate a new slap of memory and copy the data of the source array into this memory region). Instead, any array identifier will decay to a pointer to the first element of the array in almost all situation. So when you write
int x[2];
int a[2]={10,50};
timesTen(a);
this code is precisely equivalent to
int x[2];
int a[2]={10,50};
timesTen(&a[0]);
So, why does that not clash with your declaration of timesTen()? Because array parameters in function declarations decay right there, on the spot, into a pointer! So, your function declaration is precisely equivalent to this one:
int timesTen(int* a) {
This is one of the least understood features of the C language, and admittedly, it is hard to wrap your brain around this, but once you understand what pointer decay means, you will be much more at ease using pointers and arrays.
So, back to your question. Since you passed only a pointer to your array to timesTen(), and since you modify this array, the changes are directly visible in main(). There are two ways to achieve the behavior you want:
You can change the definition of timesTen() to copy the data into a destination array:
void timesTen(int size, int* source, int* dest) {
for(int i = 0; i < size; i++) dest[i] = 10*source[i];
}
int main() {
int x[2];
int a[2]={10,50};
timesTen(2, a, x); //pointer decay!
//x now contains {100, 500}
}
You can copy the data into the destination array before calling your function to modify the destination array:
void timesTen(int size, int* data) {
for(int i = 0; i < size; i++) data[i] = 10*data[i];
}
int main() {
int x[2];
int a[2]={10,50};
memcpy(x, a, sizeof(a)); //the sizeof operator is one of only two places where no pointer decay happens!
timesTen(2, x); //pointer decay!
//x now contains {100, 500}
}
In the function timesTen, since a is an array, each modification made to it in the function is also done to the parameter you passed (call by address not by value). Therefore you don't need to returns anything.
void timesTen(int a[])
{
int i;
for (i=0;i<2;i++) a[i]*=10;
}
And you just call it by:
timesTen(a);
You probably want something like this:
timesTen(a);
memmove(x, a, 2 * sizeof(x[0]));
instead of
x[2] = timesTen(a);
Note that your function does not need to return anything, because it is modifying the array on its original place. In C if you have an array parameter, it means that only a pointer is passed, not the whole array.
in main function:
int *p;
int i;
p = timesTen(a);
for ( i = 0; i < 2; i++ )
{
printf( "%d\n",*(p + i)); // here you can print the values returned from your function
}
Through pointers you could have eaisly managed it
main ()
{
int a[ 2 ];
int *ptr = timesTen(a);
for ( int i=0; i<2 ; i++)
{
printf("%d",ptr[i]);
}
And as far as
x[2] = timesTen(a);
Is concerned note that x[2] will give "value at 2nd adress from adrees of base that is x"
And it is not a variable but it is a value and you cant assign to a value.
Technically x[2] is not a lvalue.
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