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]);
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 am confused in understating the behavior of the code while searching for an element which does not exist in the array.
The result of the element index i am looking for is always zero while declaring it as int index;.
The result of the element index i am looking for is random number while declaring it as size_t index;
what is the difference between declaring the variable index as int index; andsize_t;in the code below.
The code
#include <stdio.h>
#define SIZE 5
int main(void)
{
int numbers[SIZE]={1,2,3,4,5};
int search =0; // This variable define the required number i am searching for
int start = 0 ;
int end = SIZE-1 ;
size_t index;
while (start <= end)
{
int middle = (start+end)/2;
if (search == numbers[middle])
{
index = middle;
}
if (search > numbers[middle])
{
start = middle+1 ;
}
else
{
end= middle-1 ;
}
}
printf("The index of the element is %d",index);
return 0;
}
The basic problem is that index is not initialized and that it never gets assigned when you don't find what you are searching for. Since the printf statement accesses an uninitialized variable in that case, your code have undefined behavior, i.e. anything may happen - including print of all sorts of numbers.
The result of the element index i am looking for is always zero while declaring it as int index;
That is "just by luck"
The result of the element index i am looking for is random number while declaring it as size_t index;
That is also "just by luck"
Here are a couple of action items you can take to improve your code:
Since this array is statically defined there is no need to include the SIZE define inside the []. Declare it like this int numbers[]={1,2,3,4,5}; instead of this int numbers[SIZE]={1,2,3,4,5};. Let the compiler do the math for you.
Initialize index to some value (i.e. index = 0;). this is the main cause of the problem and it is introducing undefined behavior to the program.
Change the type of size_t index to int index every variable that was declared in the program is an int and the program is treating index as an int. So it might as well be an int to avoid confusion.
Make this an else if clause instead of just an if:
else if (search > numbers[middle])
{
start = middle+1 ;
}
Add another case to have the program fail gracefully when the value to be searched is missing from the data set. Such as, printf("Data not found: %d", search);
The algorithm still isn't 100% and has some flaws but I will leave this up to you to figure out. I hope this info helps!
Best Regards!
The problem is that , the value of indexis not initialized.
initializing the variable to 0 does not solve your problem.
Because you are using index to return the position of the array element.
By initializing the index = 0 will provide he same result for the elements not present in the array as well as the for the first element to the of the array .
The better way is to initialize as size_t index = -1;
So that the result for the elements not present in the array would b -1.
Also check for the access specifier used in the printf statement, for size_t datatype. It can be ,
printf("The index of the element is %ld",index);
You are not using correct specifier for size_t, it's not %d.
Try to use %zd or %ld and it'll work fine.
Furthermore, add this after the while loop so that it doesn't show weird value of index when the element is not present in the array.
if(start>end) {
printf("That number is not present in the array");
return 0;
}
And move the line printf("The index of the element is %d",index); under the condition if (search == numbers[middle]). So that you don't get "this number is not present" even if it is present in the array.
For corrected version of your code see https://code.hackerearth.com/80043dg?key=7b325b26aec0f5425b76cc3efbdc93cf
I'm doing a program to insert numbers in an array, simple thing here, for example:
if(menu==1){
system("cls");
result=lastposition(array,20);
if(result==25){
printf("\n Error! The array is FULL!");
printf("\n Press Enter to continue");
getch();
} else{
printf("\n\n\tOption 1 selected: \n");
printf("\n Type the number to add it to the array: ");
scanf("%i",&value);
if(array[0]!=NULL){
printf("\n The first space is already filled, moving itens");
changeplace(array,20,value);
printf("\n Items moved with success!\n");
}else {
array[0] = value;
}
printf("\n Number %i added!\n",value);
printf(" Press to continue.\n");
getch();
}
So, what this does is, you type a number, and it inserts in a 20 positions array, in its first position (that's why the function "lastposition" is there, to check the lastposition filled in the array), if the first position is not filled yet(NULL), it adds in the first position, if it is already filled, the "chageplace" function moves all the values to the right, and then adds the number!
My problem is, when i declared the array, i set all its values to NULL, like this: int array[20]={NULL};! But in C, NULL change all its values to 0, and if someone in my program add 0 as a value, lets say the array already got a 5 and a 10 on it, like this [5][10][0][0][0]...[0], I'll add the zero, getting like this: [0][5][10][0][0]...[0], till there ok, but because C considers NULL=0, when i try to add another number it will check if the first position is already filled (it'll check if it's NULL, or 0, and it will return as NULL [0]), and if i try to add a 7 on it, it will replace the 0 (the added number, not the NULL) and it will get like [7][5][10][0][0]...[0]
Anyone knows how to fix this? Someway to be able to add a 0 in the function, without it being replaced by the next number because it's considered NULL? Having a real "Nothing" there, instead of "0".
PS: I cant just put random numbers in the array, to be different of 0, for 2 reasons, first, option 3 of the menu show the vector [therefore showing the random number, and 2, my function would consider it as already filled by a number!
PSĀ²: The "25" that the "lastposition" function returns is just a random number I've set to return if the last position of the array is 20 (meaning its already full)...
This is simply not possible in C. One workaround might be to change the array elements into a struct having a field used being a boolean and a field data being an int.
You can use another sentinel value to represent "not used". Say INT_MAX or INT_MIN.
You can use negative values for instance. But it's really dirty hack).
NULL is a pointer. Assigning it or comparing to any other type (like int) should at least produce a warning from the compiler. Do you enter pointers from the console?
Integer scalars mostly do not have reserved codes (and if, that would be implementation defined). So you need something out-of-band to signal "empty".
YOu can either restrict the valid range of values and use a value outside that range as "empty" tag. Or use an additional flag per entry. For float, there are similar ways, e.g. using NaN.
Version with seperate flag using a struct:
#include <stdbool.h>
struct {
bool valid;
int value;
} array[20];
Version with INT_MIN as reserved value:
#include <limits.h>
#define VALID_MIN (INT_MIN - 1)
#define EMPTY_VALUE INT_MIN
for ( int i = 0 ; i < sizeof(array) /sizeof(array[0]) ; i++ )
array[i] = EMPTY_VALUE;
....
int value;
do {
value = input_value(); // ...
} while ( value < VALID_MIN ) ;
....
You should simply track the number of filled elements in the array. :)
In C, NULL is practically always a zero cast to a pointer, which is why you are seeing a zero. There is no special "empty" value, and you shouldn't ever use NULL when dealing with integers.
One way to do this, is to have another array of booleans that will say whether it is empty or not. For example
_Bool isFull[25] = {0}; // Initialize it to all FALSE.
Then instead of checking array[i] == NULL, you check if isFull[i] == FALSE.
When adding an element (including 0), you set isFull[i] = TRUE;.
You can use a value that should not be a part of the array itself. (which means that you shouldn't input that value in the array anymore if you use it as the indicator of occupied index.) But your program will be less flexible that way since you cannot input any value you want.
Another is to use struct, which will hold one variable for the value itself, and another as indicator if it is filled or not. (it can be a boolean or int which can only 0 or 1).
struct values {
int value;
int indicator; // or bool indicator, make sure to include stdbool.h
} array[20];
One trick to accomplish what you want (adding on the top/front of the array) without using indicators of occupied index is to fill the array backwards. No moving of previous inputs to the right is also needed.
int i = max_elements; // lets say max_elements = 20
printf("\n Type the number to add it to the array: ");
scanf("%i",&value);
array[i] = value; // will fill array[20]
i--; // so that the next input will go to array[19], and so on...
But if you really want to go with changing positions,
int const_index = 0;
printf("\n Type the number to add it to the array: ");
scanf("%i",&value);
array[const_index] = value;
// change positions
for (i = max_elements; i > 0; i--)
array[i + 1] = array[i];
const_index = 0;
Or a better option is to use stack data structure.
You can take a look here on how to do it.
C Program to implement Stack Operations Using Stack
My question is very similar to the one already asked here.
However the length (and input) of the array are read from a file.
How can I evaluate the boolean expression in my example?
fread(length, 4, 1, file);
array= calloc(length, sizeof(int));
fread(array, 4, length, file);
b = 7;
// I want to compare b with every entry in array
if(b==array[0]||b==array[1]||b==array[2]||...)
// do something
end
Assuming the types match, and there is no endian-problems to take care of, you should be able to just loop:
bool array_is_b = true;
for(size_t i = 0; i < length && array_is_b; ++i)
{
array_is_b = array[i] == b;
}
After the loop, array_is_b is true if the each element is equal to b.
Here's an attempt that does away with the explict assignment, it might be faster:
bool array_is_self(const int *array, size_t length, int b)
{
for(size_t i = 0; i < length; ++i)
{
if(array[i] != b)
return false;
}
return true;
}
This re-arranges the operation into a function so that it can use return rather than a separate variable to track status. As long as the loop is running all elements up to i are equal to b. I assumed int for the array type.
A for loop is in your answer.
for(i = 0 ; i < length ; i++)
{
if(b == array[i])
{
//do something//
}
}
By the way, you have a problem with your code. A text file is made out of bytes - each character is a byte means it's being read in type char. If array is an array of integers (it looks like it) then only the ASCII values of the characters would be read into the array (look up ASCII in google for more information but basically it's a value from 0 to 255 representing characters). Even if your text file contains "numbers" it's read as characters so basically if you use fread() you'll read character but with fscanf() you can determine the type of the input.
So the expression if(b == array[i])would only be true IF array[i] is 7 (which means the value read from the text file is the character that 7 resembles - which is a BELL sound - the familliar windows error message sound - at all that can't be written into a text file so the boolean expression would be ALWAYS FALSE. Take that in mind. If you want to compare them as integers use if(b == array[i] - '0') as '0'=48 and the numbers in ASCII are from 48 to 57. so for example '4' (52) subtracted by '0' (48) is (52-48) actually integer value 4. Take that in mind. Hope I helped :P
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.