C function pointer declaration omitting parameters - c

In the code, I omitted parameters for int (*bar) and assigned &foo, which as 3 arguments, to bar. (*bar) received the numbers and gave me a return value. I thought this is ok but I've heard that this is actually UB. How does (*bar) receive the numbers? Thx
#include <stdio.h>
int foo(int a, int b, int c){
return a+b+c;
}
int main(void) {
int (*bar)() = &foo;
printf("%d", bar(1, 2, 3));
return 0;
}
edit
When I pass more than three arguments to bar() (say 5 arguments), the program works. Where do the two extra arguments go?

Related

Cannot print called float variables

I cannot print float variables when calling my functions. int variables print but floats won't print their proper value when passed to my function.
I tried to change the float to int and that worked
int main() {
int foo = 6;
call(foo);
}
void call(int bar) {
printf("%d", bar);
}
This worked and it does indeed print 6.
But, doing the same but with floats only prints out 0.00000:
int main() {
float foo = 6;
call(foo);
}
void call(float bar) {
printf("%f", bar);
}
How do I correctly call and then print float variables?
you need a forward declaration of call
void call(float integerrrr);
int main(){
float integerrrr=6;
call(integerrrr);
}
void call(float integerrrr){
printf("%f", integerrrr);
}
your compiler probably warned you about this
You could simply define call above main instead of below it. The compiler must have seen the declaration of functions when they are used, so a forward declaration like pm100 suggests is one way. Moving the whole definition above main is the another (that does not require a forward declaration).
#include <stdio.h>
void call(float integerrrr){
printf("%f", integerrrr);
}
int main(void){
float integerrrr = 6;
call(integerrrr); // now the compiler knows about this function
}
INT type variables i can print but float just does not
If your program actually compiles as-is it will use an old (obsolete) rule that makes an implicit declaration of undeclared functions when they are used. The implicit declaration would be int call(); - which does not match your actual function. The program (even the one that seems to be working) therefore had undefined behavior.
the compiler of c work from top to bottom so line by line,
so u will have to call the first function void call() then your main function:
void call(float integerrrr){
printf("%f", integerrrr);
}
int main(){
float integerrrr=6;
call(integerrrr);
}

Passing a multidimensional array of variable size

I'm trying to understand what "best practice" (or really any practice) is for passing a multidimensional array to a function in c is. Certainly this depends on the application, so lets consider writing a function to print a 2D array of variable size. In particular, I'm interested in how one would write the function printArry(__, int a, int b) in the following code. I have omitted the first parameter as I'm not exactly sure what that should be.
void printArry(_____, int a, int b){
/* what goes here? */
}
int main(int argc, char** argv){
int a1=5;
int b1=6;
int a2=7;
int a2=8;
int arry1[a1][b1];
int arry2[a2][b2];
/* set values in arrays */
printArry(arry1, a1, b1);
printArry(arry2, a2, b2);
}
The easiest way is (for C99 and later)
void printArry(int a, int b, int arr[a][b]){
/* what goes here? */
}
But, there are other ways around
void printArry(int a, int b, int arr[][b]){
/* what goes here? */
}
or
void printArry(int a, int b, int (*arr)[b]){
/* what goes here? */
}
Compiler will adjust the first two to the third syntax. So, semantically all three are identical.
And a little bit confusing which will work only as function prototype:
void printArry(int a, int b, int arr[*][*]);
This is not really an answer, but extended comment to the OP's comment question, "well you can pass the array without knowing the number of rows with this, but then how will you know when to stop printing rows?"
Answer: generally, you can't, without passing the array size too. Look at this 1-D example, which breaks the array size.
#include <stdio.h>
int procarr(int array[16], int index)
{
return array[index];
}
int main (void)
{
int arr[16] = {0};
printf("%d\n", procarr(arr, 100));
return 0;
}
Program output (although all elements initialised to 0):
768
That was undefined behaviour and there was no compiler warning. C does not provide any array overrun protection, except for array definition initialisers (although such initialisers can define the array length). You have to pass the array size too, as in
#include <stdio.h>
int procarr(int array[16], size_t index, size_t size)
{
if (index < size)
return array[index];
return -1; // or other action / flag
}
int main (void)
{
int arr[16] = {0};
printf("%d\n", procarr(arr, 100, sizeof arr / sizeof arr[0]));
return 0;
}
Program output:
-1

How to have an array of functions that returns pointers of ints

When I try to compile the following line
int* x[](), (*y)();
I get the error "x declared as an array of functions of type int()"
You cannot really declare an array of functions, but you can have an array of function pointers, which will probably give you the same effect, because you can invoke them without explicit dereferencing.
The following will declare an array of 5 function pointers which return int*.
int* (*x[5])();
The website cdecl will let you play with various pointer declarations to see what they mean in English.
Here is the golden rule for reading C declarations, stolen from this old article.
Start at the variable name (or innermost construct if no identifier is
present. Look right without jumping over a right parenthesis; say what
you see. Look left again without jumping over a parenthesis; say what
you see. Jump out a level of parentheses if any. Look right; say what
you see. Look left; say what you see. Continue in this manner until
you say the variable type or return type.
When applied to the declaration above, we say:
x is an array of 5 pointers to functions returning pointer to int.
As SteveCox correctly commented below, we note that if we run into a type qualifier on the left hand side when following the above rule, it will describe the type to its left rather than its right. For example, the following declaration declares an array of 5 pointers to functions returning const pointer to int, not pointer to const int.
int* const (*x[5])();
Try this for an array of 2 function pointers.
#include <stdio.h>
int *first(void) { return NULL; }
int *second(void) { return NULL; }
int main(void) {
int *(*fx[2])(void);
fx[0] = first;
fx[1] = second;
/* ... */
if (fx[0]() == fx[1]()) {
printf("Calling both functions returns the same value.\n");
}
return 0;
}
A practical application might look like:
#include <ansi_c.h>
int add_(int, int);
int sub_(int, int);
int mul_(int, int);
int div_(int, int);
enum {
ADD,
SUB,
MUL,
DIV
};
int (*mathOps[4])(int, int);
int main(void)
{
int i;
mathOps[ADD]=add_;
mathOps[SUB]=sub_;
mathOps[MUL]=mul_;
mathOps[DIV]=div_;
for(i=ADD;i<=DIV;i++)
{
printf("results are: %d\n", mathOps[i](3, 3));
}
getchar();
return 0;
}
int add_(int a, int b)
{
return a + b;
}
int sub_(int a, int b)
{
return a - b;
}
int mul_(int a, int b)
{
return a * b;
}
int div_(int a, int b)
{
return a / b;
}

How to use the pointer of a function in C? (No C++)

As the title says, how do I use the pointer of a function in C? Can I just take the address of the function name and pass it to another function; then dereference it and call it?
Thanks a lot.
If you know the function address, then yes. For example:
int add(int a, int b)
{
return a + b;
}
int sub(int a, int b)
{
return a - b;
}
int operation(int (*op)(int, int), int a, int b)
{
return op(a, b);
}
Then just call it like this:
printf("%d\n", operation(&add, 5, 3)); // 8
printf("%d\n", operation(&sub, 5, 3)); // 2
You can even do some array tricks:
int op = 0;
int (*my_pointer[2])(int, int) =
{
add, // op = 0 for add
sub // op = 1 for sub
};
printf("%d\n", my_pointer[op](8, 2)); // 10
well to answer your question precisely, there is a provision in C for such needs which is called "function pointer".
But you have to follow certain rules,
1) All the functions you want to call using function pointer must have same return type.
2) All the functions you want to call using function pointer must have same no of arguments and argument types.
For example,
int add(int, int);
int sub(int, int);
for above two functions you can write function pointer as,
int (*operation)(int , int);
and you can use it just as described by Flavio Torbio.
hope it helps.....

c standard library sort function from programming pearls

#include <algorithm>
#include <stdio.h>
#include <iostream>
int intcomp(int *x,int *y) { return *x-*y;};
int a[10000];
int main(void){
int i; int n=0;
while (scanf("%d",&a[n])!=EOF)
n++;
qsort(a,n,sizeof(int),intcomp);
for (int i=0;i<n;i++)
printf("%d\n",a[i]);
return 0;
}
it is just copy of code i have two question it show me that intcomp is incompatible in this code
and also what does intcomp function?
and also what is in windows 7 EOF? how tell program that it reached EOF?
the qsort() function requires a pointer with a particular signature.
Your function has the wrong signature so it is complaining.
Your function has the signature:
int intcomp(int *x,int *y)
While qsort requires the signature:
int intcomp(void const* xp,void const* yp)
Please note the difference in the parameter types.
A corrected version of the function is:
int intcomp(void const* xp,void const* yp)
{
// Modified for C as the tag on the question changed:
// int x = *static_cast<int const*>(xp);
// int y = *static_cast<int const*>(yp);
int x = *((int const*)(xp));
int y = *((int const*)(yp));
return x-y;
}
The function qsort() is passed a function pointer as the third parameter.
This function pointer (in your case intcomp()) is used to compare values in the array passed. Each call provides pointers into the array. The result of the function should be:
Less than 0: if x is smaller than y
0: If x is equal to y
Greater than 0: If x is larger than y
First of all: the question is labeled C++ and you #include <algorithm> and <iostream>, but your code is 100% C.
Martin York already gave the answer how to correct the signature of the function you pass to qsort().
However, the "true"(TM) C++ solution would be to use std::sort<> instead of qsort!
#include <algorithm>
#include <stdio.h>
bool intcomp(int a, int b) { return a<b; }
int a[10000];
int main(void){
int n=0;
while (scanf("%d",&a[n])!=EOF)
n++;
std::sort(&a[0], &a[n], intcomp);
for (int i=0;i<n;i++)
printf("%d\n",a[i]);
return 0;
}
Note that incomp() takes ints and not int pointers, and returns a bool. Just like operator<() would.
Also note that in this case, you could forget the intcomp and just use std::sort(&a[0], &a[n]), which will use std::less<>, which will use operator<(int, int).
intcomp is an "Int Compare" function. It is passed a pointer to 2 ints and returns 0 if they are the same, a positive value is x > y and a negative value is x < y.
qsort is passed a pointer to this function and calls it each time it wants to know how to sort a pair of values.
The docs for qsort should give you some more details.
eg http://www.cppreference.com/wiki/c/other/qsort
qsort is in stdlib.h, so include that file at the beginning. Note that algorithm and iostream aren't needed.
#include <stdlib.h>
As Martin York mentioned, qsort needs a function which it will use to compare the values:
void qsort( void *buf, size_t num, size_t size, int (*compare)(const void*, const void *) );
Here is a good example on how to use qsort: http://www.cppreference.com/wiki/c/other/qsort
Edit: Ri was faster....

Resources