I need a clarification for custom functions in C - c

I'm taking the CS50 class week 1 and I made the code work but I don't understand the custom functions part
void cat (int n)
I know that cat is your desired name for your function.
In my own understanding the code inside the parenthesis is the input that your custom function is taking (please correct me if my understanding is wrong)
but what I do not understand totally is the first word of the custom functions code like why is it void not int.
I would love it it you explained it in a much simpler English since English or programming vocabulary is pretty small atm.

Function format:
xxxxx yyyyy(zzzzz)
{
/* code */
return something;
}
xxxxx is the function return type. void means that function does not return anything to the caller.
yyyyy is the function name.
zzzzz are the function parameters. void means that function does not take any parameters. Parameters are separated by a comma. Parameter definition consists of type and parameter name.
examples:
int add(int x, int y)
{
return x + y;
}
the function add taking two integers as parameters and returning int
I do not understand totally is the first word of the custom functions
code like why is it void not int.
Programmer decided that function cat will not return anything

void cat (int n); // note the semicolon
This is a forward declaration of a function named cat that takes one int named n as an input parameter. It's declared void which means that the function does not return anything.
The definition of cat could look like this:
#include <stdio.h> // needed for printf etc.
void cat (int n) {
printf("the cat is %d years old\n", n); // note: using `n` here
// return; // not needed since the function is `void`
}
Forward declaration are made if you need to resolve circular dependencies:
void foo(int x) { if (x==1) bar(x+1); } // calls `bar`
void bar(int x) { if (x==1) foo(x+1); } // calls `foo`
This should not compile because when the compiler processes foo(), bar() is unknown. A forward declaration of bar() before foo() solves it:
void bar(int x); // forward declaration saves the situation
void foo(int x) { if (x==1) bar(x+1); }
void bar(int x) { if (x==1) foo(x+1); }
Forward declarations can also be used to declare all functions defined in the file at the top of the file and implement (define) them later. The list of functions then works as a sort of index of all the functions in the file. It's a matter of coding style. Example:
#include <stdio.h>
// forward declarations of all functions (except main):
void cat (int n);
// program entry point:
int main (void) {
cat(12); // calling cat with the argument 12 (an `int`)
return 0; // not strictly required when returning from main
}
// all the definitions follows:
void cat (int n) {
printf("the cat is %d years old\n", n); // prints: the cat is 12 years old
}

In your example, "void" is the return value of the function. In this case, the function is not defined to return a value and would therefor not have a "return" statement with a value.
Edit: But as pointed out below in a comment, it can have a "return" statement without a value.

The term has fallen out of use, but it may be more clear to (silently) regard the example given as a 'subroutine'. Whatever is done by cat() is to be done, but the perhaps many lines of fiddley code would distract from the flow of processing where cat() has been called. Putting those lines of code into a 'subroutine' means that the main body of code can be shorter and easier to understand.
Another benefit of a 'subroutine' is that the same processing can be done (called) from multiple locations without duplicating lines of code.
Here's a snippet of a contrived and trivial example I hope makes this plain. The task is to count from 0 to 'n', printing every so often, and then printing the final value reached:
#include <stdio.h>
// 'Subroutine' that provides some service
void out( int n ) {
/* this represents what could be many lines of code */
printf( "Have reached %d\n", n );
}
int main() {
int maxVal = 23; // some ceiling value
/* somewhere in the body of code */
int i = 0; // initial condition
out( i ); // output initial value
do {
i = i + 1; // processing
// output if a threshold reached
if( (i / 5) * 5 == i )
out( i );
} while( i < maxVal );
out( i ); // output final value
return 0;
}
Output:
Have reached 0
Have reached 5
Have reached 10
Have reached 15
Have reached 20
Have reached 23

Related

C pointers segmentation fault confusion

I am learning pointers and going through the examples from this Stanford PDF
Stanford Pointers Guide
I decided to write some code using their examples to get a better handle on what is happening. I am working from page 21 of the PDF.
When I run the code I get a segmentation fault, so I know that I'm trying to access memory that doesn't belong to me, but I don't understand where I'm going wrong.
Here is the code I have written:
#include <stdio.h>
#include <stdlib.h>
// function prototypes
void C();
void B();
void main(){
int *worthRef;
int num = 42;
worthRef = &num;
B(*worthRef);
}
// Takes value of interest by reference and adds 2
void C(int* worthRef){
*worthRef = *worthRef + 2;
printf("num = %d", &worthRef);
}
// adds 1 to value of interest then calls C()
void B(int* worthRef){
*worthRef = *worthRef + 1; // add 1 to worthRef as before
C(worthRef); // NOTE: no & required. We already have a pointer to
// the value of interest, so it can be
// passed through directly
}
// function prototypes
void C();
void B();
That comment is a lie. Those are function declarations without a prototype (which is part of the problem in this code).
B(*worthRef);
This line calls B with an int. (Given the declaration int *worthRef, the type of *worthRef is int.)
void B(int* worthRef){
But here B expects to be given a pointer to an int, which is the bug: You're passing a number where a pointer is expected.
To fix this, change the call in main to B(worthRef) (or B(&num)), and change
printf("num = %d", &worthRef);
to
printf("num = %d\n", *worthRef);
If you had included a prototype in your function declarations, then the compiler would have warned you about the problem (probably):
// function prototypes
void C(int *);
void B(int *);

Passing variable through functions

How would I pass a variable from one function to another in C? For example I want to pass the sumOfDice from function roll and use sumOfDice for the passLine function: Here is my code:
int roll()
{
int dieRollOne = (random()%6) + 1;
int dieRollTwo = (random()%6) + 1;
printf("On Dice One, you rolled a: %d\n", dieRollOne);
printf("On Dice Two, you rolled a: %d\n", dieRollTwo);
int sumOfDice = dieRollOne + dieRollTwo;
printf("The sum of you Dice is: %d\n", sumOfDice);
return sumOfDice
}
int passLine(int sumOfDice)
{
// other code
printf("the sum of dice is: %d\n", sumOfDice);
}
I would have used global variable for sumOfDice, but we are not allowed to. Would I have to pass with asterisk, like: int *num;
Nasim, this is one of the most fundamental concepts in C. It should be well-explained in any C book/tutorial you use. That said, everybody needs to learn somewhere. In order to pass values to/from a function, you start with the declaration of a function.
A function in C may receive any number of parameters but may only return a single value (or no value at all). A function requires those parameters specified in its parameter list. A function declaration takes the form of:
type name (parameter list);
The type is the return type for the function (or void). The parameter list contains the type of variables that are passed to the function. While you will normally see a parameter list in a declaration that contains both the type and name, only the type is required in the declaration. A function definition provides the function code and the function return. The parameter list for a function definition will contain both the type and name of the parameters passed.
(note: you may see old K&R function definitions without any type relying on the fact that the default type is int. That type definition/parameter list is obsolete. see Function declaration: K&R vs ANSI)
Now that you have had a Cliff's-notes version of how to declare/define a function, a short example should illustrate passing/returning values to and from a function. This first example shows the function definitions that precede the main function. In this case no separate declaration is required:
#include <stdio.h>
int bar (int x) {
return x + 5;
}
int foo (int a) {
return bar(a);
}
int main (void) {
int n = 5;
printf ("\n n = %d, foo(%d) = %d\n\n", n, n, foo(n));
return 0;
}
(note: function bar is placed before function foo because function foo relies on bar. A function must always have at minimum a declaration before it is called.)
Another example showing the common use of providing function declarations before main with the function definitions below would be:
#include <stdio.h>
int foo (int);
int bar (int);
int main (void) {
int n = 5;
printf ("\n n = %d, foo(%d) = %d\n\n", n, n, foo(n));
return 0;
}
int foo (int a) {
return bar(a);
}
int bar (int x) {
return x + 5;
}
(note: even though the function foo is defined before bar here, there is no problem. Why? Because bar is declared (at the top) before foo is called. also note: the declaration are shown with the type only, just to emphasize a point, you will normally see int foo (int a); and int bar (int x); as the declarations.)
Use/Output
The output of both is:
$ ./bin/func_pass_param
n = 5, foo(5) = 10
I hope this has cleared up some of the basics for you. If not, you can ask further, but you are far better served finding a good C book or tutorial and learning the language (at least the basics) before you attempt to compile and run a program -- it will take you far less time in the long run.

Understanding strange return syntax: return(*scriptFunction[x])(arguments);

I know the title for this is horrendous and for this I am sorry; I honestly had no idea how to ask my question as I am not well educated on this matter. Below there is a small bit of code that my question concerns as I have NO idea what is going on or if it is even valid! Although, I suspect it is valid.
return(*scriptFunction[x])(arguments);
From my understanding, you can only return 1 value in C (you can have multiple return statements but that is different and off topic). What is the above statement actually doing?
The code:
return(*scriptFunction[x])(arguments);
actually is only returning one value.
The variable scriptFunction will be an array of function pointers(1). You look up element number x of that array, and call that function, passing the argument arguments. Then the return value from that function is what you return to your caller.
Other than the function pointer aspect, it's no different to return sqrt(42).
By way of example, the following program demonstrates how this can be done:
#include <stdio.h>
// Two simple functions which add a fixed value.
int fnPlus3 (int n) { return n + 3; }
int fnPlus7 (int n) { return n + 7; }
// An array holding those two functions.
int (*scriptFunction[])(int) = { fnPlus3, fnPlus7 };
int main (void) {
// Call first function in array.
int x = 0;
printf ("%d\n", (*scriptFunction[x])(100));
// Then call second one.
x = 1;
printf ("%d\n", (*scriptFunction[x])(100));
return 0;
}
Although it prints the return value from the function rather than returning it again, it still uses the same expression and you can see it calls a different function based on the value of x:
103
107
(1) Or some form of equivalent, such as a pointer to an array of function pointers, or a pointer to a single function pointer (assuming x is always set to zero in that latter case).
Presumably scriptFunction is an array of pointers to functions. *scriptfunction[x] is then the dereferenced pointer to function (the x-th one). Finally, *scriptfunction[x](arguments) represents the invocation of that function applied to arguments, so the result of that function is what's returned in the end.
Side comment: the * is not really necessary. A pointer to function does not need to be dereferenced to call the function, i.e. you can use
return scriptFunction[x](arguments);
instead.
From the looks of it, it seems the line return (*scriptFunction[x])(arguments); scriptFunction is an array of function pointers, and this is simply invoking the function at position indexed by variable x and sending arguments variable contents as its input.
The return value of this invoked function is what ultimately gets returned.
This working example should be useful:
#include <iostream>
using namespace std;
void func_a(int i)
{
cout << "func_a: " << i << endl;
}
void func_b(int i)
{
cout << "func_b: " << i << endl;
}
int main()
{
void (*funcs[])(int) = { func_a, func_b };
for(int i = 0; i < 2; ++i)
(*funcs[i])(i+1);
return 0;
}
The output is below:
➜ /tmp g++ test.cpp -o test
➜ /tmp ./test
func_a: 1
func_b: 2
Also, for future reference, you should consult: How to ask good questions?

Declare a void function in C

I am learning C and I am studying functions. So, I read that when I implement my own function I have to declare it before the main(). If I miss the declaration the compiler will get an error message.
As I was studying this example (finds if the number is a prime number),
#include <stdio.h>
void prime(); // Function prototype(declaration)
int main()
{
int num, i, flag;
num = input(); // No argument is passed to input()
for(i=2,flag=i; i<=num/2; ++i,flag=i)
{
flag = i;
if(num%i==0)
{
printf("%d is not prime\n", num);
++flag;
break;
}
}
if(flag==i)
printf("%d is prime\n", num);
return 0;
}
int input() /* Integer value is returned from input() to calling function */
{
int n;
printf("\nEnter positive enter to check: ");
scanf("%d", &n);
return n;
}
I noticed that a function prime() is declared, but in the main, a function, input(), is called and also the function input() is implemented at the bottom. Ok, I thought it was a mistake and I change the name from prime to input.
However if I delete the declaration and I don’t put any there, the program is compiled without errors and it runs smoothly. (I compile and run it on Ubuntu.)
Is it necessary to declare a void function with not arguments?
If you don't have a forward declaration of your function before the place of usage, the compiler will create implicit declaration for you - with the signature int input(). It will take the name of the function you called, it will assume that the function is returning int, and it can accept any arguments (as Bartek noted in the comment).
For this function, the implicit declaration matches the real declaration, so you don't have problems. However, you should always be careful about this, and you should always prefer forward declarations instead of implicit ones (no matter if they are same or not). So, instead of just having forward declaration of the void prime() function (assuming that you will use it somewhere), you should also have a forward declaration of int input().
To see how can you pass any number of the arguments, consider this:
#include <stdio.h>
// Takes any number of the arguments
int foo();
// Doesn't takes any arguments
int bar(void)
{
printf("Hello from bar()!\n");
return 0;
}
int main()
{
// Both works
// However, this will print junk as you're not pushing
// Any arguments on the stack - but the compiler will assume you are
foo();
// This will print 1, 2, 3
foo(1, 2, 3);
// Works
bar();
// Doesn't work
// bar(1, 2, 3);
return 0;
}
// Definition
int foo(int i, int j, int k)
{
printf("%d %d %d\n", i, j, k);
return 0;
}
So, inside the definition of the function you're describing function arguments. However, declaration of the function is telling the compiler not to do any checks on the parameters.
Not declaring a prototype and relying on default argument/return type promotion is dangerous and was a part of old C. In C99 and onward it is illegal to call a function without first providing a declaration or definition of the function.
my question is, is it necessary to declare a void function with not arguments?
Yes. For this you have to put void in the function parenthesis.
void foo(void);
Declaring a function like
void foo();
means that it can take any number of arguments.
If prime is not used, then omit the declaration.
The code won't compile as C++, because the compiler would complain that function input is used but not declared. A C compiler might issue a warning, but C is more relaxed and does an implicit declaration of input as int input() which means that you can pass any value to input and input returns an int.
It is good style to always provide a function declaration before using the function. Only if you do this the compiler can see if you are passing too few, too many or wrongly typed arguments and how to correctly handle the return value (which might be short or char instead of int).

c program, pointers

I'm making a program that takes a three-digit integer and splits it into two integers. 224 would become 220 and 4. 114 would become 110 and 4.
Basically, you do it with modulos. I wrote what I think should work and the compiler keeps saying that there is a missing parenthesis before the &big but any changes just make more errors happen.
#include <stdio.h>
void split_num(int complete, int *big, int *little){
*little = complete%10;
*big = complete - *little;
return;
}
int main()
{
int complete, big, little;
printf("Give an integer to split: \n");
scanf("%d", &complete);
void split_num(complete, &big, &little);
printf("Num split into 2 is : %d and %d", big, little);
return 0;
}
Take out the "void" in your call to split_num(). It's only used in the function declaration (to signify that it does not return a value), not in actual invocations of it.
The line (in main())
void split_num(complete, &big, &little);
should read
split_num(complete, &big, &little);
remove the void in the line "void split_num". You don't specify return values (void) when just calling a method.
You have an error in the following line:
void split_num( complete, &big, &little );
Remove the void return type and invoke the function like so:
split_num( complete, &big, &little );
The return; statement in the split_num( ... ) function is also unnecessary.

Resources