C - differentiate between 0 and \0 in integer array [duplicate] - c

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
nul terminating a int array
I'm trying to print out all elements in an array:
int numbers[100] = {10, 9, 0, 3, 4};
printArray(numbers);
using this function:
void printArray(int array[]) {
int i=0;
while(array[i]!='\0') {
printf("%d ", array[i]);
i++;
}
printf("\n");
}
the problem is that of course C doesn't differentiate between just another zero element in the array and the end of the array, after which it's all 0 (also notated \0).
I'm aware that there's no difference grammatically between 0 and \0 so I was looking for a way or hack to achieve this:
10 9 0 3 4
instead of this
10 9
The array could also look like this: {0, 0, 0, 0} so of course the output still needs to be 0 0 0 0.
Any ideas?

Don't terminate an array with a value that could also be in the array.
You need to find a UNIQUE terminator.
Since you didn't indicate any negative numbers in your array, I recommend terminating with -1:
int numbers[100] = {10, 9, 0, 3, 4, -1};
If that doesn't work, consider: INT_MAX, or INT_MIN.
As a last resort, code a sequence of values that are guaranteed not to be in your array, such as: -1, -2, -3 which indicates the termination.
There is nothing "special" about terminating with 0 or \0. Terminate with whatever works for your case.
If your array truly can hold ALL values in ANY order, then a terminator isn't possible, and you will have to keep track of the length of the array.
From your example, this would look like:
int numbers[100] = {10, 9, 0, 3, 4};
int Count = 5;
int i;
for(i=0; i<Count; ++i)
{
// do something with numbers[i]
}

The typical ways to implement this are to:
define a sentinel value (which others have suggested)
define a struct with an int (the actual value) and a bool (indicating if it's the sentinel) and make an array of those instead
pass the length of the array with the array
define a struct that contains both the array and the length and pass that instead
Note that the first and second items are nearly identical.

For an array declared as
int numbers[100] = {10, 9, 0, 3, 4};
there's absolutely no way to distinguish the explicit 0 in the initializer from the implicit zeros used to initialize the tail portion of the array. They are the same zeros. So, what you want to do cannot be done literally.
The only way you can do it is to select some int value as a reserved dedicated terminator value and always add it at the end of the array explicitly. I.e. if you choose -42 as a terminator value, you'd have to declare it as
int numbers[100] = {10, 9, 0, 3, 4, -42};
and iterate up to the first -42 in your cycles.

Related

Cout prints incorrect values of Bidimensional int array, while code appears to be correct

Following code appears to be correct, yet it will print incorrect numbers, which are random each time! I literally copied it from C++ site and cross checked it to confirm the code is correct! And it still doesn't work!
#include <iostream>
int main()
{
int a[3][4] = {
{0, 1, 2, 3} , /* initializers for row indexed by 0 */
{4, 5, 6, 7} , /* initializers for row indexed by 1 */
{8, 9, 10, 11} /* initializers for row indexed by 2 */
};
std::cout << a[3][4];
}
When you initialize arrays in c++, the number passed into each bracket is the size of the array, however this is the upper bound, which is not actually an index, its the limit. if your index starts at 0, and you have 3 items in the arrray, then your last row would be 2. This is why c++ loops over the array are always
for(int i =0; i < array_size; i++)
With an emphisis on < and not <=.
In your code, your indexing an item out of bounds; since a[3][4] is technically the 4th col 5th row.
C++ will let you index out of bounds, and your actually just indexing random values out in memory, which isn't good.
Try printing a[2][3] and that should be what your expecting.

C Programming: Why Can This Sample Line Have Not '0' OR '\0' Character At The End Of The Array?

I am still a C programming newbie.
I have heard the character string has always '0' or '\0' as the final character.
Then I have a one question. why the sample line below has '5' at the last position?
Why isn't it '0' or '\0'?
int myArray[10] = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 };
The line above from How to initialize all members of an array to the same value?
char cArr1[] = {'a', 'b', 'c'};
char cArr2[] = "def";
int iArr3[] = {1, 2, 3};
int iArr4[5] = {1, 2, 3};
memory layout
=============
var name memory address value
cArr1 AAAA0000 'a'
AAAA0001 'b'
AAAA0002 'c'
AAAA0003 unknown (may have a '\0' by chance)
...
cArr2 BBBB0000 'd'
BBBB0001 'e'
BBBB0002 'f'
BBBB0003 '\0' is inserted by the compiler
...
iArr3 CCCC0000 1
CCCC0004 2
CCCC0008 3
CCCC000C unknown (may have any value)
...
iArr4 DDDD0000 1
DDDD0004 2
DDDD0008 3
DDDD000C 0 (not defined explicitly; initialized to 0)
DDDD0010 0 (not defined explicitly; initialized to 0)
...
Strings are character arrays the actual elements of which are terminated by zero character. And most standard C string functions relay on this convention.
This
int myArray[10] = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 };
is an integer array. Zero is a valid integer value. And it is used very often as an actual value of an array among other integer values.
Of course you can make zero a sentinel value of an integer array. But there are no standard C functions that use zero as a sentinel value for integer arrays.
"Why can this sample line have not 0 OR '\0' character at the end of the array?"
Because myArray is an array of int (and does not contain a string)! A null terminator (for strings) can only be applied to char, but not int arrays.
And even an array of char does not a null terminator per se. Only if the array of char should contain a string and you want to use the content of the array as string, a null terminator is required.
Beside that, an array of int can of course hold the int value 0 inside of the last element but you currently intermix two different things here.

int array[10] = {1 , 2, 0, 3} . How can I find out that there are 4 elements here? I know how to find the size of array

I tried this code..As you can see the problem is the empty elements are zero. So, I tried to check with it but the thing is I can have 0 as an element.
int main()
{
int array[10] = {1, 2, 0, 3, 4};
printf("%d\n", sizeof(array)/ sizeof(*array)); // This is the size of array
int i = 0;
while(array[i] != 0 && i < 10) {
i++;
};
printf("%d\n", i);
return 0;
}```
You can't. int array[10] will always create an array of 10 elements and you can't ask the compiler which of them have been assigned.
What you could do is int array[] = {1, 2, 0, 3, 4} then the compiler will infer the number of elements for you and you'll have sizeof(array)/ sizeof(*array) == 5
First set the array to a number outside the range of your inputs. Like a negative number.
for(i = 0;i < 10;i++)
array[i] = -1;
or set it to INT_MAX or INT_MIN
int array[10] = {1 , 2, 0, 3} . How can I find out that there are 4 elements here?
How can you say there are 4 elements there as you declared that int array[10] with the size of 10 elements. This implies, you already know the no. of elements. Also, in this scenario, you can't use an if statement to determine the no. of elements as you probably know that in C, if you initialize an array of 10 elements with less than 10 values, rest of them will automatically be assigned to 0.
You have several options:
You know how many elements are in the initializer, so you create another variable that stores that number:int array[10] = {1, 2, 0, 3, 4};
int num_items = 5;
You'll need to update num_items as you "add" or "remove" items to the array. If you treat the array as a stack (only add or remove at the highest index), then this is easy-ish:array[num_items++] = 7; // adds 7 after 4
...
x = array[--num_items]; // x gets 7, 7 is "removed" from the array, need special
// case logic for element 0
You pick a value that isn't valid (say -1) and initialize the remaining elements explicitly:int array[10] = {1, 2, 0, 3, 4, -1, -1, -1, -1, -1 };
You size the array for the initializer, meaning it can only ever store that many elements:int array[] = {1, 2, 0, 3, 4};
Otherwise, you'll need to use a different data structure (such as a linked list) if you need a container that can grow or shrink as items are added or removed.

Can someone explain how to append an element to an array in C programming?

If I want to append a number to an array initialized to int, how can I do that?
int arr[10] = {0, 5, 3, 64};
arr[] += 5; //Is this it?, it's not working for me...
I want {0,5, 3, 64, 5} in the end.
I'm used to Python, and in Python there is a function called list.append that appends an element to the list automatically for you. Does such function exist in C?
int arr[10] = {0, 5, 3, 64};
arr[4] = 5;
EDIT:
So I was asked to explain what's happening when you do:
int arr[10] = {0, 5, 3, 64};
you create an array with 10 elements and you allocate values for the first 4 elements of the array.
Also keep in mind that arr starts at index arr[0] and ends at index arr[9] - 10 elements
arr[0] has value 0;
arr[1] has value 5;
arr[2] has value 3;
arr[3] has value 64;
after that the array contains garbage values / zeroes because you didn't allocated any other values
But you could still allocate 6 more values so when you do
arr[4] = 5;
you allocate the value 5 to the fifth element of the array.
You could do this until you allocate values for the last index of the arr that is arr[9];
Sorry if my explanation is choppy, but I have never been good at explaining things.
There are only two ways to put a value into an array, and one is just syntactic sugar for the other:
a[i] = v;
*(a+i) = v;
Thus, to put something as the element at index 4, you don't have any choice but arr[4] = 5.
For some people which might still see this question, there is another way on how to append another array element(s) in C. You can refer to this blog which shows a C code on how to append another element in your array.
But you can also use memcpy() function, to append element(s) of another array. You can use memcpy()like this:
#include <stdio.h>
#include <string.h>
int main(void)
{
int first_array[10] = {45, 2, 48, 3, 6};
int scnd_array[] = {8, 14, 69, 23, 5};
int i;
// 5 is the number of the elements which are going to be appended
memcpy(first_array + 5, scnd_array, 5 * sizeof(int));
// loop through and print all the array
for (i = 0; i < 10; i++) {
printf("%d\n", a[i]);
}
}
You can have a counter (freePosition), which will track the next free place in an array of size n.
If you have a code like
int arr[10] = {0, 5, 3, 64}; , and you want to append or add a value to next index, you can simply add it by typing a[5] = 5.
The main advantage of doing it like this is you can add or append a value to an any index not required to be continued one, like if I want to append the value 8 to index 9, I can do it by the above concept prior to filling up before indices.
But in python by using list.append() you can do it by continued indices.
Short answer is: You don't have any choice other than:
arr[4] = 5;
void Append(int arr[],int n,int ele){
int size = n+1; // increasing the size
int arrnew[size]; // Creating the new array:
for(int i = 0; i<size;i++){
arrnew[i] = arr[i]; // copy the element old array to new array:
}
arrnew[n] = ele; // Appending the element:
}
by above simple method you can append the value

What is the use of abs() in this C code

I have a piece of code which will find out the repeating elements in an array of size n where the elements satisfy 1 <= arr[i] <= n, the code is given below:
#include<stdio.h>
#include<stdlib.h>
void printTwoElements(int arr[], int size)
{
int i;
printf("\n The repeating element is");
for(i = 0; i < size; i++)
{
if(arr[abs(arr[i])-1] > 0)
{
arr[abs(arr[i])-1] = -arr[abs(arr[i])-1];
}
else
{
printf(" %d ", abs(arr[i]));
}
}
}
/* Driver program to test above function */
int main()
{
int arr[] = {7, 3, 4, 5, 5, 6, 2};
int n = sizeof(arr)/sizeof(arr[0]);
printTwoElements(arr, n);
return 0;
}
I would like to know the use of abs() in this given code?
In the course of the algorithm, some array entries are set to negative values as a marker. Therefore the entries' absolute value has to be taken when they are used as indices into the array.
In the hope of not spoiling anything:
The algorithm requires that the array entries of an n-element array all are between 1 and n inclusive.
If any entry is larger than n or smaller than -n or 0, it will access invalid addresses, and if any element is negative, the marking logic will fail.
The logic of the algorithm is:
for each array element e:
if the value at (e-1) is positive, e has not yet been seen,
negate the value at (e-1) to mark e as seen
otherwise, e has already been seen, so print it
So since array entries become negative in the course of running the algorithm, the absolute value has to be taken to obtain valid indices.
Let us follow the algorithm for a modified example to see how it works:
before: arr = { 7, 3, 4, 5, 5, 3, 2}
i == 0: arr[0] = 7
arr[7-1] is 2 > 0 ~> negate
arr = { 7, 3, 4, 5, 5, 3, -2}
i == 1: arr[1] = 3
arr[3-1] is 4 > 0 ~> negate
arr = { 7, 3, -4, 5, 5, 3, -2}
i == 2: arr[2] is -4 ~> abs for indexing
arr[4-1] is 5 > 0 ~> negate
arr = { 7, 3, -4,-5, 5, 3, -2}
i == 3: arr[3] is -5 ~> abs for indexing
arr[5-1] is 5 > 0 ~> negate
arr = { 7, 3, -4, -5, -5, 3, -2}
i == 4: arr[4] is -5 ~> abs for indexing
arr[5-1] is -5 < 0 ~> print abs(-5) as duplicate
i == 5: arr[5] is 3
arr[3-1] is -4 < 0 ~> print abs(3) as duplicate
i == 6: arr[6] is -2 ~> abs for indexing
arr[2-1] is 3 > 0 ~> negate
arr = { 7, -3, -4, -5, -5, 3, -2}
indices of positive entries: 0, 5 ~> 1 and 6 not in original array
indices of negative entries: 1, 2, 3, 4, 6 ~> 2, 3, 4, 5, 7 in original array
If you had started with the most straightforward way to solve this, given additional O(n) space, you would have probably thought about storing "already encountered" flags in a separate (auxiliary) array to look them up afterwards:
// pseudocode (zero based indexing ignored for now)
for each value in array
if (already_encountered[value] == true)
print "found a duplicate of " + value
else
already_encountered[value] = true
Your algorithm goes a little further. Given the fact that an integer is (probably) 32-bit, and you only need to store a limited (small) range of values, each array member actually has sufficient free bits to store the "already encountered" flag.
This means that you can drop the auxiliary already_encountered array given above, and use this extra space to store the flags with no extra memory allocation.
Using some bit twiddling, you could, for example, choose to store this value at the highest bit (leaving you with 31 bits to store your numbers). Whenever you want to check if the flag is set, you would need to extract this highest bit and check it, and then finally clear the bit before printing out the value:
// pseudocode (zero based indexing ignored)
for each value in array
{
// this value might already have a flag previously encoded
// for some other element, so remove it before continuing
plain_value = remove_flag(value)
// check if the flag is set for the actual value,
// if not, set it now
if (is_flag_set(array[plain_value]) == true)
print "found a duplicate of " + plain_value
else
array[plain_value] = set_flag(array[plain_value])
}
The only thing left to do is to define set_flag, is_flag_set and remove_flag functions.
In your case, the algorithm "sets the flag" by negating the value, "tests for flag" by checking if the value is negative, and "removes the flag" by using the absolute value (hence the abs function).
This can be safely achieved because signed integers use a single bit to store their sign information, allowing the transformation to leave the original value intact (provided it is small enough).
This leaves you with your final C code:
void printTwoElements(int arr[], int size)
{
int i;
printf("\n The repeating element is");
for(i = 0; i < size; i++)
{
// remove the flag
int plain_value = abs(arr[i]);
// is flag set?
if(arr[plain_value-1] < 0)
{
printf(" %d ", plain_value);
}
else
{
// set the flag by negating
arr[plain_value-1] = -arr[plain_value-1];
}
}
}
It's trying to ensure that the program never attempts a negative array index while walking through the elements.
abs() is the absolute value function in C. It makes sure your array index is not negative.

Resources