简体   繁体   中英

Is it possible to use format specifiers as arguments for a function

I'm trying to write a function that allows me to initialise every element of a matrix with a given value. I'd like for this function to be as generic as possible, meaning that it would be able to treat matrices of any data type (float, char, etc). The function would obviously need as one of the argument the value that the user wants the elements of the matrix to be initialised with. Since this value could be of any kind of data type, I don't know how to go about this. Standard functions such as printf and scanf are able to accept arguments of any kind thanks to their use of format specifiers (%d, %f, etc). This got me wondering: how and is it even possible to use format specifiers in a programmer-defined function? Ideally, my function would look something like this:

void initMatrix(void*** matrixToInit, int nRows, int nCols, const char format, void(?) value)

So that upon calling it I would have to write something like:

char matrixOfAs[3][3];

initMatrix(&matrixOfAs, 3, 3, "%c", 'A');

Is something like this feasible? Are there other solutions to this problem?

Assuming the matrix is a proper 2-D array of the element type (an array of array of element type), and not a 1-D array of pointer to element type, you could pass a void * pointer to the first element of the matrix to be initialized, the dimensions of the matrix, the element size, and a pointer to an initial element value as illustrated by the following:

#include <string.h>
#include <stdio.h>

void initMatrix(void *matrixToInit, unsigned int nRows, unsigned int nCols,
        size_t elemSize, const void *elemVal)
{
    size_t offset, end;

    end = nRows * nCols * elemSize;
    for (offset = 0; offset < end; offset += elemSize) {
        memcpy((char *)matrixToInit + offset, elemVal, elemSize);
    }
}

int main(void)
{
    char matrixOfAs[3][3];
    int i, j;

    initMatrix(&matrixOfAs[0][0], 3, 3, sizeof(char), (char []){ 'A' });
    for (i = 0; i < 3; i++) {
        for (j = 0; j < 3; j++) {
            printf(" %c", matrixOfAs[i][j]);
        }
        printf("\n");
    }
    return 0;
}

If you do not like the compound literal array value (char []){ 'A' } which I passed to the parameter elemVal (allowing the array value to decay to a pointer to its first element), you can replace it with a pointer to an initialized variable of type char in this case, eg define char a = 'A'; and replace (char []){ 'A' } with &a .

To make this function generic for any data type you choose to use, just create the function that doesnt handle a spesific data type but uses function pointers instead.

It means instead of passing this function the symbol of which type the user choose and then create a case for int , case for char and case for float , pass functions that hanle each type as an argument.

For example, make the function initMatrix like:

void initMatrix(void*** matrix, int nRows, int nCols, void(*creatematrix)(void ***, int, int));

Now, Create another function that handle the creation of int **matrix , lets call it void CreateIntMatrix(void ***matrix, int m, int m); and pass a pointer to this function as an argument of initmatrix function. Now, when you call initMatrix to handle int data types, just call it like that:

void initMatrix(&matrixOfAs, 3, 3, CreateIntMatrix);

you should create as well function that handle char, double etc..

Now, when you creating the initMatrix function, create it like that:

void initMatrix(void*** matrix, int nRows, int nCols, void(*creatematrix)(void ***, int, int)){
    /*Make something*/
    creatematrix(matrix, nRows, nCols)//initialize any type of matrix
    /*Make something*/
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM