Is it normal that void pointers give warnings? - c

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;
}

Related

What do I do with the error in implementing the stack?

#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);
}

Will an If inside An If always be read? Not nested, but put right in front of the last one

The second if is always executing, no matter what the values from the first one was, I´m comparing char arrays from a struct.
Tried doing all of the comparisons in one If, like this:
if(strcmp(t[j].NomePeca, t[n].NomePeca) == 0 && strcmp(t[j].nroPoltrona, t[n].nroPoltrona) == 0 && strcmp(t[j].hora, t[n].hora) == 0 && strcmp(t[j].data,t[n].data) == 0) { ... }
Same thing.
struct TabelaIngresso {
char NomePeca[30];
char data[10];
char hora[5];
int aPagar;
char nroPoltrona[3];
};
// ............................
if (strcmp(t[j].NomePeca, t[n].NomePeca) == 0 && strcmp(t[j].nroPoltrona, t[n].nroPoltrona) == 0) {
if((strcmp(t[j].hora,t[n].hora) == 0) && (strcmp(t[j].data,t[n].data) == 0)) {
anulado = 1;
printf("\nCompra anulada pois a poltrona nao esta disponivel!\n");
strcpy (t[j].NomePeca, "Anulado");
strcpy (t[j].data, "Anulado");
strcpy (t[j].hora, "Anulado");
t[j].nroPoltrona[3] = '0';
t[j].aPagar = 0;
}
}
This If should only be executed if all of the strings are the same.
You might be asking about behavior called Short-circuit evaluation. It is the default behavior of the majority of the commonly used programming languages. The idea is that in a boolean expression the next argument is executed or evaluated only if the first argument does not suffice to determine the value of the expression. Have a look at the example:
function foo() {
console.log('foo');
return false;
}
function bar() {
console.log('bar');
return true;
}
if (foo() && bar()) {
console.log('bar() will not ever be called');
} else {
console.log('calling foo() is enough');
}
The code above is equivalent to:
const bool = && bar();
if (foo()) {
if (bar()) {
console.log('bar() will not ever be called');
}
} else if (!bar()) {
console.log('calling foo() is enough');
}
But it's much easier to read the code from the first snippet.

Error with bool function

I am a new C developer (I am used to programming in Java), and have tried create, what I thought was a simple bool function. Although I am getting an error which I don't understand how to fix:
#include <stdio.h>
#include <stdlib.h>
typedef enum { false, true } bool;
int main() {
int currentNumber, round = 1;
printf("Numbers generated will be between 1 and 20. \n");
currentNumber = rand() % 20;
bool validNumber = false;
do {
if(currentNumber != 0) {
validNumber == true;
} else {
currentNumber = rand() % 20;
}
}while(validNumber == false);
printf("You're on round" + ("%d", round));
printf("You're current number is: " + ("%d", currentNumber));
printf("Higher or Lower (H/L)?");
char userInput [20];
scanf("%s", &userInput);
if((userInput[0] == 'h') || (userInput[0] == 'H')) {
completeRound(round, 'H', currentNumber);
} else if((userInput[0] == 'l') || (userInput[0] == 'L')) {
completeRound(round, 'L', currentNumber);
}
}
void completeRound(int round, char input, int currentNumber) {
int initialVal = currentNumber, newVal;
if(input == 'H') {
newVal = rand() % 20;
bool checkResult(initialVal, newVal, input);
} else {
newVal = rand() % 20;
bool checkResult(initialVal, newVal, input);
}
}
bool checkResult(int initialVal, int finalVal, char input);
bool checkResult(int initialVal, int finalVal, char input) {
if(input == 'H') {
if(initialVal <= finalVal) {
return true;
} else {
return false;
}
}
if(input == 'L') {
if(initialVal >= finalVal) {
return true;
}else {
return false;
}
}
printf("An error has occurred! Aborting game...");
return false;
}
The error is as follows:
\main.c|39|error: conflicting types for 'checkResult'
At first, I thought that for some reason, in C you could only pass certain data types as arguments to a bool method, although I can not find a straight answer to this on Google. Other than that; I can not understand what it means by "conflicting types" (this is the first time I've debugged a C program.
The function I have used to call checkResult is as follows:
Before calling the function you need to write its prototype also. By default compiler is considering it as return type of int but actually it is bool.
so write bool checkResult(int initialVal, int finalVal, char input) before calling checkResult.
You probably have a typo in your code. The line
bool checkResult(initialVal, newVal, temp);
implicitly creates a prototype for a bool function. The types of the arguments are omitted and default to int in C versions prior to C99. This declaration is in conflict with the actual declaration, whose third parameter is of type char.
You probably meant something like this:
bool okay = checkResult(initialVal, newVal, temp);
This defines a bool variable okay and initialises it with the result of the function call. (But note that this variable is local to the current scope, so in your example you'd lose the result immediately.)
It is legal in C to declare a function inside a function body, although it is not good practice. It is more usual to declare them in headers or at the beginning of the file.
As of C99, implicit function declarations are invalid. There also isn't a default argument or function return type of int. You might consider to enforce the C99 standard (eg with -std=c99in gcc) to avoid falling into the implicit-declaration trap.
You have called functions before declaring them.So is the error. Because by default the return type of a c function is "int".
Add
void completeRound(int , char , int );
and
bool checkResult(int , int , char);
after your typedef (better this way than declaring them in body of the calling function).
And since checkResult() is returning a value of type bool you better assign it to a variable of type bool like
bool okay = checkResult(initialVal, newVal, temp); this.

Creating int function which in case of an error can not return a valid int value

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
//...
}

What is best approach to define function which takes true or false as parameter in C

As title stated, I'm writing function taking 2 boolean as parameters but don't know what is the best way to do! What are your suggestions?
c99 already provides the bool data type if you are using that, you can use it directly.
Else another ways are:
Simple way: Use integers and treat 0 as false and 1 as true.
Verbose way: Create enum with true and false names and use that.
Code Sample:
typedef enum
{
FALSE = 0,
TRUE = 1
}Boolean;
int doSomething(Boolean var1, Boolean var2)
{
if(var1 == TRUE)
return 1;
else
return 0;
}
int main()
{
Boolean var1 = FALSE;
Boolean var2 = TRUE;
int ret = doSomething(var1,var2);
return 0;
}
You can use the C99 bool type
#include <stdbool.h> //don't forget to include this library
void func(bool a, bool b)
{
}
int main(void)
{
bool a = true, b = false;
func(a, b);
return 0;
}
take a look at :
C99 boolean data type?
Using two int values should work fine:
void func(int x, int y)
{
if(x) // x is non-zero
{
// do something
}
if(y) // z is non-zero
{
// do something
}
}
func(0, 1); // x is false, y is true
You could #define true and false to be something like 1 and 0:
#define FALSE 0
#define TRUE 1
func(FALSE, TRUE);
typedef enum boolean_t{
FALSE = 0,
TRUE
}boolean;
int main(){
fun1(TRUE);
}
int fun1(boolean val)
{
if (val == TRUE){
printf("True\n");
}else{
printf("False\n");
}
}
Try something like this. An int can act like a bool. Zero is false. Everything else is true.
#include <stdio.h>
void function (int boolValue)
{
if (boolValue)
{
printf("true");
}
else
{
printf("false");
}
}
int main(void)
{
function(1 == 2);
function(1 > 2);
return 0;
}
If size matters to you, you could as well try (assuming you only have a C89 Compiler)
#define false 0
#define true 1
typedef char Boolean;
//...
Boolean test = true;
if( test )
puts("Heya!");
else
puts("Not Heya!");
//...
and your Boolean is guaranteed to have sizeof() == 1

Resources