Adding up matrices/ returning an array - c

I'm a begginer to C and I've got some problems with programming a function which would take two matrices, add them up and return the result as a third matrix. The fundamental problem is making a function return an array.
I found some solutions online on how to return an array by returning a pointer to the first element of the array, but couldn't apply it to my situation with two-dimensional array. I know how to add matrices in main function, but I need to break the program down into several functions.
Here is my code
float matrix_add(float matrixA[MAX_SIZE][MAX_SIZE], float matrixB[MAX_SIZE][MAX_SIZE], int column, int line)
{
float matrixRes[MAX_SIZE][MAX_SIZE];
for (int i=0; i<column; i++)
{
for (int j=0; j<line; j++)
{
matrixRes[i][j]=matrixA[i][j]+matrixB[i][j];
}
}
return matrixRes;
}
I've tried one of the solutions I've found online:
float *matrix_add(float matrixA[MAX_SIZE][MAX_SIZE], float matrixB[MAX_SIZE][MAX_SIZE], int column, int line)
{
static float *matrixRes[MAX_SIZE][MAX_SIZE];
for (int i=0; i<column; i++)
{
for (int j=0; j<line; j++)
{
*matrixRes[i][j]=matrixA[i][j]+matrixB[i][j];
}
}
return matrixRes;
But there are a few problems with it - I don't understand it, and the function still doesn't work - it returns false results and there is a warning in the compiler "return from incompatible pointer type".
Also, I'm not sure how to call it (maybe that's the problem with the solution I found?). I wanted to get some specific value from the array and called the function like this
matrix_add(matrixA, matrixB, column, line)[value][value]);
Where matrixA and B are some 2d arrays, column and line are integer variables. This returns an error (subscripted value is neither array nor pointer nor a vector)
Can you point me in the right direction and tell me how to make this function work (and explain the solution)? MAX_SIZE is predefined value (10) as in this assignment I'm supposed to use static memory allocation (but if you can help me by using dynamic allocation, that's fine)
The main function looks like this
int main()
{
int column_num[2], line_num[2];
float matrixA[MAX_SIZE][MAX_SIZE], matrixB[MAX_SIZE][MAX_SIZE];
scanf("%d", &column_num[0]);
scanf("%d", &line_num[0]);
matrix_load_val(matrixA, column_num[0], line_num[0]);
scanf("%d", &column_num[1]);
scanf("%d", &line_num[1]);
matrix_load_val(matrixB, column_num[1], line_num[1]);
}
for (int i=0; i<column_num[0]; i++)
{
for(int j=0; j<line_num[0]; j++)
{
printf("%0.5g\n", matrix_add(matrixA, matrixB, i, j));
}
}
matrix_load_val is a procedure which asks the user for values and puts them in a resultant matrix (it works for sure, tested)

Your attempt isn't too far off. You have a viable idea to declare a static array and "return it," but first we need to understand what that means.
In C, array types are strange beasts. You can't directly return an array of values like you can in other languages. Instead, you return a pointer. We say the array type decays to a pointer. For one-dimensional arrays, this isn't too scary:
float *get_array(void) {
static float my_array[2] = { 1, 2 };
return my_array;
}
float *result = get_array();
For multidimensional arrays, the decay is much trickier and uglier:
Note that when array-to-pointer decay is applied, a multidimensional array is converted to a pointer to its first element (e.g., a pointer to its first row or to its first plane): array-to-pointer decay is applied only once.
To return a pointer to a two-dimensional array, the syntax is:
float (*get_array(void))[2] {
static float my_array[2][2] = { { 1, 2 }, { 3, 4 } };
return my_array;
}
float (*result)[2] = get_array();
Applying this, we can tweak your code to make it work (some braces omitted for brevity):
float (*matrix_add(float matrixA[MAX_SIZE][MAX_SIZE], float matrixB[MAX_SIZE][MAX_SIZE], int column, int line))[MAX_SIZE]
{
static float matrixRes[MAX_SIZE][MAX_SIZE];
for (int i = 0; i < column; ++i)
for (int j = 0; j < line; ++j)
matrixRes[i][j] = matrixA[i][j] + matrixB[i][j];
return matrixRes;
}
However, a more idiomatic C pattern for this type of thing is to have the caller pass in a pointer to the output array. The function then populates this array. This is called an output parameter. This also eliminates the static variable and its associated issues (such as thread safety and subsequent calls clobbering the results of previous calls).
void matrix_add(
const float matrixA[MAX_SIZE][MAX_SIZE], /* "input parameter" */
const float matrixB[MAX_SIZE][MAX_SIZE], /* "input parameter" */
float matrixRes[MAX_SIZE][MAX_SIZE], /* "output parameter" */
int column,
int line)
{
for (int i = 0; i < column; ++i)
for (int j = 0; j < line; ++j)
matrixRes[i][j] = matrixA[i][j] + matrixB[i][j];
}
Notice we've also made the input parameters const to reflect the fact that the function doesn't modify those arrays. This makes it clear from the function's prototype which are the input and which are output parameters.
* I also took the liberty of reformatting a bit, and of changing i++ to ++i because it's a good habit, although it makes no difference in this particular case.

I recommend that you pass another matrix to the function which can be used to populate the result:
void matrix_add(float matrixA[MAX_SIZE][MAX_SIZE], float matrixB[MAX_SIZE][MAX_SIZE], float matrixRes[MAX_SIZE][MAX_SIZE], int column, int line)
{
for (int i=0; i<column; i++)
{
for (int j=0; j<line; j++)
{
matrixRes[i][j]=matrixA[i][j]+matrixB[i][j];
}
}
}
After you call matrix_add, matrixRes will have the results. This works because you're passing the address of matrixRes to matrix_add, that is, matrixRes is not local to matrix_add as in the case of column and line.

Related

problem with task with arrays and pointers

I have a task:
In the main code, declare a two-dimensional array [ 5 ][ 8 ]
(declaration on this matter).
Save the setter setting, which will set the individual coefficient values ​​according to the scheme (values ​​decrease from 40 to 1).
The parameters of the function are two pointers. The first pointing to the first element, the second pointing to the last element.
There can only be one loop inside this function!
Save the printing configuration, which will be displayed on the screen. A function parameter can be translated into a two-dimensional array, with a const modifier.
Here it's classic, two loops to print.
In the main code:
• declare a two-dimensional array, • enter the setting configuration
• correct printing effect
my code:
#include <stdio.h>
void set2(int *a, int *b)
{
int start = 40;
for(int *p = a; p < b; p++, start--)
{
*p = start;
}
}
void print3(const int tab[][])
{
for(int i = 0; i<5; i++)
{
for(int j = 0; j<8; j++)
{
printf("%3i", tab[i][j]);
}
putchar('\n');
}
}
int main()
{
int tab[5][8] = {0};
set2(tab, &tab[4][7]);
print3(tab);
return 0;
}
I get several errors and I am not able to understand what I am doing wrong. Could you help me? Thanks for all the answers.
I believe there are two issues.
The first is in set2, where you need to change p < b to p <= b, since you want to modify the last element, tab[4][7], too. Furthermore, you need to send &tab[0][0] as the first parameter since you want a pointer to the first element.
Second, as the compiler suggests, 'declaration of ‘tab’ as multidimensional array must have bounds for all dimensions except the first'. You must change void print3(const int tab[][]) to void print3(const int tab[][8]).

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.

Use a function to change the contents of the array, i.e. multiply each number in the array by 2

Question
Use your function to change the contents of the array, i.e. multiply each number in the array by 2.
When your function has finished and your program continues in your main(), print the contents of your array in your main().
See if the changes made to the contents of the array in your function can be seen. If not, why?
Further
I'm trying to multiply the original array by 2 onto another array. Can anyone spot where I've went wrong?
#include <stdio.h>
#include <math.h>
#define SIZE 5
//function signatures
int getMultiples(int[]);
//main function
int main()
{
//main variables
int array[SIZE];
int multiples[SIZE];
printf("\nPlease enter 5 numbers into an array.\n");
for(int i = 0; i < SIZE; i++)
{
scanf("%d", &array[i]);
}
multiples[] = getMultiples(array);
printf("\nThis program will multiply all numbers by 2\n\n");
for (int i = 0; i < SIZE; i++)
{
printf("%d\n", multiples[i]);
}
return 0;
}
int getMultiples(int arr[])
{
//function variables
int i;
int multiples[SIZE];
for (i = 0; i < SIZE; i++)
{
multiples[i] = arr[i] * 2;
}
return multiples[];
}
This statement
multiples[] = getMultiples(array);
is syntactically and semantically invalid. This construction multiples[] is wrong and arrays do not have the assignment operator.
Also the definition of the function getMultiples is also wrong.
Again this statement
return multiples[];
is invalid.
What you are trying to do is to return the local array
int multiples[SIZE];
but the function return type is int. At least you needed to declare the return type as int *.
But in any case the local array that has automatic storage duration will not be alive after exiting the function.
If to use your approach then the function can look the following way
void getMultiples( int a1[], const int a2[], size_t n )
{
for ( size_t i = 0; i < n; i++ )
{
a1[i] = 2 * a2[i];
}
}
and in main the function is called like
getMultiples( multiples, array, SIZE );
Pay attention to that the function definition should not depend on the magic number SIZE.
By the way in your assignment there is written
Use your function to change the contents of the array, i.e. multiply
each number in the array by 2.
It means that you need to change the source array,
In this case the auxiliary array multiples is redundant. The function could be defined the following way
void getMultiples( int a[], size_t n )
{
for ( size_t i = 0; i < n; i++ )
{
a[i] *= 2;
}
}
and called in main like
getMultiples( array, SIZE );
You promise to return a single int.
int getMultiples(...);
You don't:
return multiples[];
You attempt to assign to a whole array (either a single int or an array....).
multiples[] = getMultiples(array);
That does not work in C.
And judging from what happens when trying your code, your compiler should have told you.

Use of a function on a 2d array

I have written code which allows me to modify the elements of a 1D array within my function by passing the element of the array:
I print the original array
I pass each element of the array to the function
Within the function I add the value 50 to each element of the array
I then call the function, and print out to screen the modified element value (i.e the value of each element +50)
I have been able to do this for a 1D array, with example values in the array being (10,20,30) and the valued printed after modification being (60,70,80).
What I am hoping to do is adapt that code to work for 2D arrays, you will see my attempt at doing this below. This code focuses on the use of int, but once I understand how to achieve this I am hoping to adapt for the use of a 2D string as well.
With the code below:
My objective is
Print to screen the original 2D array
Pass each element of the 2D array to the function
Within the function add the value 50 to each element of the array
Then call the function, and print out the modified element values to the screen(expected result displayed on screen 60,61,etc,.)
So far I have been able to print the original 2D array to the screen. It is the function I think I am messing up and would appreciate any advice. Thank you.
#include <stdio.h>
#include <string.h>
#define M 4
#define N 2
int function(int **arr);
int main() {
int i, a;
int arr[N][M] = {10, 11, 12, 13, 14, 15, 16, 17};
// the int array first
for(i = 0; i < N; i++) {
for(size_t j = 0; j < M; j++) {
// Accessing each variable
printf("value of arr[%d] is %d\n", i, arr[i][j]);
}
}
printf("\n ***values after modification***\n");
a = function(&arr[i][0]);
// int array print results
for(int i = 0; i < N; i++) {
for(size_t j = 0; j < M; j++) {
printf("value of arr %d\n", arr[i][j]);
}
}
return 0;
}
int function(int **arr) {
int i;
int j;
for(int i = 0; i < 3; i++) {
for(size_t j = 0; j < 5; j++) {
arr[i][j] = arr[i][j] + 50;
}
}
}
My apologies in advance for silly mistakes I am very new to C.
Thank you in advance.
The function int function(int **arr) does not return an int so make it void.
When you call it, a = function(&arr[i][0]);, you do not use a after the assignment. I suggest that you remove a from the program completely since it's not used anywhere.
The call to the function, function(&arr[i][0]);, should simply be function(arr);
The function signature needs to include the extent of all but the outermost dimension:
void function(int arr[][M])
Inside the function, you use 3 and 5 instead of N and M. That accesses the array out of bounds.
In function, the i and j you declare at the start of the function are unused. Remove them.
arr[i][j] = arr[i][j] + 50; is better written as arr[i][j] += 50;
When initializing a multidimensional array, use braces to make it simpler to read the code:
int arr[N][M] = {{10, 11, 12, 13}, {14, 15, 16, 17}};
In main you mix int and size_t for the indexing variables. I suggest you settle for one type.
Remove unused header files (string.h)
Example:
#include <stdio.h>
#define N 2
#define M 4
void function(int arr[][M]) {
for(int i = 0; i < N; i++) {
for(size_t j = 0; j < M; j++) {
arr[i][j] += 50;
}
}
}
int main() {
int arr[N][M] = {{10, 11, 12, 13}, {14, 15, 16, 17}};
for(size_t i = 0; i < N; i++) {
for(size_t j = 0; j < M; j++) {
printf("value of arr[%zu][%zu] is %d\n", i, j, arr[i][j]);
}
}
printf("\n ***values after modification***\n");
function(arr);
// int array print results
for(size_t i = 0; i < N; i++) {
for(size_t j = 0; j < M; j++) {
printf("value of arr[%zu][%zu] is %d\n", i, j, arr[i][j]);
}
}
}
Since you print the array more than once, you could also add a function to do so to not have to repeat that code in main:
void print(int arr[][M]) {
for(size_t i = 0; i < N; i++) {
for(size_t j = 0; j < M; j++) {
printf("value of arr[%zu][%zu] is %d\n", i, j, arr[i][j]);
}
}
}
Two-Dimensional arrays in C (and C++) are actually one-dimensional arrays whose elements are one-dimensional arrays. The indexing operator [] has left-to-right semantics, so for a type arr[N][M] the first index (with N elements) is evaluated first. The resulting expression, e.g. arr[0], the first element in arr, is a one-dimensional array with M elements. Of course that array can be indexed again , e.g. arr[0][1], resulting in the second int in the first sub-array.
One of the quirks in the C language is that if you use an array as a function argument, what the function sees is a pointer to the first element. An array used as an argument "decays" or, as the standard says, is "adjusted" that way. This is no different for two-dimensional arrays, except that the elements of a two-dimensional array are themselves arrays. Therefore, what the receiving function gets is a pointer to int arr[M].
Consider: If you want to pass a simple integer array, say intArr[3], to a function, what the function sees is a pointer to the first element. Such a function declaration might look like void f(int *intPtr) and for this example is simply called with f(intArr). An alternative way to write this is void f(int intPtr[]). It means exactly the same: The parameter is a pointer to an int, not an array. It is pointing to the first — maybe even only — element in a succession of ints.
The logic with 2-dimensional arrays is exactly the same — except that the elements, as discussed, have the type "array of M ints", e.g. int subArr[M]. A pointer argument to such a type can be written in two ways, like with the simple int array: As a pointer like void f(int (*subArrPtr)[M]) or in array notation with the number of top-level elements unknown, like void f(int arr[][M]). Like with the simple int array the two parameter notations are entirely equivalent and interchangeable. Both actually declare a pointer, so (*subArrPtr)[M] is, so to speak, more to the point(er) but perhaps more obscure.
The reason for the funny parentheses in (*subArrPtr)is that we must dereference the pointer first in order to obtain the actual array, and only then index that. Without the parentheses the indexing operator [] would have precedence. You can look up precedences in this table. [] is in group 1 with the highest priority while the dereferencing operator * (not the multiplication!) is in group 2. Without the parentheses we would index first and only then dereference the array element (which must therefore be a pointer), that is, we would declare an array of pointers instead of a pointer to an array.
The two possible, interchangeable signatures for your function therefore are
void function( int (*arrArg)[M] ); // pointer notation
void function( int arrArg[][M] ); // "array" notation (but actually a pointer)
The entire program, also correcting the problems Ted mentioned, and without printing the original values (we know them, after all), is below. I have also adapted the initialization of the two-dimensional array so that the sub-arrays become visible. C is very lenient with initializing structures and arrays; it simply lets you write consecutive values and fills the elements of nested subobjects as the come. But I think showing the structure helps understanding the code and also reveals mistakes, like having the wrong number of elements in the subarrays. I have declared the function one way and defined it the other way to show that the function signatures are equivalent. I also changed the names of the defines and of the function to give them more meaning.
#include<stdio.h>
#define NUM_ELEMS_SUBARRAY 4
#define NUM_ELEMS_ARRAY 2
/// #arrArg Is a pointer to the first in a row of one-dimensional
/// arrays with NUM_ELEMS_SUBARRAY ints each.
void add50ToElems(int arrArg[][NUM_ELEMS_SUBARRAY]);
int main()
{
// Show the nested structure of the 2-dimensional array.
int arr[NUM_ELEMS_ARRAY][NUM_ELEMS_SUBARRAY] =
{
{10, 11, 12, 13},
{14, 15, 16, 17}
};
// Modify the array
add50ToElems(arr);
// print results
for (int i = 0; i < NUM_ELEMS_ARRAY; i++) {
for (int j = 0; j < NUM_ELEMS_SUBARRAY; j++)
{
printf("value of arr[%d][%d]: %d\n", i, j, arr[i][j]);
}
}
return 0;
}
// Equivalent to declaration above
void add50ToElems(int (*arrArg)[NUM_ELEMS_SUBARRAY])
{
for (int i = 0; i < NUM_ELEMS_ARRAY; i++)
{
for (size_t j = 0; j < NUM_ELEMS_SUBARRAY; j++)
{
//arrArg[i][j] = arrArg[i][j] + 50;
arrArg[i][j] += 50; // more idiomatic
}
}
}
Why is it wrong to pass a two-dimensional array to a function expecting a pointer-to-pointer? Let's consider what void f(int *p) means. It receives a pointer to an int which often is the beginning of an array, that is, of a succession of ints lying one after the other in memory. For example
void f(int *p) { for(int i=0; i<3; ++i) { printf("%d ", p[i]); }
may be called with a pointer to the first element of an array:
static int arr[3];
void g() { f(arr); }
Of course this minimal example is unsafe (how does f know there are three ints?) but it serves the purpose.
So what would void f(int **p); mean? Analogously it is a pointer, pointing to the first in a succession of pointers which are lying one after the other in memory. We see already why this will spell disaster if we pass the address of a 2-dimensional array: The objects there are not pointers, but all ints! Consider:
int arr1[2] = { 1,2 };
int arr2[2] = { 2,3 };
int arr3[2] = { 3,4 };
// This array contains addresses which point
// to the first element in each of the above arrays.
int *arrOfPtrToStartOfArrays[3] // The array of pointers
= { arr1, arr2, arr3 }; // arrays decay to pointers
int **ptrToArrOfPtrs = arrOfPtrToStartOfArrays;
void f(int **pp)
{
for(int pi=0; pi<3; pi++) // iterate the pointers in the array
{
int *p = pp[pi]; // pp element is a pointer
// iterate through the ints starting at each address
// pointed to by pp[pi]
for(int i=0; i<2; i++) // two ints in each arr
{
printf("%d ", pp[pi][i]); // show double indexing of array of pointers
// Since pp[pi] is now p, we can also say:
printf("%d\n", p[i]); // index int pointer
}
}
}
int main()
{
f(ptrToArrOfPtrs);
}
f iterates through an array of pointers. It thinks that the value at that address, and at the subsequent addresses, are pointers! That is what the declaration int **pp means.
Now if we pass the address of an array full of ints instead, f will still think that the memory there is full of pointers. An expression like int *p = pp[i]; above will read an integer number (e.g., 1) and think it is an address. p[i] in the printf call will then attempt to access the memory at address 1.
Let's end with a discussion of why the idea that one should pass a 2-dimensional array as a pointer to a pointer is so common. One reason is that while declaring a 2-dimensional array argument as void f(int **arr); is dead wrong, you can access the first (but only the first) element of it with e.g. int i = **arr. The reason this works is that the first dereferencing gives you the first sub-array, to which you can in turn apply the dereferencing operator, yielding its first element. But if you pass the array as an argument to a function it does not decay to a pointer to a pointer, but instead, as discussed, to a pointer to its first element.
The second source of confusion is that accessing elements the array-of-pointers uses the same double-indexing as accessing elements in a true two-dimensional array: pp[pi][i] vs. arr[i][j]. But the code produced by these expressions is entirely different and spells disaster if the wrong type is passed. Your compiler warns about that, by the way.

Passing an array created from fscanf into a new function

I have successfully fscanf a text file and saved in to an array E2N1. I am trying to pass this into a function as a pointer but it is not working. Whenever I try to call E2N1[0][0], it says that E2N is neither an array or a pointer. I've been looking all over for a solution on this.
(Sorry E2N was meant to be E2N1)
I use fscanf as:
int E2N1[noz.rowE2N][Q.N];
FILE* f = fopen("E2N.txt", "r");
for(i=0; i<noz.rowE2N; i++){
for (j=0; j<Q.N; j++){
fscanf(f,"%d",&E2N1[i][j]);
}
fscanf(f,"\n");
}
fclose(f);
and again I can't pass E2N1 into function.
Your help will be greatly appreciated.
The function is:
double *dudtF = stiffness(&U, &massM, &noz, &newV, &E2N1, &I2E, &B2E, &PP, &QQ);
and I write the function header as:
double *stiffness(double *U, double *massM, MESH *meshN, double *V1, int *E2N1, int *I2E, int *B2E, ordApprox *pp, ordApprox *qq)
V1, I2E, B2E are three arrays and I'm trying to do the same with them as I am trying to do with E2N1.
The funny thing about arrays is that they actually act as pointers.
if you have array char a[3] the variable is equivalent to char* p the same way if you have array char b[3][4] the variable b is equivalent to char** q. In other words, you should consider changing the handling in the method to take reference to reference (and possibly once more to reference) to integer.
Try google... here are some results I've got.
http://www.dailyfreecode.com/code/illustrate-2d-array-int-pointers-929.aspx
http://www.cs.cmu.edu/~ab/15-123S09/lectures/Lecture%2006%20-%20%20Pointer%20to%20a%20pointer.pdf
You don't need to pass as &E2N1, just pass as E2N1 no & as array name itself translates to pointer.
double *dudtF = stiffness(&U, &massM, &noz, &newV, E2N1, &I2E, &B2E, &PP, &QQ);
Also, you need to take it as int ** as its 2-dimensional array.
double *stiffness(double *U, double *massM, MESH *meshN, double *V1, int **E2N1, int *I2E, int *B2E, ordApprox *pp, ordApprox *qq)
Here is the example how to transfer matrix from one function to another ...
void foo (int **a_matrix)
{
int value = a_matrix[9][8];
a_matrix[9][8] = 15;
}
void main ()
{
#define ROWS 10
#define COLUMNS 10
int **matrix = 0;
matrix = new int *[ROWS] ;
for( int i = 0 ; i < ROWS ; i++ )
matrix[i] = new int[COLUMNS];
matrix[9][8] = 5;
int z = matrix[9][8] ;
foo (matrix);
z = matrix[9][8] ;
}
You cannot reference a multi-dimensional array passed to a function by point referencing as in the following:
int iVals[10][10];
foo(iVals);
void foo(int** pvals)
{
// accessing the array as follows will cause an access violation
cout << pvals[0][1]; // access violation or unpredictable results
}
You will need to specify the second dimension to the array in the function prototype
for example:
foo(int ivals[][10])
{
cout << ivals[0][1]; // works fine
}
If do not know the dimensions, then I would suggest you follow the principles outlined here:
void foo(int *p, int r, int c)
{
for(int i=0; i<r; i++)
{
for(int j=0; j<c; j++)
{
printf("%d\n", p[i*c+j]);
}
}
}
int c[6][6];
// pointer to the first element
foo(&c[0][0], 6, 6);
// cast
foo((int*)c, 6, 6);
// dereferencing
foo(c[0], 6, 6);
// dereferencing
foo(*c, 6, 6);
I hope this helps.
Alternatively you could use SAFEARRAY - see:
http://limbioliong.wordpress.com/2011/06/22/passing-multi-dimensional-managed-array-to-c-part-2/

Resources