Multiple function calling? - c

Hi extremely new to programming. Just want to know if for example I have a function called void blink(void). If I write a code
2 * blink();
is it the same as
blink();
blink();
?

2 * blink();
No, this will not call blink() 2 times, this will multiply 2 with the value that blink() returns. Because blink() is void (that means blink() doesn't return anything), this will cause an error.
I have a variable 'num' and I want the function to be called as much
as the num value
You should use a for loop. For example:
for(int i = 1; i <= num; ++i)
/* this is the same as for(int i = 0; i < num; ++i) */
{
blink();
}

I do not know where you took this syntax from, but it will not call the function twice. It will multiply the function return value by two.
int blink(void)
{
return 5;
}
int main(void)
{
int result;
result = 2 * blink();
printf("%d\n", result);
}
https://godbolt.org/z/4nrGj3M6W
if blink has void return type it will simple not compile.
Another way of multiple calling function using function pointer:
void blink(void)
{
printf("BLIMK!!!\n");
}
void callMultiple(void (*func)(void), size_t ntimes)
{
while(ntimes--) func();
}
int main(void)
{
size_t times;
if(scanf("%zu", &times) == 1)
{
callMultiple(blink, times);
}
}
https://godbolt.org/z/jWEd9hnK9

Related

How should I call other function's value to another function's condition statement?

I am trying to create two functions and put them outside the main{ }.
The question requires the user to enter a number that should be end_size > start_size > 9.
And if not just prompt it again.
I have two questions.
Here is the first problem, in function int get_start_size, the function should be stored the value in int start_size. Then, why I cannot call it from another function int get_end_size?
#include <cs50.h>
#include <stdio.h>
int get_start_size(void);
int get_end_size(void);
int main(void)
{
int i = get_start_size();
printf("%i\n", i);
int j = get_end_size();
printf("%i\n", j);
}
int get_start_size(void)
{
int start_size;
do
{
start_size = get_int("Start size is:");
}
while (start_size < 9);
return start_size;
}
int get_end_size(void)
{
int end_size;
do
{
end_size = get_int("End size is:");
}
while (end_size < start_size); //<<<<<<<<<<<<<this is the alert I got, use of undeclared identifier 'start_size'.
return end_size;
}
And the second problem is if I change it like this:
int get_end_size(void)
{
int end_size;
int k = get_start_size(); //<<<<<<<<<<<<< Should I call function like this?
do
{
end_size = get_int("End size is:");
}
while (end_size < k); //this is the problem I got, how to use value "int s" from other function "int get_start_size(void)"?
return end_size;
}
The result will be like this:
~/lab/ $ ./population
Start size is:10
10
Start size is:10 //duplicated prompt
End size is:22
22
~/lab/ $
The result quite meet my goal, but I think I called the function in the wrong way because it asks the user to enter two times the start size. How should I do it instead? Thanks.
Local Variables
Variables that are declared inside a function or block are called
local variables. They can be used only by statements that are inside
that function or block of code. Local variables are not known to
functions outside their own.
start_size is not visible inside get_end_size(), to make it visible, pass the value as a parameter to the function:
The prototype should be:
int get_end_size(int start_size);
For your second snippet, I understand that you want to return 2 values from the function, you can achieve that using a struct:
struct size
{
int start, end;
};
struct size get_size(void)
{
struct size size = {0, 0};
size.start = get_start_size();
do
{
size.end = get_int("End size is:");
}
while (size.end < size.start);
return size;
}
Or you can use pointers:
void get_size(int *start, int *end)
{
*start = get_start_size();
do
{
*end = get_int("End size is:");
}
while (*end < *start);
}
call it from main using:
int start, end;
get_size(&start, &end);
Or you can pass an array:
enum {START, END};
void get_size(int size[])
{
size[START] = get_start_size();
do
{
size[END] = get_int("End size is:");
}
while (size[END] < size[START]);
}
In this case, main should look like:
int size[2];
get_size(size);

I am trying to pass 2 sums from a subroutine back to the main function in C

I am currently trying to take a sum from two different subroutine and pass it back to the main function, but every time I do this, it just comes up with a zero value and I am unsure why. I have tried putting my print statements in the main function and just doing calculations in the subroutines and that still didn't work, so I know that my variables aren't returning right and my sum is an actual number. How do I pass my variable sum back to my main function correctly?
Here is my code:
#include<stdio.h>
int X[2000];
int Y[2000];
int main()
{
FILE*fpdata1= NULL;
FILE*fpdata2 = NULL;
fpdata1=fopen("DataSet1.txt","r");
fpdata2=fopen("DataSet2.txt","r");
if(fpdata1==NULL || fpdata2 == NULL)
{
printf("file couldn't be found");
}
int i=0;
while(i<2000)
{
fscanf(fpdata1,"%d!",&X[i]);
fscanf(fpdata2,"%d!",&Y[i]);
// printf("This is X: %d\n",X[i]);
// printf("This is Y: %d\n",Y[i]);
i++;
}
fclose(fpdata1);
fclose(fpdata2);
avgX(X);
avgY(Y);
float sum;
float sumY;
float totalsum;
float totalavg;
totalsum= sum + sumY;
totalavg= totalsum/4000;
printf("Sum X: %f\n\n",sum);
printf("Total sum: %f\n\n",totalsum);
printf("The total average is: %0.3f\n\n",totalavg);
return 0;
}
int avgX(int X[])
{
int i=0;
float averageX;
float sum;
sum = 0;
while (i<2000)
{
sum += X[i];
i++;
}
averageX = sum/2000;
printf("Sum of X: %f\n\n",sum);
printf("The sum of Data Set 1 is: %0.3f\n\n",averageX);
return(sum);
}
int avgY(int Y[])
{
int i=0;
float averageY;
float sumY;
sumY = 0;
while (i<2000)
{
sumY += Y[i];
i++;
}
averageY = sumY/2000;
printf("Sum of Y: %f\n\n",sumY);
printf("The sum of Data Set 2 is: %0.3f\n\n",averageY);
return (sumY);
}
Firstly, it would appear you are expecting the lines
avgX(X);
avgY(Y);
to somehow update the sum and sumY variables in the main function. This is a fundamental misunderstanding of how memory is accessed.
Local variable declarations with the same identifier are not shared between functions. They can be accessed only from within the function in which they are declared (and only for the duration of the function call).
In this example, the apples variables in each of the functions have absolutely no correlation to one another. Expecting this program to print 15 is wrong. This program has undefined behavior because foo and bar read values from uninitialized variables.
void foo(void) {
int apples;
/* This is undefined behaviour,
* as apples was never initialized. Do not do this. */
apples += 5;
}
void bar(void) {
int apples;
/* This is undefined behaviour,
* as apples was never initialized. Do not do this. */
printf("%d\n", apples);
}
int main(void) {
int apples = 10;
foo();
bar();
return 0;
}
Instead of this, you'll want to utilize the arguments and return values of your functions. In this example, in main we pass the value of apples as an argument to foo, which adds 5 to this value and returns the result. We assign this return value, overwriting our previous value.
int foo(int val) {
return value + 5;
}
void bar(int val) {
printf("%d\n", val);
}
int main(void) {
int apples = 10;
apples = foo(apples);
bar(apples);
return 0;
}
Again note that the val parameters do not refer some "shared variable", they are local to both foo and bar individually.
As for the specifics of your program:
The functions avgX and avgY do the exact same thing, just with different identifiers.
It would be better to write a more generic summation function with an additional length parameter so that you are not hard-coding data sizes everywhere.
int sum_ints(int *values, size_t length) {
int result = 0;
for (size_t i = 0; i < length; i++)
result += values[i];
return result;
}
You can then easily write averaging logic utilizing this function.
You do check that your file pointers are not invalid, which is good, but you don't halt the program or otherwise remedy the issue.
It is potentially naive to assume a file will always contain exactly 2000 entries. You can use the return value of fscanf, which is the number of conversions that took place, to test if you've failed to read data. Its also used to signify errors.
Though the fact that global variables are zeroed-out saves you from potentially operating on unpopulated data (in the event the files contain less than 2000 entries), it would be best to avoid global variables when there is an alternative option.
It might be better to separate the reading of files to its own function, so that failures can be handled per-file, and reading limits can be untethered.
int main(void) or int main(int argc, char **argv) are the correct, valid signatures for main.
With all that said, here is a substantially refactored version of your code. Note that an implicit conversion takes place when we assign the integer return value of sum_ints to our floating point variables.
#include <stdio.h>
#include <stdlib.h>
#define DATA_SIZE 2000
int sum_ints(int *values, size_t length) {
int result = 0;
for (size_t i = 0; i < length; i++)
result += values[i];
return result;
}
size_t read_int_file(int *dest, size_t sz, const char *fname) {
FILE *file;
size_t i;
if ((file = fopen(fname, "r")) == NULL) {
fprintf(stderr, "Critical: Failed to open file: %s\n", fname);
exit(EXIT_FAILURE);
}
for (i = 0; i < sz; i++)
if (fscanf(file, "%d!", dest + i) != 1)
break;
fclose(file);
return i;
}
int main(void) {
int data_x[DATA_SIZE] = { 0 },
data_y[DATA_SIZE] = { 0 };
size_t data_x_len = read_int_file(data_x, DATA_SIZE, "DataSet1.txt");
size_t data_y_len = read_int_file(data_y, DATA_SIZE, "DataSet2.txt");
float sum_x = sum_ints(data_x, data_x_len),
sum_y = sum_ints(data_y, data_y_len);
float total_sum = sum_x + sum_y;
float total_average = total_sum / (data_x_len + data_y_len);
printf("Sums: [X = %.2f] [Y = %.2f] [Total = %.2f]\n"
"The total average is: %0.3f\n",
sum_x, sum_y, total_sum,
total_average);
}

Is this the right way to pass an array back from the function to main

The program is running without errors, but it stops after it runs this function since it seems that the array is not being passed back. Is this the right way to pass the array back to the function? I've included only the essential code below. Please could you point out where I might be wrong.
int matchedNumbersfunc(int lotoNumbers[],int ticketNumbers[], int *numbersRight);
int main()
{
int lotoNumbers[7];
int ticketNumbers[7];
int matchedNumbers[7];
int numbersRight = 0;
matchedNumbers[7] = matchedNumbersfunc(ticketNumbers, lotoNumbers, &numbersRight);
return 0;
}
int matchedNumbersfunc(int lotoNumbers[],int ticketNumbers[], int *numbersRight)
{
int matchedNumbers[7];
int i, k ,j;
*numbersRight = 0;
for(k=0;k<7;k++)
{
matchedNumbers[k] = 0;
}
for(i=0;i<7;i++)
{
for(j=0;j<7;j++)
{
if(ticketNumbers[i] == lotoNumbers[j])
{
matchedNumbers[i] = ticketNumbers[i];
}
}
if(matchedNumbers[i] != 0)
{
printf("You have a winning number: %d\n", matchedNumbers[i]);
*numbersRight = *numbersRight + 1;
if(matchedNumbers[6] != 0)
{
*numbersRight = *numbersRight - 1;
}
}
}
return matchedNumbers[7];
}
So, you are returning a single value rather than an array. And as it happens, you are returning a value off the end of the array, and assigning to a value off the end of another array. Your arrays have 7 elements, indexed 0 to 6.
What you need to do is pass an array to the function and let the function populate it. A simple example:
void foo(int array[], size_t count)
{
for (size_t i = 0; i < count; i++)
array[i] = i;
}
Which you would call like this:
int myArray[7];
foo(myArray, 7);
Another solution is to allocate a new array dynamically in your function and return a pointer to that array with this prototype:
int* matchedNumbersfunc(int lotoNumbers[],int ticketNumbers[], int *numbersRight);
Your revised function would start like this:
int* matchedNumbers;
int i, k ,j;
*numbersRight = 0;
matchedNumbers = (int*) calloc (7, sizeof(int));
if (matchedNumbers==NULL)
return NULL;
for(k=0;k<7;k++)
...
return (matchedNumbers);
In the main() you do not need to allocate the table, but just a pointer:
...
int *matchedNumbers;
...
matchedNumbers = matchedNumbersfunc(...);
if (matchedNumbers==NULL)
{ /* not enough memory - some kind of error processing */ }
free (matchedNumbers); // once you don't need the result anymore
return 0;
For your simple programme dynamic allocation could be overkill. But for more complex processing, this approach could be useful as well.

Passing array into function in c

I'm getting gcc errors when I compile my code. The errors are about "passing argument 1 of ‘print_path’ makes pointer from integer without a cast".
Here is my function prototype:
void print_path(int previous[], int desired_node_index);
Here is my function:
void print_path(int previous[], int desired_node_index)
{
if( previous[desired_node_index] != -1 )
print_path( previous[desired_node_index] );
printf("-> %d ", previous[desired_node_index]);
}
and here is where I call my function:
print_path(previous, dest_index);
I'm obviously passing it in wrong, or else I'm doing something incorrectly about how to pass an array into a function. Any help?
Thanks guys!
This is obviously a recursive function. Note that print_path() takes 2 parameters: the first is an int array, and the second is an index to a position inside that array.
Calling it:
print_path( previous[desired_node_index] );
is absolutely wrong (unless you have overloaded this function), because it expects 2 parameters and you are only passing it one. What you should be doing is:
print_path( previous, desired_node_index );
What you seem to be missing in this function is an operation to increase/decrease the index variable, else you will always be printing the same position in the array.
Without knowing what is exactly that you are trying to do, there's the possibility that you wanted to do this:
print_path( previous, previous[desired_node_index] );
An obvious error is:
print_path( previous[desired_node_index] );
I'm not sure what you're trying to do, but I guess you want something like:
#include <stdio.h>
void print_path(int *previous, int desired_node_index);
int main(void) {
int dest_index = 2;
int previous[5] = { -1, 0, 1, 2, 3};
print_path(previous, dest_index);
return 0;
}
void print_path(int *previous, int desired_node_index) {
if( previous[desired_node_index] != -1 )
print_path( previous, previous[desired_node_index]);
printf("-> %d ", previous[desired_node_index]);
}
void receive_array(int *temp_arr)
{
int i=0;
do
{
temp_arr[i]=temp_arr[i]+1;
i++;
}
while((char)temp_arr[i]!='\0');
}
here I have made some modifications. The array temp_arr2[] is a buffer array. In my actual program, I printed the array from the main(). Here, for doing the same thing, one need to store back the end result of some computation into temp_arr[].MAX can be a macro or a global variable. In the previous one, I just forgot to edit the lines: temp_arr[i]=temp_arr[i]+1; (my demo sample code) :)
void receive_array(int *temp_arr)
{
int i=0;
int temp_arr2[MAX];
do
{
temp_arr2[i]=temp_arr[i];
i++;
}
while((char)temp_arr[i]!='\0');
}
If you want to pass array to function and return after changing the elements from the function you can see the following example:
You may find the solution at: https://github.com/krishnabhat81/Send-and-return-array-from-function-in-C
#include <stdio.h>
/*
If you want to return a single-dimension array from a function, you would have to
declare a function returning a pointer as in the following example:
*/
int *getRandom(int arr[])
{
static int r[10];
/*Second point to remember is that C does not advocate to return the address of a
local variable to outside of the function so you would have to define the
local variable as static variable.*/
int i;
for ( i = 0; i < 10; ++i)
{
r[i] = arr[i]+1;//rand();
printf( "r[%d] = %d\n", i, r[i]);
}
return r;
}
/* main function to call above defined function */
int main ()
{
/* a pointer to an int */
int *p;
int i;
int arris[10] = {110,22,33,44,5,6,7,8,9,20};
p = getRandom(arris);
for ( i = 0; i < 10; i++ )
{
printf( "*(p + %d) : %d\n", i, *(p + i));
}
return 0;
}
return 0;
}

C Recursion program won't compile w/ GCC

#include <stdio.h>
int main (void)
{
int n, x;
int factorial (int n)
{
if (x<=0)
{
printf("x equals: ");
return 1;
}
else
{
return n * factorial (n-1);
}
f(x)=f(x-1)+2; //says error is here
}
return 0;
}
I've tried some things and can't get it to work. I could just be overtired and looking past the smallest thing but help would be much appreciated! Thanks :)
You cannot declare a function definition inside of main() or any other function ... function definitions have to be stand-alone and cannot have embedded function definitions inside of them.
Also I'm not sure what you're doing on the line that you've marked as an error since f() is not a defined function, so you can't call it. Furthermore, it would need to return some type of l-value, such as a pointer to a static variable declared inside the function, or a pointer passed by reference to the function and even then the syntax is not right since there would be a required dereference ... so basically you can't do what you're doing on that line.
To get something that compiles, try
#include <stdio.h>
int factorial (int n)
{
if (n <= 0)
{
return 1;
}
else
{
return n * factorial (n-1);
}
}
int main (void)
{
int x;
x = factorial(5);
printf("Factorial of 5 is equal to %d", x);
return 0;
}
Use indentation to see possible problems with scope:
#include <stdio.h>
int main (void)
{
int n, x;
int factorial (int n)
{
if (x<=0)
{
printf("x equals: ");
return 1;
}
else
{
return n * factorial (n-1);
}
f(x)=f(x-1)+2; //says error is here
}
return 0;
}
As far as I can remember, C doesn't have closures.
A function cannot be defined inside another function. However gcc allows it as an extension. You have defined a function named factorial but are trying to use f which hasn't been declared anywhere.

Resources