C how do I check if an array is full? - c

I have an array: array[3][3]
I will let the user input data into the array as long as it is not full. As soon as the array gets full I want to stop the user from inserting more data into it.

C has no array bounds check. You have to do it yourself. Use a variable to keep track of how many items you have inserted, and stop when your counter is equal to the array size.

You cannot check if "array is full". To do what u want to do, keep track of index while adding elements to array.

You need to keep track of the data inserted by a user. When your counter reaches the size of the array, the array is full. :D There is not other way in C to achieve this result as it does not provide any means of verifying how many elements are in the array.

Introduce a variable for counting the number of cells filled. You adjust this variable whenever you add/remove data to your array. Then, in order to check if your array is full, just check if this variable is equal to the total number of cells in your array.

The most simple way in my opinion is to dynamically allocate memory using calloc(), where you can initialise the array elements to, for example, zeros. The you can check if the array is full by checking, if the last element in the array is still zero or not. Of course, if the last element is still zero, then the array is not full.

First of all this is not an array but a matrix (aka array of array). you already know that the matrix has dimensions 3x3 and then you could do something like this:
int x, y;
int array[3][3];
for (x = 0; x<2; x++)
{
for (y = 0; y<2; y++)
{
//I assume that it is an array of int
printf("Insert number at %d - %d" ,x,y);
scanf("%d" ,&array[x][y]);
}
}
Now the user can only insert 3*3=9 values.

There are no way to array bound check in C, However with better coding practice we check whether array is full.
For example, consider in your array a[3][3] you don't want to have some particular value. That value could be anything! 0xFF or 0 or anything which is in the integer range! and you have to make sure that value is never given as the input to the array, and then you can verify whether your array a[3][3] is full!
/*part of coed in main*/
/*here initialize the array with 0, assuming that 0 will never be a part of array a[3][3]*/
for(i=0; i<3; i++)
{
for(j=0;j<3;j++)
{
a[i][j] = 0; // assuming that 0 will never be a part of array a[3][3]
}
}
while(CheckArray(**a)!=0)
{
printf("give array input:\n")
scanf("%d", &a[row][column]); //writing to empty cell of an array
}
//CheckArray code
int CheckArray(int a[][])
{
for(i=0; i<3; i++)
{
for(j=0;j<3;j++)
{
if(a[i][j] == 0) // assuming that 0 will never be a part of array a[3][3]
{
row = i; // row and column must be global variables in this example!
column = j; // row and column must be global variables in this example!
return 1;
}
else
{
// no need to do anything here
}
}
}
//if code reaches here then array is full!
printf("Array is full.\n");
return 0;
}
You can still optimize the above code! this is just one way of checking whether array is full with better coding practice!

If possible, you could initialize all elements in the array to a certain value that your program would otherwise consider "illegal" or "invalid". E.g. an array of positive numbers can be initialized to be all -1's. Or an array of chars can be initialized to be all NULL characters.
Then, just look at the last element if it is set to the default value.
measurement = sizeof(myarray) / sizeof(element); //or just a constant
while(myarray[measurement-1] == defaultvalue){
//insert code here...
}

Encapsulate the behavior into a struct with getter/setter functions that check for the max length of the desired vector:
typedef varvector
varvector;
struct varvector {
int length;
void* vector;
};
varvector* varvector_create(int length) {
varvector* container = malloc(sizeof(varvector));
void* vector = malloc(length);
if(container && vector) {
container->vector = vector;
}
return(container);
}
void varvector_destroy(varvector* container) {
free(container.vector);
free(container);
}
varvector_get(varvector* container, int position) {
if(position < container.length) {
return(container->vector[position]);
}
}
varvector_set(varvector* container, int position, char value) {
if(position < container.length) {
container->vector[position] = value
}
}
Object Oriented Programming is a design pattern which happens to have syntactic support in some languages and happens to not have syntactic support in C.
This does not mean that you cannot use this design pattern in your work, it just means you have to either use a library that already provides this for you (glib, ooc) or if you only need a small subset of these features, write your own basic functions.

You can assume that the last element of an array has id=0.
Then in function add check if there is an element with id=0.
int add(char *source, char *target, int size) {
int index = 0;
for (int i = 0; i < size; i++) {
if (target[i].id == 0) {
index = i;
break;
}
}
if (index >= 0 && index < size) {
if (index < size - 1) target[index + 1].id = 0;
// check that element with id=0 is the last in the array
//write code to add your element here
return index;
}
}

Related

convert an array to multi dimensional C without using pointer

First of all, I would like to know if its possible. If so, please checkout my code and tell me what is wrong.
int m[n]; // this is where I pass the values to a array
for(int i=0;i<n;i++) {
scanf("%d",&a);
m[i]=a;
}
int v[n][b]; // this is where I pass the values from a array to a 2d array
for(int i=0;i<n;i++) { // but for some reason it doesnt work
for(int j=0;j<b;j++) {
v[i][j]=m[i];
}
}
}
The output is :
something like this
v[0][0]:0
v[0][1]:0
v[1][0]:1
v[1][1]:1
....
but I want something like this:
v[0][0]:0
v[0][1]:1
v[1][0]:2
v[1][1]:3
without repeating the values
P.S- if I need to use pointers you can also explain me that way but I would prefer the first one.
In assigning to v[i][j], you are constantly reassigning whatever value was in m[i].
Instead try:
v[i][j] = m[i*n + j];
This is only going to work if the array m has n*b elements.
i*n represents the row you're working on, and j is the column. Or vice-versa, it's up to you how you imagine it.
#include <stdio.h>
int main(){
int m[6]; // this is where I pass the values to a array
int i;
int j;
int k;
int a;
for(i=0;i<6;i++) {
scanf("%d",&a);
m[i]=a;
}
k=0;
int v[2][3]; // this is where I pass the values from a array to a 2d array
for(i=0;i<2;i++) { // but for some reason it doesnt work
for(j=0;j<3;j++) {
v[i][j]=m[3*k+j]; // 3 is the maximum i value [n of your code]
}
k++;
}
return 0;
}
Just used OP's code and changed:
1) Defined all integer variables.
2) the int inside the for removed to be compatible code with every c compiler (OP doesn't really need this changes)
3) Added a variable k that been increased with the changes of outer loop variable and used it in the command v[i][j]=m[3*k+j]; to give the appropriate m value to the new array. (3 been explained in the comment of the same line)
See #Pablo's comment for not using k
Assuming you have at least as many elements in your 1D array as your 2D array and you want to fill in your 2D array in row major order, it suffices to just increment an index for your 1D array every time you read an element from it.
int v[n][b];
int k = 0;
for(int i=0;i<n;i++) {
for(int j=0;j<b;j++) {
v[i][j]=m[k++];
}
}

A string of codes connected to multiple strings.I have some doubts about the two dimensional array and the for loop. Thank you very much!

/* link many strings*/
#include<stdio.h>
char *mystrcat(char * strDest, char * strSrc);
int main(void)
{
int n;
while(scanf("%d",&n))//输入要连接的字符串个数
{
if(n==0) break;//输入0结束
else
{
char words[n][100];
int i=0;
int j;
for(i=0;i<=n;i++)
{
while(fgets(words[i],100,stdin)!=NULL)
{
j=0;
while(words[i][j]!='\n')
j++;
if(words[i][j]=='\n') words[i][j]='\0';break;
}
}//输入字符串
for(i=n;i>0;i--)
{
mystrcat(words[i-1],words[i]);
}//连接这几个字符串
fputs(words[0],stdout);//输出字符串
printf("\n");
}
}
return 0;
}
//strcat函数原型
char *mystrcat(char * strDest,char * strSrc)
{
char *res=strDest;
while(*strDest)strDest++;
while(*strDest=*strSrc)
{
strDest++;
strSrc++;
}
return res;
}
This is a string of correct code to connect multiple strings. But I think n should be n-1 in two for cycles. But if you change the n to n-1, you can only enter n-1 strings, one less than I think. Can you tell me where my idea is wrong?
for(i=0;i<=n;i++)
Accessing array index out of bound when i=n - this is undefined behavior. So of course indexing should be from n-1 to 0( at max) or 0 to n-1.
And also array indexing in C starts from 0. So there are n elements that you are accessing, not n-1.
So corrections would be
for(i=0;i<=n-1;i++)
The thing is - you are reading in the n locations having index 0 to n-1 on the array and then you concatenate them one by one and at last all concatenated strings will be in words[0]. You are printing it out.
The second loop would be like
for(i=n-1;i>0;i--)
{
mystrcat(words[i-1],words[i]);
}
The idea is no matter what while accessing array indices don't access array index out bound. Here you can simply write it like this as shown in the second case. The thing is here we have ensured that all the indices used are from {0,1,2,3...,n-1}.
First determine what you want to do, if you want to take n string and then try to concatenate them then yes you can. That's what is being done here. but a much cleaner way to do it would be that keep a different result string on which you will concatenate n strings. That will not overwrite or change the already inputted strings.

What's the point of using linear search with sentinel?

My goal is to understand why adopting linear search with sentinel is preferred than using a standard linear search.
#include <stdio.h>
int linearSearch(int array[], int length) {
int elementToSearch;
printf("Insert the element to be searched: ");
scanf("%d", &elementToSearch);
for (int i = 0; i < length; i++) {
if (array[i] == elementToSearch) {
return i; // I found the position of the element requested
}
}
return -1; // The element to be searched is not in the array
}
int main() {
int myArray[] = {2, 4, 9, 2, 9, 10};
int myArrayLength = 6;
linearSearch(myArray, myArrayLength);
return 0;
}
Wikipedia mentions:
Another way to reduce the overhead is to eliminate all checking of the loop index. This can be done by inserting the desired item itself as a sentinel value at the far end of the list.
If I implement linear search with sentinel, I have to
array[length + 1] = elementToSearch;
Though, the loop stops checking the elements of the array once the element to be searched is found. What's the point of using linear search with sentinel?
A standard linear search would go through all the elements checking the array index every time to check when it has reached the last element. Like the way your code does.
for (int i = 0; i < length; i++) {
if (array[i] == elementToSearch) {
return i; // I found the position of the element requested
}
}
But, the idea is sentinel search is to keep the element to be searched in the end, and to skip the array index searching, this will reduce one comparison in each iteration.
while(a[i] != element)
i++;
First, lets turn your example into a solution that uses sentinels.
#include <stdio.h>
int linearSearch(int array[], int length, int elementToSearch) {
int i = 0;
array[length] = elementToSearch;
while (array[i] != elementToSearch) {
i++;
}
return i;
}
int main() {
int myArray[] = {2, 4, 9, 2, 9, 10, -1};
int myArrayLength = 6;
int mySearch = 9;
printf("result is %d\n", linearSearch(myArray, myArrayLength, mySearch));
return 0;
}
Notice that the array now has an extra slot at the end to hold the sentinel value. (If we don't do that, the behavior of writing to array[length] is undefined.)
The purpose of the sentinel approach is to reduce the number of tests performed for each loop iteration. Compare:
// Original
for (int i = 0; i < length; i++) {
if (array[i] == elementToSearch) {
return i;
}
}
return -1;
// New
while (array[i] != elementToSearch) {
i++;
}
return i;
In the first version, the code is testing both i and array[i] for each loop iteration. In the second version, i is not tested.
For a large array, the performance difference could be significant.
But what are the downsides?
The result when the value is not found is different; -1 versus length.
We have to make the array bigger to hold the sentinel value. (And if we don't get it right we risk clobbering something on the stack or heap. Ouch!)
The array cannot be read-only. We have to be able to update it.
This won't work if multiple threads are searching the same array for different elements.
Using the sentinel value allows to remove variable i and correspondingly its checking and increasing.
In your linear search the loop looks the following way
for (int i = 0; i < length; i++) {
if (array[i] == elementToSearch) {
return i; // I found the position of the element requested
}
}
So variable i is introduced, initialized, compared in each iteration of the loop, increased and used to calculate the next element in the array.
Also the function has in fact three parameters if to pass to the function the searched value
int linearSearch(int array[], int length, int value) {
//...
Using the sentinel value the function can be rewritten the following way
int * linearSearch( int array[], int value )
{
while ( *array != value ) ++array;
return array;
}
And inside the caller you can check whether the array has the value the following way
int *target = linearSearch( array, value );
int index = target == array + size - 1 ? -1 : target - array;
If you add the value to search for, you can reduce one comparison in every loop, so that the running time is reduced.
It may look like for(i = 0;;i++) if(array[i] == elementToSearch) return i;.
If you append the value to search for at the end of the array, when instead of using a for loop with initialization, condition and increment you can a simpler loop like
while (array[i++] != elementToSearch)
;
Then the loop condition is the check for the value you search for, which means less code to execute inside the loop.
The point is that you can convert the for loop into a while/repeat loop. Notice how you are checking i < length each time. If you covert it,
do {
} while (array[i++] != elementToSearch);
Then you don't have to do that extra checking. (in this case, array.length is now one bigger)
Although the sentinel approach seems to shave off a few cycles per iteration in the loop, this approach is not a good idea:
the array must be defined with an extra slot and passing its length as 1 less than the defined length is confusing and error prone;
the array must be modifiable;
if the search function modifies the array to set the sentinel value, this constitutes a side effect that can be confusing and unexpected;
the search function with a sentinel cannot be used for a portion of the array;
the sentinel approach is inherently not thread safe: seaching the same array for 2 different values in 2 different threads would not work whereas searching a constant read only array from multiple threads would be fine;
the benefits are small and only for large arrays. If this search becomes a performance bottleneck, you should probably not use linear scanning. You could sort the array and use a binary search or you could use a hash table.
optimizing compilers for modern CPUs can generate code where both comparisons will be performed in parallel, hence incur no overhead;
As a rule of thumb, a search function should not have side effects. A good example of the Principe of least surprise.

how to write function which returns the position of the number in the array?

I have just started leran about C++. And I have to do one exercise but I don't know how. Please help me.
I have to write the function which returns the position of the number in the array,rate and size are pass to this function and the value of the expression|tab[i]_M| is the maximum, where M is the average of all the elements.
Thank you for your help
You will want to look at the values in your array one by one. You can access the individual values like this:
yourarray[index]
The best way to do it is a loop. There are several loops available in C++. You can use the for loop for example. Inside of the loop you check if the value is the one you are looking for
for (int i = 0; ...
{
if your array[i] == your value
If you found the value, break the loop and return the index i.
// Returns the index of the first occurrence of a value in the array, or -1 if not found
int GetPositionInArray(int array[], int value)
{
for (int i = 0; i < sizeof(array)/sizeof(int); i++) {
if (array[i] == value)
return i;
}
return -1;
}

In C check to see if an int exists?

I have a 13x13 array with elements but not every element is number. If its not a number, then its filled with blank space so I am trying to figure out how to check to see if a number exists at a given index. If a number exists, it does a job if not, it goes back to the loop. This is what I have:
int *spaceCheck;
int i, Value;
for(i=0;i<169;i++){
spaceCheck = &Array[i];
if(!spaceCheck){
continue;
else
//do this job
}
Can I do this? Is there any other better way to check? Thank you for you help.
Its an array of integers of 169 elements. So when the data(numbers) is initially loaded, there are only 80 elements loaded from the file into the array. The rest of the space in the array is filled with blank space (printf(" ")). Sorry for the confusion.
To do what you are asking, you need to use a sentinel value that indicates "no value", eg:
const int novalue = -1; // or whatever you want, as long as it is unique
int Array[169];
for (i=0;i<169;i++)
Array[i] = novalue;
...
for(i=0;i<169;i++){
Value = Array[i];
if(Value == novalue)
continue;
//do this job
}
Otherwise, create an array on structs instead of ints:
struct sValue
{
char valid;
int value;
};
sValue Array[169];
for (i=0;i<169;i++)
Array[i].valid = 0;
...
for(i=0;i<169;i++){
if(Array[i].valid == 0)
continue;
Value = Array[i].value;
//do this job
}
The array elements may not be initialized with zero always. The first thing you need to do is initialize it with a default value. say 0 or -1 or whatever. Then you can modify your code as follows:
int *spaceCheck;
int i, Value;
for(i=0;i<169;i++){
spaceCheck = &Array[i];
if(*spaceCheck!=default_value){
continue;
else
//do this job
}
Note that you were also storing the reference of the array element. If you want to check its data you need to use the dereferencing operator *. Hope that this is what you want. Simpler way to write the above code is to not use pointers at all. It is as follows:
int i, Value;
for(i=0;i<169;i++){
if(Array[i]!=default_value){
continue;
else
//do this job
}
I think here in this statement :if(!spaceCheck) you are checking the address of the variable to be true and you are not comparing it with any value.As for example ,if((*spacecheck)!=Array[i][j])//considering you have a 2-D array)will be logically correct as per your question.Well the following code may clear your concept,it is based on conditions similar to what you have provided here,
int *spaceCheck;
int i,j, Value;
for(i=0;i<13;i++){
for(j=0;j<13;j++){
spaceCheck=&array[i][j];//array is 2-D
if(*spaceCheck!=array[i][j])
continue;
else
//do this job
}}

Resources