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
Related
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
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I am trying to sum an array of numbers. The array has a length determined by an input and then the user gives the array. There were no compilation errors and I am able to run other programs. On the immediate start of running the program I am given a message that program has stopped working and that windows is searching for solution.
#include <stdio.h>
int main()
{
int sum, length, count;
int array[length];
sum=0;
scanf("%d",&length);
scanf("%d",&sum);
for(count=0; count<length-1; count++)
{
sum = sum + array[count];
}
printf("%d", sum);
return 0;
}
When you declare your array it depends on length but you ask the user for length after.
A solution could be to ask the user for length (scanf("%d",&length);) before declaring your actual array (int array[length];).
you should move int array[length] to after scanf("%d", &length). But it is not allowed in C to declare variables after the first non-declaration (it is however possible if you compile this program as C++).
In fact, in standard C you can't have a non-const length definition for an array variable. gcc on the other hand for example allows this nevertheless.
In your case, the problem is that length has an undefined value at the declaration of int array[length];. If you are lucky, your data segment has been initialized to zero (there is no guarantee for that) but otherwise, it may be any value, including a value which leads the program to exceed your physical memory.
A more standard way of doing this is:
int *array = NULL;
scanf("%d",&length);
...
array = (int*) malloc(sizeof(int) * length);
...
free(array);
By the way, even after fixing that, you will most likely get random numbers because you never actually assign the contents of the elements of array.
Local variable are initialized to 0. Hence value of length is 0. So you array is of length. You are then reading length, say 10, from stdin and expect the array to be of length 10. This can't be. Since this is a stack variable, the size is determined in time of pre-processing and not in run time. If you want to define the array length in run time then use malloc.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int sum, length, count;
int *array;
sum=0;
scanf("%d", &length);
scanf("%d",&sum);
array = (int *)malloc(sizeof(int) * length);
if (array == NULL) return 0;
memset(array, length, 0);
for(count=0; count<length-1; count++)
{
sum = sum + array[count];
}
printf("%d", sum);
return 0;
}
Thanks.
first problem:
the length variable is being used to set the number of entries in the array[], before the variable length is set. Therefore, length will contain what ever trash happens to be on the stack when the program starts so the number of entries defined in array[] is an unknown.
This results in undefined behaviour and could lead to a seg fault event, depending on what was on the stack and what the user entered for length.
second problem:
The array array[] is never initialized so will contain what ever trash is on the stack at program startup. This means the value being printed could be anything. And the 'sum' could overflow, depending on the trash values in array[]
OP program lacks the part of data input, it's asking for sum instead of the values to sum, which is weird. The only inputs requested are also never checked (the return value of scanf must always be checked).
In C (at least C99 and optionally C11) Variable Length Arrays, like the one defined by int array[length], can be used, but the variable length here is used uninitialized and before it is even asked to the user.
Moreover, the loop where the sum is calculated stops before the last element of the array (not really a big deal in this case, considering that all those variables are uninitialized...).
A better way to perform this task could be this:
#include <stdio.h>
// helper function to read an integer from stdin
int read_int( int *value ) {
int ret = 0;
while ( (ret = scanf("%d", value)) != 1 ) {
if ( ret == EOF ) {
printf("Error: Unexpected end of input.\n");
break;
}
scanf("%*[^\n]"); // ignore the rest of the line
printf("Please, enter a number!\n");
}
return ret;
}
int main(void) {
int sum = 0,
length = 0,
count,
i;
printf("Please, enter the number of values you want to add: ");
if ( read_int(&length) == EOF )
return -1;
// Use a VLA to store the numbers
int array[length];
// input the values
for ( count = 0; count < length; ++count ) {
// please, note ^^^^^^^^ the range check
printf("Value n° %2d: ", count + 1);
if ( read_int(&array[count]) == EOF ) {
printf("Warning: You entered only %d values out of %d.\n",
count, length);
break;
}
// you can sum the values right here, without using an array...
}
// sum the values in the array
for ( i = 0; i < count; ++i ) {
// ^^^^^^^^^ sum only the inputted values
sum += array[i];
}
printf("The sum of the values is:\n%d\n", sum);
return 0;
}
This question already has answers here:
how does array[100] = {0} set the entire array to 0?
(4 answers)
Closed 6 years ago.
For the famous problem.
There are 100 people standing in a circle numbered from 1 to 100. The first person is having a sword and kills the the person standing next to him clockwise i.e 1 kills 2 and so on. Which is the last number to remain alive? Which is the last number standing?
In the following C code for this problem.
void main(){
int i=0, j; //i has the sword, j gets killed.
int a[N]={0}; //0=not killed
while(1){
if(i != N-1) j = i + 1;
else j = 0;
while(a[j])
if((j + 1) == N) j = 0; //loop back to 0
else j++; //skip over the killed people
if(i==j){ //if i is the only one left, stop
printf("\n\n\n%d is left!", i+1);
return;
}
a[j] = 1; //kill j
printf(" %d kills %d.", i+1, j+1);
if(j != N-1) i = j + 1;
else i=0;
while(a[i])
if((i + 1) == N) i = 0;
else i++;
}
}
Please tell me meaning of int a[N]={0};//0=not killed in line no. 6 Thanks.
In your code,
int a[N]={0};
is initializing all the members of the array a to 0.
As per the C11 standard, chapter §6.7.9, initalization, (emphasis mine)
If there are fewer initializers in a brace-enclosed list than there are elements or members
of an aggregate, or fewer characters in a string literal used to initialize an array of known
size than there are elements in the array, the remainder of the aggregate shall be
initialized implicitly the same as objects that have static storage duration.
and, for intializer value of static storage type int, which is arithmetic type,
[...] if it has arithmetic type, it is initialized to (positive or unsigned) zero;
and a is an array of type int, so it will have all it's members initialized 0 as the values. a[0] will be explicitly initialized to 0 (supplied), and the rest will get the implicit initialization.
FWIW, the N has to be a compile-time constant value, like
#define N 50 //or any value
for this to work.
It basically tells the compiler that this will be an array of size N and will all be zero-initialized. So when you try to show the output of this array you'll see N zeroes.
It is somewhat similar to :
memset(a, 0, N * sizeof(int))
I wrote some code to count the bits in a word. When I printf() the count it prints 32 as expected but when I stuck the same code in a function and printed the return value it gives me some crazy large number.
I then copy/pasted the code back into main() printed the count and printed the return value of my function at the same time and hey both gave me 32 but if I then comment out the code in main() my function again prints the large number.
Anyone have an idea about why this is happening?
#include <stdio.h>
int wordlength();
int main() {
printf("%d", wordlength()); // prints 4195424 but
// if I uncomment the code below
// it then prints 32 like I want
// int count;
// unsigned int n = ~0;
//
// while( n != 0) {
// n = n >> 1;
// count++;
// }
// printf("\n%d", count); // prints 32 as expected
return 0;
}
int wordlength() {
int count;
unsigned int n = ~0;
while( n != 0) {
n = n >> 1;
count++;
}
return count;
}
In your wordlength() function, count is an automatic local scope variable and is not initialized explicitly. So, the initial value is indeterminate.
To quote C11 standard, chapter §6.7.9
If an object that has automatic storage duration is not initialized explicitly, its value is
indeterminate. [...]
You're readily applying post-increment onto it. It invokes undefined behavior.
Related, annex §J.2, reasons for undefined behavior,
The value of an object with automatic storage duration is used while it is
indeterminate.
So, your program exhibits UB and not guaranteed to produce any valid result, at all.
Solution: Initialize count to 0.
FWIW, regarding the comment
// if I uncomment the code below
// it then prints 32 like I want
is also a result of UB.
You have to initialize count to 0 or something, or it will have undefined value.
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.