I'm trying to use a separate function to input data using scanf() (outside of main). This new function is supposed to print a line and then receive input from the user. However something appears to be going awry between the scanf in the function and the printf() function in the main that I am testing it with.
I believe that I am receiving a pointer from the function but certain compiler warning are making me wonder if my assumption about the pointer is even correct.
I am confused by the output of this code:
#include <stdio.h>
void set_Info(void);
int main()
{
int scanNum = 0;
set_Info();
printf("%d", &scanNum);
return 0;
}
void set_Info(void) /* start of function definition */
{
int scanNum;
printf("Scan test, enter a number");
scanf("%d",&scanNum);
}
If I provide a number, say 2, the result of the printf statement in the main() is:
2665560
Now, in so far as I am able to tell that output appears to me like a memory address so what i attempted to do to fix that is dereference the pointer in main like so :
int scanNum = 0;
int scanNumHolder;
set_Info();
scanNumHolder = *scanNum;
printf("%d", &scanNumHolder);
I believe that this code makes scanNum variable to become assigned to the dereferenced value of scanNum. However I get the same output as above when I do this. Which leads me to believe one of two things. Either that I am not correctly dereferencing scanNum, or that scanNum is not in fact a pointer at all in this situation.
The most common error I receive from the compiler is:
error: invalid type argument of unary ‘*’ (have ‘int’)
Which makes sense, I suppose, if I'm attempting to treat an int value as a pointer.
If it is the case that scanNum is not being dereferenced correctly, how can I achieve this?
Thank you for the help
*Update
Thanks for the help.
Just to recap
My set_info function needs to be passed an address parameter. The reason an address parameter has to be used is because the local memory of a function is erased after the function call ends. So in order to do work a variable declared in the main function, I pass the address of the variable in question so that when the function ends the changes are not lost.
Inside the main function, when set_info is called with &scanNum as the argument, it passes a reference tp the variable so that it can be assigned the value generated by the scanf statement in the function.
I realize that what I was doing wrong as correctly pointed out by the awesome people of SO, is that I am trying to call set_info like it returns a value but in fact changes the variable like I actually want.
Thanks again for the help!
This function:
void set_Info(void)
{
int scanNum;
scanf("%d", &scanNum);
}
reads the integral number from the standard input and stores it into scanNum variable, which is local variable with automatic storage duration that exists only within the scope of this function.
And the body of your main:
int scanNum = 0;
set_Info();
printf("%d", &scanNum);
defines a local variable called scanNum, then calls a set_Info() function which doesn't affect scanNum defined in main in any way and then it prints the address of scanNum variable.
This is what you are trying to do:
void set_Info(int* num)
{
// read an integer and store it into int that num points to:
scanf("%d", num);
}
int main()
{
int scanNum = 0;
// pass the address of scanNum to set_Info function so that
// changes to scanNum are visible in the body of main as well:
set_Info(&scanNum);
printf("%d", scanNum);
return 0;
}
I also recommend you spend more time reading some book with C basics before you'll continue programming :)
I would pass in the variable into your set_Info function, so that it knows where to save the data. This would then allow you to scan multiple values, and you would simple increment the pointer. Be sure to pass the variable address into set_Info() using &variableName, since that function expects a pointer
#include <stdio.h>
void set_Info(int *pScanNum);
int main()
{
int scanNum = 0;
set_Info(&scanNum);
printf("%d", scanNum);
return 0;
}
//Pass in the pointer to scanNum
void set_Info(int *pScanNum)
{
printf("Scan test, enter a number");
scanf("%d",pScanNum);
}
Get rid of your ampersand! Printf wants an integer not a pointer.
printf("%d", scanNum);
And as liho said, you need to return scanNum from set_info so you can get at it outside of the function.
int scanNum = set_Info();
Related
I am trying to write a code in C about a type of encryption.
My code:
#include<stdio.h>
int* number_split(int x)
{
int arr[5],i=0,j=0;
static int ar1[5];
while(x!=0)
{
x=x%10;
arr[i]=x;
++i;
}
for(i=4;i<=0;i--)
{
ar1[j]=arr[i];
++j;
}
return ar1;
}
int main()
{
int n,k,*arr,i=0,l;
printf("Please enter any number:");
scanf("%d",&n);
printf("Please enter a key:");
scanf("%d",&k);
arr=number_split(n);
l=k%5;
for(i=l;i<4;i++)
{
printf("%d\t",arr[i]);
}
for(i=0;i<l;i++)
{
printf("%d\t",arr[i]);
}
return 0;
}
I had looked up into the internet and found that static or globally declared arrays can be returned to other functions. So, I decided to modify my code, but now the problem is that I am getting Segmentation fault(core dumped) and I don't know why. Can someone please help me?
You need to declare your method before using it, like this:
#include<stdio.h>
int* reverse(int* ar);
void number_split(int x)
{
...
or, of course, you could simply move the definition of your reverse method before using it, i.e. before defining the number split method.
So I tried using dynamic memory allocation
Nope, I mean not as far as I can tell, there is no dynamic memory allocation anywhere happening in your code.
You are using a locally defined array instead, and that's why you get this warning (by enabling warnings in your compiler, e.g. Wall, Wextra flags in GCC):
main.c:24:12: warning: function returns address of local variable [-Wreturn-local-addr]
24 | return ar1;
| ^~~
So the issue that here:
int* reverse(int* ar)
{
int ar1[5],i=0,j=0;
// your logic
return ar1;
}
by the time you return the array, the method will have terminated, and since that array was a local variable to that method, it will go out of scope, its lifetime will end (and will be destroyed).
That means, that when the caller would like to use that array, there is no array left in memory to be used, so the caller will just use some memory filled with garbage.
Here, you could dynamically allocate the array, which typically, in a correct program, will stay on memory until you, explicitly, ask for its de-allocation.
error saying that my function type is conflicting?
Because the prototype of the method is:
void number_split(int x);
but you are calling it like this:
arr = number_split(n);
even though its return type is void. Thus the warning:
main.c:34:8: error: void value not ignored as it ought to be
34 | arr=number_split(n);
| ^
number_split is defined as to not return anything:
void number_split(int x)
yet you expect it to return something:
arr=number_split(n);
Even if you define it to return the correct type, which would be
int *number_split(int x)
you let it return a local variable arr. But that variable won't exist after the function returns. So you either need to pass it the array in which to return the result, or let it allocate memory using malloc. I leave that as an excercise for you.
For starters the program does not make sense and if it will even compile has undefined behavior.
For example in this for loop
for(i=sizeof(ar);i<=0;i--)
there is used sizeof( int * ). It seems you mean
for(i=sizeof(ar1);i<=0;i--)
And the function returns a pointer to a local array that will not be alive after exiting the function.
int ar1[5],i=0,j=0;
//...
return ar1;
Or this loop
while(x!=0)
{
x=x%10;
arr[i]=x;
++i;
}
has at most two iterations due to this statement
x=x%10;
It seems you mean
do
{
arr[i] = x % 10;
++i;
} while ( x /= 10 );
The function number_split declared like
void number_split(int x)
has the return type void. But you are using the return type to assign it to a pointer
int n,k,*arr,i=0,l;
// ...
arr=number_split(n);
And the function reverse shall be declared before the function number_split.
The title describes what I'm trying to do, but I'm getting the error message that I never declared base1. I actually know this, but I'm not exactly sure how to actually fix the problem.
int getBase1(void);
int setBase1(double);
int main(void){
getBase1();
setBase1(base1);
}
int getBase1(void){
printf("Please enter the length of a base: ");
return;
}
int setBase1(double base1){
scanf("%lf", &base1);
}
You must use pointer, otherwise the variable inside the method will not point to the same memory adress. Using pointer you'll be putting the value inside the memory address of the variable that you pass in the function call.
One more thing, this way you will not need return values.
Try this way:
#include <stdio.h>
void getBase1(void);
void setBase1(double *base1);
int main(void){
double base1;
getBase1();
setBase1(&base1);
printf("%lf", base1);
}
void getBase1(void){
printf("Please enter the length of a base: ");
}
void setBase1(double *base1){
scanf("%lf", base1);
}
Seems like you're quite new to C programming. Here's a thing, you simply can't use scanf to modify a value of a main function variable without using pointers. If you read about scanf, you would find out that scanf requires the memory address of a variable; that's why scanf is able to read the format string and modify your variable. So what you're trying to achieve is pretty much similar to scanf, you have to pass the address of base1; first of all declare it! Since that's what compiler is crying about. Do the following things:
Declare and pass the address of the variable you want to modify. Pass the address of base1 like this:
double base1;
getBase1();
setBase1(&base1);
In the function getBase1 you're doing a void return, but your function signature tells the compiler that you would return an int. So your functions should look like this:
void getBase1(void);
void setBase1(double *);
Since your setBase1 is receiving an address, there is no need for an ampersand(&). Simply pass the pointer value received:
void setBase1(double *pBase) { scanf("%lf", pBase); }
You have many errors in your code, first int main(), should have the return type and your function doesn't return anything either. base1 is not declared.
error: ‘base1’ undeclared (first use in this function)
setBase1(base1);
^
where is the base1 in your main function?
Its basic your passing base1 as an argument to setBase1 but base1 is not declared.
I know that If a function has no argument & only return type (say int), then I can change my int variable by assigning the function to my variable as below,
main()
{
int var_name;
var_name = func();
printf("My variable value is updated as : %d", a);
}
func()
{ return 100; }
Also I know that If I have my function's return type as void, with no arguments, then I can only print the value inside the function itself and cannot return anything in turn.
But, my doubt is, is there anything else that I can do to update my var_name by calling a function with no arguments & no return type ?
ie., void func(void); by using something like pointer concepts ??
I could not able to find the exact answer for the same by my searches among so many websites.. I will be very grateful if someone can help me out finding whether I can do it by this way or not,.
Thanks,.
It is possible to modify a local variable in main, from a function with no arguments and no return value, if there's a global pointer to it:
#include <stdio.h>
int *p;
void func() {
*p = 6;
}
int main() {
int a = 5;
p = &a;
func();
printf("a = %d\n", a); // prints: a = 6
return 0;
}
There's no good way to do that. If you want the function to modify a local variable, you should probably change the function so it either returns a value that you can assign to the variable, or takes the variable's address as an argument.
But if you don't mind writing some ugly code, you can define a global (file-scope) pointer variable, assign the local variable's address to the global pointer, and then use that to modify the variable inside the function.
An example:
#include <stdio.h>
int *global_pointer;
void func(void) {
*global_pointer = 42;
}
int main(void) {
int local_variable = 0;
global_pointer = &local_variable;
func();
printf("local_variable = %d\n", local_variable);
}
It's very easy to shoot yourself in the foot his way. For example, if you refer to the pointer after the calling function has terminated (and the local variable no longer exists), you'll have undefined behavior.
This technique can actually be useful if you need to make a quick temporary change in a body of code in which you can't make major interface changes. Just don't do it in code that will be maintained by anyone else -- and wash your hands afterward.
You can have global variable
int var_name;
void func();
int main()
{
func();
printf("%d\n",var_name);
}
void func()
{
var_name = 20;
}
But if your variable is local to main() then this can't be done.
There are two ways to modify the value of var_name.
Make changes in the calling function and return the value.( which you have already shown)
Pass the address of the var_name to the function and have pointer as arguement in the func(int *p) and modify the value inside the func()
Thats it!! No other way this can be done.
I'm trying to understand the behavior of pointers in C in context of passing them as arguments to function, so I tried messing around and making the following test case:
void function1(int argument)
{
argument=4;
}
and
void function2(int* argument)
{
*argument=5;
}
if I run the following statements:
int var1;
int* var2;
function1(var1);
function1(*var2);
function2(&var1);
function2(var2);
In which cases will changes made to the variables be reflected in the calling function?
I tried running the following sample code but am not able to understand output
#include <stdio.h>
void funone(int arg)
{
arg=5;
}
void funtwo(int* arg)
{
*arg=6;
}
int main(void) {
int var1=0;
int *var2;
var2=(int *)malloc(sizeof(int));
*var2=0;
funone(var1);
printf("%d",var1);
funone(*var2);
printf("%d",*var2);
funtwo(&var1);
printf("%d",var1);
funtwo(var2);
printf("%d",*var2);
return 0;
}
the output I'm getting is
0066
what is the implication of this output?
Your code for function1 changes the value of the variable in the function only. So there are no repercussions of the change outside of the function.
Your function2 works (ie, changes the values it points to) because pointers can point to variables outside of it's scope. But your first function keeps the value inside of it's scope, and once the function returns any changes are lost.
This explanation should be present in any good tutorial about pointers.
Neither of those examples will work as you're simply setting the value of the pointer using those functions. Below you will find a version which achieves the behaviour you wish:
void function2(int* argument)
{
*argument=5;
}
The reason for the asterisk before the argument parameter is because you are dereferencing the value of the pointer (you are getting access to it) and therefore you may, at that point change its value...
I hope this helps...
What are Function Pointers in plain English?
In simple english,
A FUNCTION_POINTER is a pointer which points towards the address of
fuction's first instruction, like a POINTER which points towards the
address of a variable.
Take a example of a program to understand the concept
Sum of all integers upto the user i/p
-
#include <stdio.h>
int IsAny(long n)
{
return 1;
}
long AddIf(long limit, int (*funPointer)(long))
{
long sum = 0;
register int i;
for(i = 1; i <= limit; ++i)
{
if(funPointer(i))
sum += i;
}
return sum;
}
int main(void)
{
long l, total;
printf("Enter a positive integer: ");
scanf("%ld", &l);
total = AddIf(l, IsAny);
printf("Sum of all integers upto %ld is %ld\n", l, total);
}
Here FUNCTION_POINTER is called to call IsAny function in AddIf with a declaration
as int (*funPointer)(long)) in AddIf function
As you asked in plain english, let's give it a try.
A pointer is an address in memory. A pointer has a type so the program can "find" the object you are refering to when using your pointer.
A function pointer uses the same logic. It declares a function that will be used has a method parameter for exemple. So you know that you will use a function that will have an input and an ouput in that method but the logic in that function don't need to be known.
From there you can send any function pointer to be used as the program only concern is that you will send and receive predefined types.
According wiki
A function pointer (or subroutine pointer or procedure pointer) is a type of pointer supported by third-generation programming languages (such as PL/I, COBOL, Fortran,1 dBASE dBL, and C) and object-oriented programming languages (such as C++ and D).2 Instead of referring to data values, a function pointer points to executable code within memory. When dereferenced, a function pointer can be used to invoke the function it points to and pass it arguments just like a normal function call. Such an invocation is also known as an "indirect" call, because the function is being invoked indirectly through a variable instead of directly through a fixed name or address. Function pointers can be used to simplify code by providing a simple way to select a function to execute based on run-time values.
Pointer = That hold the address of a variable or means simple memory.
As same like pointer , function pointer that hold the address of a function.
Syntax :
return type (*fp) (argument);
Example:
void f1()
{
printf("in function f1");
}
int main()
{
/* declaring a function pointer
* argument void
* return type is also void
*/
void (*fun_ptr) (void);
fun_pt= f1(); // fun_pthold the address of f1
(*fun_pt)(); // calling a function f1
}