I'm having trouble with macros in C. Is there any way to call and get the value of a parameter in macro to call a function?
The example code below generates an error:
#define order(i) fruits_i##_banana()
void fruits_1_banana()
{
printf("Order banana\n");
}
int main()
{
int a = 1;
order(a);
}
You need to use ## before and after i.
#define order( i ) fruits_##i##_banana()
void fruits_1_banana()
{
printf("Order banana\n");
}
int main()
{
order(1);
}
Note that you cannot pass a to order because macro expansion doesn't take the value of a variable, it just uses the variable name as it is.
References: https://learn.microsoft.com/en-us/cpp/preprocessor/token-pasting-operator-hash-hash?view=msvc-160
Instead, you can use an array of function pointers:
#include <stdio.h>
static void fruits_0_banana(void)
{
printf("Order banana 0\n");
}
static void fruits_1_banana(void)
{
printf("Order banana 1\n");
}
static void (*order[])(void) = {
fruits_0_banana, // Or NULL if you don't need it
fruits_1_banana,
// ...
};
int main(void)
{
int a = 1;
order[a]();
return 0;
}
Related
I wrote some simplifyed code to demonstrate the case. The goal is to call some funtions out of an struct array. In this implementation i get the following remark: "call to function 'unidentified function' not made in the presence of a prototype"
I guess that typedefs has to be used. I just dont get it working with typedefs.
#include <stdio.h>
#include<stdbool.h>
struct FuctionCallList
{
void (*const call_function)();
bool activated;
};
void testPrint1(void);
void testPrint2(void);
struct FuctionCallList sFuctionCallList[] =
{ //Function to call Activ
{testPrint1, false},
{testPrint2, true}
};
__uint16_t sFuctionCallListSize = sizeof(sFuctionCallList) / sizeof(struct FuctionCallList);
void testPrint1()
{
printf("Hello World function 1");
}
void testPrint2()
{
printf("Hello World function 2");
}
int main()
{
__uint8_t i;
for(i = 0; i < sFuctionCallListSize; i++)
{
if(sFuctionCallList[i].activated == true)
{
sFuctionCallList[i].call_function(); // problematic call
}
}
return 0;
}
I'm writing a program that can modify rows and cols from a function of a function. I don't understand how to do pointer of a pointer.
void changeNum(int*setRows, int *setCol)
{
changeNum2(*setRows,*setCol);
}
void changeNum2(int*setRows, int *setCol)
{
*setRows=5;
*setCol=5;
}
int main() {
int*row=10;
int* col=10;
changeNum(&row,&col);
printf("%d %d",row,col);
return 0;
}
First
int*row=10;
int* col=10;
This is wrong. Assigning hardcoded address. You don't want this
int row=10;
int col=10;
How to get the address of the row and col?
&row and &col.
How to pass it to function?
Call it, changeNum(&row,&col);
void changeNum(int*setRows, int *setCol)
{
...
}
How to pass pointer to pointer?
void changeNum(int*setRows, int *setCol)
{
chnageNum2(&setRows, &setCol);
}
ChangeNum2 how it would change value?
void chnageNum2(int **setRows, int **setCol){
**setRows = 110;
**setCol = 110;
}
Can we do the same change using changeNum() only?
Yes we can do that.
void changeNum(int*setRows, int *setCol)
{
*setRows = 110;
*setCol = 110;
}
Definitely check this. Grab a book. It will help a lot.
The complete code will be
void changeNum(int*setRows, int *setCol)
{
changeNum2(&setRows,&setCol);
}
void changeNum2(int**setRows, int **setCol)
{
**setRows=5;
**setCol=5;
}
int main(void) {
int row=10;
int col=10;
changeNum(&row,&col);
printf("%d %d",row,col);
return 0;
}
#include <stdio.h>
void changeNum(int*, int*);
void changeNum2(int*, int*);
void changeNum(int* setRows, int *setCol) {
changeNum2(setRows,setCol);
}
void changeNum2(int* setRows, int *setCol) {
*setRows=5;
*setCol=5;
}
int main() {
int row=10;
int col=10;
changeNum(&row, &col);
printf("%d %d\n", row, col);
return 0;
}
It takes sometime to grasp that every C function parameter is passed by value. So you can safely pass setRows pointer to the second function simply by its value.
Also, it's necessary to declare previously the function changeNum2, I've included the declaration without parameter names to clarify it's possible.
I strongly recommend reading this book: https://en.wikipedia.org/wiki/The_C_Programming_Language, specially chapter 5 (Pointers and arrays).
You can find a PDF copy easily. It's where I finally learned this concept.
I am writing a program in C which uses an array of function pointers. If I do not include an argument I am able to call the functions with my code without an issue.
int (*functionsArray[2][3])() = {
{functionOne,functionTwo,functionThree},
{functionFour,functionFive,functionSix}
};
However when I try and pass the argument int x:
int (*functionsArray[2][3])(int x) = {
{functionOne,functionTwo,functionThree},
{functionFour,functionFive,functionSix}
};
I get an error:
invalid conversion from 'int (*)()' to 'int (*)(int)'
Also none of these functions return an int, shouldn't I be able to declare them as void?
void(*functionsArray[2][3])(int x) = {
{functionOne,functionTwo,functionThree},
{functionFour,functionFive,functionSix}
};
Trying this results in an error:
error: invalid conversion from 'int (*)()' to 'void (*)(int)'
Thanks.
That will work fine, provided you declare the functions correctly:
#include <stdio.h>
int functionOne(int x) { return 1; }
int functionTwo(int x) { return 2; }
int functionThree(int x) { return 3; }
int functionFour(int x) { return 4; }
int functionFive(int x) { return 5; }
int functionSix(int x) { return 6; }
int (*functionsArray[2][3])(int x) = {
{functionOne, functionTwo, functionThree},
{functionFour, functionFive, functionSix}
};
int main (void) {
printf ("%d\n", (functionsArray[0][1])(99));
printf ("%d\n", (functionsArray[1][2])(99));
return 0;
}
The output of that program is 2 and 6.
It will also work if you want no return value:
#include <stdio.h>
void functionOne(int x) { puts ("1"); }
void functionTwo(int x) { puts ("2"); }
void functionThree(int x) { puts ("3"); }
void functionFour(int x) { puts ("4"); }
void functionFive(int x) { puts ("5"); }
void functionSix(int x) { puts ("6"); }
void (*functionsArray[2][3])(int x) = {
{functionOne, functionTwo, functionThree},
{functionFour, functionFive, functionSix}
};
int main (void) {
(functionsArray[0][1])(99);
(functionsArray[1][2])(99);
return 0;
}
That program also outputs 2 and 6, as expected.
It all comes down to ensuring that the function declarations match the type given in the array.
When you declare an array:
int (*functionsArray[2][3])(int x) =
{
{functionOne,functionTwo,functionThree},
{functionFour,functionFive,functionSix}
};
every element of the array has to be of type int (*)(int). Otherwise, the compiler correctly reports an error.
Take a simple case:
void foo()
{
}
int (*fp)(int x) = foo;
should result in the same compiler error because you are trying to initialize a variable of type int (*)(int) using foo, whose type is void (*)().
I am a Beginner in Functions.I wanna integrate that Functions in my main program. The program should scan a int number and then square it(sum=b*b). Then the program should output the result.
#include <stdio.h>
#include <stdlib.h>
void funktion(int);
void out(int);
int main(int)
{
int sum,b,v,w,z;
{
funktion();
calculator();
out();
printf("%i",sum);
}
return 0;
}
void funktion(int v)
{
printf("Enter any number that is to be squared!");
}
void calculator(int w) //calculate b*b
{
scanf("%i",&b);
sum=b*b;
}
void out(int z)
{
printf("Sum:");
}
Please give me some tips. ;)
Thx & Best regards!
Are you looking for this kind of solution: i just made little changes. you may need to do some initializing things if u gonna use this code
#include <stdio.h>
#include <stdlib.h>
void funktion(int);
void out(int);
int main()
{
int sum,b;
{
printf("Enter any number that is to be squared!");
scanf("%i",&b);
sum = funktion(b);
out(sum);
}
return 0;
}
int funktion(int b)
{
return b*b;
}
void out(int sum)
{
printf("Sum:%d",sum);
}
void funktion(int);
void out(int);
These two functions need not contain any arguments as you declared to be int's, because you are not performing any computation on sum, since they are just prints inside those functions.
So make them as,
void funktion(void);
void out(void);
and call those routines as,
funktion();
out();
void funktion(int)
{
printf("Enter any number that is to be squared!");
}
void out(int)
{
printf("Sum:");
}
to call these functions you are passing some value so you receive them with parameters.
void funktion(int a)
{
printf("Enter any number that is to be squared!");
}
void out(int b)
{
printf("Sum:");
}
You can make use of the passed value in functions using these variables, a nd b in corresponding functions.
If you dont want to access those passed values in the called functins then you dont need to pass the value. So change the functions to receive nothing, it can be
#include <stdio.h>
#include <stdlib.h>
void funktion();
void out();
int main()
{
int sum,b;
{
funktion();
scanf("%i",&b);
sum=b*b;
out();
printf("%i",sum);
}
return 0;
}
void funktion()
{
printf("Enter any number that is to be squared!");
}
void out()
{
printf("Sum:");
}
make the call to function without passing arguments. you can even specify void as type to indicate that function doesn't take any parameters.
To calculate in other function and return the value use return statement.
int calculator() //calculate b*b
{
scanf("%i",&b);
sum=b*b;
return sum;
}
change the function call statement to,
sum=calculator();
When I compile the following C function / program I get errors like "missing ';' before 'type' 'remainder' : undeclared identifier" - what is wrong with this function?
#include <stdio.h>
void conversionTo(int number,int base) {
if(number==0)
return;
int remainder=number%base;
conversionTo((number/base),base);
if(remainder<10)
printf("%c",'0'+remainder);
else
printf("%c",'a'-10+remainder);
}
int main() {
conversionTo(int number,int base);
return 0;
}
I'm not a C expert, but from experience very long ago I believe you cannot declare variables in the middle of a function.
Also, it's unclear what you are trying to do with the function / print statements.
Try this:
#include <stdio.h>
void conversionTo(int number,int base) {
int remainder=number%base;
if(number==0)
return;
conversionTo((number/base),base);
if(remainder<10)
printf("%c",'0'+ remainder); // Through the way ASCII works that gives the ASCII rep
// of the remainder.
else
printf("%c",'a'-10+remainder); // Hex digits (A-F).
}
int main() {
conversionTo(/*Any number here*/10, /*any base number here*/2);
return 0;
}
You need to defines variables, then they can be used.
So this:
int main() {
conversionTo(int number,int base);
return 0;
}
should become this:
int main(void)
{
int number;
int base:
number = 47;
base = 11;
conversionTo(number, base);
return 0;
}
Also non C99 compliant compilers do not like having variables declared in the middle of a context:
void conversionTo(int number,int base) {
if(number==0)
return;
int remainder=number%base; /* this would fail. */
conversionTo((number/base),base);
To get around this open another context:
void conversionTo(int number,int base) {
if(number==0)
return;
{
int remainder=number%base;
conversionTo((number/base),base);
if(remainder<10)
printf("%c",'0'+remainder);
else
printf("%c",'a'-10+remainder);
}
}
You have to invoke your function with a value or variable, not a declaration:
conversionTo(123, 10); // using constant value
or
int number = 123, base = 10; // variable declaration
conversionTo(number, base); // using variable
You are calling your function wrong - pass the arguments this way:
conversionTo(2,2); // assuming you want to convert 2 to binary
or
int number = 123, base = 10;
conversionTo(number, base); // note this is not the same number and base as in the definition of your conversionTo function
Full code:
#include <stdio.h>
void conversionTo(int number,int base)
{
if(number==0)
return;
int remainder=number%base;
conversionTo((number/base),base);
if(remainder<10)
printf("%c",'0'+remainder);
else
printf("%c",'a'-10+remainder);
}
int main()
{
conversionTo(2,2); // assuming you want to convert 2 to binary
return 0;
}
There are 3 things when using functions:
Function declaration / prototype - the prototype of your function is:
void conversionTo(int ,int );
Function definition:
void conversionTo(int number,int base /* Parameter list*/)
{
// your functionality
}
Function call where you pass your arguments to your function:
conversionTo(2,2);
The statement conversionTo(int number,int base); simply re-declares it. Try this even this will compile:
int main()
{
printf("Hello World");
int main();
}
conversionTo(int number, int base)
is the syntax for declaring which parameters the function can take. To actually call the function, you need to omit the type (assuming you have variables of the respective name)
int number = 5;
int base = 10;
conversionTo(number, base); // <-- no int here!
Or you can use numbers directly:
conversionTo(5, 10);
Your function definition number and base in your function declaration void conversionTo(int number, int base) are the names that the values passed to it will have inside the function. So, if you call conversionTo(2,5), 2 will be seen inside the function as number, while 5 will be seen as base.
If you want to use variables instead of contants to call the function, you could do that:
int main()
{
int base = 2;
int number = 5;
conversionTo(base, number);
return 0;
}
In this confusing example, the variables base and value have value 2 and 5, respectively. But as you pass them to the function, the values inside it will be number = 2 and base = 5. This shows that those variables are actually different, despite of having the same name.
You should compile with $CC -std=c99, to enable declaring variables in the middle of a block.
(see section 6.8 in the specification)
The declaration "int remainder" must come before any statements in a block.
A declaration may have an initializer as you have here.
You could do:
void conversionTo(int number,int base) {
if (number > 0) {
int remainder...
}
}
since the function will not work with negative numbers.
To fix the other bugs in the routine:
void conversionTo(int number,int base)
{
if(number>=0&&base>0&&base<=36)
{
int remainder=number%base;
number/=base;
if(number>0)conversionTo(number,base);
printf("%c",(remainder<10)?'0'+remainder:'a'+remainder-10);
}
}
This will print a 0 if number is zero and only recurse if needed.