global variable is not incrementing properly - c

int count;
int main(){
count=0;
printf("%6d\t %6d\t %6d\t ",i+1,multiFib(i),count);
}
int multiFib(int x){
if (x<2){
return 1;
count++;
}}
In this code, count always gives 0 result. I made it a global variable, not to define it in the function again. How can I increase that variable?
It outputs in order; that is not problem. It gives the result:
1 1 0
-
2 1 0
-
3 2 0
So, count is not increasing — but why?

Although order of evaluation is not guaranteed (see multiple other answers), there is another, more fundamental problem (actually, two of them):
int multiFib(int x)
{
if (x<2){
return 1;
count++;
}
}
You attempt to increment count after you've returned from your function. Your compiler should be warning about unreachable code.
You don't return a value from multiFib() when the input is bigger than 2.
The fragment of main() that you show references an undefined variable i. I assume that is because you deleted a for (i = 0; i < 40; i++) loop from before the printf() statement. To fix the 'order of evaluation' problem, you might want to use:
int count;
int main(void)
{
for (int i = 0; i < 40; i++)
{
count = 0;
int fib = multiFib(i);
printf("%3d %10d %10d\n", i+1, fib, count);
}
return(0);
}
This evaluates the number of calls to multiFib() for each top-level call to the function.
For the multiFib() function itself, you probably need:
int multiFib(int x)
{
count++;
if (x < 2)
return x;
else
return multiFib(x-1) + multiFib(x-2);
}
Though this is an appallingly slow implementation of Fibonacci numbers so you shouldn't use this as an answer to your homework (but it does make a 'working' function).
Example output:
1 0 1
2 1 1
3 1 3
4 2 5
5 3 9
6 5 15
7 8 25
8 13 41
9 21 67
10 34 109
11 55 177
12 89 287
13 144 465
14 233 753
15 377 1219
16 610 1973
17 987 3193
18 1597 5167
19 2584 8361
20 4181 13529
21 6765 21891
22 10946 35421
23 17711 57313
24 28657 92735
25 46368 150049
26 75025 242785
27 121393 392835
28 196418 635621
29 317811 1028457
30 514229 1664079
31 832040 2692537
32 1346269 4356617
33 2178309 7049155
34 3524578 11405773
35 5702887 18454929
36 9227465 29860703
37 14930352 48315633
38 24157817 78176337
39 39088169 126491971
40 63245986 204668309
Note that if you go much beyond 40, you start getting arithmetic overflow. It also gets to be very (very, very) slow.

This:
if (x<2){
return 1;
count++;
}
You return from the function before you increment count. So it's never incremented.
Return doesn't just set the returned value. It actually exits the function at that point.
Just swap the order of those two lines. Also, you should keep an eye on your compiler warnings. Any decent compiler will warn you that the count++; line is unreachable.

printf("%6d\t %6d\t %6d\t ",i+1,multiFib(i),count);
The order of function argument evaluation is unspecified in C. multiFib can be evaluated before or after count in the printf function call.

The order of evaluation of function arguments is not specified.
In your code,
printf("%6d\t %6d\t %6d\t ",i+1,multiFib(i),count);
The argument to printf function multiFib(i) might be getting called after printing count.
Try this,
printf("%6d\t",multiFib(i));
printf("%6d\t %6d\t ",i+1,count);
to check the result.

As it was said in another answers, problem is that order of evaluation of function arguments is not specified, so in your example:
printf("%6d\t %6d\t %6d\t ",i+1,multiFib(i),count);
You can not be sure if count will be evaluated before or after passing multiFib(i) to the printf() function.
Please look here for more detailed information about evaluation order in C++, or here for evaluation order in C.
You might also find useful to force evaluation order by separating your printf into two calls:
printf("%6d\t",multiFib(i));
printf("%6d\t %6d\t ",i+1,count);
like Nishith Jain M R suggested in his answer.

Related

First function in code executing, but code following the first function is not executed

My code executes the first function, but anything after the first function is not executed. I compiled using gcc -o -Wall and received no error messages.
when I tried to execute the code, I receive the execution at the bottom. I am not sure why the program will not execute more of the code. In the first function I can add more to the function to make work but it won't touch the other functions.
1 #include <stdio.h>
2 //functions prototypes
3 void compute_discount(void);
4 int print_results(void);
5
6
7 //defined Gloabal var
8 double Mdisc;
9 double Cost_of_purchase;
10 double DiscTot;
11 double Sales_tax;
12 double Total_price;
13 char military;
14
15 int main (void) {
16 //declare variables
17
18 //Cost of purchase
19 printf("Cost of purchase?\t\t$");
20 scanf ("%lf",&Cost_of_purchase);
21
22 //Military?
23 printf("In military (y or n)?\t\t\n");
24 scanf("%s",&military);
25
26 }
27
28
29 //function to compute discount
30 void compute_discount(void){
31
32 //compute military discount
33 switch(military){
34 case 'y':
35 case 'Y':
36 if(Cost_of_purchase > 150) {
37 Mdisc = .15 * Cost_of_purchase;
38 } else if (Cost_of_purchase < 150) {
39 Mdisc = .10 * Cost_of_purchase;
40 }
41 break;
42 case 'n':
43 case 'N':
44 Mdisc = 0;
45 break;
46 default:
47 printf("Error:bad input");
48 }
49
50 //cost minus military discount
51 DiscTot = Cost_of_purchase - Mdisc;
52 //sales tax
53 Sales_tax = .05 * DiscTot;
54 //Total Calculated
55 Total_price = DiscTot + Sales_tax;
56
57 printf("maybe this is the problem%f",Mdisc);
58 }
59
60 //function to print results
61 int print_results(void){
62
63 //if input is n N y Y then use below, this is not dependant on if military only if the letter is accepted
64 switch(military){
65 case 'y':
66 case 'Y':
67 case 'n':
68 case 'N':
69 printf("Military discount (15%%): \t\t$%f", Mdisc);
70 printf("Discounted total: \t\t$%f", DiscTot);
71 printf("Sales tax (5%%): \t\t$%f", Sales_tax);
72 printf("Total: \t\t$%f", Total_price);
73 break;
74 }
75 return(0);
76 }
Result of execution:
[p18d541#csci112 lab1]$ gcc -o lab1 -Wall lab1.c
[p18d541#csci112 lab1]$ ./lab1
Cost of purchase? $500
In military (y or n)?
y
[p18d541#csci112 lab1]$
I am wondering what more needs to be done to fix this issue, or what ways I can use to make the program execute those functions other than int main().
On this line:
scanf("%s",&military);
You're passing the address of a single char. While the %s format specifier expects a char * parameter which is what is being passed, it also expects it to point to the first byte of an array so that it may store a string. Because of this, the function attempts to write more than one byte when only one byte is available. Writing past the bounds of an object triggers undefined behavior.
This can be fixed by using the %c format specifier which is for reading a single char. You'll also need to add a space before it to consume the newline that the prior scanf left in the input buffer:
scanf(" %c",&military);
You also never called compute_discount and print_results, so you need to do that after reading the user's input.
int main (void)
{
printf("Cost of purchase?\t\t$");
scanf ("%lf",&Cost_of_purchase);
//Military?
printf("In military (y or n)?\t\t\n");
scanf(" %c",&military);
compute_discount();
print_results();
return 0;
}
You defined functions you want to use, but you are not calling these functions at all. Imagine a scenario, where you wanted to define a function to sum two numbers, int a and int b, and then call the function to count the sum. It would be:
int sum(int a, int b) {
return a + b;
}
int main() {
int a = 5;
int b = 10;
printf("result: %d\n", sum(a, b));
// ^^^^^^^^^
// call sum function
}
It means that after defining the function, you need to use it, so your main would be:
int main (void) {
printf("Cost of purchase?\t\t$");
scanf ("%lf",&Cost_of_purchase);
printf("In military (y or n)?\t\t\n");
scanf("%s",&military);
// Finally call your defined functions:
compute_discount();
print_results();
}
The other functions (besides main) are not executed because they are never called. main is called automatically when you run the program, but any other functions must be explicitly called. Add calls to compute_discount and print_results at the bottom of main, following the second scanf.
BTW, your second scanfis particularly dangerous, because you are using a "%s" format to read a single character... what happens if the user types in "yes"... where do the 'e' and the 's' go?

C program to check lottery numbers: why some tests fail?

This program takes as an input the following lines:
23 12 33 19 10 8
5
23 19 8 12 60 18
14 60 12 44 54 10
8 3 12 19 33 10
33 15 7 60 12 10
22 12 19 23 33 11
23 12 33 19 10 8 ( The first line ) are the lottery results.
n ( in this specific case, 5 ) informs how many lines will follow below.
Each line has 6 numbers. The number order doesn't matter.
The rules are: numbers range from 1 to 60 ( including 1 and 60 ) and they never repeat themselves in the same line.
The variable "quadra" stores how many lines have got 4 numbers right.
The variable "quina" stores how many lines have got 5 numbers right.
The variable "sena" stores how many lines have got 6 numbers right.
So, a computer program is running some tests over my code below and it's claiming that it goes wrong for most of them, but I can't see what's the problem here. Does anybody have a clue? Is this code wrong, or is there something wrong with the software that's testing this code?
#include <stdio.h>
int main(){
int mega[6];
int v[50500][6];
int n,swap;
int i,j,k; //counters
int quadra,quina,sena;
quadra = 0;
quina = 0;
sena = 0;
for(i=0;i<6;++i) scanf("%i",&mega[i]); //first line, lottery results
scanf("%i",&n);
for(i=0;i<n;++i){
for(j=0;j<6;++j){
scanf("%i",&v[i][j]);
}
}
for(i=0;i<n;++i){
for(j=0;j<6;++j){
for(k=0;k<6;++k){
if(v[i][j] == mega[k]){
v[i][j] = 61;
}
}
}
}
//reverse bubble sort
for(i=0;i<n;++i){
for(j=0;j<6;++j){
for(k=j+1;k<6;++k){
if(v[i][j] < v[i][k]){
swap = v[i][k];
v[i][k] = v[i][j];
v[i][j] = swap;
}
}
}
}
for(i=0;i<n;++i){
for(j=0;v[i][j] == 61 && j<6;++j);
if(j == 4) ++quadra;
else if(j == 5) ++quina;
else if(j == 6) ++sena;
}
return 0;
}
Your code is true, I understood and tried the flow of it. Looks fine but if you dont need to sort everyline (and use j as a counter in this loop for(j=0;v[i][j] == 61 && j<6;++j); ), you can use simpler ifstatements to compare real lottery results with the ones that entered. What I mean is that your algorithm is a little complex. Try a simple one and see how it works.
Yes, there are a couple of noteworthy issues with your code:
Compile time indicates possibility of uninitialized variable:
But, run-time results in fatal run-time at unknown source location. Stack overflow. It is likely due to this line:
int v[50500][6];
Increase your stack size. It needs to be about 2.5Mbytes for v alone.
Also, this line may not be what you intended:
for(i=0;i<6;++i) scanf("%i",&mega[i]); //first line, lottery results
^
If you meant to loop around the remainder of the code, remove the ; after the for() statement, and use curly braces:
for(i=0;i<6;++i) scanf("%i",&mega[i]) //first line, lottery results
{
scanf("%i",&n);
....

I am trying to set a value to an array, but I can't seem to figure out why what I did on line 31 is wrong

I have a data file in the format <0:00> - <19321> , <1:00> - <19324>, up to <24:00> - <19648>, so for every hour there is the total power used so far(the total is incremented), I am supposed to calculate the power used, find the average, and the highest usage of power and its index(time), (I don't need help with finding the max power used at its time index). I traced the problem down to line 31, but I don't understand why what I did was wrong. Can someone explain to me why the code in line 31 isn't saving the value of power used into the array? And how I can fix it? Thanks in advance!
float compute_usage(int num, int vals[], int use[], int *hi_idx)
15 {
16 int i;// i is a general counter for all for loops
17 int r1, r2, u, v, pow_dif, temp;//for loop 1
18 int tot;//for loop 2
19 int max_use, init, fina, diff;//for loop 3 //don't have to worry about this for loop, I am good here
20 float avg;//average power used
21
22 for(r1=r2=i=u=v=0;i<num;i++)//for loop 1
23 {
24 r1= vals[v++];//I set values of every hour as reading 1 & 2(later)
25 #ifdef DEBUG
26 printf("pre-debug: use is %d\n", use[u]);
27 #endif
28 if(r1!=0 && r2!=0)
29 {
30 pow_dif = (r1 - r2);//I take the to readings, and calculate the difference, that difference is the power used in the interval between a time period
31 use[u++] = pow_dif; //I'm suppose to save the power used in the interval in an array here
32 }
33 r2=r1;//the first reading becomes the second after the if statement, this way I always have 2 readings to calculate the power used int the interval
34 #ifdef DEBUG
35 printf("for1-debug3: pow_dif is %d\n", pow_dif);
36 printf("for1-debug4: (%d,%d) \n", u, use[u]);
37 #endif
38
39 }
40 for(tot=i=u=0;i<num;i++)//for loop 2
41 {tot = tot + use[u++];}
42
43 avg = tot/(num-1);
44 #ifdef DEBUG
45 printf("for2-debug1: the tot is %d\n", tot);
46 printf("for2-debug2: avg power usage is %f\n", avg);
47 #endif
Just to understand, how did you figure out that the code in line 31 is problematic? Is it the printf statement in line 36?
When you do this:
use[u++] = pow_dif; //I'm suppose to save the power used in the interval in an array here
printf("for1-debug4: (%d,%d) \n", u, use[u]);
The "u" variable in printf statement is incremented in the previous operation (u++), so you are looking past the element you changed.
use[u++] = pow_dif; //I.e. u=0 here, but u=1 after this is executed.
printf("...\n", u=1, use[1]);
What is the "i" for in this loop? Why don't you try "u++" in the for statement instead of "i++" and remove the "u++" in the use assignment expression?

sscanf not detecting the right numbers

I'm having a hard time using sscanf to scan hour and minutes from a list. Below is a small snip of the list.
1704 86 2:30p 5:50p Daily
1711 17 10:40a 2:15p 5
1712 86 3:10p 6:30p 1
1731 48 6:25a 9:30a 156
1732 100 10:15a 1:30p Daily
1733 6 2:15p 3:39p Daily
I've tried this, but it keeps getting me segmentation Fault.(I'm putting this information into structures).
for(i=0;i<check_enter;i++){
sscanf(all_flights[i],
"%d %d %d:%d%c %d:%d%c %s",
&all_flights_divid[i].flight_number,
&all_flights_divid[i].route_id,
&all_flights_divid[i].departure_time_hour,
&all_flights_divid[i].departure_time_minute,
&all_flights_divid[i].departure_time_format,
&all_flights_divid[i].arrival_time_minute,
&all_flights_divid[i].arrival_time_minute,
&all_flights_divid[i].arrival_time_format,
&all_flights_divid[i].frequency);
printf("%d ",all_flights_divid[i].flight_number);
printf("%d ",all_flights_divid[i].route_id);
printf("%d ",all_flights_divid[i].departure_time_hour);
printf("%d ",all_flights_divid[i].departure_time_minute);
printf("%c ",all_flights_divid[i].departure_time_format);
printf("%d ",all_flights_divid[i].arrival_time_hour);
printf("%d ",all_flights_divid[i].arrival_time_minute);
printf("%c ",all_flights_divid[i].arrival_time_format);
printf("%s\n",all_flights_divid[i].frequency);
}
This is how I declared it.
struct all_flights{
int flight_number;
int route_id;
int departure_time_hour;
int departure_time_minute;
char departure_time_format;
int arrival_time_hour;
int arrival_time_minute;
char arrival_time_format;
char frequency[10];
};
struct all_flights all_flights_divid[3000];
These are the results I get
1704 86 2 30 p 0 50 p Daily
1711 17 10 40 a 0 15 p 5
1712 86 3 10 p 0 30 p 1
1731 48 6 25 a 0 30 a 156
1732 100 10 15 a 0 30 p Daily
1733 6 2 15 p 0 39 p Daily
Small mistake, that might be the problem:
this:
&all_flights_divid[1].flight_number,
should be:
&all_flights_divid[i].flight_number,
// ^
Edit:
Also, you read arrival_time_minute twice, and not reading arrival_time_hour at all. Fix it and it should be OK.
Most of the results seem to be fine, except the first field.
Now if you check your code..
&all_flights_divid[1]
fix it with
&all_flights_divid[i]

C array permutations with macros

Is it possible to generate a specific permutation of an array with a macro in C?
i.e. If I have an array X with elements:
0 1 2 3 4 5
x = ["0","1","1","0","1","0"]
I was thinking there may be some macro foo for something like this:
#define S_2Permute(x) = [x[5], x[3], x[4], x[2], x[1]]
where I redefine the order of the array, so the element in the original position 5 is now in position 0.
Any ideas?
EXAMPLE USE
I am starting to create an implementation of the DES encryption algorithm. DES requires several permutation/expansions where I would have to re-order all of the elements in the array, sometimes shrinking the array and sometimes expanding it. I was hoping to just be able to define a macro to permute the arrays for me.
EDIT2
Well in DES the first step is something called the initial permutation. So initially I have some 64-bit key, which for this example can be 0-15 hex:
0123456789ABCDEF
which expands to:
0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111
The IP (initial permutation) would permute this string so that every element in the array would be in a new position:
IP =
58 50 42 34 26 18 10 2
60 52 44 36 28 20 12 4
62 54 46 38 30 22 14 6
64 56 48 40 32 24 16 8
57 49 41 33 25 17 9 1
59 51 43 35 27 19 11 3
61 53 45 37 29 21 13 5
63 55 47 39 31 23 15 7
So the new 1st element in the bitstring would be the 58th element(bit) from the original bitstring.
So I would have all of these bits stored in an array of characters:
x = [0,0,0,0,0,0,0,1,0,0,1,0,0,0,1,1,0,1,0,0,0,1,0,1,0,1,1,0,0,
1,1,1,1,0,0,0,1,0,0,1,1,0,1,0,1,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,1,1,1,1]
and then just call
IP_PERMUTE(x);
And macro magic will have moved all of the bits into the new correct positions.
Absolutely - you're almost there with your example. Try this:
#define S_2Permute(x) {x[5], x[3], x[4], x[2], x[1]}
Then later:
int x[] = {1,2,3,4,5,6};
int y[] = S_2Permute(x); // y is now {6,4,5,3,2}
Two things to remember:
1) in C, arrays are numbered from 0, so it's possible you meant:
#define S_2Permute(x) {x[4], x[2], x[3], x[1], x[0]}
2) If you're using gcc, you can compile with -E to see the output from the preprocessor (very good for debugging macro expansions).
However, I don't think I'd actually do it this way - I'd say the code will be easier to read (and potentially less error prone) if you generate the permutations programmatically - and I doubt that it'll be a large performance hit.
Since you say you're having trouble compiling this, here's a test program that works for me in gcc 4.6.1:
#include <stdio.h>
#define S_2Permute(x) {x[5], x[3], x[4], x[2], x[1]}
int main(void) {
int x[] = {1,2,3,4,5,6};
int y[] = S_2Permute(x);
for(int i = 0; i < 5; i++) {
printf("%d,",y[i]);
}
printf("\n");
}
I compiled with gcc test.c -std=c99 -Wall
I'm new so apologies if it's not ok to offer a different means of solution but have you considered using an inline function instead of a macro?
I love single lines of code that do a lot as much as the next guy, but it makes more sense to me to do it this way:
//I would have an array that defined how I wanted to swap the positions, I'll assume 5 elements
short reordering[5] = {4,1,3,2,0};
inline void permuteArray(char array[]) {
char swap = array[reordering[0]];
array[reordering[0]] = array[reordinger[1]];
array[reordering[1]] = array[reordinger[2]];
array[reordering[2]] = array[reordinger[3]];
array[reordering[3]] = array[reordinger[4]];
array[reordering[4]] = swap;
}
This may not be as pretty or efficient as a macro, but it could save you some headaches managing and maintaining your code (and could always be swapped for the macro version Timothy suggest.
I am doing something vary similar. This is my code. The variable that comes in is a ulong, so then i convert it to a bit array and then rearrange all the bits and then turn it back into a ulong.
public override ulong Permutation(ulong input, int[] permuation)
{
byte[] test = BitConverter.GetBytes(input);
BitArray test2 = new BitArray(test);
BitArray final = new BitArray(test);
ulong x = 0;
ulong y = 1;
for (int i = 0; i < permuation.Length; i++)
{
final[i] = test2[(permuation[i]-1)];
}
for (int i = 0; i < final.Length; i++)
{
if (final[i] == true)
{
x += (1 * y);
}
else
{
x += (0 * y);
}
y = y * 2;
}
return x;
}

Resources