#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2013
    Posts
    6
    Rep Power
    0

    Return Value in a function


    Hello all,

    Hoping that somebody is able to help me with the following problem:

    I have a function that returns a value TRUE that is necessary for the some other functions to be activated. This function reads a data file, prints them but does not store them. I want to store these values in a matrix. At the end I want the function to return this matrix so I can process this data. Here lays the problem, the matrix is being created but I do not know how I can return this marix since there is allready something being returned (the value TRUE).

    Can somebody help me?

    Regards,
    Tim
  2. #2
  3. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,379
    Rep Power
    1871
    Is the size of the matrix known at compile time?

    Is the size of the matrix known before you call this function?
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper
  4. #3
  5. Java Junkie
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jan 2004
    Location
    Mobile, Alabama
    Posts
    4,021
    Rep Power
    1285
    You can use reference parameters.
  6. #4
  7. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2013
    Posts
    6
    Rep Power
    0
    Originally Posted by salem
    Is the size of the matrix known at compile time?

    Is the size of the matrix known before you call this function?
    No, it is not known upfront. Only when all the data is being read this size is known. For now I have set this size to the right amount determined empirically.
  8. #5
  9. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2013
    Posts
    6
    Rep Power
    0
    Originally Posted by bullet
    You can use reference parameters.
    With what intention? Reference parameters are some kind of substitution, right?
  10. #6
  11. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,379
    Rep Power
    1871
    Well if it's C++, then I'd go with

    bool readMatrix ( vector<vector<int> > &mat );
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper
  12. #7
  13. Java Junkie
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jan 2004
    Location
    Mobile, Alabama
    Posts
    4,021
    Rep Power
    1285
    Originally Posted by Tim Akker
    With what intention? Reference parameters are some kind of substitution, right?
    With reference parameters, you send the address of a variable instead of the value, so you can set the value of the actual parameter in the function.

    This is an example of using a function that needs to set two things. It returns a dynamic array of ints, and sets the size of the array through a parameter.

    Code:
    #include <iostream>
    using namespace std;
    
    int* fill(int& size);
    
    int main() {
       int size;
    
       int* array = fill(size);
    
       for (int counter=0;counter<size;counter++)
          cout << array[counter] << endl;
    
       return(0);
    }
    
    int* fill(int& size) {
       size;
    
       cout << "How large an array do you want?" << endl;
    
       cin >> size;
    
       int* output = new int[size];
    
       for (int counter=0;counter<size;counter++)
          output[counter] = 1;
    
       return(output);
    }
  14. #8
  15. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2013
    Posts
    6
    Rep Power
    0
    Originally Posted by salem
    Well if it's C++, then I'd go with

    bool readMatrix ( vector<vector<int> > &mat );
    Sorry, I forgot to mension: It's C.
  16. #9
  17. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2013
    Posts
    6
    Rep Power
    0
    Originally Posted by bullet
    With reference parameters, you send the address of a variable instead of the value, so you can set the value of the actual parameter in the function.

    This is an example of using a function that needs to set two things. It returns a dynamic array of ints, and sets the size of the array through a parameter.

    Code:
    #include <iostream>
    using namespace std;
    
    int* fill(int& size);
    
    int main() {
       int size;
    
       int* array = fill(size);
    
       for (int counter=0;counter<size;counter++)
          cout << array[counter] << endl;
    
       return(0);
    }
    
    int* fill(int& size) {
       size;
    
       cout << "How large an array do you want?" << endl;
    
       cin >> size;
    
       int* output = new int[size];
    
       for (int counter=0;counter<size;counter++)
          output[counter] = 1;
    
       return(output);
    }
    Thanks for your quick response. I forgot to mention that I am using C. So I can not use #include <iostream>. Is it still possible to use reference parameters in C?

    Maybe it is nice to see the function:

    Code:
    int read_transitions(FILE *fp)
    {
        char *line;
        int orig, dest, event;
    	int i = 0;
    	int list[118][2];
    
        for(;;) {
            line = read_noncomment_line(fp);
            if (line == NULL) break;
    
            if (is_empty_line(line)) continue; /* Silently skip empty lines. */
    
            orig = strtol(line, &line, 10); /* Read originating state. */
            if (*line != ' ' && *line != '\t') return FALSE;
    
            event = strtol(line, &line, 10); /* Read event number. */
            if (*line != ' ' && *line != '\t') return FALSE;
    
            dest = strtol(line, NULL, 10); /* Read destination state. */
    		
    		i = i + 1;
    
    		list[i][1] = orig;
    		list[i][2] = dest;
            printf("Transition %d from %d to %d %d %d \n", event, orig, dest, list[i][1], list[i][2]);
    
        }
    		for(int k = 1; k < 118; k++) 
    		{
    		printf("%d %d\n", list[k][1], list[k][2]);
    		} 
    		//This printed Matrix is the one I want to be exported.
    
        return TRUE;
    
    }
  18. #10
  19. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2009
    Posts
    149
    Rep Power
    36
    Originally Posted by Tim Akker
    Here lays the problem, the matrix is being created but I do not know how I can return this marix since there is allready something being returned (the value TRUE).
    Instead of declaring your matrix inside the function, you may declare it in your main and pass it in as an int***. There are likely better ways of doing this; this is just an example I came up with on the fly here that happens to work.

    For example:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <assert.h>
    
    int foo(int*** x, int d1, int d2)
    {
    	//dynamically allocate x
    	*x = (int**)malloc(d1*sizeof(int*));
    	int** y = *x;
    	
    	for(int i = 0; i < d1; i += 1)
    		y[i] = (int*)malloc(d2 * sizeof(int));
    		
    	for(int i = 0; i < d1; i += 1)
    	{
    		for(int j = 0; j < d2; j += 1)
    		{
    			//do stuff with x[i][j]
    			y[i][j] = (i + 1) * (j + 1);
    		}
    	}
    	return 1; //returns an integer
    }
    
    int main(int argc, char** argv)
    {
    	int** x;
    	int booleanReturn;
    	int sizeD1, sizeD2;
    	
    	if(argc != 3)
    		exit(0);
    	
    	//getting the size from command line arguments here,
    	//you're probably getting yours from a file	
    	sizeD1 = atoi(argv[1]);
    	sizeD2 = atoi(argv[2]);
    	
    	assert(sizeD1 > 0 && sizeD2 > 0);
    		
    	booleanReturn = foo(&x, sizeD1, sizeD2);
    	
    	if(booleanReturn)
    	{
    		for(int i = 0; i < sizeD1; i += 1)
    		{
    			for(int j = 0; j < sizeD2; j += 1)
    				printf("%d ", x[i][j]);
    			printf("\n");
    		}
    	}
    	
    	//always free your mallocs
    	for(int i = 0; i < sizeD1; i += 1)
    		free(x[i]);
    	free(x);
    	exit(0);
    }
    Last edited by jakotheshadows; March 6th, 2013 at 05:04 PM.
  20. #11
  21. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,145
    Rep Power
    2222
    Yes, it is, with pointers.

    And BTW, your array indices are wrong. The 118 rows are indexed by the 118 values of zero to 117. Similarly, the two columns are Column Zero and Column One. Array indices in C always start with zero.

    Here's one idea that declares the array outside of the function and passes it in to be filled, along with a pointer to an int variable that the function can write to number of array entries to.
    Code:
    // declare list somewhere external to this function and pass it in.
    //   eg:  if (read_transitions(fp, list, &count))
    int read_transitions(FILE *fp, int list[][2], int *count)
    {
        char *line;
        int orig, dest, event;
        int i = 0;
     
        for(;;) 
        {
            line = read_noncomment_line(fp);
            if (line == NULL) 
                break;
    
            if (is_empty_line(line)) 
                continue; /* Silently skip empty lines. */
    
            orig = strtol(line, &line, 10); /* Read originating state. */
            if (*line != ' ' && *line != '\t') return FALSE;
    
            event = strtol(line, &line, 10); /* Read event number. */
            if (*line != ' ' && *line != '\t') 
                return FALSE;
    
            dest = strtol(line, NULL, 10); /* Read destination state. */
            
            // WRONG!  Indexing should start from zero, not from one!
    //        i = i + 1;
    //
    //        list[i][1] = orig;
    //        list[i][2] = dest;
    //        printf("Transition %d from %d to %d %d %d \n", event, orig, dest, list[i][1], list[i][2]);
    
            // Should instead be something like:
            list[i][0] = orig;
            list[i][1] = dest;
            printf("Transition %d from %d to %d %d %d \n", event, orig, dest, list[i][0], list[i][1]);
            
            i = i + 1;
        }
        
        // This is incorrect.  
        // Also, you're only iterating 117 times
    //    for(int k = 1; k < 118; k++) 
    //    {
    //        printf("%d %d\n", list[k][1], list[k][2]);
    //    }
    
        // Should instead be:
        // Note that this iterates all 118 times
        for(int k = 0; k < 118; k++) 
        {
            printf("%d %d\n", list[k][0], list[k][1]);
        }
         
        //This printed Matrix is the one I want to be exported.
    
        // "return" the number of items through the pointer parameter
        *count = i;
        
        return TRUE;
    }
    Though as jacotheshadows says, there's more than one way. If you kept the array in the function and returned its address, then you'd have to declare it as static so that it would continue to exist after returning from the function -- local variables go away as soon as you leave the function.
    Last edited by dwise1_aol; March 6th, 2013 at 05:23 PM.
  22. #12
  23. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2013
    Posts
    6
    Rep Power
    0
    Originally Posted by dwise1_aol
    Yes, it is, with pointers.

    And BTW, your array indices are wrong. The 118 rows are indexed by the 118 values of zero to 117. Similarly, the two columns are Column Zero and Column One. Array indices in C always start with zero.

    Here's one idea that declares the array outside of the function and passes it in to be filled, along with a pointer to an int variable that the function can write to number of array entries to.
    Thanks for your response. Did not know that, learned something new today!

IMN logo majestic logo threadwatch logo seochat tools logo