0
  1. Taking in input from the main matrix_1, I need to create a new one and print it with only the odd numbers. Now I'm printing it from the function, but I need to print it from the main(); how can I do that?
#include <stdio.h>
#define len 4

void copiaDispari();

int main () {

    int i, j, matrix_1[len][len];

    for (i=0; i < len; i++){
        for (j=0; j < len; j++) {
            printf ("Inserisci il numero della matrice %d %d:", i, j);
            scanf ("%d", &matrix_1[i][j]);
        }
    }

    copiaDispari(matrix_1);

    for (i=0; i < len; i++){
        for (j=0; j < len; j++) {
            printf ("%d", matrix_2[i][j]);
        }
        printf("\n");
    }

    return 0;
}

void copiaDispari(int matrix_1[len][len]) {

    int matrix_2[len][len]= {{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}, i, j, l=0, m=0;


    for (i=0; i < len; i++){
        for (j=0; j < len; j++){
            if (matrix_1[i][j]%2!=0){
                if (l==4) {
                    l=0; m++;
                }
                matrix_2[m][l] = matrix_1[i][j];
                l++;
            }
        }
    }

    for (i=0; i < len; i++){
        for (j=0; j < len; j++) {
            printf ("%d", matrix_2[i][j]);
        }
        printf("\n");
    }

    return;
}
  1. Imagine I have to pass 5 or 6 variables from a function void yeah() to another function void yessss(); how can I achieve it?
  2. When should I use a void function, and when an int function?
Deduplicator
  • 44,692
  • 7
  • 66
  • 118
yepitis
  • 23
  • 4
  • It is conventional to use upper-case for constants — such as `#define LEN 4` — leaving lower-case for use with variables. Someone seeing `int matrix_1[len][len]` expects `len` to be a variable, not a constant. Variable length arrays are allowed in C99 and beyond. – Jonathan Leffler Jan 12 '20 at 16:03
  • thanks for the advice, may you help me with the program? [In this exercise i'm taking in input from the main a matrix and i need to create a new one with the function named copiaDispari and print it with only the odds numbers... now i'm printing it from the function copiaDispari, but I need to print it from the main(), how can I do that?, In order to do that I think that I should somehow pass the matrix_2 to the main and then with 2 for loops I should print it.] – yepitis Jan 12 '20 at 16:07
  • See examples of the caller pre-creating the result matrix and of the callee dynamically allocating the result matrix at https://stackoverflow.com/questions/14088804/how-to-return-matrix-2d-array-from-function-c – jarmod Jan 12 '20 at 16:11

2 Answers2

0
  1. The simplest approach is to allocate the second array in main() and pass it as an argument to the function (as well as the first array).

    int i, j, matrix_1[len][len], matrix_2[len][len] = { { 0 } };
    …
    copiaDispari(matrix_1, matrix_2);
    …
    void copiaDispari(int matrix_1[len][len], matrix_2[len][len])
    {
        …
    }
    

    Other techniques use dynamic memory management (malloc() et al), or encapsulate the array in a structure and pass the structure type around (you can return structures that contain arrays; you can't return arrays from functions), or (sometimes, but not often) using a static array in the function and returning a pointer to it (don't do this), or using a global variable (don't do this, either!).

  2. Functions can have semi-indefinitely large numbers of parameters. C11 §5.2.4.1 Translation limits requires the compiler to accept function definitions and calls with at least 127 arguments. A mere 5 or 6 doesn't cause a compiler any angst. However, reducing the number of arguments is a good idea.

    If you want to return multiple values from a function, you can pass multiple pointers to the function and have it modify the variables via the pointers. Or you can wrap the set of variables into a structure and pass a pointer to a suitable structure, or you can return a suitable structure to the calling function.

  3. When the function produces a value that will be used by the calling code, you should often not use a void function. You can pass pointers to variables and the function might modify those to return its answer. If the function can fail, you might have it return 0 on success and some other value on failure; that precludes it having the return type void, of course. Error handling is a major part of C programming. If a function doesn't return a value to indicate success or failure, it can be hard to know whether there a problems.


Incidentally, the forward declaration of the function should not be:

void copiaDispari();

In your original code, it should be:

void copiaDispari(int m1[len][len]);

In the revised code, it should be;

void copiaDispari(int m1[len][len], int m2[len][len]);

This will help prevent mistakes such as calling the function with the wrong number of arguments.

You should never write a function declaration with () for the argument list. That says the function takes an indeterminate number of arguments (but it isn't a variable argument list function like printf()). If the function takes no arguments, write int function(void); in the declaration, and for consistency, int function(void) { … } in the definition. Although you can write int function() { … } in the definition, this does not provide a prototype for the function and it can be miscalled in the same source file. Note that C++ differs from C in this area. Old C code (from before the C89/C90 standard was produced) uses the () notation; it didn't have a choice. Code written in this millennium should not use the () notation.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • Hi Jonathan, I just do not understand a thing, when you say "The simplest approach is to allocate the second array in main() and pass it as an argument to the function (as well as the first array)." I know it works cause I have tested but shouldn't the changes disappear as soon as the function is finished? I mean I'm not modifing the original matrix through a pointer, but I'm just modifing the matrix in the function. To clear my thoughts I tried to declare a variable 'int a=0' in the main passed it into the function and modified it to a=10 in the function. Then if i go to print it i get 0. – yepitis Jan 12 '20 at 19:19
  • How can I explain it? – yepitis Jan 12 '20 at 19:19
  • When you pass an array to a function, it is passed via a pointer, which means that changes made to the contents of the array by the function are visible to the calling function — it is the array in the calling function that is modified. So no, the changes don't vanish when the called function returtns. This is in contrast to simple values such as an integer, where the called function gets a copy of the value in the calling function, and cannot affect the value in the called function. – Jonathan Leffler Jan 12 '20 at 19:44
  • So if I pass an array, or a matrix I do not have to pass the pointer but i can just pass the array/matrix itself, whereas if I'm using a int, char, string i have to use pointers? – yepitis Jan 12 '20 at 20:23
  • Oh gosh — that gets complicated fast. Mostly right — my main concern is where you placed 'strings' in your list. If you have an array `SomeType array[SIZE];` and you pass it to a function like `function(array)`, then the type is automatically converted from `SomeType []` to `SomeType *`. If you write `function(&array)`, then you pass a `Sometype (*)[]` — a pointer to an array — which is a quite different type. If you pass a non-array type `SomeType simple;` using `function(simple);`, then you pass a copy of the variable; you have to use `function(&simple)` to pass a pointer. _[…continued…]_ – Jonathan Leffler Jan 12 '20 at 20:47
  • _[…continuation…]_ With strings, you somewhere have a `char string[SIZE];`, which is an array, so the rules of arrays apply. Calling `function(string)` passes a `char *` to the function. You might instead have `char *pointer = string;` and then you call `function(pointer)` to pass a pointer too. If you pass a pointer of some sort, then the called function can modify what the pointer points at. If you don't pass a pointer (or an array that 'decays' into a pointer), then the called function cannot modify the value in the calling function. – Jonathan Leffler Jan 12 '20 at 20:50
0
  1. [rephrased] how to send data back to the calling function?

Basically you have two options

create the object to hold the data in the calling function, pass a pointer and have the called function use that

int main(void) {
    int src1[10][10] = {0};
    int src2[10][10] = {0};
    fx(src1, src2);
}

or use malloc() (and friends) in the called function then return that to the caller which will be responsible to free the resources.

typedef int m2[10][10];

int main(void) {
    int src[10][10] = {0};
    m2 *dst = fx(src);
    // use dst
    free(dst);
}

m2 *fx(int m[10][10]) {
    m2 *x = malloc(10 * 10 * sizeof (int));
    // work with m to change x values
    return x;
}

A third option, to be frowned upon (no example code), is to use global variables.

  1. how to pass 5 or 6 variables between functions?

Basically, just specify them in the calling code, like

printf("%s bought %d %s for %.2f\n", name, quantity, "apples", quantity * price);

Or, if the variables are related, you can try grouping them in a struct and pass a pointer

struct GroupData {
    char name[100];
    int quantity;
    char item[100];
    double price;
};
struct GroupData x = {"John", 42, "apple", 0.31};
workwithdata(&x); // can also pass a copy of the struct
                  // workwithcopy(x);
  1. when to use void function or int function?

use void when there is no need to use a value from the function

void beep(void); // sounds the bell

use int when you want to use a value from the function

int currenttemp(void); // returns the temperature
pmg
  • 106,608
  • 13
  • 126
  • 198