For this part I actually just need to scanf a value into a variable and then put it into an equation to spit out a number.
Analogue input (-5V to 5V):
1
e is -1073750280
the code:
printf("Analogue input (-5V -5V):\n");
scanf("%d",e);
printf("e is: %d \n", e);
The number that e prints out as changes every time I run the program. I figure it has to do with memory but I cannot figure out what.
these are the variable declarations:
uint16_t *pointer;
int e,d,i;
C passes all of its function parameters by value, not by reference. That means functions cannot modify their parameters directly:
void NoChange(int i) {
printf("Before: %d\n", i);
i = 10; // Changes only the local copy of the variable.
printf("After: %d\n", i);
}
main() {
int n = 1;
printf("Start: %d\n", n);
NoChange(n);
printf("End: %d\n", n);
}
Output:
Start: 1
Before: 1
After: 10
End: 1
If you want a function to change the contents of a variable, you need to pass its address. Then the function can modify the data at that address, which effectively modifies the variable:
void Change(int *i) {
printf("Before: %d\n", *i);
*i = 10; // Changes the memory that i points to.
printf("After: %d\n", *i);
}
main() {
int n = 1;
printf("Start: %d\n", n);
Change(n);
printf("End: %d\n", n);
}
Output:
Start: 1
Before: 1
After: 10
End: 10
So in order for the scanf() function to store data in a variable, you need to pass it the address of that variable, like this:
int e;
scanf("%d", &e);
scanf("%d", &e); is the correct answer as others have pointed out. The scanf function needs a pointer to where you want it to store the data, otherwise it doesn't know where your variable is.
Since scanf was expecting a pointer it converted the uninitialized value stored inside e to a pointer and stored the result there. This is undefined behaviour, a phrase you will see in the C/C++ section a lot, and you shouldn't do it.
Also, since scanf did nothing to your variable, printf was printing the uninitialized value of e, which is why you were getting the unexpected result.
scanf("%d",&e);
You are missing &.
Related
I was doing some exercises on codewars, and had to make a digital_root function (recursively add all digits of a number together, up untill there's only one digit left).
I was fairly confident that I did it right, but for some reason my while-loop never broke, even though my prints showed that len was 1.
#include <stdio.h>
#include <string.h>
int digital_root(int n) {
char number[10];
sprintf(number, "%d", n);
int len = strlen(number);
printf("Outer print: %s %d %d\n", number, n, len);
int sum = 0;
while(len > 1)
{
sum = 0;
for(int i = 0; i<len; i++)
{
sum += number[i] - '0';
}
sprintf(number, "%d", sum);
int len = strlen(getal); //!!!
printf("Inner print: %s %d %d\n", number, sum, len);
}
return sum;
}
It took me a long time to figure out what was wrong. I noticed that I copy pasted the 'int' keyword when I recalculated the len in the while loop (line marked with !!!). When I removed that (because it was not needed to redefine it as an int, it already was), everything suddenly worked like it was supposed to.
This kinda confused me. Why would this matter? I understand that redefining it is bad practice, but I don't get how this would result in the while-loop not breaking?
The used compiler is Clan3.6/C11.
(Ps. When I tried the same code in TIO, it worked in both cases...)
You're not redefining an existing variable, you're defining a new variable.
Consider this example:
#include <stdio.h>
int main(void) {
int x = 42;
printf("Outside, start. x (%p) = %d\n", (void *)&x, x);
{
printf("Inner block, start. x (%p) = %d\n", (void *)&x, x);
int x = 123;
printf("Inner block, end. x (%p) = %d\n", (void *)&x, x);
}
printf("Outside, end. x (%p) = %d\n", (void *)&x, x);
return 0;
}
Sample output:
Outside, start. x (0x7ffd6e6b8abc) = 42
Inner block, start. x (0x7ffd6e6b8abc) = 42
Inner block, end. x (0x7ffd6e6b8ab8) = 123
Outside, end. x (0x7ffd6e6b8abc) = 42
[Live demo]
This program outputs the memory address and value of x. Most uses of x refer to the outer variable declared at the beginning of main. But within the inner block, after int x = 123;, all occurrences of x refer to a second, separate variable that happens to also be called x (but is otherwise independent).
When execution leaves the inner block, the outer x variable becomes visible again.
This is also referred to as shadowing.
In your code, the outer len is never modified, so while(len > 1) is always true.
By the way, shadowing is a very common concept in most languages that support block scoping:
Perl
JavaScript
Haskell
Common Lisp
Your second int len creates a second, parallel, variable that goes away at the end of the {} block. The original len then returns to life, completely unchanged. Without the second int the original variable is changed. With it the original len is effectively an unchanged constant and infinite loop.
Does anyone know why my program prints -69 in below case? I expect it to print default/ garbage value of uninitialized primitive data types in C language. Thanks.
#include<stdio.h>
int a = 0; //global I get it
void doesSomething(){
int a ; //I override global declaration to test.
printf("I am int a : %d\n", a); //but I am aware this is not.
a = -69; //why the function call on 2nd time prints -69?
}
int main(){
a = 99; //I re-assign a from 0 -> 99
doesSomething(); // I expect it to print random value of int a
doesSomething(); // expect it to print random value, but prints -69 , why??
int uninitialized_variable;
printf("The uninitialized integer value is %d\n", uninitialized_variable);
}
What you have is undefined behavior, you can't predict the behavior of undefined behavior beforehand.
However it this case it's easy to understand. The local variable a in the doesSomething function is placed at a specific position on the stack, and that position does not change between calls. So what you're seeing is the previous value.
If you had called something else in between, you would have gotten different results.
Yeah.. Your function reuse two times the same segment of memory.. So, the second time you call "doesSomething()", variable "a" will be still "random".. For example the following code fill call another function between the two calls and you OS will give you differen segments:
#include<stdio.h>
int a = 0; //global I get it
void doesSomething(){
int a; //I override global declaration to test.
printf("I am int a : %d\n", a); //but I am aware this is not.
a = -69; //why the function call on 2nd time prints -69?
}
int main(){
a = 99; //I re-assign a from 0 -> 99
doesSomething(); // I expect it to print random value of int a
printf( "edadadadaf\n" );
doesSomething(); // expect it to print random value, but prints -69 , why??
int uninitialized_variable;
printf("The uninitialized integer value is %d\n", uninitialized_variable);
}
I am having some trouble with pointers.
The gist of it is, I am trying to define pointers in one function and call that function in my main to use those pointers.
The exact instructions for my assignment are as follows:
Write two functions, one that reads three numbers from the keyboard
and one that prints some information about these three numbers.
Input Function
Write a function that has three integer pointer parameters, and that
asks the user to enter three whole numbers. The values entered at the
keyboard should be read into the addresses stored in the pointer
parameters.
Note: recall that scanf requires the address of a variable and that
pointers store addresses.
Printing Values
Write a second function called a2question2, with no return value and
no parameters. The function should declare three integer variables
and then use your input function to read values into these variables.
The function should then print the sum, the average, the product, and
the smallest and largest of these numbers.
Here is what I have so far:
int pntloc (int *x, int *y, int *z){
int a = 0;
int b = 0;
int c = 0;
printf("Please enter integer #1: ");
scanf ("%d", & a);
printf ("Please enter integer #2: ");
scanf ("%d", & b);
printf("Please enter integer #3: ");
scanf ("%d", & c);
*x = &a;
*y = &b;
*z = &c;
return *x, *y, *z;
}
// Fourth function
main (){
int x, y, z;
pntloc(x, y, z);
int sum = 0;
int average = 0;
int product = 0;
int smallest = 0;
int largest = 0;
printf ("%d", x);
}
However, after the program asks me for the three integers, it crashes without doing anything.
The first function works fine by its self (tested it by making it the main function without parameters and printed the pointer values) ie:
printf ("%d", *x);
So I guess the values are just not passing from one function to the next. I've tried various ways of writing the first and second function but nothing seems to work.
The best I got was getting the program not to crash but the printed value was nowhere to what I inputted before.
Any ideas how to do this?
Your program is probably crashing because of two errors:
1) You are returning the local address of the variables a, b and c:
*x = &a; // This line says follow the 'x' pointer, and set the value there to
// the address of 'a'
Since a is defined locally (i.e. inside the function), that address is invalid once the function returns.
What you probably meant is:
*x = a; // Follow the 'x' pointer, and set the value there to the value of 'a'
2) You're not passing pointers to pntloc() (your compiler should be warning you about this one)
int x, y, z;
pntloc(x, y, z); // The passes the VALUES of x, y and z
You probably meant:
pntloc(&x, &y, &z); // Pass the ADDRESSES of x, y and z
Some other improvements that aren't causing your crash:
You can massively shorten pntloc() by not using the local variables:
void pntloc (int *x, int *y, int *z){
printf("Please enter integer #1: ");
scanf ("%d", x);
printf ("Please enter integer #2: ");
scanf ("%d", y);
printf("Please enter integer #3: ");
scanf ("%d", z);
}
Note that the & has been removed inside the scanf() call. You asked about it in comments, so here's a bit more explanation: &x says "the address of x", but when you have a pointer, you already have an address. A quick example:
int a; // 'a' is an integer variable
int *b = &a; // 'b' is a pointer to the integer variable 'a'
scanf("%d",&a); // This statement reads an integer into 'a'.
// We pass it the address of 'a', which is written &a
scanf("%d",b); // This statement also reads an integer into 'a'.
// We pass it the address of 'a', which is stored
// in the pointer 'b'.
Since we have pointers passed in to the function:
void pntloc (int *x, int *y, int *z){ // Three pointers to ints
we can pass them straight in to scanf(), and don't need to (and shouldn't) use & when we do.
Note that I also removed the return statement:
return *x, *y, *z;
I don't think this return statement is doing what you think it is. Remember that C only allows one return value from a function.
But why does it compile, you ask? Well, here's what's happening - but feel free to ignore this bit if it is confusing: The comma operator evaluates left to right, discarding the left hand result as it goes. So, your return statement is equivalent to:
*x;
*y;
return *z;
The comma operator is useful when the left hand statement has a side effect, and you want to write everything on one line. In my opinion, it makes code much harder to read, but there are one or two situations where it makes things cleaner. For a beginner, I recommend the following rule: Only use commas inside the round brackets of functions.
Since you weren't using the return value from the function when you called it:
pntloc(&x,&y,&z);
I removed the return entirely, and set the return type to void.
*x = &a;
*y = &b;
*z = &c;
Will cause mayhem and death! a b and c are local variables, so you are setting the contents of x y and z to addresses that will be invalid once you return from the function where a b and c are defined.
Perhaps you mean:
*x = a;
*y = b;
*z = c;
in main(),
pntloc(&x, &y, &z);
and
*x = a;
...
printf ("%d", x);
while you pass the *x as a parameter in pntloc(), you can't change *x 's value after calling the function.
and pntloc() don't need to return them, returning 0 or 1 is enough.
int main()
{
int value = 4321;
int *ptrVal = &value;
printf("%d %d",++value,(*(int*)ptrVal)--);
return 0;
}
How does pre-increment/post increment works in above print statement ?
And why is answer 4321 4321 ?
You are modifying the object value twice between two sequence points: you are invoking undefined behavior. Undefined behavior means your program can print 4321 4321, print 42 or even just crash.
A correct version of your program would be:
int value = 4321;
int *ptrVal = &value;
++value;
(*ptrVal)--; // no need to cast to int *
printf("%d %d", value, *ptrVal); // same as printf("%d %d", value, value);
Of course you don't need any temporary pointer to achieve this.
The code above is just broken. It is unspecified how it will work or what the answer will be. You need a sequence point between modifications or modifications and accesses.
int x=0;
int*a=&x;
void foo(int * a) {
static x=0;
x++;
printf("x's value %d ", x);
*a+=x;
a=&x;
*a=x+10;
}
int main(void) {
foo(a);
printf("a's value %d\n ", *a);
foo(a);
printf("a's value %d ", *a);
return 1;
}
I'm trying to analyze the above. First iteration of foo, when the function reaches to a=&x, the a after the function stops to get affected by what happens, since at the end of the function the pointer would go back to the original value he pointed to, now 1. the static x is now 1 as well. Second iteration: How's x got the value 12?! the static x became 2, and so I expected 3 to be the value of a.
The output is:
x's value 1 a's value 1
x's value 12 a's value 13
a=&x;
*a=x+10;
The above code adds 10 to x, because you set a to be a pointer to x, and then set the value pointed to by a to x+10.
The line a=&x makes a point to the static function-local variable x (since it's the innermost in scope). Thus *a=x+10 in the next line is equivalent to x=x+10, and x is 11 as we exit the function. At the next call, we increment x by 1, and it becomes 12.