How do you differentiate between zero and not-initialised in C? - c

How do you check if a value is zero or has not been given?
int points[3];
points[0]=1;
points[1]=0;
for(int i=0;i<sizeof(points)/sizeof(*points);i++){
if(points[i]&&points>0){printf("Value is %d \n",points[i]);}
else if(!points[i]){printf("Value is zero \n");}
else{printf("Not set/provided\n");} // catching points[2]
}
Here, how do you differentiate between points[1] and points[2]?

"How do you differentiate between zero and not-set" and "how do you differentiate between points[1] and points[2]" implies a misunderstanding. points[2] in this case is not initialized nor assigned. It is not specified to be any legitimate value.
if(points[i] ... is UB when i==2.
Assign points[2] before reading it.
How do you differentiate between zero and not-initialised in C?
Code does so by keeping track of elements initialized or assigned prior. In this case, only points[0], points[1] has been assigned. Code does not attempt to differentiate by reading points[i].
A common idiom is to first zero fill the entire object:
int points[3] = { 0 };

There is no general way without initialization.
In some cases such as debug mode in vs, they will be initialized with zero, but in generally, c or c++ engine will set random values to non-initialized variables.
You have to do as follows:
int points[3] = {1, 0, -1};
for (int i = 0; i < 3; i++)
{
if (points[i] > 0) printf("value: %d", points[i]);
else if (points[i] == 0) printf("value is zero");
else printf("value is not setted.");
}

C does not have any feature to find uninitialized value. If the uninitialized variable is static or global, its value will be always 0, else it could be anything in the range of the type of variable. What you can do is assign a sentinel value as an indicator.
For example, if you are certain that the value of the variable will always be positive then you can assign a negative number to keep track, if the variable is ever changed or not

Related

how to test if a variable is valid or whether it is initialized or not in C?

I am learning C from scratch with Harvard's cs50 course.
I've been given an array that's been initialized this way:
int stuff[9][9];
now I have to handle it.
I want to check if each item of the array exists: if not, make stuff[i][j] = 0, otherwise, stuff[i][j]++
But I am searching without resulting on how to check if the variable I am manipulating exists or is valid or whatever: there is no !!stuff[i][j], nor some typeof stuff[i][j] or comparing if (stuff[i][j] == 'undefined') or NULL or any variations of that which I can use...
So, how can I check if a declared variable has not yet been initialized?
update
I've made a test with this:
int a[3];
for(int i = 0; i < 3; i++)
{
a[i] = a[i] || 0;
}
for(int i = 0; i < 3; i++)
{
printf("a[%i] -> %i\n", i, a[i]);
}
so, if a[i] didn't exist (i.e. had no value assigned to it), it would receive value 0.
this was the output of the printf:
a[0] -> 1
a[1] -> 1
a[2] -> 0
That's good because this approach didn't throw an error, but... what are those numbers??
Assuming the above array is a local variable and not a global, the values of the array are uninitialized and in fact you can't check whether a variable is uninitialized or not, as simply attempting to read such a variable can trigger undefined behavior.
It sounds like you want all array elements to start with the value 0. The simplest way to do this is to initialize the array as such:
int stuff[9][9] = {{ 0 }};
Which explicitly sets element [0][0] to 0 and implicitly sets all other elements to 0.
Alternately, you can create a loop to set all values to 0 to start before doing your "regular" processing.

Are are elements of an empty array NULL valued?

I tried this Armstrong program but found myself entangled in this empty array thing. Working of this program has been bothering me for a while now and still can't seem to figure it what's wrong here. Yea, so just wanted to ask what value are the elements of an empty or incomplete array assigned to? Is it the NULL character i.e. '\0'? I tried checking it on an online C compiler where this assertion seems true but GCC tells us the opposite. I tried this approach to Armstrong problem and here's my code:
#include <stdio.h>
#include <math.h>
int main()
{
int num,i,cub,j;
i = cub = 0;
int sto[20];
scanf("%d",&num);
j = num;
while(num != 0)
{
sto[i] = num%10;
num = num / 10;
i++;
}
i = 0;
while(sto[i] != '\0')
{
cub += pow(sto[i],3);
i++;
}
num = j;
printf("cub: %d num: %d\n\n",cub,num);
if(j == cub)
printf("The number is an Armstrong number");
else
printf("The number is not an Armstrong number");
return 0;
}
I know there is other approach to this problem but what I am looking for is the answer to the above mentioned question.
The values in that array are going to be undefined. They might be zero, they might be whatever values happened to be there from when that portion of the stack was last used. The same principle is applicable to heap memory.
so just wanted to ask what value are the elements of an empty or incomplete array assigned to? Is it the NULL character i.e. '\0'?
No, when declared in the body of a function as you've done it here (i.e. with no initializer), the contents are undefined. In practice, the values will be whatever random data happens to have last been in the stack at those locations. When an "automatic" array is declared as you've done here, the compiler simply inserts a stack increment to reserve space, but does nothing else. It could be zero, but probably not.
You have declared an array in a block scope without storage specifier static
int sto[20];
such an array has automatic storage duration. That is it will not be alive after exiting the block where it is defined.
If you would declare the array in the file scope for example before the function main or with the storage specifier static in a block it would have static storage duration.
From the C Standard (6.7.9 Initialization)
10 If an object that has automatic storage duration is not initialized
explicitly, its value is indeterminate. If an object that has static
or thread storage duration is not initialized explicitly, then:
— if it has pointer type, it is initialized to a null pointer;
— if it has arithmetic type, it is initialized to (positive or
unsigned) zero;
— if it is an aggregate, every member is initialized (recursively)
according to these rules, and any padding is initialized to zero bits;
— if it is a union, the first named member is initialized
(recursively) according to these rules, and any padding is initialized
to zero bits;
C doesn't have an end marker, the Programmer's supposed to handle it. Refer to this link:End of array in C language
Suggestion: Add an end marker in your array, for instance, insert 'x' at the end of your array, and loop until you find the marker. Or just use a counter variable as in this code.
#include <stdio.h>
#include <math.h>
int main()
{
int num,i,cub,j;
i = cub = 0;
int sto[20];
scanf("%d",&num);
j = num;
while(num != 0)
{
sto[i] = num%10;
num = num / 10;
i++;
}
int counter = 0;
while(counter < i)
{
cub += pow(sto[counter],3);
counter++;
}
num = j;
printf("cub: %d num: %d\n\n",cub,num);
if(j == cub)
printf("The number is an Armstrong number");
else
printf("The number is not an Armstrong number");
return 0;
}
I hope this answers your question.
The initial values of sto are indeterminate - they could be pretty much anything, and they can be different each time you run that code.
If you want to make sure all the elements contain a specific value, you can either:
explicitly initialize all 20 elements;
explicitly initialize some elements, with the remainder implicitly initialized to 0;
declare the array with the static keyword to implicitly initialize all elements to 0 (although this changes how the array is allocated and stored);
If you want all elements to initially be 0, you could do one of the following:
int sto[20] = {0}; // explicitly initializes first element to 0, implicitly
// initializes remaining elements to 0
static int sto[20]; // implicitly initializes all elements to 0, *but*
// changes how sto is stored
If you want all the elements to be initialized to something other than 0, then you'll either need to initialize all the elements explicitly:
int sto[20] = {-1, -1, -1, -1, -1, ... };
or use a loop:
for ( size_t i = 0; i < 20; i++ )
sto[i] = -1; // or whatever initial value

type conversion data printing Error in C lang

In C
int n=100;
printf("%d", (int)(sqrt((double)n)));
When I use this code it prints the correct answer (10).
But following code always prints 0
int n;
int max = (int)(sqrt((double)n));
printf("%d", max);
Why are the answers are different ?
int n=100;
printf("%d", (int)(sqrt((double)n)));
In this case, the value of n is known i.e, 100. So sqrt((double)n) returns the correct value.
int n;
int max = (int)(sqrt((double)n));
printf("%d", max);
Here, the variable n is uninitialized. The variable could be holding an indeterminate value depending upon whether it is declared locally (inside a block, in which case the value of n would be a junk value) or globally (outside a block, in which case the value of n would be zero). Always initialize your variables to avoid such errors.

Variable being used without being initialized? C Language

I can't quite figure out what my issue is here. I keep getting an error in my code.
Error: Run-Time Check Failure: Variable used without being initialized.
: warning C4700: uninitialized local variable 'b' used
can someone help me solve this problem ? Any help would be appreciated.I'm using visual studio as a compiler for C and I'm a beginner in it and this is a one of the assignment. I don't see why i keep getting this issue if i input "int b;" in the beginning of the program. Wouldn't that variable be initialized?
Here is the code:
#include <stdio.h>
//Create a program that asks the user to enter a number until the user enters a -1 to stop
int main()
{
int b;
//as long as the number is not -1, print the number on the screen
while(b!=-1) {
printf("Hello there! would you please enter a number?");
scanf(" %d",&b);
//as long as the number is not -1, print the number on the screen
if(b!=-1){
printf("Thank you for your time and consideration but the following %d you entered wasn't quite what we expected. Can you please enter another?\n",b);
//When the user enters a -1 print the message “Have a Nice Day :)” and end the program
}else {
printf("Have a Nice Day :), and see you soon\n");
}
}
return 0;
}
When you declare a variable, such as you have:
int b;
It is not initialised to have any value, it's value is unknown until you initialise it.
To fix this error, replace
int b;
With
int b = 0;
Error is here:
int main()
{
int b;
//as long as the number is not -1, print the number on the screen
while(b!=-1) {
Since you haven't initialized b, it can be anything. You then use it as a condition for while loop. This is very dangerous.
It may be that system randomly assign value of -1 ( its a rare possibility ) to it .. in that case your while loop will not be actioned
Intialize b to some value
For eg do this:
int b = 0;
You're doing:
int b;
and then doing:
while(b!=-1) {
without ever initializing b. The problem is exactly what your warning is telling you it is.
C does not automatically initialize local variables for you, the programmer has to take care of that. int b allocates memory for your variable, but doesn't put a value in there, and it will contain whatever garbage value was in that memory prior to allocation. Your variable won't be initialized until you explicit assign, or another function explicitly assigns, a value to it.
int b;
is a variable declaration. Explicitly, the value is not initialized. The compiler will emit instructions for the program to reserve space to store an integer at a later time.
int b = 1;
this is a variable declaration with initialization.
int b;
while (b != -1)
this is use of an uninitialized variable, but so is
int a = rand() % 3; // so 'a' can be 0, 1 and or 2.
int b;
if (a == 0)
b = 1;
else if (a == 1)
b = 2;
printf("b = %d\n", b);
this is also a potential cause of uninitialized use of b. If 'a' is 2, we never assign a default value to b.
Upshot is you should always try to specify the default value with the declaration. If the logic that will determine initialization is complex, consider using an out-of-bounds value, as you are using -1.
Can you spot the bug in the following?
int b = -1;
if (a == 0)
b = 1;
else if (a == 1)
b = 2;
else if (a > 2)
b = 3;
if (b == -1) {
// this is an error, handle it.
}

Strange output from simple C program to find the largest continuous subarray in an array

I am very new to C, and I was just playing around and seeing if I could recreate a simple subarray adding program (finds the largest continuous subarray in an array). I ran in to an odd issue where if I defined n as an integer and used it as a condition in my for loop I would get absolute junk back.
Forgive this weird code, I pretty much just copied and pasted a file I was monkeying around with (lots of extra printfs etc). If I run this, I get an output of "4196053", or something similar to that, for each printf call in the for loop. Even in the first printf call (before entering the loop) it seems to be messed up.
#include <stdio.h>
int maxI (int a, int b)
{
int max = (a >= b) ? a : b;
return max;
}
int main (void)
{
int array[] = { -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5};
int n = 11;
int maxSoFar, i = 0;
int maxHere = 0;
printf ("%i\n", maxSoFar); //why is it screwing up here?
for (i = 0; i < n; i++) {
printf ("%i\n", maxSoFar);
maxHere = maxI(maxHere + array[i], 0);
maxSoFar = maxI(maxSoFar, maxHere);
}
printf ("The max is %i.\n", maxSoFar);
return 0;
}
If I just use 11 in the conditional instead of a variable it works fine. Anyone know what is going on here?
maxSoFar is having some arbitrary data, so you need to initialize it first
int maxSoFar = 0, i = 0;
^^Initialize to zero
Your error is here
int maxSoFar, i = 0
You never declared maxSoFar so it's using garbage data.
Initialize it to 0, and you should be good.
It gives you a garbage value because you never initialize maxSoFar. This means that it will have the value of whatever was left in memory at that point.
You main issue is that maxSoFar is a local(automatic) variable and is therefore if it is not initialized it will have an indeterminate value, so the results of this program are also indeterminate. The fix would be to properly initialize maxSoFar, probably to the first element of array.
For completeness sake, the relevant section of the C99 draft standard is 6.7.8 Initialization paragraph 10 which says:
If an object that has automatic storage duration is not initialized explicitly, its value is
indeterminate.[...]

Resources