defining 2D array in c in VS Express 2012 - c

#include<stdio.h>
void main()//this is the way that we pragram in c
{
int arr[][]={{1,2},{1,2},{1,3}};//in class it wasnt required to initialize both
}
the errors:
Error 1 error C2087: 'arr' : missing subscript
Error 2 error C2078: too many initializers
3 IntelliSense: an array may not have elements of this type
I am a beginner , and i saw in class that the professor did the same thing.
also i asked my instructor and he told me that it should raise this error.
can someone please addres me to where and what is the problem?

You're missing the type; all but the first dimension must be specified; and you're missing commas between the aggregate initializers. Working example:
int main(void) {
int arr[][2] = {{1,2}, {1,2}, {1,3}};
}

When you have such a declaration
int arr[][]={{1,2},{1,2},{1,3}};
then the compiler can determine the number of the elements for the left most dimension. There are three initializers so the left most dimension is equal to 3. However the compiler is unable to determine the number of elements in the right most dimension because all these declarations are valid
int arr[][2]={{1,2},{1,2},{1,3}};
int arr[][20]={{1,2},{1,2},{1,3}};
int arr[][200]={{1,2},{1,2},{1,3}};
So you need explicitly to specify the number of elements in the right most dimension of the array. As I can guess you mean the following array declaration
int arr[][2]={{1,2},{1,2},{1,3}};
that is equivalent to
int arr[3][2]={{1,2},{1,2},{1,3}};
Though the MS VS allows a declaration of main like
void main()
nevertheless according to the C Standard the function main without parameters shall be declared like
int main( void )
even if a rerun statement is absent.

You should add type to your array declaration - for example int arr[][].
If you don't want to specify size of columns and rows you have to do it dynamically. For example this way:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int r = 3, c = 4, i, j, count;
int **arr = (int **)malloc(r * sizeof(int *));
for (i=0; i<r; i++)
arr[i] = (int *)malloc(c * sizeof(int));
// Note that arr[i][j] is same as *(*(arr+i)+j)
count = 0;
for (i = 0; i < r; i++)
for (j = 0; j < c; j++)
arr[i][j] = ++count; // OR *(*(arr+i)+j) = ++count
for (i = 0; i < r; i++)
for (j = 0; j < c; j++)
printf("%d ", arr[i][j]);
/* Code for further processing and free the
dynamically allocated memory */
return 0;
}

Related

C: how to give 2D Array to a function

I want to pass a 2D array already filled with chars to a different method to do something with it.
Background: I am trying to implement GameOfLife. And I have already successfully implement the gameboard with a random amount of living cells. But now I want to pass the board(Array) to a different method to continue working with it. How to do so?
//wow das wird hurenshon
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
void spielStarten(int x, int amountOfLiving){
char feld[x][x];
for(int i = 0; i < x; i++){
for(int j = 0; j < x; j++){
feld[i][j] = 'o';
}
}
for(int i = 0; i < amountOfLiving; i++){
int a = (rand()%x);
int b = (rand()%x);
feld[a][b] = 'x';
}
printf("Gameboard: \n");
for(int i = 0; i < x; i++){
for(int j = 0; j < x; j++){
printf("%c ", feld[i][j]);
}
printf("\n");
}
spielRun(feld);
}
void spielRun(char feld[][]){
int neighbCount;
char feldNew[][] = feld[][];
for(int i = 0; i < x; i++) {
for(int j = 0; j < x; j++) {
checkForNeighbours(feld[x][y]);
// in progress
}
}
}
int main(int argc, char* argv[]){
srand(time(NULL));
int x = 16;
if(argc < 2 || argc > 3){
printf("2. Argument eine Zahl fuer Feldgroesse eingeben\n");
printf("1. Argument eine Zahl 0-10 fuer ungefähre prozentuale Belegung mit lebenden
Zellen eingeben \n");
return 0;
}
if(argv[2] != NULL){
x = atoi(argv[2]);
}
int i;
i = atoi(argv[1]);
i = (x^2)*(0,1*i);
spielStarten (x,i);
return 0;
}
In the last line of the Method "Spiel starten" i want to give the array to the next Method "spielRun".
Edit: thanks to an other user I found this struture:
void printarray( char (*array)[50], int SIZE )
But it doesn't work for me since I can´t hardcode the number, because the arraysize depends on a user input.
thanks!
The difficulty here is that the size of your array is not known statically (once upon a time, your code would even not compile for the same reason).
That, combined with the fact that 2D-arrays are not arrays of 1D arrays (contrarily to what happen when you malloc a int ** and then every int * in it), and so it doesn't make sense not to specify the size when passing it to a function.
When using arrays of arrays (technically, pointers to a bunch of pointers to ints), like this
void f(int **a){
printf("%d %d %d\n", a[0][0], a[1][0], a[0][1]);
}
int main(){
int **t=malloc(10*sizeof(int *));
for(int i=0; i<10; i++) t[i]=malloc(20*sizeof(int));
f(t);
}
That code is useless, it prints only unitialized values. But point is, f understands what values it is supposed to print. Pointers arithmetics tells it what a[1] is, and then what a[1][0] is.
But if this 2D-array is not pointers to pointers, but real arrays, like this
void f(int a[][20]){
printf("%d %d %d\n", a[0][0], a[1][0], a[0][1]);
}
int main(){
int t[10][20];
f(t);
}
Then, it is essential that the called function knows the size (or at least all sizes, but for the first dimension) of the array. Because it is not pointers to pointers. It is an area of 200 ints. The compiler needs to know the shape to deduce that t[5][3] is the 5×20+3=103th int at address t.
So, that is roughly what is (better) explained in the link that was given in comments: you need to specify the size.
Like I did here.
Now, in your case, it is more complicated, because you don't know (statically) the size.
So three methods. You could switch to pointers to pointers. You could cast your array into a char * and then do the index computation yourself (x*i+j). Or with modern enough C, you can just pass the size, and then use it, even in parameters, declaration
void f(int x, int a[][x]){
printf("%d %d %d\n", a[0][0], a[1][0], a[0][1]);
}
int main(){
int t[10][20];
f(t);
}
Anyway, from an applicative point of view (or just to avoid segfault) you need to know the size. So you would have had to pass it. So why not pass it as first parameter (Note that the function in which you have this size problem, spielRun, does refers to a x, which it doesn't know. So, passing the size x would have been your next problem anyway)
So, spielRun could look like this (not commenting in other errors it contains)
void spielRun(int x, char feld[][x]){
int neighbCount;
char feldNew[][] = feld[][]; // Other error
for(int i = 0; i < x; i++) {
for(int j = 0; j < x; j++) {
checkForNeighbours(feld[i][j]); // Corrected one here
// in progress
}
}
}
And then calls to this spielRun could be
spielRun(x, feld);
Note that I address only the passing of array of size x here. There are plenty of other errors, and, anyway, it is obviously not a finished code. For example, you can't neither declare a double array char newFeld[][] = oldFeld[][]; nor affect it that way. You need to explicitly copy that yourself, and to specify size (which you can do, if you pass it).
I am also pretty sure that i = (x^2)*(0,1*i); does not remotely what you expect it to do.

How to write a square matrix multiplication function in C? [duplicate]

This question already has answers here:
How to pass 2D array (matrix) in a function in C?
(4 answers)
Closed 1 year ago.
int Ma_Multiplication(int A[][], int B[][], int size){
int C[size][size];
for( i = 0 ; i< size ; ++i){
for( j=0 ; j< size ; ++j){
C[i][j] = 0;
for( k = 0 ; k < size; ++k)
C[i][j] = C[i][j] + (A[i][k]*B[k][j]);
printf("%d ",C[i][j]);
printf("\n");
}
}
I wrote this function to calculate multiplication of 2 matrices. But when I debugged, it told me this:
error: array type has incomplete element type 'int[]'
4 | int MATRIX(int A[][], int size){
| ^
Could anyone can explain this? Thank u so much!
C does not allow declaration of arrays with element of incomplete type. Thus int A[] is ok. However, int A[][] is not because it's element type is int[] which is incomplete.
To fix I suggest fully defining the parameters using VLA types:
int Ma_Multiplication(int size, int A[size][size], int B[size][size]) {
...
}
If you want to keep an original ordering of parameters you must use an extension (GCC and CLANG) allowing to declare the parameters.
int Ma_Multiplication(int size; int A[size][size], int B[size][size], int size)
This extension may get mainlined into upcoming C23 standard

Segmentation fault in passing multidimensional arrays to functions in C

We saw passing arrays to functions using pointers in my intro. to C class, and I'm trying to learn how to pass multidimensional arrays on my own. I tried writing a function to assign the values of the entries of a matrix onto a local array, but I get a segmentation fault. I was hoping someone could explain why this happens and how to fix it. I'm using the terminal on macOS Sierra. Thanks in advance. My code is below:
#include <stdio.h>
#include <stdlib.h>
void fillMatrix();
int main(void){
int rows, cols;
printf("\nEnter the number of columns:\n");
scanf("%d", &cols);
printf("\nEnter the number of rows:\n");
scanf("%d", &rows);
int matrix[rows][cols];
fillMatrix(&matrix[rows][cols], rows, cols);
for (int i = 0; i < rows; ++i){
for (int j = 0; j < (cols - 1); ++j){
printf("%d ", matrix[i][j]);
} printf("%d\n", matrix[i][(cols -1)]);
}
return 0;
}
void fillMatrix( int *matrix, int rows, int cols ){
for (int i = 0; i < rows; ++i){
for (int j = 0; j < cols; ++j){
printf("\nPlease enter the A(%d,%d) entry:\n", i, j);
scanf("%d", &*(matrix + (i*cols) + j));
}
}
return;
}
Given the declaration
int matrix[rows][cols];
This code is wrong:
fillMatrix(&matrix[rows][cols], rows, cols);
The address of &matrix[rows][cols] is past the end of the matrix.
The first element of the matrix is &matrix[0][0], and the last element of the matrix is &matrix[rows-1][cols-1].
Also, this declaration
void fillMatrix();
will cause problems with this defintion:
void fillMatrix( int *matrix, int rows, int cols ){
...
They need to match. Right now, because of the void fillMatrix() declaration up top, arguments get passed to the function via default argument promotion, but because the definition has explicit arguments, the function itself expects the arguments to be passed as int * or int. You're probably not having problems with that as the defaults for those arguments are likely the same as those arguments, but function definitions and declarations generally must match exactly.
I haven't examined your code for other issues.
In C when you are declaring an array you need to specify its size at the time of compilation. When you decelerate the array in line
int matrix[rows][cols];
You actually initialise its size with rubbish values. In case of my compiler it was initialised with size of [0][0]. In order to achieve what you want you need to do one of two things:
Specify explicitly what is the size of the array before compilation
Dynamically allocate space for the array

Function passing of multidimensional array in c

#include <stdio.h>
void spiral(int a[10][10]) {
printf("%d", a[1][3]);
}
int main() {
int r, c, j, i;
scanf("%d%d", &r, &c);
int a[r][c];
for (i = 0; i < r; i++)
for (j = 0; j < c; j++) {
scanf("%d", &a[i][j]);
}
spiral(a);
return 0;
}
When I give a 3 x 6 array
1 2 3 4 5 6
7 8 9 10 11 12
13 14 15 16 17 18
The output is 14, while it should be 10
How to fix this issue?
If you enter 3 and 6 for r and c (respectively) then the type of a is not int[10][10] (or int(*)[10] as the spiral argument really is), it's int[3][6]. The memory layout is completely different for the arrays, leading to undefined behavior.
You can solve this by passing the size along to the function, and using it in the declaration of the array:
void spiral(const size_t r, const size_t c, int (*a)[c]) { ... }
Call it like expected:
spiral(r, c, a);
As noted using int a[r][c] as argument might be easier to read and understand, but it gives a false impression that a is actually an array. It's not. The compiler treats the argument as a pointer to an array of c integers, i.e. int (*a)[c].
This makes me a little conflicted... On the one hand I'm all for making things easier to read and understand (which means it will be easier to maintain), on the other hand newbies often get it wrong and think that one can pass an array intact when in fact it decays to a pointer which can lead to misunderstandings.
A few things are wrong: in void spiral() you ask for a 2D-array of 10*10, but you do not give that. Keep that part as a variable, so only ask the type you receive and not what you want to receive and with creating a dynamic array you should always do that with malloc or calloc and free them afterwards. This might be a bit hard at first, but when you start creating bigger programs this is a must if you have a question or do not understand the pointers in the program called (*) then ask me:
#include <stdio.h>
#include <stdlib.h>
void spiral(int **a) {
printf("%d", a[1][3]);
}
int main() {
int r, c, j, i;
scanf("%d%d", &r, &c);
int **a = malloc(r * sizeof(int*));
for (i = 0; i < r; i++) {
a[i] = malloc(c * sizeof(int));
}
for (i = 0; i < r; i++) {
for (j = 0; j < c; j++) {
scanf("%d", &a[i][j]);
}
}
spiral(a);
for (i = 0; i < r; i++) {
free(a[i]);
}
free(a);
return 0;
}

malloc a char[][]

I am trying to malloc a char to have rows and columns with one letter in each cell. Something similar to int x[i][j] where I have i*rows and j*columns. Basically I want to make this:
|
1
222
33333
4444444
I tried with this code but it gives me an error: assignment makes an integer from pointer without a cast
A=(char**) malloc (5*sizeof(char*));
for(i=0;i<N+2;i++)`{
A[i]=(char*) malloc(7*sizeof(char));
}
for(i=0;i<3;i++){
for(j=0;j<7;j++){
left=3;
right=3;
if((j>=left)&&(j<=right)){
A[i][j]=i;
}
}
left--;
right++;
}
I would go with different approach:
#define STEPS 5
#define ARRAY_SIZE STEPS*STEPS
The size of the array in your case can be easily calculated by the formula above.
Now, you just need to allocate fixed size of bytes, and fill it. That's it. Even more, the version below will simply out-beat your version in simplicity and performance.
int i, j;
char *array;
array = malloc(ARRAY_SIZE);
for (i = 0; i < STEPS; i++)
for (j = 0; j < (i * 2 + 1); j++)
*(array + i * STEPS + j) = i + 1;
Proof.
This compiles fine for me, as long as I add this around your code snippet; note that "A" was declared as being of type "char **". It won't work if you write, say "char A[][]".
#include <stdlib.h>
int main() {
const int N = 10;
int i, j, left, right;
char **A;
/* your code */
return 0;
}

Resources