The return data-type of a function,whose prototype is declared in main(), is void.
It cointains an instruction return; as in
main()
{
void create(int *p);
*some code*
}
void create(node *list)
{
*some code*
return;
}
What will it return,and where will it return??
It's not going to return anything, you might have return statements in a void function to kind of alter the flow and exit from the function. ie rather than:
void do_something(int i)
{
if (i > 1) {
/* do something */
}
/* otherwise do nothing */
}
you might have:
void do_something(int i)
{
if (i <= 1)
return;
/* if haven't returned, do something */
}
In this case doesn't mean much.
return; means exit suddenly from this function returning void.
int a()
{
return 10;
}
void b()
{
return; // we have nothing to return, this is a void function.
}
void c()
{
// we don't need return; it is optional.
}
return; for a void function is not useful, it can be omitted, is optional.
However sometime it is useful, for example, for exiting a loop or a switch.
void xxx()
{
int i = 0;
while (1)
{
if (++i >= 100)
return; // we exit from the function when we get 100.
}
}
return; won't return anything, which matches the declared void return type of the function create. It will return to the caller of the function it appears in (not shown in your example), just like return EXPRESSION; will.
In this particular piece of code, return; is redundant since it appears at the very end of create, but it's useful when you want to exit a function prematurely:
void print_error(char const *errmsg)
{
if (errmsg == NULL)
// nothing to print
return;
perror(errmsg);
}
it will return from the executing function with a void return value (which means no value).
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 1 year ago.
Improve this question
Question:
I want to create a reusable function, because in my code much line that use same code structure
The code using for example if { if { `Only here's the different` } }. Of course the pattern not same as this, this using as an example.
I've been code using framework such as Laravel, there's a directive called as SLOT
Is there any way I can inject code in the middle of for loop? Or anything same as SLOT inside C programming
Sample code:
void functionname() {
for (int i=0; i < total_count; i++) {
SELECT THE ITEM (i)
if (a == b) return;
if (c) {
CODE INJECT HERE
}
}
}
Forget to mention before, a, b, c and so on from the coding above is getting from ITEM (i)
You should use a callback. i.e. you should send a function pointer (i.e. the address of the function you want to execute) and use that pointer to execute that function inside your loop.
In the example below, p is a pointer to a function taking a const char * for a parameter and returning an int.
int (*p)(const char *s) ;
NB: all functions passed as parameter, to be used as callback must have the same prototype (which is why such functions are often declared taking a generic pointer parameter void * to accept whatever you've got to send to the function).
So with your example and with functions taking void * as a parameter and returning void *, and with param defining a parameter that you want to feed to your function, this gives us the following code:
void functionname(void *(*func)(void *)) {
for (int i=0; i < total_count; i++) {
SELECT THE ITEM (i)
if (a == b) return;
if (c) {
func(¶m);
}
}
}
you can call your function wiht whatever function respecting the prototype... For instance:
void *my_custom_function(void *param) {
...
}
...
functionname(my_custom_function);
...
As suggested in the comment by KamilCik, use function pointers:
void functionname(void *fx)(void)) {
for (int i=0; i < total_count; i++) {
SELECT THE ITEM (i)
if (a == b) return;
if (c) {
//CODE INJECT HERE
fx();
}
}
}
And use it like
void foo(void) { puts("foo() called"); }
void bar(void) { puts("bar() called"); }
int main(void) {
functionname(foo);
functionname(bar);
}
For a concrete example:
#include <stdio.h>
int a = 1;
int b = 2;
typedef void (*selector)(int, int *);
typedef void (*injector)(void);
void select1(int x, int *c) { printf("%s: %d\n", __func__, *c = x); }
void select2(int x, int *c) { printf("%s: %d\n", __func__, *c = x); }
void inject1(void) { printf("%s\n", __func__); }
void inject2(void) { printf("%s\n", __func__); }
void
functionname(size_t total_count, selector SELECT_THE_ITEM,
injector CODE_INJECT_HERE )
{
for (size_t i=0; i < total_count; i++) {
int c;
SELECT_THE_ITEM (i, &c);
if (a == b) return;
if (c) {
CODE_INJECT_HERE();
}
}
}
int
main(void)
{
functionname(2, select1, inject1);
functionname(3, select2, inject2);
}
You can do what you ask by defining your "CODE INJECT HERE" as the body of a function, and passing a pointer to that function:
void functionname(void (*inject)(void)) {
for (int i=0; i < total_count; i++) {
SELECT THE ITEM (i)
if (a == b) return;
if (c) {
inject();
}
}
}
void do_something(void) {
CODE INJECT HERE
}
void do_something_else(void) {
OTHER CODE INJECT HERE
}
int main(void) {
functionname(do_something));
functionname(do_something_else));
}
Do note, however, that this is not simple code injection in the same sense as a macro would provide. In particular, the executions of do_something() and do_something_else() will not see the local variables of main() or of functionname(), and the do_* functions can return only from themselves, not from a caller further up the chain. The former can be mitigated to some extent by passing parameters to the do_* functions (which they must be prepared to accept).
Another alternative would be to use a macro instead of a function to provide the common framework. It would look something like this:
#define frame_it(x) do { \
for (int i=0; i < total_count; i++) { \
SELECT THE ITEM (i) \
if (a == b) return; \
if (c) { \
x \
} \
} \
} while (0)
int main(void) {
frame_it(
CODE INJECT HERE
);
frame_it(
OTHER CODE INJECT HERE
);
}
That keeps the CODE INJECT HERE code in the function using it, which might be advantageous if in fact each such piece of code is used in only one place. It also allows both that code and the framing code to access the local variables of the function in which they appear, and to return from that function if desired.
However, macro programming has earned a mostly-deserved reputation for being error prone and difficult to read and debug. Your particular need may be one that is well served by this approach, but do not choose this direction lightly.
Function pointers are great for this. You can typedef the function signatures you'd like to support. Example:
/* A signature for condition checking functions, taking a "void*" argument
and returning true or false */
typedef bool(*cond_check_t)(void*);
/* A signature for functions to execute if a condition is met. This takes a
"void*" argument but you decide what you need */
typedef void(*exec_t)(void*);
You can package these two in a struct to form a nice pair:
typedef struct {
cond_check_t checker;
exec_t executor;
} check_exec_t;
And with that, another struct to keep a bunch of these condition and executor pairs:
typedef struct {
size_t size;
size_t capacity;
check_exec_t *conditionals;
} cond_pack_t;
You then create support functions for adding checkers and executors and a function to processes one of these packaged checkers and executors.
cond_pack_t* cond_pack_create(size_t capacity) {
cond_pack_t* cp = malloc(sizeof(*cp));
if(cp) {
cp->conditionals = malloc(sizeof(*cp->conditionals) * capacity);
if(cp->conditionals) {
cp->size = 0;
cp->capacity = capacity;
} else {
free(cp);
cp = NULL;
}
}
return cp;
}
void cond_pack_destroy(cond_pack_t *cp) {
free(cp->conditionals);
free(cp);
}
bool cond_pack_add(cond_pack_t *cp, cond_check_t checker, exec_t executor) {
if(cp->size == cp->capacity) return false;
cp->conditionals[cp->size].checker = checker;
cp->conditionals[cp->size].executor = executor;
++cp->size;
return true;
}
void cond_pack_process(cond_pack_t *cp) {
for(size_t i = 0; i < cp->size; ++i) {
if(cp->conditionals[i].checker(NULL)) { /* execute checker */
cp->conditionals[i].executor(NULL); /* execute executor */
}
}
}
With that, a usage example could look like this
//---
bool some_check(void *foo) {
return true;
}
void some_executor(void *foo) {
printf("some_executor\n");
}
bool some_other_check(void *foo) {
return false;
}
void some_other_executor(void *foo) {
printf("some_other_executor\n");
}
int main() {
cond_pack_t *cp = cond_pack_create(10);
if(cp) {
cond_pack_add(cp, some_check, some_executor);
cond_pack_add(cp, some_other_check, some_other_executor);
cond_pack_process(cp); /* run all the checkers / executors */
cond_pack_destroy(cp);
}
}
Demo
#include <stdio.h>
#define stack 100
void push(int x);
int st[stack];
int top = -1;
int IsEmpty()
{
if (top < 0)
return false;
else
return true;
}
int Isfull()
{
if (top >= stack - 1)
return true;
else
return false;
}
void push(int x)
{
if (Isfull() == true)
printf("stack is full");
else
st[++top]=x;
}
int pop() {
if (IsEmpty() == true)
printf("stack is empty.");
else
return stack[top--];/// There is an error in this part. (expression must have pointer-to-object type)
}
int main()
{
push(3);
}
int pop() {
if (IsEmpty() == true)
printf("stack is empty.");
else
return stack[top--];There is an error in this part. (expression must have pointer-to-object type)
expression must have pointer-to-object type
Stack is being implemented as an array And then there's this error.
What should I do?
Is this a Syntex error? Tell me the wrong part.
and If there is anything else that needs to be corrected, please let me know.
C language is difficult. Have you all experienced this kind of error?
return stack[top--]; same as return 100[top--];.
I suspect you wanted return st[top--];
Use a different name for the stack size too to avoid such name collisions.
// #define stack 100
#define STACK_SIZE 100
I see 3 problems:
A simple typo:
return stack[top--]; ==> return st[top--];
stack is the array size but your array is named st
Missing return value
This code has no return value when the stack is empty.
int pop() {
if (IsEmpty() == true)
printf("stack is empty.");
// No return value here
else
Even if the stack is empty you must return a value. So you need to handle that in another way. One option is to return a dummy value (e.g. zero), another is to exit the program or change the pop-function signature so that it can tell whether it was succesful. For instance:
// Option 1: Return dummy value
int pop() {
if (IsEmpty()) return 0;
return stack[top--];
}
// Option 2: Exit program
int pop() {
if (IsEmpty()) exit(1);
return stack[top--];
}
// Option 3: Let the function tell whether is was a success
int pop(int* data) {
if (IsEmpty()) return 0;
*data = stack[top--];
return 1;
}
The last pop-function returns 1 on success - zero otherwise.
Wrong logic
This function:
int IsEmpty()
{
if (top < 0)
return false;
else
return true;
}
is wrong. Change it to:
int IsEmpty()
{
if (top < 0)
return true;
else
return false;
}
or more simple
int IsEmpty()
{
return (top < 0);
}
I'm doing a school project and i'm going out of my away to get a better grade
With that being said i'm trying to use void pointers and type casting to make my program as general as possible for any type of scenario i throw at it.
I did some code and it does everything it should do but it gives me some warnings whenever i rebuild all but no warning when i compile it.
Side note: I know i am returning an integer to a pointer, but i can't return an local pointer otherwise it will not give me the result i need.
#define VERDADEIRO 1
#define FALSO 0
void * removido(info* tab,int pos)
{
if(strcmp(tab[pos].nome,REMOVIDO) != 0)
{
return FALSO;
}
else
{
return VERDADEIRO;
}
}
void * vazio(info* tab,int pos)
{
if(strcmp(tab[pos].nome,CHAVENULA)!= 0)
{
return FALSO;
}
else
{
return VERDADEIRO;
}
}
int listar(info * tab)
{
int i,c=0,j;
for(i=0;i<HASHTAM;i++)
{
if((int *)removido(tab,i) ==FALSO && (int *)vazio(tab,i)==FALSO)
{
printf("Nome: %s",tab[i].nome);
printf("NIF: %d\n",tab[i].NIF);
printf("Morada: %s",tab[i].morada);
printf("Telefone: %d\n",tab[i].telefone);
printf("Codigo Postal: %d - %d\n",tab[i].codigopostal/1000,tab[i].codigopostal%1000);
printf("Data de nasicmento: %d - %d - %d\n",tab[i].datanascimento%100,(tab[i].datanascimento%10000)/100,tab[i].datanascimento/10000);
printf("Associado: %s\n",tab[i].infoassociado.associado);
if(associado(tab,i)==VERDADEIRO)
{
for(j=0;j<10;j++)
{
printf("Cota de %d anos atras - Estado: %c\n",j+1,tab[i].infoassociado.cotas[j]);
}
}
c++;
}
}
The warnings are comparison between pointer and integer and return makes pointer from integer without a cast.
No, they're not normal. They're telling you that you're using pointers incorrectly. FALSO and VERDADEIRO are not pointers.
Functions which return true and false are not a good use of void pointers, or pointers in general. Nor do you have to define your own true and false values. Instead use the booleans true and false from stdbool.h. (Note: this was added in C99 and some professors cling to the C90 standard.)
#include <stdbool.h>
bool removido(info* tab,int pos)
{
if(strcmp(tab[pos].nome,REMOVIDO) != 0) {
return false;
}
else {
return true;
}
}
bool vazio(info* tab,int pos)
{
if(strcmp(tab[pos].nome,CHAVENULA)!= 0) {
return false;
}
else {
return true;
}
}
And then later you can simply check whether the return value is true or false using normal boolean checks.
if( !removido(tab,i) && !vazio(tab,i) ) {
...
}
Note that double negatives make code difficult to understand. If you check for equality and return true, that is simpler.
bool vazio(info* tab,int pos)
{
if(strcmp(tab[pos].nome,CHAVENULA)== 0) {
return true;
}
else {
return false;
}
}
To really simplify the code, you can take advantage that strcmp(...) == 0 returns a boolean (technically it returns 0 or 1 which can be used as a boolean) and reduce those functions to one line.
bool removido(info* tab,int pos)
{
return strcmp(tab[pos].nome,REMOVIDO) == 0;
}
i want to call "function2();" only for single time when recurfunc() was called for the first time.
recurfunc()
{
function2(); //to be called first time only in a recursive function
static int i= 0;
i++;
if(i>20)
return;
else
recurfunc();
}
A trivial change to your code:
void recurfunc() // * Remember to specify return type *
{
static int i= 0;
if (i==0)
function2(); // called only the first time.
i++;
if(i>20)
return;
else
recurfunc();
}
Use a helper function :
void recurfunc() {
function2();
helperRecurFunc();
}
where helperRecurFunc() is your original method without the call to func2()
I am trying to create a function will return the value located in the struct. My issue is trying to figure out what I can return by the function if theInfo = NULL?
Below is what I have created so far. Is this possible to do?
int getTime(struct * theInfo){
if(theInfo != NULL){
return theInfo->waitTime;
}
else{
printf("getTime Patron is nonexistent\n");
return(thePatron);
}
}
You need to return two pieces of information - the number, and an indication of whether or not that number is valid. One way to do it is changing the signature of the function to indicate whether or not it returned anything, and in case when it does, stick that value in a variable. Here is an example of how you can do it:
// This function returns 1 or 0.
// 1 indicates success; 0 indicates failure
// If your compiler is up to C99 standard, use "bool" instead of "int" below
int getTime(struct * theInfo, int *result) {
if(theInfo != NULL){
*result = theInfo->waitTime;
return 1;
} else{
// result stays unchanged
return 0;
}
}
Now you can use this new function like this:
int res;
if (getTime(&myInfo, &res)) {
printf("getTime returned %d\n", res);
} else {
printf("getTime Patron is nonexistent\n");
}
A less general alternative can be used when you do not need to return a full range of numbers. For example, if the valid time returned by your function is always positive, you could adopt a convention that uses negative numbers to indicate that there was an error. This approach is also valid, but it relies more on a convention, so a reader of your code would need to look through your function documentation to see what is going on.
You could pass a pointer and return a boolean value indicating success:
bool getTime(MyStruct* info, int* time) {
if (info) {
*time = info->waitTime;
return true;
}
*time = 0;
return false;
}
Then somewhere you would just call:
int time;
if (!getTime(info, &time)) {
// TODO: retrieval of time failed
}
Just return -1. I am sure that wait time is always positive.
So return -1 if it is NULL and then check for -1
else{
printf("getTime Patron is nonexistent\n");
return -1;
}
void someFunc() {
//...
int wtime = getTime(astruct);
if (wtime == -1)
// error
//...
}