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.
Related
I have created an array of function pointers to swap two variables.
pointer pointing to these functions namely: swap1, swap2. swap3 and swap4.
swap2 is swaping using pointer passed as arguments.
but while declaring the function pointer, only int and int are passed as arguments. after compiling this causes many warnings.
so do we have a better way of passing the argument, where we put condition in function call itself.
code is given below.
#include <stdio.h>
int swap1(int ,int );
int swap2(int* ,int* );
int swap3(int ,int );
int swap4(int, int);
int swap1(int a,int b)
{
int temp=a;
a=b;
b=temp;
printf("swapped with 3rd variable :%d, %d\n", a,b);
}
int swap2(int *a,int *b)
{
int temp = *a;
*a = *b;
*b = temp;
printf("swapped with pointer :%d, %d\n", *a,*b);
}
int swap3(int a,int b)
{
a+=b;
b=a-b;
a-=b;
printf("swapped with 2 variable :%d, %d\n", a,b);
}
int swap4(int a,int b)
{
a=a^b;
b=a^b;
a=a^b;
printf("swapped with bitwise operation :%d, %d\n", a,b);
}
int main()
{
int ch;
int a=3;
int b=4;
printf("enter the option from 0 to 3\n");
scanf("%d",&ch);
int (*swap[4])(int, int) ={swap1,swap2,swap3,swap4};// function pointer
/*can we pass something like int(*swap[4]( condition statement for 'pointer to variable' or 'variable')*/
if (ch==1)// at '1' location, swap2 is called.
{
(*swap[ch])(&a,&b);//passing the addresses
}
else
{
(*swap[ch])(a,b);
}
return 0;
}
some warnings are as follows.
at line 36 in file '9e748221\script.c'
WARNING: found pointer to int where int is expected
at line 47 in file '9e748221\script.c'
WARNING: found pointer to int where int is expected
at line 47 in file '9e748221\script.c'
Well yes. There are a number of problems with your code, but I'll focus on the ones to which the warnings you presented pertain. You declare swap as an array of four pointers to functions that accept two int arguments and return an int:
int (*swap[4])(int, int)
Your function swap2() is not such a function, so a pointer to it is not of the correct type to be a member of the array. Your compiler might do you a better favor by rejecting the code altogether instead of merely emitting warnings.
Having entered a pointer to swap2() into the array anyway, over the compiler's warnings, how do you suppose the program could call that function correctly via the pointer? The type of the pointer requires function arguments to be ints; your compiler again performs the dubious service of accepting your code with only warnings instead of rejecting it.
Since the arguments in fact provided are the correct type, it might actually work on systems and under conditions where the representations of int and int * are compatible. That is no excuse, however, for writing such code.
Because pointers and ints are unchanged by the default argument promotions, one alternative would be to omit the prototype from your array declaration:
int (*swap[4])() = {swap1,swap2,swap3,swap4};
That says that each pointer points to a function that returns int and accepts a fixed but unspecified number of arguments of unspecified types. At the point of the call, the actual arguments will be subject to the default argument promotions, but that is not a problem in this case. This option does prevent the compiler from performing type checking on the arguments, but in fact you cannot do this correctly otherwise.
Your compiler might still warn about this, or could be induced to warn about it with the right options, but the resulting code nevertheless conforms and does the right thing, in the sense that it calls the pointed-to functions with the correct arguments.
To deal with the warnings first: You declare an array of functions which take int parameters. This means that swap2 is incompatible with the type of element for the array you put it in. This will generate a diagnostic.
Furthermore, when you call one of the functions in the array, the same array declaration tells the compiler that the parameters need to be ints not pointers to int. You get two diagnostics here, one for each parameter.
To fix the above all your functions need to have compatible prototypes with the element type of the array. Should it be int or int*? This brings us to the other problem.
C function arguments are always pass by value. This means that the argument is copied from the variable onto the stack (or into the argument register depending on the calling convention and argument count - for the rest of this post, I'll assume arguments are placed on the stack for simplicity's sake). If it's a literal, the literal value is put on the stack. If the values on the stack are changed by the callee no attempt is made by the caller, after the function returns, to put the new values back in the variables. The arguments are simply thrown away.
Therefore, in C, if you want to do the equivalent of call by reference, you need to pass pointers to the variables you use as arguments as per swap2. All your functions and the array should therefore use int*. Obviously, that makes one of swap1 and swap2 redundant.
The correct array definition is
int (*swap[4])(int*, int*) = {swap1, swap2, swap3, swap4};
and the definition of each function should be modified to take int* parameters. I'd resist the temptation to use int (*swap[4])() simply because it circumvents type safety. You could easily forget the & in front of an int argument when the called function is expecting a pointer which could be disastrous - the best case scenario when you do that is a seg fault.
The others have done great work explaining what the problems are. You should definitely read them first.
I wanted to actually show you a working solution for that sort of problem.
Consider the following (working) simple program :
// main.c
#include <stdio.h>
void swap1(int* aPtr, int* bPtr) {
printf("swap1 has been called.\n");
int tmp = *aPtr;
*aPtr = *bPtr;
*bPtr = tmp;
}
void swap2(int* aPtr, int* bPtr) {
printf("swap2 has been called.\n");
*aPtr += *bPtr;
*bPtr = *aPtr - *bPtr;
*aPtr -= *bPtr;
}
int main() {
int a = 1, b = 2;
printf("a is now %d, and b is %d\n\n", a, b);
// Declare and set the function table
void (*swapTbl[2])(int*, int*) = {&swap1, &swap2};
// Ask for a choice
int choice;
printf("Which swap algorithm to use? (specify '1' or '2')\n>>> ");
scanf("%d", &choice);
printf("\n");
// Swap a and b using the right function
swapTbl[choice - 1](&a, &b);
// Print the values of a and b
printf("a is now %d, and b is %d\n\n", a, b);
return 0;
}
First of, if we try to compile and execute it:
$ gcc main.c && ./a.out
a is now 1, and b is 2
Which swap algorithm to use? (specify '1' or '2')
>>> 2
swap2 has been called.
a is now 2, and b is 1
As myself and others mentioned in answers and in the comments, your functions should all have the same prototype. That means, they must take the same arguments and return the same type. I assumed you actually wanted to make a and b change, so I opted for int*, int* arguments. See #JeremyP 's answer for an explanation of why.
I am trying to pass a user entered variable "find" into this function and return the subscript location of the number (in an existing array) that the user entered. I saw some other posts about this but couldn't understand really what was being explained. Sorry, beginner student.
It isn't quite complete but I cannot compile due to a couple of errors that I am not sure about.
Warning passing argument 2 of 'finder' makes pointer from integer without a cast. Its pointing at:
num_loc = finder(find, sort_num[10]);
Here I am setting "num_loc" to the return of "where" in the function
num_loc = finder(find, sort_num[10]);
printf( "\nYour number is located in memory location %d of the array",num_loc );
"[Note] expected 'int *' but argument is of type 'int'" which is pointing to my function prototype.
//fprototype outside the main at the beginning of the file
int finder(int f,int x[]);
Here is my function:
//function located at the end of the file outside the main
int finder(int f, int x[])
{
int found = 0;
int where;
int i = 0;
while (found != 1){
if (x[i] == f){
found = 1;
where = i;
return where;
}
else{
++i;
}
}
}
num_loc = finder(find, sort_num[10]);
is equivalent to
int num = sort_num[10]; // Problem. Accessing array out of bounds.
num_loc = finder(find, num); // Problem. Using an `int` when an `int*` is expected.
// That's what the compiler is complaining about.
You need to use just sort_num in the call to finder.
num_loc = finder(find, sort_num);
The real solution involves changing finder to accept another argument that indicates the number of elements in sort_num. Otherwise, you run the risk of accessing the array out of bounds. It can also be simplified quite a bit.
int finder(int f, int x[], int arraySize)
{
for ( int i = 0; i < arraySize; ++i )
{
if (x[i] == f)
{
return i;
}
}
// Not found
return -1;
}
and then call it with:
num_loc = finder(find, sort_num, 10);
This is the first part of your function definition:
int finder(int f, int x[])
Your second argument is an int pointer, which the compiler is telling you by saying :
expected 'int *'
You called your function with this:
num_loc = finder(find, sort_num[10]);
If sort_num is an integer array, then sort_num[10] evaluates to the integer at the 11th place in that array. So you're passing your finder function that integer, instead of an int pointer. If sort_num is an integer array, re-write your call as:
num_loc = finder(find, sort_num);
This way you will be passing an int pointer that holds the address of the first element in the sort_num array.
Ok so, I'm trying to write a program which numerically evaluates integrals using Simpson's 3/8 rule. I'm having issues passing the values from Integral *newintegral to the simpson() function. I'm not massively confident in my understanding of structures and pointers, and I've been reviewing the lecture notes and checking online for information all day and I still can't understand why it's not working.
At the moment when I try to build my program it comes up with a number of errors, particularly: on line 46 "expected expression before Integral" and on most of 55-63 "invalid type of argument of '->' (have 'Integral') I don't understand why the first one is occurring because all my lecturers examples of this type of thing, when passing a structure to a function just have the syntax func(Struct_define_name individual_struct_name). I thought this is what I was doing with mind (Integral being the name of the structure type and i being the specific structure) but obviously not.
I think these two problems are connected so I included all of my code for context, however the lines which actually have errors are 46 and 55-63 as mentioned above. I've probably defined the structure wrong in the first place or something though.
(Incidentally the maths in the simpson() function doesn't actually work properly now anyway, but that's not something I'm concerned about)
Also I tried looking at other similar questions but I didn't understand what the other code was doing so I couldn't extrapolate how to fix my code from that. I know this isn't very relevant to other people but I really don't understand programming well enough to try and phrase my question in a general sense...
'#include <stdio.h>
#include <stdlib.h>
#include <math.h>
typedef struct integral {
double result, limits[2];
int degree;
double coefficients[];
} Integral;
// Prototype of function that calculates integral using Simpson's 3/8 rule
double simpson(Integral i);
// function (?) which initialises structure
Integral *newintegral() {
Integral *i = malloc(sizeof *i);
double lim1_in, lim2_in;
int degree_input, n;
printf("Please enter the degree of the polynomial.\n");
scanf("%d", °ree_input);
i->degree = degree_input;
printf("Please enter the %d coefficients of the polynomial, starting\n"
"from the highest power term in the polynomial.\n", (i->degree+1));
for (n=i->degree+1; n>0; n=n-1) {
scanf("%lg", &i->coefficients[n-1]);
}
printf("Please enter the upper limit of the integral.\n");
scanf("%lg", &lim1_in);
i->limits[0] = lim1_in;
printf("Please enter the lower limit of the integral.\n");
scanf("%lg", &lim2_in);
i->limits[1] = lim2_in;
return i;
}
int main() {
Integral *i = newintegral();
simpson(Integral i);
return 0;
}
double simpson(Integral i) {
int n;
double term1, term2, term3, term4;
for (n=(i->degree); n>0; n=n-1) {
term1=(pow(i->limits[1],n)*(i->coefficients[n]))+term1;
term2=(pow(((((2*(i->limits[1]))+(i->limits[0])))/3),n)*(i->coefficients[n]))+term2;
term3=(pow(((((2*(i->limits[0]))+(i->limits[1])))/3),n)*(i->coefficients[n]))+term3;
term4=(pow(i->limits[0],n)*(i->coefficients[n]))+term4;
}
i->result = (((i->limits[0])-(i->limits[1]))/8)*(term1+(3*term2)+(3*term3)+term4);
printf("The integral is %lg\n", i->result);
return 0;
}'
You're currently passing a pointer to a function that takes a single Integral argument.
Your prototype, double simpson(Integral i); tells the compiler "declare a function called simpson that returns a double and takes a single Integral referenced by the identifier i inside the function.
However, in main() you say:
int main() {
//declare a pointer to an Integral and assign it to the return of 'i'
Integral *i = newintegral();
//call the function simpson with i.
//However, you are redeclaring the type of the function argument, so the compiler will complain.
simpson(Integral i);
return 0;
}
Your call, simpson(Integral i); will not work because you are redeclaring the type of the function argument. The compiler will state:
:46:13: error: expected expression before ‘Integral’
What you really need is for simpson() to take a pointer to Integral as its argument. You have actually already handled this inside the function, (using i->) but your function prototype is telling the compiler that you are passing the whole struct Integral as the function argument.
Solution:
Change your function prototype as follows:
double simpson(Integral *i); // function returning double taking single pointer to an Integral named i.
...and change main() to look like the following:
int main(void) { //In C main has two valid definitions:
//int main(void), or int main(int argc, char **argv)
Integral *i = newintegral();
simpson(i);
return 0;
}
So in conclusion, your understanding of pointers is correct, but not how you pass a pointer to a function.
**Sidenote:
Remember to always build your code with all warnings enabled. The compiler will give you very useful diagnostics that will help you quickly find solutions to problems like this. For GCC, as a minimum, use gcc -Wall myprogram.c
Two obvious problems:-
Line 46 : simpson(Integral i);
...should be just simpson(i);. Putting a type there is simply an error.
And this, later:
double simpson(Integral i)
.. tells the compiler to pass in Integral object yet you use the indirection operator i.e i->limits as though you'd been passed a pointer. The easiest fix is to make the function expect a pointer, like this:
double simpson(Integral *i)
C is a reasonably new language to me, most of my programming knowledge is based around Java, or web-based languages - so please be gentle if I come across as a complete noob with this question!
I have an array of type unsigned long, with size 100000, declared in main(). When a certain condition of user input is met, a record() function call is made which initiates some hardware to begin audio recording (not really important to the scope of the question).
At the record() function call, as long as a 'ready' flag in a register is initialised, the contents of the register is copied to an array cell - this process iterates until all 100000 cells of the array have been recorded to.
The array from the record() function now needs be returned to a variable in main(). I have tried this by simply returning a variable of type unsigned long from the method call - but I can't seem to make this work. I have also tried this using pointers - but my inexperience with C is showing when I try this.
My code for using pointers is:
int main(void){
...
unsigned long recordingOne[100000];
unsigned long *ptrOne;
ptrOne = &recordingOne;
...
initiateRecording(ptrOne);
}
void initiateRecording(unsigned long *ptr){
unsigned long returnOne[100000];
for(i = 0; i<100001; i++){
returnOne[i] = AD0DR1 //AD0DR1 corresponds to hardware register
}
*ptr = returnOne;
}
For this I get two warnings:
(in function main) warning: assignment from incompatible pointer type [enabled by default]
(in function initiateRecording) warning: assignment makes integer from pointer without a cast [enabled by default]
When I tried this previously without pointers, I tried passing an array as a parameter, and then returning an array. That looked something like this:
int main(void){
...
unsigned long recordingOne[100000];
...
recordingOne = initiateRecording();
}
unsigned long[] initiateRecording(){
unsigned long toReturnOne[100000];
for(i = 0; i<100001; i++){
toReturnOne[i] = AD0DR1 //AD0DR1 corresponds to hardware register
}
return toReturnOne;
}
The compiler wasn't a fan of this either - I'm struggling to declare a return object of type unsigned long that is also an array.
As always, your help is very much appreciated!
Here is the best method:
int main(void)
{
...
unsigned long recordingOne[100000];
unsigned long *ptrOne; // <<<--- Don't need this
ptrOne = &recordingOne; // <<<--- Don't need this
...
initiateRecording(recordingOne); <<<--- Pass address of array directly
}
void initiateRecording(unsigned long *ptr)
{
for(i = 0; i<100000; i++) <<<---- If i == 100000 undefined behavior, such as a segmentation fault, may occur; change 100001 to 100000
ptr[i] = AD0DR1 // <<<--- write directly to array
}
The accessible elements in recordingOne are from [0] to [99999]
The source of both compiler warnings is the following: when you initialize a C array like int array[100];, the symbol array is a pointer to the first element of the array. So when you write something like int *p = &array, the result is that p points not to the beginning of array, but to the location in memory that holds the pointer to the beginning of array. What you want is int *p = &array[0].
Edit: or int *p = array works just fine too, as pointed out in a comment in another answer.
The following code displays an error if the Storage Class of the parameters of the function int *check(register int,register int); declared as some other Storage Class.
I compiled this code on Code::Blocks 10.05 IDE with GNU GCC Compiler. What is the reason behind the error? Is it a compiler specific error or a general one?
The code section begins from here:
int *check(register int, register int);
int main()
{
int *c;
c = check(10, 20);
printf("%d\n", c);
return 0;
}
int *check(register int i,register int j)
{
int *p = i;
int *q = j;
if(i >= 45)
return (p);
else
return (q);
}
int *check(register int i,register int j)
{
int *p=i;
int *q=j;
Type mismatch of p q and i j. Perhaps what you want is :
int *check(int i, int j)
{
int *p=&i;
int *q=&j;
Correction: Note that register cannot be used with &. Besides, the keyword register has little usage because the compiler usually ignores it and does the optimization itself.
int *check(register int i,register int j)
{
int *p=i;
int *q=j;
if(i >= 45)
return (p);
else
return (q);
}
While register storage class specifier is allowed on parameter declaration, parameters i and j have int type while p and q are of type int *. This makes the declaration of p and q invalid.
You cannot just change this to:
int *p=&i;
int *q=&j;
as the & operator does not allow you to have an operand of register storage class.
You cannot also also change the parameter declaration from register int i and register int j to int i and int j and then return the address of i and j object as their lifetime ends at the exit of the function.
In your case you should just not use pointers: use int parameters and an int return value.
First type mismatch:
int *p=i;
int *q=j;
Second side note & not applied/valid on register variables.
From: address of register variable in C and C++
In C, you cannot take the address of a variable with register storage. Cf. C11 6.7.1/6:
A declaration of an identifier for an object with storage-class specifier register
suggests that access to the object be as fast as possible. The extent to which such
suggestions are effective is implementation-defined.
third: Returning address of local object is Undefined behavior (and parameters of functions counts in local variables). Don't return address of that there life is till function returns.
Suggestion:
To return address, you need to do dynamic allocation and return address of that. for example:
int *check(int i,int j){
int *p= malloc(sizeof (int));
int *q= malloc(sizeof (int));
*p = i;
*q = j;
if(i >= 45){
free(q);
return (p);
}
else{
free(p);
return (q);
}
}
Note returned address is not of i, j, but its address of dynamically allocated memory. Don't forget to call free(a) in main().
In my machine with GCC 4.7.3 on Ubuntu 13.04, the output is
$gcc test.c
test.c: In function ‘main’:
test.c:7:3: warning: incompatible implicit declaration of built-in function ‘printf’ [enabled by default]
test.c:7:3: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int *’ [-Wformat]
test.c: In function ‘check’:
test.c:13:12: warning: initialization makes pointer from integer without a cast [enabled by default]
test.c:14:12: warning: initialization makes pointer from integer without a cast [enabled by default]
$./a.out
20
It accepts the program with a lot of warnings. And there is not a single word says "storage class". so I wonder what version of GCC you are using?
The first two warnings can be fixed by #include <stdio.h> and change %d in the printf function call to %p. Let's ignore those for now and focus on the rest two. Depends on what you want to do, you can have different options to eliminate them.
If you want to return the address of i or j as a stack based variable (which is unusual because it is invalid after return to the caller), you can do
int *check( int i, int j)
{
int *p = &i;
int *q = &j;
...
You cannot obtain the address of a register variable, so you have to remove them. In this case, with your main function your program will print something like 0x7fffc83021f8 in my machine. That is the pointer value to the variable j, although it is not valid at the time we prints it, as long as you do not attempt to dereference it everything is OK.
If this is not what you want, you probably want to force the integer i or j to represent a pointer, then you need to do
int *check(register int i,register int j)
{
int *p=(int *)i;
int *q=(int *)j;
if(i >= 45)
return (p);
else
return (q);
}
Note in this case the use of register keyword is OK although it may have very limited effect. Also this would still warn you when you compile the code in some machine (especially 64 bit GCC).
Although strange, but this code have some sense: usually an integer that too close to zero is not a valid pointer.
So what this code does is: it returns i's value as a pointer if it's a valid pointer(value greater than 45), or return js value. The result in this case is 0x14 (remember we need to replace %d to %p, so the output is in hexadecimal).
EDIT
After look at your main function I believe what is wanted here would be
int check(register int i,register int j)
{
int p=i;
int q=j;
if(i >= 45)
return (p);
else
return (q);
}
But anyway this code can be simplified as
int check(register int i,register int j)
{
if(i >= 45)
return i;
else
return j;
}
or even
int check(register int i,register int j)
{
return i>=45 ? i : j;
}
in these cases the main function should be
int main()
{
int c;
c = check(10, 20);
printf("%d\n", c);
return 0;
}
Note since the data type of c is now int so the %p for printf is restored back to %d. The output is the same of the original code: 20.
OK now I see what you are asking.
If you have a function prototype declaration like this:
int *check(register int, register int);
As soon as the compiler sees this, it can enforce a rule that no code will attempt to obtain the address of the parameters. It is up to the compiler to consider a consistent way to generate code for function calls through out the program based on this fact. This may or may not be the same as
int *check(int, int);
Which performs the default treatment of parameters (but again the compiler will ensure it is consistent through out the program).
But consider the following:
int *check(auto int, auto int);
The compiler do not know weather the address of the parameter is going to be used or not unless it sees the actual implementation. So it cannot assume anything. The programmer obviously want some optimization, but the compiler do not have any further information to do so.
So it does not make sense to specify a parameter to be auto.
What if use auto for parameters of function definition? Again this makes little sense. The compiler can have a strategy that if there is no attempt to obtain the parameter address then treat it as register other use stack for it. But for parameters that do not use auto the rule would be the same. So it does not gives the compiler any further information.
Other storage classes are even makes no sense for parameters in function definition. It is not possible to pass a parameter through static data area or the heap (you can only pass pointers - which actually in the stack or registers).