Call by Reference Function - c

I would just like a push in the right direction here with my homework assignment. Here is the question:
(1) Write a C function called input which returns void, this
function prompts the user for input of
two integers followed by a double
precision value. This function reads
these values from the keyboard and
finds the product of the two integers
entered. The function uses call by
reference to communicate the values of
the three values read and the product
calculated back to the main program.
The main program then prints the
three values read and the product
calculated. Provide test results for
the input: 3 5 23.5. Do not use arrays
or global variables in your program.
And here is my code:
#include <stdio.h>
#include <stdlib.h>
void input(int *day, int *month, double *k, double *pro);
int main(void){
int i,j;
double k, pro;
input(&i, &j, &k, &pro);
printf("%f\n", pro);
return 0;
}
void input(int *i, int *j, double *k, double *pro){
int x,y;
double z;
double product;
scanf("%d", &x);
scanf("%d", &y);
scanf("%f", &z);
*pro += (x * y * z);
}
I can't figure out how to reference the variables with pointers really, it is just not working out for me.
Any help would be great!

You adding to pro but that is not initialized, you are not passing values back apart from pro. You store values into the addresses of variables passed in. In that case you need to dereference pointers to access/retrieve value, *i, and in your method use the passed addresses directly - then you don't need to take address of them again.
This works - I replaced double with float ... :
#include <stdio.h>
#include <stdlib.h>
void input(int *day, int *month, float *k, float *pro);
int main(void){
int i,j;
float k, pro;
i = j = k = pro = 0;
input(&i, &j, &k, &pro);
printf("%f\n", pro);
printf("%d : %d : %f\n", i,j,k);
return 0;
}
void input(int *i, int *j, float *k, float *pro){
scanf("%d", i);
scanf("%d", j);
scanf("%f", k);
printf("%d - %d - %f\n", *i,*j,*k);
*pro += (*i * *j * *k);
}
Output:
1
2
3.5
1 - 2 - 3.500000
7.000000
1 : 2 : 3.500000

You're almost there, but instead of making new variables x, y, and z, use the pointers you passed:
scanf("%d", i);
scanf("%d", j);
scanf("%f", k);
*pro += ((*i) * (*j) * (*k));

When reading the numbers in the input function you can make use of the pointers iptr, jptr, kptr and proptr to read the values directly into variables i,j and k declared in the main function as:
void input(int *iptr, int *jptr, double *kptr, double *proptr){
scanf("%d", iptr); // read directly into i using pointer to i.
scanf("%d", jptr);
scanf("%f", kptr);
*proptr = ( (*iptr) * (*jptr) ); // compute product and assign to pro.
}

*pro += (x * y * z);
This is going to break horribly. You're adding the product to whatever garbage happens to be in pro beforehand. You want to remove the +, i.e.:
*pro = (x * y * z);

What your program is not doing is setting the values of the input to i, j, and k.
Instead of using x,y and z, use the parameters instead.

Related

Not able to find my segmentation fault in this code of t-test

I have written this program for t-test. I'll add other functions as well, but first, I need to find my error. Here's my code
# include <stdio.h>
# include <math.h>
float mean(float x[], int size)
{
float sum = 0.0;
for (int i=0; i<size;i++)
sum += x[i];
return sum/size;
}
float sumsq(float x[], int size)
{
float sum = 0.0;
for (int i=0; i<size;i++)
sum += pow(x[i]-mean(x,size),2);
return sum;
}
int input(n)
{
float x[n];
printf("Enter the values one by one");
for (int i = 0; i<n;i++)
scanf("%f", &x[i]);
return x;
}
void t_check(float x)// Make sure to write this function before each of the t-tests. That is because it is of void type. If the t-test is done before the checking function is declared, then it assumes it's datatype to be "int", and we get an error. So either write the t-check function before those functions, or just define it at the beginning of the program
{
float t_tab;
printf("Enter the tabulated value of t");
scanf("%f",&t_tab);
if (x<t_tab)
printf("We do not have enough evidence to reject the null hypothesis");
else
printf("Reject the null hypothesis");
}
float t_diff_of_means()
{
float x=0.0,y=0.0,s1=0.0,s2=0.0,S=0.0,t=0.0,tcal;
int n,m,a,b;
printf("Enter the number of variables in population 1");
scanf("%d", &n);
a = input(n);
printf("Enter the number of variables in population 2");
scanf("%d", &m);
b = input(m);
x = mean(a,n);
y = mean(b,m);
s1 = sumsq(a, n);
s2 = sumsq(b, m);
S = sqrt((s1+s2)/(n+m-2));
t = (x-y)/(S*sqrt(1.0/n+1.0/m));
t_check(t);
}
int main(void)
{
t_diff_of_means();
return 0;
}
It gives segmentation fault as an error. I'm not able to understand where my code uses any memory uses a part of memory that is not allocated to it
The main issue is you expect input() to read an array floats but you return an int. You should declare the type of the argument n. You cannot return an address to a local variable as it out of scope for caller. The easiest option is to the declare the array variable in main() then pass it to input to populate (pun). (not fixed) Check that return value of scanf() otherwise the variable you expect to be initialized may not be.
t_diff_of_means() is declared to return a float but nothing is returned. Not sure what you want to return so I changed the return type to void.
Tweaked various prompts to make it more them more readable.
#include <stdio.h>
#include <math.h>
float mean(float x[], int size)
{
float sum = 0.0;
for (int i=0; i<size;i++)
sum += x[i];
return sum/size;
}
float sumsq(float x[], int size)
{
float sum = 0.0;
for (int i=0; i<size;i++)
sum += pow(x[i]-mean(x,size),2);
return sum;
}
void input(size_t n, float a[n])
{
printf("Enter the values one by one: ");
for (int i = 0; i<n;i++)
scanf("%f", a+i);
}
void t_check(float x)
{
float t_tab;
printf("Enter the tabulated value of t: ");
scanf("%f",&t_tab);
if (x<t_tab)
printf("We do not have enough evidence to reject the null hypothesis\n");
else
printf("Reject the null hypothesis\n");
}
void t_diff_of_means()
{
float x=0.0,y=0.0,s1=0.0,s2=0.0,S=0.0,t=0.0;
int n,m;
printf("Enter the number of variables in population 1: ");
scanf("%d", &n);
float a[n];
input(n, a);
printf("Enter the number of variables in population 2: ");
scanf("%d", &m);
float b[m];
input(m, b);
x = mean(a,n);
y = mean(b,m);
s1 = sumsq(a, n);
s2 = sumsq(b, m);
S = sqrt((s1+s2)/(n+m-2));
t = (x-y)/(S*sqrt(1.0/n+1.0/m));
t_check(t);
}
int main(void)
{
t_diff_of_means();
return 0;
}
and example run:
Enter the number of variables in population 1: 2
Enter the values one by one: 1
2
Enter the number of variables in population 2: 2
Enter the values one by one: 2
3
Enter the tabulated value of t: 0.05
We do not have enough evidence to reject the null hypothesis
Consider eliminating the variables you only use once (x, y, s1, s2, S, t and t_cal):
t_check(
(mean(a, n) - mean(b, m)) / (sqrt((sumsq(a, n)+sumsq(b, m))/(n+m-2))*sqrt(1.0/n+1.0/m))
);
then I observed that this only depends on variables a, n, b and m so push that calculation into t_check():
void t_check(size_t a_len, float a[a_len], size_t b_len, float b[b_len]) {
float t = (mean(a, a_len) - mean(b, b_len)) / (sqrt((sumsq(a, a_len)+sumsq(b, b_len))/(a_len+b_len-2))*sqrt(1.0/a_len+1.0/b_len));
// ...
}
Then I changed the length types to size_t and used the clearer variable names in t_diff_of_means():
void t_diff_of_means()
{
printf("Enter the number of variables in population 1: ");
size_t a_len;
scanf("%zu", &a_len);
float a[a_len];
input(a_len, a);
printf("Enter the number of variables in population 2: ");
size_t b_len;
scanf("%zu", &b_len);
float b[b_len];
input(b_len, b);
t_check(a_len, a, b_len, b);
}
We could take this another step by observing the two first sections in t_diff_of_means() are very similar, so we could have input() take a prompt and a pointer to an array of floats along with elements read. input() would then need to dynamically allocate the array of floats. This means most of our functions take a array of float and length argument. Let's create a type for that and refactor our functions to use it:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
struct array {
size_t len;
float *data;
};
float mean(struct array *a)
{
float sum = 0;
for (int i=0; i<a->len;i++)
sum += a->data[i];
return sum/a->len;
}
float sumsq(struct array *a)
{
float sum = 0;
for (int i=0; i<a->len;i++)
sum += pow(a->data[i] - mean(a), 2);
return sum;
}
void input(int prompt, struct array *a)
{
printf("Enter the number of variables in population %d: ", prompt);
scanf("%zu", &a->len);
a->data = malloc(a->len * sizeof(a->data[0]));
//if(!a->data) ...
printf("Enter the values one by one: ");
for (int i = 0; i<a->len;i++)
scanf("%f", &a->data[i]);
}
void t_check(struct array a[2])
{
float t = (mean(a) - mean(a+1)) / (
sqrt(
(sumsq(a) + sumsq(a+1)) / (a[0].len + a[1].len-2)
) * sqrt(1.0/a[0].len + 1.0/a[1].len)
);
printf("Enter the tabulated value of t: ");
float t_tab;
scanf("%f",&t_tab);
if (t<t_tab)
printf("We do not have enough evidence to reject the null hypothesis\n");
else
printf("Reject the null hypothesis\n");
}
int main(void)
{
struct array a[2];
input(1, a);
input(2, a+1);
t_check(a);
}
This would be a good base to add additional functions to.

C - Why do I keep printing out the Memory Address instead of the value in the array

I am having trouble printing out the values stored in the array. It seems to be printing out the memory address instead. Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void getMatrix(int x, int y);
void printMatrix(int arr[], int x, int y);
int product(int arr1[], int arr2[]);
int main(void){
//Variables that will store matrix size
int m, n, o, p;
//Prompt user for size of Matrix A
printf("Enter the rows and columns of Matrix A with space in between: ");
//Read input
scanf("%d %d", &m, &n);
//Prompt user for the size of Matrix B
printf("Enter the rows and columns of Matrix B with space in between: ");
//Read input
scanf("%d %d", &o, &p);
//Seed RND Generator
srand(time(NULL));
//Check input
if(n != o){
while(n != o){
printf("Matrix Sizes are not valid. Please enter valid sizes for the Matrices: ");
scanf("%d %d %d %d", &m, &n, &o, &p);
}
}
//Function Calls
printf("Matrix 1:\n");
getMatrix(m, n);
printf("\nMatrix 2:\n");
getMatrix(o, p);
}
void getMatrix(int x, int y){
//Counter
int c;
//Size Declaration
int size = x * y;
//Array Declaration
int arr[size];
for(c = 0; c < size; c++){
arr[c] = rand()%10;
}
printMatrix(arr[size], x, y);
}
void printMatrix(int arr[], int x, int y){
//Counters
int i, j;
for(i = 0; i < y; i++){
printf("\n");
for(j = 0; j < x; j++){
printf("%d ", arr[j]);
}
}
}
So basically this code is supposed to take in input and create a variable length array and its supposed to store random numbers in a 1 dimensional array and then they have to be printed out in the form of a 2d array or a matrix. I feel there might be something wrong with the parameters of the printMatrix function or when passing the array obtained in the getMatrix function. Any help would be appreciated, thank you.
EDIT: Thank you all for the help. I didn't even think about using this as a solution. But it works now and prints out the numbers that it is supposed to. Thanks again
This declaration
int arr[size];
says that arr is an array of size ints. Thus,
printMatrix( arr[size], x, y );
passes the value that happens to be where the first int just outside arr would be for the first argument, which the function interprets to be the address of the array to be printed.
Also, note that printMatrix keeps printing the first row again and again, as opposed to each successive row.
I believe the problem lies with this line of code:
printMatrix(arr[size], x, y);
It should be
printMatrix(arr, x, y);
The printMatrix function expects an array, but in your code you pass an element from the array.
What you are doing in the following line:
printMatrix(arr[size], x, y);
Is invoking undefined behavior. Since you have declared your array to be arr[size], the counter of your array must range from 0 to size - 1.
When you are trying to pass arr[size], rather than passing the whole array (which, judging form the program, is what you want it to do), you pass arr at element size, which is one index out of bounds.
Going into a bit more technical explaination of why this happens, the memory space that is right after the block allocated for arr must be empty, so you don't get segmentation fault, and instead, you get the address of that out-of-bound element. However, if it was filled up, then that would have caused a segmentation fault, and would have resulted in a runtime error.
To pass arr, you need to remove the index specifier:
printMatrix(arr, x, y);

How to return a value with void function without parameter in c

I'm new to C language and coding and I encountered a question asking me to change the function header of:
float RealRoot_1(float a, float b, float c);
float RealRoot_2(float a,float b,float c);
to become:
void RealRoot_1(void);
void RealRoot_2(void);
I was told that it has something to do with Global Variables but I still couldn't figure it out after trying quite some time. Can anyone please explain on how to do it? Thanks a lot.
The source file is as below:
#include<stdio.h>
#include<math.h>
int main()
{
float RealRoot_1(float a, float b, float c); // Prototype declaration
float RealRoot_2(float a, float b, float c);
// Defining Input Variables
float x, y, z;
// Defining Output Variables
float Root_1, Root_2;
printf("Please enter the factor of X^2: ");
scanf("%f",&x);
printf("Please enter the factor of X: ");
scanf("%f",&y);
printf("Please enter the free factor: ");
scanf("%f",&z);
Root_1 = RealRoot_1(x,y,z);
Root_2 = RealRoot_2(x,y,z);
printf("the First Root is: %f \n", Root_1);
printf("the Second Root is: %f \n", Root_2);
system("pause");
}
float RealRoot_1(float a, float b, float c)
{
float x;
x = (-1*b + sqrt(pow(b,2) - 4 * a * c)) / (2 * a);
return x;
}
float RealRoot_2(float a, float b, float c)
{
float x;
x = (-1*b - sqrt(pow(b,2) - 4 * a * c)) / (2 * a);
return x;
}
This can be done by using global variables. You need to ensure that the variable names used in the function are the same as the ones used in the main code.
#include<stdio.h>
#include<math.h>
void RealRoot_1(void); // Prototype declaration
void RealRoot_2(void);
float x, y, z;
float Root_1, Root_2;
int main()
{
// Defining Output Variables
printf("Please enter the factor of X^2: ");
scanf("%f",&x);
printf("Please enter the factor of X: ");
scanf("%f",&y);
printf("Please enter the free factor: ");
scanf("%f",&z);
RealRoot_1();
RealRoot_2();
printf("the First Root is: %f \n", Root_1);
printf("the Second Root is: %f \n", Root_2);
system("pause");
}
void RealRoot_1(void)
{
Root_1 = (-1*y + sqrt(pow(y,2) - 4 * x * z)) / (2 * x);
}
void RealRoot_2(void)
{
Root_2 = (-1*y - sqrt(pow(y,2) - 4 * x * z)) / (2 * x);
}
Please note that this is a worse way of doing things than was given in the initial problem. In the initial exercise. You are loosing modularity and using too many globals is in general a bad idea.
You can also see Are global variables bad?
This should be self explanatory:
float RR_a, RR_b, RR_c;
float RR_d; // store result here(like a return value)
void RealRoot_1(void); // prototypes
void RealRoot_2(void);
void main(void)
{
printf("Please enter the factor of X^2: ");
scanf("%f",&RR_a);
printf("Please enter the factor of X: ");
scanf("%f",&RR_b);
printf("Please enter the free factor: ");
scanf("%f",&RR_c);
RealRoot_1();
printf("the First Root is: %f \n", RR_d);
RealRoot_2();
printf("the Second Root is: %f \n", RR_d);
system("pause");
}
void RealRoot_1(void)
{
float x;
x = (-1*RR_b + sqrt(pow(RR_b,2) - 4 * RR_a * RR_c)) / (2 * RR_a);
RR_d = x;
}
void RealRoot_2(void)
{
float x;
x = (-1*RR_b - sqrt(pow(RR_b,2) - 4 * RR_a * RR_c)) / (2 * RR_a);
RR_d = x;
}
Notice that after calling RealRoot_1 we now print the result before calling RealRoot_2. That's because the result of RealRoot_1 which is stored in RR_d is overwritten by RealRoot_2, thus it is lost.
You can circumvent this by declaring a second return variable, RR_d_2 and storing the result of RealRoot_2 in it.
We do not need duplicates for RR_a, RR_b or RR_c because their values are not modified within the functions.
This way of writing functions has limitations, which will be obvious when faced with recursion or multi-threading.

How to call a void function in C

Ok so I have written this code with four different functions, and the main purpose of it is to display in a table from angles 0-90 what the angle, time, distance of a velocity is. the velocity is inputed from the user.
But when I call the void function that is making the function I get an error "undefined reference to `create_table'" Here is my code.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define G 9.8 /* gravitation acceleration 9.8 m/s^2 */
#define PI 3.141592654
void create_table(double v);
double Projectile_travel_time(double a, double v);
double Projectile_travel_distance(double a, double v);
double degree_to_radian(double d);
int main(void)
{
int n;
double velocity;
printf ("please enter the velocity at which the projectile is launched (m/sec): ");
n = scanf("%lf" ,&velocity);
if(n != 1)
{
printf("Invlid input. Bye...");
exit(1);
}
while (velocity < 0 )
{
printf ("please enter a positive number for velocity: ");
n = scanf("%lf", &velocity);
if(n != 1)
{
printf("Invlid input. Bye...");
exit(1);
}
}
create_table(velocity);
return 0;
}
void create_table(double v)
{
printf("Angle t d\n");
printf("(deg) (sec) (m)\n");
double a,i;
for( a=0; a<=90; a+=5)
{
for(i=0; i<=2; i++)
{
double t = Projectile_travel_time(a, v);
double s = Projectile_travel_distance(a, v);
printf("%d %d %d\n", a, t, s);
}
}
}
double Projectile_travel_time(double a, double v)
{
double t = ((2*v*sin(degree_to_radian(a)))/(G));
return t;
}
double Projectile_travel_distance(double a, double v)
{
double d = ((v*v)/G)*sin(2*degree_to_radian(a));
return d;
}
double degree_to_radian(double d)
{
double r = d*atan(1) * 4 / 180;
return r;
}
any help would be appreciated.
thanks
edit I have edited the code but now have encountered another problem with my outputs being completely off. Any suggestions how my functions are incorrect?
You must keep the functions you create outside of the main function
Try to implement your functions outside the main()
You need to move the function definitions out of main. C does not support nested functions.
Edit: That is, in GCC they are, but it's not portable.
I have edited the code but now have encountered another problem with my outputs being completely off.
Change
printf("%d %d %d\n", a, t, s);
to
printf("%lf %lf %lf\n", a, t, s);
You can use %7.3f to align all the values.
Write all the function definitions create_table, Projectile_travel_time, Projectile_travel_distance and degree_to_radian outside the main.
Linker is not able to find the definition of create_table at the point at which you are calling create_table.

confliction type for a user defined function in c

I am working in c after a long time.Here i have to achieve three functionality which includes
get a number and show half
2.Get the square of the number
3.Get two number and show their summation and sabtraction.
I am using devC++ and when i compile the code i get the error i mentioned in the title which conflict type if squareInput.What is wrong here:
#include<stdio.h>
#include<conio.h>
int main(){
float x;
printf("enter a number\n");
scanf("%f",&x);
//TASK 1 : display half of the number
pirntf("half of x is = %.3f",x);
//TASK 2 : square of number
squareInput(x); //call square function from here
// TASK 3 : get two numbers and display both summation and sabtraction
float num1,num2; // declare two floating number( floating numbers can hold decimal point numbers
printf("enter num1 \n");
scanf("num1 is =%f",&num1);
printf("enter num2 \n");
scanf("num2 is =%f",num2);
calculate(num1,num2);// call calculate function
getch();
}
float squareInput(float input){
float square=input*input;
printf("\n square of the number is %.3f \n",square);
return 0;
}
float calculate(float num1,float num2){
//summation
float summation= num1+num2; // declare antoher variable called summation to hold the sum
//sabtraction
float sabtraction=num1-num2;
printf("summation is %.2f \n",summation);
printf("sabtraction is %.2f \n",sabtraction);
return 0;
}
Things will go wrong without prototypes. Add
float squareInput(float input);
float calculate(float num1,float num2);
in front of int main().
If you don't declare a function before it's called, the compiler assumes it as a int-returning function. However, squareInput() return float, so the compiler(or linker, maybe) complains to you.
Also note that definitions are declarations(but not vice versa, obviously), so moving the definitions of squareInput() and calculate() in front of where they are called works too.
At the time you call squareInput and calculate, they haven't been defined yet. So C assumes an implicit declaration of int squareInput() and int calculate(). These implicit declarations conflict with the definitions of these functions.
You can fix this by either adding declarations for each of these functions before main:
float squareInput(float input);
float calculate(float num1,float num2);
Or by simply moving the functions in their entirety before main.
Be sure to add prototypes when you use a function. That way you do not need to worry too much about the order in which you call them.
Also try to separate your problems into smaller bits if you can. A comment like TAKS1 shows you that you actually want a function with that name.
#include <stdio.h>
//prototypes
void AskUserForOneNumer(float * number, const char * question );
void TASK_1(float x);
void TASK_2(float x);
void TASK_3(float a, float b);
int main()
{
float x, a, b;
AskUserForOneNumer(&x, "enter x");
AskUserForOneNumer(&a, "enter a");
AskUserForOneNumer(&b, "enter b");
TASK_1(x);
TASK_2(x);
TASK_3(a, b);
}
void TASK_1(float x)
{
printf("x = %g\n", x);
printf("0.5 * x = %g\n", 0.5 * x);
}
void TASK_2(float x)
{
printf("x = %g\n", x);
printf("x * x = %g\n", x * x);
}
void TASK_3(float a, float b)
{
printf("a = %g\n", a);
printf("b = %g\n", b);
printf("a + b = %g\n", a + b);
printf("a - b = %g\n", a - b);
}
void AskUserForOneNumer(float * number, const char * question)
{
float x;
printf("%s\n", question);
scanf("%f", &x);
printf("your input was %g\n", x);
*number = x;
}

Resources