I'm creating a table of an arrays where the user can input the value themselves, and I will show them the table of value except the number 0 is use to exit from the scanf
so I don't want number 0 to be store in the array
but I'm seeing number 0 for the next value of an array so I'm wondering if 0 is a default value of an array.
to make it a bit more clear
let say the user entered;
5
4
3
2
1
and 0
so what I suppose to show in my program output is
5
4
3
2
1
which I use array to display the index of 0-4 [1-5]
but just to make sure if number 0 is not store so I call array[5] to see if the next value is 0 or something else and it always display 0 so I want to know if there is a way to make sure that 0 is not going to store in the array
this is what I use to make sure
if(enter != 0){
array[i - 1] = enter;
Sorry if my question is complicated.
Thanks
If the array is with static storage duration it will be initialized to 0. In any other case, elements will not be initialized, i.e. will contain random bits.
Static storage duration have global variables, file scope static variables and block scope static variables.
I revide my answer. Every array that you allocate can contain garbage, or not. The compiler can clear it for you, or not. In your case, I would clear the array with something like -1. Else you will have some undefined values in there, that be 0 or not. It's just not defined, every compiler can behave differently.
Test it:
#include <stdio.h>
void array(void);
int main(void) {
int c[10], i;
printf("Array 1: ");
for(i = 0; i < 10; i++) {
printf("%d", c[i]);
}
printf("\n");
array();
int b[10];
for(i = 0; i < 10; i++) {
printf("%d ",b[i]);
}
printf("\n");
return 0;
}
void array(void) {
int a[10] = {1,2,3,4,5,6,7,8,9,0};
return;
}
It depends, but generally arrays defined at compile-time are full of 0 by default. Arrays defined at run-time not necessarily, they could be 0 or full of crap.
Related
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.
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
I tried to compare int variable with the function in two ways:
storing the int function return value in a variable then comparing with another
in value.
Directly comparing the int variable and the function call.
Here I got the answer for the first one but not for the second one.
Why does this happen?
My code:
#include < stdio.h >
int count = 0;
int countDigits(int);
int main() {
int i;
int result = countDigits(435);
for (i = 0; i < result; i++) {
printf("id %d\n", 3);
}
for (i = 0; i < countDigits(435); i++) {
printf("i =%d\n", i);
}
}
int countDigits(int n) {
if (n == 0) {
return count;
} else {
countDigits(n / 10);
count++;
}
}
We can.
It's just that your function has a logical error. Debug it, and you will be fine.
Enabling compiler warnings would have helped you. For example with GCC and Wall flag, you get:
prog.c: In function 'countDigits':
prog.c:32:1: warning: control reaches end of non-void
function [-Wreturn-type]
}
^
Tip: Think of what your function does if n us different than zero.
count is a global variable.
The function countDigits(n) adds the number of decimal digits in n to count and
If n is zero it returns 1.
If n is non-zero the return value is undefined.
Since countDigits(435) has an undefined value, anything can happen and no further analysis is necessary.
Let's assume that this obvious error is corrected by inserting return count; after count++;. In this case, the function returns the incremented count.
So we have this nice sequence:
Set result to countDigits(435).
countDigits(435) adds 3 to count and returns 3.
Set i to 0 and compare to countDigits(435).
countDigits(435) adds 3 to count and returns 6. 0 is less than 6, so the for loop continues.
Now i is 1, and we compare it to countDigits(435).
countDigits(435) adds 3 to count and returns 9. 1 is less than 9, so the for loop continues.
Now i is 2, and we compare it to countDigits(435).
countDigits(435) adds 3 to count and returns 12. 2 is less than 12, so the for loop continues.
... And so on.
Morality:
Beware of side effects. Never use and modify global variables unless you have a good reason to.
When you must use side effects, keep them prominent in your mind.
It is possible to compare a variable directly with the output of a function. However, your function countDigits has several problems.
Not all code paths return a value - you're missing a return statement in the else block. This alone makes the output of the function undefined.
It's not algorithmically correct. Have you tried debugging it? Just start with printing the output for different inputs and you'll see.
Modifying and returning a global variable count inside that function is a really bad practice - it should be local to the function. When it's global, every call to the function modifies a [possibly] already modified variable.
Others have already addressed the problem here with globals, so I will not go into details about that. Instead, here is a solution without globals:
int countDigits(int n) {
int count = 0;
while(n>0) {
n/=10;
count++;
}
return count;
}
I guess you could be philosophical about whether 0 has 0 or 1 digit, but your code implied that you wanted it to be 0. If you want it to be 1 instead, just change the first row to int count = 1.
Suppose that I have associated (in my mind, not as code) a status thing with an integer array of size n.
int array[n] = {0,0,1,0,1,0,1,0,1,.......}. (only 0 and 1 in this array)
Status '0' means 'locked' in my context. Similarly, '1' means 'unlocked'.
I want that everytime, I print the variable, e.g. int array[3], I want to output its status as a string and not the actual value of variable.
How do I do this? Is there a way I can actually replace 0 with "locked" and 1 with "unlocked"?
P.S. - I DON'T want to create another array with data type string or simply putting an if-else equation. Help with macros will be much appreciated.
Sure, you can use string literals and decide which to use based on the value of the array slot.
for (int i = 0; i < n; i++) {
const char *is_locked = (array[i] == 0) ? "locked" : "unlocked";
printf("status of %d: %s\n", i, is_locked);
}
Is that an assignment which isn't well understood ?
I think the comment of Mike Housky is correct. But let me add some more "Macros", perhaps this answer will be downvoted.
#define LOCKED 0
#define UNLOCKED 1
#define PRINT(x) (x == LOCKED) ? printf("locked") : printf("unlocked")
use as
int array[n] = {0,0,1,0,1,0,1,0,1,.......}
or
int array[n] = {LOCKED,UNLOCKED,LOCKED,.......}
PRINT(array[3]);
Output of the program:
#include <stdio.h>
int main()
{
int size;
printf("Enter the size of array: ");
scanf("%d",&size);
int b[size],i = 0;
printf("Enter %d integers to be printed: ",size);
while(i++ < size)
{
scanf("%d",&b[i]);
printf("%d %d\n", i, b[i]);
}
return 0;
}
for size = 5 and input numbers :
0 1 2 3 4
is
1 0
2 1
3 2
4 3
5 4
where first column is for i and second for elements of array b.
It is clear that i in the loop while(i++ < size) { incremented to 1 before entering the loop. This loop should have to store/print the value at/of b[1], b[2], b[3], b[4] but not b[5] as loop will terminate at i = 5.
How this code is printing the value of b[5]?
I have tested it for different array size and it is not printing any garbage value.
By reading and writing past the array, your program invokes undefined behavior. It doesn't mean that it has to crash or print garbage values, it can pretend working fine. Apparently, that's what is happening in this case.
In your loop, the condition i < size is checked before i is incremented. But, i is incremented before entering the body of the loop and not after it, so it is possible to access b[5] in this case, as i would be incremented after checking i < size with i=4. You do not want that, as this causes undefined program behavior.
If you try to access an element in the array which does not exist, e.g. array[size], you are accessing the next spot in the memory right after the array. In this case you are lucky, but if this meant you were accessing a part of the memory where your program isn't allowed to do so, you'd get a segmentation fault.
you could use a for cycle instead of a while so instead of while(i++<size)you could use for(i = 0; i < size; i++) that should solve your problem my friend :)