Function definition not allowed / [closed] - c

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
My professor gave us this code in class to show how a program works and said "go home and try it and you'll see it works".... well after 30 minutes I cannot get it to run. can someone please help me and point me in the right direction. Thank you!
-I get function definition on the end "double g(double x)"
-On the first else where x_left = x_mid control reaches end of non-void function
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#define FALSE 0
#define TRUE 1
#define NO_ROOT -99999.0
//function prototypes
double bisect(double, double, double, double f(double farg));
// evaluation of function
double g(double);
double h(double);
int main(void) {
double x_left, x_right, epsilon, root; //declare variables
// get endpoint and error tolerance
printf("\nEnter interval endpoints > ");
scanf("%lf%lf", &x_left, &x_right);
printf("\nEnter tolerance > ");
scanf("%lf", &epsilon);
//use bisect function to look for roots of functions
printf("\n\n For function g(x)");
root = bisect(x_left, x_right, epsilon, g);
if (root != NO_ROOT)
printf("\n g(%.7f) = %e\n", root, g(root));
printf("\n\n For function h(x)");
root = bisect(x_left, x_right, epsilon, h);
if (root != NO_ROOT)
printf("\n h(%.7f) = %e\n", root, h(root));
system("pause");
return (0);
}
// bisection method program coding
double bisect(double x_left, double x_right, double epsilon, double f(double farg)){
double x_mid, f_left, f_right, f_mid;
int root_found;
// computes function at initial end points
f_left = f(x_left);
f_right = f(x_right);
// if no change in sign
if (f_left * f_right > 0) {
printf("\nmay not be no root in [%.7f, %.7f]\n\n", x_left, x_right);
return NO_ROOT;
}
// searches as long as interval size is large enough
root_found = FALSE;
while (fabs(x_right - x_left) > epsilon && !root_found) {
// compute the mid point
x_mid = (x_left + x_right) / 2.0;
f_mid = f(x_mid);
if (f_mid == 0.0) {
root_found = TRUE;}
else if (f_left * f_mid < 0.0) {
x_right = x_mid;
} else {
x_left = x_mid;
}
// trace loop execution
if (root_found)
printf("\nRoot found at x = %.7f , midpoint of [%.7f, %.7f] ", x_mid, x_leftx_right);
else
printf("\nNew interval is [%.7f, %.7f] \n\n", x_left, x_right);
//if there is a root
return ((x_left + x_right)/2.0);
}
// functions for which roots are sought
double g(double x){
return (5 * pow(x, 3.0) - 2 * pow(x, 2.0) +3);
}
double h(double x){
return (pow(x, 4.0) - 3 * pow(x,2.0) - 8);
};
}

I get an error on this line:
printf("\nRoot found at x = %.7f , midpoint of [%.7f, %.7f] ", x_mid, x_leftx_right
saying that x_leftx_right is undeclared.
If I change this to x_left, x_right then it compiles OK except for "undefined reference to g" and "undefined reference to h".
The reason for the undefined reference to g is that you never provided a function definition for the function g that was prototyped by double g(double);. You did provide a nested function g within bisect. Nested functions are a non-standard extension, and bisect::g is a different function to g. Similarly for h.
To fix this, move the definitions of g and h to be after the end of the bisect function; instead of inside that function.
The reason for your "control reaches end of non-void function" warning is probably because there is no return statement after the while loop.
Your line return ((x_left + x_right)/2.0); line is within the loop begun by while (fabs(x_right - x_left) > epsilon && !root_found) {. If this loop finishes by the loop condition no longer being true, then the execution hits the end of the function without returning anything.
NB. If you indent your code properly so that you line up { then you are less likely to have this sort of problem. Your editor should have a key that you can use to find matching curly-braces. Also, operating your compiler in strict standard mode would have given an error about the use of nested function.
`

Related

Prevent Frama-C's slicing plugin from changing input code

Given a C file, I want to compute the backward slice for some criteria and compare the slice to the original code. Because I don't want to implement a slicing program from cratch, I've already tried to get used to Frama-C which seems to help with this task.
However, my problem is, that Frama-C's slicing plugin changes the preprocessed input code, so that it makes it harder to identify which lines of the original also appear in the slice.
Example:
Input file test1.c:
double func1(double param) {
return 2+param;
}
int main() {
int a=3;
double c=4.0;
double d=10.0;
if(a<c)
c=(double)a/4.0;
double res = func1(c);
return 0;
}
Preprocessed file (yielded by frama-c test1.c -print -ocode test1_norm.c):
/* Generated by Frama-C */
double func1(double param)
{
double __retres;
__retres = (double)2 + param;
return __retres;
}
int main(void)
{
int __retres;
int a;
double c;
double d;
double res;
a = 3;
c = 4.0;
d = 10.0;
if ((double)a < c) c = (double)a / 4.0;
res = func1(c);
__retres = 0;
return __retres;
}
Slice (yielded by frama-c -slice-calls func1 test1.c -then-on 'Slicing export' -print):
/* Generated by Frama-C */
double func1_slice_1(double param)
{
double __retres;
__retres = (double)2 + param;
return __retres;
}
void main(void)
{
int a;
double c;
double res;
a = 3;
c = 4.0;
c = (double)a / 4.0;
res = func1_slice_1(c);
return;
}
Note that the signature of main differs and that the name of func1 was changed to func1_slice_1.
Is there a way to suppress that behaviour in order to make the slice and the (preprocessed) original more easily comparable (in terms of a computable diff)?
First, to clarify a simpler question that you don't need answering but that someone searching for the same keywords could, you cannot have the sliced program printed as a selection of the lines of the original program (most of the differences between the two corresponds to lost information, basically. If the information was there, it would be used to print the most resembling program possible).
What you can do is print Frama-C's representation of the original program, which you are already doing with frama-c test2.c -print -ocode test2_norm.c.
To solve your problem of func1 being renamed to func1_slice_1, you can try playing with option -slicing-level 0:
$ frama-c -slicing-level 0 -slice-calls func1 test1.c -then-on 'Slicing export' -print
...
/* Generated by Frama-C */
double func1(double param)
{
double __retres;
__retres = (double)2 + param;
return __retres;
}
void main(void)
{
int a;
double c;
double res;
a = 3;
c = 4.0;
c = (double)a / 4.0;
res = func1(c);
return;
}
I think this will prevent the slicer from slicing inside func1 at all. The help says:
-slicing-level <n> set the default level of slicing used to propagate to the
calls
0 : don't slice the called functions
1 : don't slice the called functions but propagate the
marks anyway
2 : try to use existing slices, create at most one
3 : most precise slices

How to fix my code?

Taylor series expansion of cos(x) with a given accuracy
eps
Recursive approach
[Error] overloaded function with no contextual type information
How can I fix this error?
Photo1
#include <stdio.h>
#include <math.h>
double cos(double x, double eps, double s=0,double n=0,double a=0) {
if (abs(n)<1){
cos=cos(x, eps,1,1,1);
}
else {
a = -a*x*x / ((2*n-1) * (2*n));
if (abs(a)<=eps) {
cos=s;
}
else{
cos=cos(x, eps, s+a, a,n+1);
}
}
}
int main () {
double x;
scanf("%f", &x);
cos(x, 0.000000000000001);
}
You included math.h, which has a function named cos, that works a bit differently.
You have overloaded that name (eg. written another function also with the name cos) but have not given the compiler any means to deduce which version of cos you want to call.
Fix this by naming your function something different and unique.
Here's my attempt at a fix:
double TaylorCOS(double x, double eps, double s=0,double n=0,double a=0)
{
if (abs(n)<1)
{
return TaylorCOS(x, eps,1,1,1);
}
a = -a*x*x / ((2*n-1) * (2*n));
if (abs(a)<=eps)
{
return s;
}
return TaylorCOS(x, eps, s+a, a,n+1);
}
You can't assign to a function identifier like you do in
cos=s;
cos=cos(x, eps, s+a, a,n+1);
Neither in C, nor in C++. This program is broken beyond repair.

C program for solving equation using bisection method

this program is for solving equation using bisection method gives error "function show return a value".
In this method we are given a function f(x) and we approximate 2 roots a and b
for the function such that f(a).f(b)<0.
Then we find another point
c=(a+b)/2
if f(c)==0
then root=c;
else
if f(a).f(c)<0
b=c;
if f(b).f(c)<0
a=c;
and we repeat these steps for the given number of iterations
#include<stdio.h>
#include<math.h>
#define e 0.000001/*e is the prescribed accuracy*/
main()
{
double g1,g2,g,v,v1,v2,prev;
int found=0,converged=0,i=0;
double f(double);
printf("We apply Bisection method to find a real root of the non-linear equation f(x) = 0, where f(x) = x^(2.7182818)-3cosx+1n");
while(found==0)/*This loop will continue until a range is found in between which a real root lies*/
{
printf("nEnter the first guess : ");
scanf("%lf",&g1);
v1=f(g1);
printf("nEnter the second guess : ");
scanf("%lf",&g2);
v2=f(g2);
if(v1*v2>0)
{
found=0;
g1++;
printf("nRoot does not lie in [%lf,%lf].n",g1-1,g2);
printf("nn..Enter two new guesses..nn");/*Previous two guesses are inappropriate*/
}
else
found=1;
}
printf("nThere is a real root which lies in [%lf,%lf].n",g1,g2);
while(converged==0)/*This loop will continue until a real root is found*/
{
printf("nnIteration = %dnn",i);
printf("a[%d](-ve)tb[%d](+ve)tbbx[%d]=(a[%d]+b[%d])/2tf(x[%d])n",i,i,i+1,i,i,i+1);
printf("%lft",g1);
printf("%lft",g2);
g=(g1+g2)/2;
v=f(g);
printf("%lft",g);
printf("t%lf",v);
if(v<0)
g1=g;
else
g2=g;
if(fabs(prev-v)<e)
converged=1;
else
prev=v;
i=i+1;
}
printf("nnThe approximate value of the root is : %lfn",g);
}
/*This function returns values of f(x)*/
double f(double x)
{
return pow(2.7182818,x)-3*cos(x)+1;
}
When tested with initial values of 1, and 2 and an iteration of 20, the result comes out to 1.154172. which is a root of the system.
When tested with inital values of 1, 1, and iteration of 20, the result comes out to 1.0000, which is wrong.
You should check that the initial conditions for the roots are met, i.e. f(a) * f(b) < 0.
f(1) = -1, f(1)* f(1) = +1, therefore the initial conditions are not satisfied in the second case.

Recursive bisection method program stopped working

I have a problem with bisection method (recursive implementation) that doesn't work. The program just crashes after entering a&b values ...
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#define e 0.0001
#define dbg 1
using namespace std;
double f(double x){
return x*x*x-x-2;
}
double bisection(double a,double b){
double x1;
x1=(b+a)/2;
if(x1>e){
if(f(b)*f(x1)<0)
{
a=x1;
}
else
if(f(a)*f(x1)<0)
b=x1;
bisection(a,b);
}
return x1;
}
int main () {
int a,b;
double root;
printf("a=");
scanf("%d",&a);
printf("b=");
scanf("%d",&b);
if(f(a)*f(b)<0){
root=bisection(a,b);
printf("root %g",root);
}
system("pause");
return 0;
}
I have tried to display some debugging messages, but I couldn't figure it out.
As #Gene pointed out, you never use the result of the recursive call. Further, what you DO return is just the midpoint between a&b, which you don't need recursion to find. (Related?)
Note that, if the 2 ifs used to change either a or b for the recursive call both fail, then you make a recursive call w/ unchanged values of a & b ==> infinite recursion, a sure way to get a segfault.

Exponential (exp) function in C - segmentation fault

I use this code, but get an segmentation error. What is wrong here ?
GNU nano 2.2.6 File: taak8.c
#include<stdio.h>
double recursie(double som,double oud, double x, int stap){
double y = oud*x/stap;
if(y >= 1/1000){
return recursie(som+y,y,x,stap++);
} else {
return som;
}
}
double exp(double x){
return recursie(1,1,x,1);
}
int main(){
double inp;
scanf("%lf",&inp);
printf("your result %lf",exp(inp));
return 0;
}
if(y >= 1/1000) problem is there. 1/1000 will always be 0. so put 0 there directly.
But i think you wanted to do this below , try this instead
if(y >= 1.0/1000)
and this also
recursie(som+y,y,x,++stap);
use ++stap to increment stap instead of stap++.Because you have to send the incremented value of stap to recursive function call.
You need to increment your step before you call the recursive step, not after. In other words, you need to use pre-increment, not post-increment:
return recursie(som+y,y,x,stap+1);

Resources