hi,

i have some code which is taking a value of how many moves a function is making to an array of numbers, and displaying it but basically, when i call the function initially, it will give the correct number of moves, when i call it again its adding the value to the previously displayed number unless i close the whole program down and start again. how do i reset the value each time i call the function.

i know its a very easy question for someone with a brain but i am still building mine and would really appreciate the help.

thanks

this is the code which is troubling me

long moves(int mode){
    // adds to i in counting mode (>0), returns i
	static int i=0;
	if(mode)
		i+=mode;
	return i;
}

hi,

iwhen i call it again its adding the value to the previously displayed number unless i close the whole program down and start again. how do i reset the value each time i call the function.

static int i=0; The static keyword makes the i to retain the value even when the function is done. Remove static.

thanks for your reply

i have tried that because thats what i thought too but when i do that, i just get a value of 0 returned to me

[T]hanks for your reply[.]

have tried that because thats what thought [as well], but when do that, just get a value of 0 returned to me[.]

Post your rectified function `moves' and the caller for it.

Edited 6 Years Ago by Aia: n/a

Here's the program so you can see what's going on. I have removed the static in the 'moves' function so you can see it just gives me a value of 0, but the 'compares' function works in the same way and WITH the static, it gives the correct value;

Oh and sorry for my spelling and punctuation, I hope this post is better.

//* Basic Sort Function Program *//

// Date: 18th March 2010
// Version: 1.1
// ----------------------------------------------------------------------------

// include directory libraries -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
#include <math.h>
#include <time.h>
#define N 5000
//-----------------------------------------------------------------------------

// declare functions -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
int random (void);  // creates random numbers

void sort(float *a,int low,int high);
   /* parameters: starting address of array and low and high indexes */
void merge(float *low1,float *high1, float *high2);
  /* parameters: pointers to low and high elements of half 1 
      calculates low element of half 2 as high1+1 and gets high
      element of half 2 directly */

long moves(int mode);

long compares(int mode);

int dupe(int i,float *a);

void mergesort (void);    // does merge sort

char menu(void);  //displays main menu and returns option selected
//-----------------------------------------------------------------------------

// Main function -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
int main(void){
	int i, j;                         // number of records in database table
	int finish=0;                      // 0 means continue loop. 1 means quit
	char option='z';                   // menu option


	do{                                // Do while loop to keep the menu always coming up after functions
		option=menu();
		switch(option){
			case 'r': case 'R':{       // when 'r' pressed
				random();     // the display function is done
				break;                 // and the do loop is broken out of
			}

			case 'm': case 'M':{       // when 'm' pressed
				mergesort();              // the merge function is done
				break;                 // and the do loop is broken out of
			}
			
			case 'q': case 'Q':{       // when 'q' pressed
                finish=1;              // finish is set to 1 meaning the loop breaks 
				break;                 // and the do loop is broken out of
			}
			

			default:{                  // when anything other than 'case' is pressed
				printf("option: %c not valid\n\n",option); // display a message to user
				break;                 // and the do loop is broken out of
			}
		}

	}while(! finish);                  // now the do is broken

	printf("press any key to exit\n\n"); // display a user message
	getch();                           // holds the screen display
	return 0;
}                                      // end of main

/*=========================DISPLAY MENU & INPUT==============================*/
char menu(void){                        //displays main menu and returns option selected
	char option='z';                    //option input : invalid default value z
	// display the menu - with formatting and user prompt 
    printf("         enter     for option\n");
	printf("         =====   ==============\n");
	printf("           r     generate Random numbers\n");
	printf("           m     Merge sort\n");
	printf("           q     Quit */\n\n");
	printf(">> ");
    scanf("%c",&option);                // read in the input from the user
	fflush(stdin);                      // get rid of pesky newline from input buffer
	return option;                      // return the input selection to the main function
}                                       // end of menu function
/*===========================================================================*/

/*==========================Generate random numbers============================*/
int random (void)
{
         time_t t;
         int num, i;
         float numbers;
         FILE *fh;
         fh=fopen("rand.txt","w");
         

         
         srand((unsigned) time (&t));
         do{
            printf("enter number of random numbers you wish to generate\n");
            printf("it must be either 100, 200, 500, 1000, 2000, or 5000:\n");
            scanf("%d",&num);
            fflush(stdin);                             //avoid using \n after enter number
            if (num != 10 && num != 100 && num != 200 && num != 500 && num != 1000 && num != 2000 && num != 5000) {
               printf("Error: you are trying to generate an invalid amount!\n\n");
               }
            } while ((num != 10 && num != 100 && num != 200 && num != 500 && num != 1000 && num != 2000 && num != 5000));
                          // while the number entered is incorrect, keep asking user for number
                                   
         printf("random numbers from 0 to 99:\n\n");
         for(i=0; i<num; i++){
                  numbers = ((long int)((double)rand()*(double)rand()) %1000000l) /10000.0;
                  printf("%lf\n",numbers);
                  fprintf(fh,"%lf\n",numbers);
         }
         
         fclose(fh);
         getch();
         return 0;
}                                       // end of random function
/*===========================================================================*/

///*===========================merge sort============================*/
void mergesort (void) {

     int j;
     char buff[BUFSIZ];
     float a[N];
     FILE *in;
     in=fopen("rand.txt","r");
     FILE *out;

       

  /* input numbers: reads up to 5000 floats in text format from rand.txt file
      into array a[] */
     int i=0;
     while(fgets(buff,BUFSIZ,in)!=NULL){
           a[i]=atof(buff);
	       i++;
     }

     sort(a,0,--i); /* sort the array a[] into ascending order */

     printf("%d floats merge sorted in %ld moves using %ld comparisons\n"
		 ,i+1,moves(0),compares(0));
     if(dupe(i,a))
            printf("Duplicate keys found\n");
     else
            printf("All keys unique\n");
  
     getch();
             
             /* now output sorted data in a paged listing */
     for(j=0;j<=i;j++){
         if(j%20==0){
	          printf("press a key to continue\n");
	          getch();
	          system("cls"); 
	          }//end of if
         printf("number %d is %lf\n",j+1,a[j]);

     } //end of for
  
     getch();
} /* end of main function */

/*===========================================================================*/

/***************count number of moves*****************/
long moves(int mode){
    // adds to i in counting mode (>0), returns i
	static int i=0;
	if(mode)
		i+=mode;
	return i;
}
/***************count number of comparidsons*****************/
long compares(int mode){
        //adds to i in counting mode (>0), returns i
	static int i=0;
    if(mode)
		i+=mode;
	return i;
	
}


///*===========================================================================*/
void sort(float *a,int low,int high){
  /* sort numbers by sorting array in two halves then merging 2 halves */
  int mid;
  if(high==low) return; /* only 1 element, already sorted */
  mid=(low+high)/2;
  sort(a,low,mid);  /* sort 1st half of array */
  sort(a,mid+1,high);  /* sort 2nd half of array */
  merge(a+low,a+mid,a+high); /* merge 2 halves of array */
} /* end of sort function */

/***************check for duplicate keys*****************/
int dupe(int i,float *a){ /*returns 1 if duplicate keys found in sorted array
                   or a 0 if all keys unique*/
  int x=0;
  for(x=0;x<i-1;x++){
     if(a[x]==a[x+1])
     return 1;
  }
  return 0;    
}

//******************************************************************************
void merge(float *low1,float *high1, float *high2){
  float *low2=high1+1; /* bottom of second half starts at 
                                      next position after top of first half */
  float *low=low1; /* place to block copy merged data back */
  static float comb[N],*combpos; 
          /* pointer to combined storage for merged data */
  size_t combsize,i;
  combsize=(((size_t)high2-(size_t)low1)/sizeof(float))+1; /* number of floats */
  combpos=comb;

  while(low1<=high1&&low2<=high2){
    compares(1);   /* next statement is a comparison */
    if(*low1 <= *low2){
       /* copy next value from lower half to combined */
      *combpos=*low1;
      combpos++;
      low1++;
    } else {
       /* copy next value from upper half to combined */
      *combpos=*low2;
      combpos++;
      low2++;
    } /* end of else */
  } /* end of while */


  /* at most 1 of next 2 loops will operate */
  while(low1<=high1){ /* copy remaining items in 1st half to combined */
     *combpos=*low1;
     combpos++;
     low1++;
  }
  while(low2<=high2){ /* copy remaining items in 2nd half to combined */
     *combpos=*low2;
     combpos++;
     low2++;
  }

  /* copy merged data back from combined storage to original */
  for(i=0;i<combsize;i++){
    *(low+i)=*(comb+i);
    moves(2); /* each item had to be moved twice */

  }
} /* end of merge function */

P.S. Please excuse the mess of the code structure.

Edited 6 Years Ago by churni: Additional Comment

Comments
For willing to improve.

There are plenty of concepts that we could discuss of your code. However, let's get to the root of the asked question/problem.

If we modify the `moves' function without the static.

int moves(int mode){
    /* adds to i in counting mode (>0), returns i */
	int i=0;
	if(mode)
            i+=mode;
	return i;
}

Since you are returning an int the type of return should be an int and not a long.

Now, you call `moves' twice.
Here,

printf("%d floats merge sorted in %ld moves using %ld comparisons\n"
		 ,i+1,moves(0),compares(0));

...and here.

moves(2); /* each item had to be moved twice */

Let's look at the first one. moves(0) What does printf() display?
`0' since it will not enter into

if(mode)
		i+=mode;

The second call in the for loop is irrelevant since the result doesn't get anywhere. Nevertheless, when the i variable in `moves' was static the result of this call was kept for the scope of the program.

[edit:]
I am not trying to fix your program. Just pointing an explanation to your question.

Edited 6 Years Ago by Aia: n/a

Thanks, I do appreciate your help. I am a beginner at this so let me try and explain what i thought was going on.

In the 'printf' statement you highlighted, i thought this was just bringing up the value of 'moves'. I don't quite understand what the 0 is doing.

In the second highlighted piece of code with the 'moves(2)', I thought this was where the calculation of the function is taking place. For example, all of the sorting is being done and then it is somehow calculated into how many moves have taken place.

And the obviously the function I initially showed you was the calculation I speak of.

But now you've showed me that I am wrong - very appreciative - but it leaves me more confused.

I understand that if 'moves(0)' has the 0, it will not enter the for loop of the function (Is that correct?) and so will just display 0. but what I don't understand is why if the static is typed in, a value does appear.

Hmm... I think I need to start again or something. Its just frustrating that all I want to do is reset this value that is being displayed - the next time it is called.

Going back to your original function, between runs you have to have a way to zero your counter. Using a static value, you can't zero i when the new run starts.

Edited 6 Years Ago by WaltP: n/a

i think i've tried that too, like zeroing them at the menu but to no avail!

Further reading concerning scope , static , and global variables could help you understand.
Meanwhile, compile and execute this snippet and see if it brings clarity.

# include <stdio.h>

/* without static scope */
int moves (int mode)
{
    int i = 0;
    if (mode) {
        i += mode;
    }

    return i;
}

/* now with static scope */
int moves2 (int mode)
{
    static int i = 0;
    if (mode) {
        i += mode;
    }
    return i;
}

int main (void)
{
    int x = 0;
    
    /* value of i is destroy at completion of function */
    for (x = 0; x < 4; x++ ) {
        printf("Value returned when moves(%d) = %d\n", x, moves(x));
    }
    putchar('\n');

    /* value in i is kept when function has finished */
    for (x = 0; x < 4; x++ ) {
        printf("Value returned when moves2(%d) = %d\n", x, moves2(x));
    }
    putchar('\n');

    /* one more time */
    for (x = 0; x < 4; x++ ) {
        printf("Value returned when moves2(%d) = %d\n", x, moves2(x));
    }

    return 0;
}

Edited 6 Years Ago by Aia: n/a

Ooh, ok - understandings!

I get what you're saying about static holding the value. But in the program I sent you, why are there issues when i remove the static?

Because when you remove static, it's a local variable that has 0 loaded when the function starts ( int i=0 )
Pass the counter value into and out of the function.

Edited 6 Years Ago by WaltP: n/a

i will try that later on tonight and will report back to you both tomorrow. thank you so very much for your time and effort with me. rep will be given!

hi guys,

i had a word with one of my friends and we found a way of resetting the values through the use of a for loop;

printf("%d floats merge sorted in %ld moves using %ld comparisons\n"
		            ,i,moves(0),compares(0));
     if(dupe(i,a))
            printf("Duplicate keys found\n");
     else
            printf("All keys unique\n");
            getch();
            compares(-1);
            moves(-1);

that would reset the values to -1 and then in the function i added this for statement;

long moves(int mode){
    // adds to i in counting mode (>0), returns i
	static int i=0;
	if(mode>0)
	          i+=mode;
    else if (mode==0)
         return i;
		//i+=mode;
	else if (mode<0)
    i=0;
}
Comments
is very wonderful post cause it help others,like me.
This article has been dead for over six months. Start a new discussion instead.