Need help returning/passing multiple arrays - c

I have an assignment in my computer science class where I am writing a program that will need to return multiple array. Technically I could do this just fine, but the way the assignment is set up make it difficult for me to gauge certain things.
Basically, I have to declare two arrays and a variable in the main() function and send them to a function called input().
Input() will take these three things, which are NumberOfYears, Year[NumberOfYears],DataForYear[NumberOfYears]. NumberOfYears will be taken using a scanf(), and that will determine how many times a for() loop runs that will use a scanf() for Year[] and DataForYear[]. Year[] and DataForYear[] must use the same scanf() statement, which I know how to do.
After taking all of this, I need to create a function called output() which will basically printf() all of the values the user just gave me (being Year[] and DataForYear[]). However, I need a way to return both arrays to the main function, as well as NumberOfYears. I have heard this can be done using something called structs, however we have not learned this yet and I am sure my instructor will not approve.
The instructor's notes suggested that only NumberOfYears should be returned to the main function, but I simply do not see how this is possible. If you have a way that I can pass of these things along to output() without having to return them, that would be great to. Otherwise, I just need some sort of way to do this, and the rest of program is history.

Functions can return via their parameters as well as their return:
int doMyThing( int *somethingElse ) {
*somethingElse = 40;
return 2;
}
int main( void ) {
int a;
int b = doMyThing( &a );
printf( stdout, "%d\n", a + b ); // prints "42"
}
And you can extend that to arrays by using int **somethingElse, or whatever you need.

In C, anytime you pass an 'array', you actually pass a pointer. So your return type can be something like int*, depending on the type of the array you need to pass back. You can use &x to get the address of variable x (e.g. the first element of your array) if necessary.
The other possibility is that since you're passing a pointer you don't even need to actually return it. You can modify your array inside the input function and then see it's changed afterward in main without doing more work.

Related

Understanding how to turn a chunk of code that appears in main(){} into a function or functions in C

I'm working on a user-space driver which reads data off of a device by sending and receiving reports (it's a hid device).
Here is my initial code http://pastebin.com/ufbvziUR
EDIT NOTE: From the sound of the answers and comments it would seem I will need to wrap my C code inside of some Objective-C since the app that will be consuming this driver is written in Objective-C.
As of now I have just added all the code into the main() function and I'm able to grab data and print it out to the log window with the main purpose of logging out the buffer array. This code will be apart of a much larger app though and will need to be ran by getting called rather than just automatically running.
So I figured I would wrap all the code that appears in main() inside of a large function called getData(). I want to return an array called char buffer[] (a char array full of bytes) when this function get run. My initial thought to declare it would be like so since I know you cannot really return an array from a function only a pointer so I just let the caller allocate the buffer and pass it the size.
char *getData(int user){
unsigned char *buffer = malloc(2800);
// ... do all the stuff
return buffer;
}
Then in main()
int main(){
int user = 1;
unsigned char *buffer = getData(user);
}
Is this a proper approach?
A couple of things feel wrong to me here. First is wrapping that much code into a single function and two I'm not quite sure how to break out of the function when one of my error checks returns 1; since this function will need to return an array. I'm still really new to C and am getting confused on how to approach this when I don't have objects or classes to work with.
void getData(unsigned char *buffer, int user){...}
Defines a function that is not returning anything.
If you want to return some value - like for instance error code, you need a function returning an int.
int getData(unsigned char *buffer, int user){...}
To get out of function returning void differently then reaching the end of the function, you can also use return but then without any arguments.
As you've already noticed you aren't passing array to the function so there is no reason to return it at all. You could return the pointer if you wanted but the is no need to do so. The main function knows where the array is anyway.
It's generally considered a good habit to keep main as short as possible. You can also divide getData into smaller functions which would make the code more readable. You could for instance make every chunk marked by # pragma mark - ... a separate function. Or even better, see whether there are any parts of the program that are doing the same or similar thing. Then you can generalize this functionality into one function and use it multiple times.

'Return' as a function in an array of function pointers

So here's what I'm working with.
{
int Test;
void (*functions[5])() = {
return,
one,
two,
three,
four
};
for (Test = takeInput(5);; Test = takeInput(5)){
cls();
Print(L"0) Abort\n");
Print(L"1) One\n");
Print(L"2) Two\n");
Print(L"3) Three\n");
Print(L"4) Four\n");
Print(L"Enter Selection: ");
(*functions[Test])();
}
}
That's the gist of what I'm trying to do. This is sort of a menu system for some context (and takeInput(5), will pause for input, stopping the loop until someone inputs a number).
What the problem is, is that using return in that way is apparently wrong. I figured that seeing as how (i thought) return is a function, i can't see why it wouldn't be able to be put into a function pointer array in order to break out of the menu. I suppose I could make a dummy function that basically just returns true when called, and check for that (the problem with that being that all the other functions return void). Even if that worked, I would rather have a solution that is as self contained as the above, non-working example.
Is there a nice, clean, hopefully short way of doing this that is better than anything I've thought of yet?
return is not a function, it has no address and therefore you can't have it in the array of pointers to functions.
Further, Test appears uninitialized when you use it the first couple of times:
for (Test;
and
(*functions[Test])();
If you want to break out of the for loop, you have to use either break or return or an appropriate condition between the two semicolons in for(;condition;).
A function call will not break the loop. Unless, it's something exotic like abort(), exit() or longjmp().
I'd replace return in your function array with NULL and test for the null before executing the function, returning when the function pointer is NULL.

Getting return value from a function in C

consider the the two functions :
int add1(int x,int y)
{
return x+y;
}
void add2(int x,int y,int *sum)
{
*sum=x+y;
}
I generally use functions of the form add1 but I found some codes using functions of the form add2.
Even if the size return value is large(like an array or struct) we can just return its ponter
I wonder if there any reason for using the second form?
There's also the reason of returning success state.
There are a lot of functions like:
bool f(int arg1, int arg2, int *ret)
{
}
Where bool (or enum) return the success of the function. Instead of checking if ret is null... (And if you had more than 1 variable).
If you want to return two values from your function, then C is helpless unless you use pointers just like your function add2.
void add2()
{
/* Some Code */
*ptr1=Something;
*ptr2=Something;
}
Form 2 is very common for "multiple returns" in C. A canonical example is returning the address to a buffer and the length of the buffer:
/* Returns a buffer based on param. Returns -1 on failure, or 0 on success.
Buffer is returned in buf and buflen. */
int get_buffer(void *param, char **buf, int *buflen);
Functions of the form 2 are not faster than functions of the form 1 when you're using things as small as int. In fact, in this case, the second one is slower because you have to dereference the passed pointer. It's only useful in this case if your aim was to pass in an array of values)
Always use functions of the form 1 unless you want to pass in a very large piece of data to the function. In that case, the form 2 would be faster.
The reason we use the second form is because for large objects, we want to avoid copying them. Instead of copying them, we could just pass their memory addresses to the function. This is where the pointer comes in. So instead of giving the function all the data, you would just tell it where this data. (I hope this analogy is good enough)
It is largely a matter of preference and local conventions. The second form might be used alongside a bunch of other similar functions where the third parameter in each of them is always passed as a pointer to a return value.
Personally, I like the first form for almost all purposes: it does not require a pointer to be passed, and it allows some type flexibility in handling the return value.
Returning a value by writing to memory passed via a pointer is reasonable, when the returned object is large, or when the return value of the function is used for other purposes (e.g. signaling error conditions). In the code you have shown, neither of these two is the case, so I'd go for the first implementation.
When you return a pointer from a function, you have to make sure that the pointed to memory is valid after the function call. This means, the pointer must point to the heap, making an allocation on the heap necessary. This puts a burdon on the caller; he has to deallocate memory that he did not explicitly allocate.

Why would I pass function parameters by value in C?

I am dusting off my C skills working on some C libraries of mine. After having put together a first working implementation I am now going over the code to make it more efficient. Currently I am on the topic of passing function parameters by reference or value.
My question is, why would I ever pass any function parameter by value in C? The code might look cleaner, but wouldn't it always be less efficient than passing by reference?
Because it's not as important to code for the computer as it is to code for the next human being. If you are passing references around then any reader must assume that any called function could change the value of his parameters and would be obligated to check it or copy the parameter before calling.
Your function signature is a contract and divides your code up so that you don't have to fit the entire code base into your head in order to comprehend what is going on in some area, by passing references you are making the next guy's life worse, your biggest job as a programmer should be making the next guy's life better--because the next guy will probably be you.
In C, all arguments are passed by value. A true pass by reference is when you see the effect of a modification without any explicit indirection at all:
void f(int c, int *p) {
c++; // in C you can't change the original paramenter passed like this
p++; // or this
}
Using values instead of pointers though, is frequently desirable:
int sum(int a, int b) {
return a + b;
}
You would not write this like:
int sum(int *a, int *b) {
return *a + *b;
}
Because it is not safe and it is inefficient. Inefficient because there is an additional indirection. Moreover, in C, a pointer argument suggests the caller that the value will be modified through the pointer (especially true when the pointed type has a size less than or equal to the pointer itself).
Please refer to Passing by reference in C. Pass by reference is a misnomer in C. It refers to passing the address of a variable instead of the variable, but you are passing a pointer to the variable by value.
That said, if you were to pass the variable as a pointer, then yes it would be marginally more efficient, but the main reason is to be able to modify the original variable it points to. If you don't want to be able to do this, it is recommended you take it by value to make your intent clear.
Of course, all this is moot in terms of one of Cs heavier data structures. Arrays are passed by a pointer to their first variable whether you like it or not.
Two reasons:
Often times you will have to dereference the pointer you've passed in many times (think a long for-loop). You don't want to dereference every single time you want to look up the value at that address. Direct access is faster.
Sometimes you want to modify the passed-in value inside you function, but not in the caller. Example:
void foo( int count ){
while (count>0){
printf("%d\n",count);
count--;
}
}
If you wanted to do the above with something passed by reference, you would haev to create yet another variable inside your function to store it first.

input scanner that takes any type

i am trying to write an easier version of scanf. i want to basically be able for a pointer to be assigned whatever was scanned on user input like this:
int *p = (int) w_insc();
so here is my implementation:
void *w_insc()
{
void *temp = 0;
scanf("???", &temp);
return &temp;
}
i am confused as what to assign the format parameter in scanf to. i also think returning an address of a variable that will soon be destroyed is not right so i thought of doing this:
int *p = 0;
p = (int) w_insc((int) p);
can someone help
You are right that returning a pointer to a soon-to-be-destroyed variable is not correct. You can solve this problem by returning a pointer to a memory region allocated with malloc (although the caller must remember to free this memory), or by taking a pointer as the argument to w_insc, and then filling in the pointer with the returned value.
However, there are much broader issues with trying to implement the w_insc function. There is no way for w_insc to know what the caller expects. Just because the caller casts the return value of w_insc to int doesn't allow w_insc to know that it should return an int. The only information that a C function has available to it is its set of parameters, plus any global variables in the program (and global variables are usually the wrong way to solve your problem). Note that a C function has no way of knowing what the caller will do with its return value. As a result, there is no way to write w_insc to take no parameters and return something scanned correctly based on some cast that the caller makes.
You could add a parameter to w_insc, making the declaration into
int w_insc(const char *format, ...)
This allows the caller to pass in a format string and a series of arguments detailing what they expect to get out of standard input. However, with this implementation you have just wrapped scanf with ... another function that looks just like scanf.
My advice: use the standard library functions, since they are standardized, and someone reading your code will know instantly what it means, rather than having to read through the definition of a nearly-trivial wrapper like the w_insc you have described.

Resources