I have a small program which when compiling throws me the following errors
error #2168: Operands of '+' have incompatible types 'struct agenda' and 'int'.
error #2113: Left operand of '.' has incompatible type 'int'.
error #2088: Lvalue required.
This is the code that I have done
#include <stdio.h>
struct agenda{
int order, cellular;
char name[30], last_name[30], street[30], city[30], mail[50];
}contact[10];
int main(void)
{
struct agenda *ptrcontact;
ptrcontact = &contact[0];
(*ptrcontact+3).order = 3;
printf("\n\n %d", (*ptrcontact).order);
return 0;
}
because it throws these errors and how to fix them?
You need to change
(*ptrcontact+3).order = 3;
to
ptrcontact[3].order = 3;
or, at least,
(*(ptrcontact+3)).order = 3;
or,
(ptrcontact + 3)->order = 3;
Otherwise, as per the precedence rule, * has higher precedence over +, causing the error.
Just to add to that, ptrcontact is a pointer ( to struct agenda) and can be used as an operand to + operator.
OTOH, *ptrcontact is of type struct agenda and cannot be used as an operand to + operator.
You are dereferencing the pointer which yields the struct and obviously you can't add anything to that. Dereference operator has the highest priority, you need to do it like this: (*(ptr + 3)).order or use the arrow instead of star dot: (ptr + 3) -> order
Your problem here is operations priority:
(*ptrcontact+3).order = 3;
This derefers ptrcontract and then tries to add number to dereferred structure. Which gives you exact situation you report.
My recommendations:
Either avoid address ariphmetics in such cases. Operate array indexes.
int baseIndex = 0;
contact[baseIndex + 3].order = 3;
Or if you really have to do so, hide address arithmetic from outside:
(pcontact + 3)->order = 3;
And finally learn C language operations priority or, to do it once (but some C people don't like C++), C++ operations priority
the error is in the lines
(*ptrcontact+3).order = 3; and printf("\n\n %d", (*ptrcontact).order);. In this instructions use -> instead of . the errors will be solved.
Related
So I solved my problem, wasn't that hard, but I'm wandering why the first version wasn't working.
So here, an example of my problem :
typedef struct a {
int i;
} A;
typedef struct b {
int i;
A a;
} B;
typedef B * PB;
PB create_B(int ia, int ib) {
PB b = malloc(sizeof(B));
b->i = ib;
b->a = {ia};
}
I get an error from the compiler saying :
"error: expected expression before ‘{’ token"
at line: b->a = {ia};
But i don't really get what is the problem.
I solved it casting the structure :
PB create_B(int ia, int ib) {
PB b = malloc(sizeof(B));
b->i = ib;
b->a = (A){ia};
}
But the types are well defined no ? I mean it's kind of obvious to me that {ia} is of type A since b->a is of type A aswell.
I am probably wrong on this last saying (compiler is probably right). So if you have an example where this situation isn't obvious and really need a cast, it would be really appreciated, or jut an explanation at least.
Thank you for your time.
Barioth
PS :
I could have done that too i guess
PB create_B(int ia, int ib) {
PB b = malloc(sizeof(B));
*b = (B){ib, {ia}};
}
But i still need a cast...
{ia} is not an expression in C and cannot be used in an expression statement.
{ia} is part of a syntax for definitions. In a definition, a list of initial values may be given in braces after an =. (And the braces may be omitted when initializing a scalar object.) This is a special syntax for initializing in a definition and is not an assignment like using = in an expression.
(A){ia} is an expression; it is a construct called a compound literal. After a type name in parentheses, initial values are given inside braces. This creates an object of the stated type. That object may then be used in an expression, such as as the right operand of an assignment.
I have to learn it for my study. Is their any way to cast a pointer to integer. I have to give myEulerForward1 a pointer as a paramter and i always get this error message :
eulerZahl.c: In function ‘main’:
eulerZahl.c:38:35: warning: passing argument 1 of ‘myEulerForward1’ makes pointer from integer without a cast [-Wint-conversion]
double forward = myEulerForward1(k);
^
eulerZahl.c:16:8: note: expected ‘int *’ but argument is of type ‘int’
double myEulerForward1(int *n1){
^~~~~~~~~~~~~~~
Can someone help me with it?
#include <stdio.h>
#include <stdint.h>
double kFactorial(int k){
if(k <= 1){
return 1;
}
return k * kFactorial(k - 1);
}
double myEulerForward1(int *n1){
double n = 1;
double euler, nFact = 1;
for(int i = sizeof(&n1); i >= 0; i--){
nFact*= i;
euler = euler + (1.0/nFact);
}
return euler;
}
int main(){
int k = 4;
double factorial = kFactorial(k);
printf("The factorial of %d is: %lf ", k, factorial);
double forward = myEulerForward1(k);
printf("The Eulers Number: %lf", forward);
}
First i can see an error at sizeof(&n1);
Of course n1 is a pointeur. His Value is a RAM address. But for see his Deferenced value, you must use * before n1. & is used for get the adress of something. * is used for get the inside of a pointer.
Use : sizeof(*n1);
In Second, i see that you get a pointer in the prototype of myEulerForward1
double myEulerForward1(int *n1)
It's your compile error. He said that your function need a pointer (an adress) and that you put everything except that.
So when you call this function, you must put a pointer (a RAM adress).
And for do that, in the calling of the function, you must use & of course for get the adress of n1 and not his number value.
Use : double forward = myEulerForward1(&k);
Well, yes, it is possible to convert a pointer to an int, and vice versa.
However, you are making a serious mistake in asking that question. There are circumstances where converting an int to a pointer, or vice versa, makes sense. But, in your code, you would be using it as a blunt instrument to force the compiler to accept bad code.
Your compiler is complaining because you have passed an int to a function that expects an int *.
Forcing the issue, by converting that int to a pointer, will stop the compiler complaining, but then you'll (possibly) get some form of runtime error, since the function will receive an invalid pointer.
Your choices are
remove the * from double myEulerForward1(int *n1). This will mean, the function expects an int, so your code that passes an int will be correct.
Call the function as myEulerForward1(&k) which passes an address of k (which is not k converted to a pointer) as a pointer.
Looking at the body of myEulerForward1() there are other problems as well. You need to read up and better understand what sizeof does. Whether your function accepts an int or a pointer (int *) the logic of your function is faulty.
So, I have written a function for insertion into a queue viz en_queue. The function body is:
void en_queue(queue,max,front,rear)
{
int ch1;
printf("\n Enter element to add->");
scanf("%d",&ch1);
if(front==0 && rear==(max-1))
{
printf("\n Caution!! Queue Overflow!!");
}
else if(rear==(max-1) && front>0)
{
rear=0;
*queue[rear]=ch1;
}
else if(front==-1 && rear==-1)
{
front=rear=0;
*queue[rear]=0;
}
else
{
rear++;
*queue[rear]=ch1;
}
}
And the prototype declaration is:
void en_queue(int *,int, int, int);
And during calling, I called it like:
en_queue(queue,MAX,front,rear);
where queue[MAX] is an array (#define MAX 10), MAX is the number of elements the array can incorporate and both front and rear are integers with current value -1. I am getting repeated errors of type error: pointer expected and Conflicting argument declarations for function 'en_queue'.
I can't see why arguments are not matching. Because I passed an address of the array and received it in a pointer variable and worked with the pointer. So how can there be error?
First:
void en_queue(queue,max,front,rear)
{
should be:
void en_queue(int *queue, int max, int front, int rear)
{
And second, expressions like *queue[rear] = 0; should be just queue[rear] = 0; because queue is int*.
Note: An expression a[i] == *(a + i), so if a is pointer then in expression a[i] you doesn't need to deference * explicitly.
In your expression *queue[rear], you are getting error type error: pointer expected because you dereference twice e.g. *queue[rear] == * *(queue + rear) because *(queue + rear) is not pointer but a int hence compiler message is need a pointer.
Compiler message: "Conflicting argument declarations for function en_queue()" because of first argument is int*. As in function definition you doesn't specify type of arguments default is considered int type.
If queue is int * then the correct way to access it as an "array" is
queue[index];
and NOT *queue[index]
queue[index] is actually *(queue + index).
if you do *queue[index] you are actually doing *(*(queue + index)) .
(queue + index) will get to the address location index locations away from the addres stored in queue . *(queue + index) will dereference it by getting the value stored at the address. *(*(queue + index)) will use the fetched value as an address and try to make another fetch, which is wrong because now you dereference an integer.
While you can write a declaration without naming your arguments, just giving the type specifiers, you cannot write a definition with only the names and without the specifiers. The conflicting argument declarations error is because of this, because the compiler interprets the argument names in your definition as types rather than names. Think about it, how could the compiler know the difference between a name given without a type and a type given without a name?
As #grijesh has written, you should write your definition as:
void en_queue(int *queue, int max, int front, int rear)
instead.
The other problem is that you're dereferencing your pointer twice, which doesn't make sense with a pointer to an integer. An array and a pointer are similar in the way that they give a memory address that you can use to do further indexing. This can be done by using the regular index operator:
queue[index]
or using the explicit pointer dereferencing operator *, and pointer arithmetic like this:
*(queue + index)
Read more about pointer arithmetic here.
You said: ..where queue[MAX] is an array..
Your declaration is: void en_queue(int *,int, int, int);
Then what does this mean: *queue[rear]=ch1;
You are trying to dereference an integer
Correct all the instances in your program like above to: queue[rear] = ch1;
I have a struct
typedef struct _scaffale {
int NumeroScaffale;
scaffali * succ;
copia** pos;
} scaffale;
in which I have an array of the struct copia. The error comes in the following code:
copia** temp;
temp=scaff->pos;
(temp+controllo)=nuovo->copie;
in the third row to be precise. The question is: why this line give me that error while in the following code in which I use the same construct it is perfectly allowed:
while(i<=MAXLIBRI){
if ((temp+i)!=NULL) {
i=i+1;
}
else break;
}
(temp+controllo) is an rvalue. By that I mean it's a computed value, not a location to put something. I'm guessing that what you really meant is *(temp+controllo) = nuovo->copie; instead, which would have assigned nuovo->copie into the location identified by temp+controllo.
For an analogy, if i is an int, you can say i = 3, but you can't say (i+1) = 3. I hope it's obvious why.
(temp+controllo) is a computed value, and doesn't follow the language rules for being a proper l-value which is a fancy way of saying "you can't put it on the left of an assignment operator".
I am suppose to be creating a memory map of this program for my class, but when I try to compile it, I get an error:
invalid operands to binary expression ('double *' and 'double *')
I am a student, please do not edit the code to print out memory locations, I need to write that myself.
main()
{
double testd;
int testi;
FILE *fpt;
struct frog {
double *x, y;
}frog;
struct frog turtle, *apple, tv[3];
testi = 2;
apple = &turtle;
apple->x = &testd
*(turtle).x = 7.3; //this is where im getting the error.
(*apple).y = 3.6;
turtle.y = 1.5;
for (testi = 0; testi < 3; testi++)
tv[testi].x = &(tv[(testi+1)%3].y);
*(tv[1].x) = 6.4;
}
You are missing the ; at the end of the previous line.
You are not wrong to dereference *(turtle).x instead of *(turtle.x). The . operator has higher precedence than the * operator, meaning those two statements are equivalent and you don't even need parentheses: you could just do *turtle.x.
Check out this site for precedence ordering.
You are missing the ; at end of the previous line.
The compiler then interprets the * at the beginning of the line as a multiplication symbol and complains because that doesn't work out so well.
You simply forgot ; after apple->x = &testd statement.
On a side note, in C you have to say struct before a structure, and main function is supposed to return an integer. You also need to include header files with declarations of data structures and functions that you are using (i.e. stdio.h). Not to mention that // comment style is C99, and C programmers don't really use it.. /* */ comments are awesome.