Array size calculation without using inbuilt functions - c

How do I find the size of an integer array without using any inbuilt (standard) functions? Here's my attempt at it:
int fun(int a[25],int ele)
{
int flag=0,i=0;
while(a[i]!=NULL)
{
flag++;
i++;
}
return flag;
}

The most common way of sending data around in arrays is by null-terminating the arrays. (However, this may not work for you if, for example, 0 is a valid integer to have in your array. In this case, you might want to use -1, for example.)
int array_len(int *arr)
{
const int TERMINATOR = 0; // or -1, as the case may be
int i = 0;
while (arr[i] != TERMINATOR)
i++;
return i;
}
However, a better method is probably just sending not only an array, but an array and a length whenever passing around data. That way, you don't need to keep calling functions like this to get array lengths in your various functions.

You can't.
The behaviour on going past the bounds of the array is undefined.
You could model the array with some sort of value acting as a terminator, but that's hardly practical. Pass the size as an extra parameter, of if you really want to have just one argument, use a struct.

C does not store the size of the array with it. In C strings a NULL terminator is used to determine the size of the array, but this is convention. Either pass the size as an argument to the function, or choose a value that is considered the end of the array and search for it.

In you while loop condition -
while(a[i]!=NULL)//replace NULL with such value which is unique and not used in your array.
Use -1 or something.
You may think to use '\0' instead of NULL but then if your array has 0 in between also then also loop will stop. (if 0 is in array don't use '\0').

Related

how to loop through array using pointer without known the size of the array [duplicate]

This question already has answers here:
Length of array in function argument
(9 answers)
Closed 8 years ago.
I have a question about loop through array using pointer, for example:
bool loopArray(int* array)
{
/*for(){}*/
}
within this function, I need to loop through this array without known the size of the array, how to loop it?
You can't.
Errrm, that's it.
You either provide a size parameter:
bool loopArray(int* array,size_t sz)
{
for(size_t i=0;i<sz;++i){
//Do stuff with array[i]....
}
}
Or a pointer to the 'end' of the array. You're allowed to point to one past the end and convention is to pass one-past-the-end as end. That allows you to specify 'empty' when begin==end:
bool loopArray(int* array,int* end)
{
for(;array!=end;++array){
//Do stuff with *array....
}
}
Looking at the previous example you would have defined int* end=array+sz before calling.
The second is faster and has the added benefit that other C programmers will start to recognize you as one of their own! If you see that as a benefit....
PS: For completeness: You can ensure you have a 'sentinel'. A sentinel is some value that indicates 'end'. The C standard library uses '\0' as the sentinel in character strings. Mores the pity.
That trick can work particularly when you're dealing with arrays of pointers and use NULL as the sentinel.
However it's not something to recommend as a general answer. It's error-prone, has a big overhead if you need to know the size, it restricts your ability to access 'sub-arrays' without modifying them and forbids you from using the sentinel as a value and breaks programs that do so by accident.
Other than that it's great.
it is impossible. You need some kind of information about the size; otherwise you will inevitabilly go past its borders...
A pointer doesn't "contain" any information about the size of the array that was allocated; it only points to a place in memory.
EXCEPT
There might be a way around; if you know what is the last element in your array (which MUST always be present then). This is used for example in char arrays (where the last element is \0)
You can't.
But you could do something on the lines of how the C standard library models strings. Given a char*, or a const char*, functions like strlen stop once 0 is reached (known as the null terminator).
So (i) either reserve an int value which acts as your terminator, or (ii) pass the length.
Either way, pass a const int* if you don't intend to modify the contents.

C: Iterate through an array of strings

I'm currently learning C and am struggling with how to iterate through an array of strings.
Let's just say I define an array, like so:
char* argv_custom[] = {"--debug", "--verbose", "--test", "--ultimate"};
Now, how would I go about determining the number of strings within argv_custom? (e.g. argc_custom)
Am I going the right way about this in the first place? Also, is it possible to do something like:
Pseudocode
if ('--debug' in argv_custom) { // do stuff }
Now, how would I go about determining the number of strings within argv_custom?
The canonical way:
int argc_custom = sizeof(argv_custom) / sizeof(argv_custom[0]);
Note: This only works on the array itself, as soon as you have a pointer (such as if you pass argv_custom to a function), it no longer works:
char **p = argv_custom;
int argc_custom = sizeof(p) / sizeof(p[0]); // No me gusta
is it possible to do something like: ...
There's no shortcut. You would have to iterate over each string, and do strcmp. Of course, you could (and probably should) wrap this behaviour into a function.
you can do sizeof(argv_custom)/sizeof(argv_custom[0]). This calculates the total length of the array divided by the size of every single element.
I've had this question quite a few times and from what I've found my favorite solution is to just iterate through the pointer until null. sizeof stops working as soon as you start using functions and passing the arrays around.
Here's a paradigm I've used time and time again in my assignments and it's been really helpful. The exact same thing can be used for getting the length of a cstring or iterating through its characters.
char* argv_custom[] = {"--debug", "--verbose", "--test", "--ultimate"};
char **temp = argv_custom;
int size = 0;
while (*temp) {
++size;
++temp;
}
This is not preferred over using sizeof, however it's an alternative when you want to loop through it.

Length of array in function argument

This is well known code to compute array length in C:
sizeof(array)/sizeof(type)
But I can't seem to find out the length of the array passed as an argument to a function:
#include <stdio.h>
int length(const char* array[]) {
return sizeof(array)/sizeof(char*);
}
int main() {
const char* friends[] = { "John", "Jack", "Jim" };
printf("%d %d", sizeof(friends)/sizeof(char*), length(friends)); // 3 1
}
I assume that array is copied by value to the function argument as constant pointer and reference to it should solve this, but this declaration is not valid:
int length(const char**& array);
I find passing the array length as second argument to be redundant information, but why is the standard declaration of main like this:
int main(int argc, char** argv);
Please explain if it is possible to find out the array length in function argument, and if so, why is there the redundancy in main.
sizeof only works to find the length of the array if you apply it to the original array.
int a[5]; //real array. NOT a pointer
sizeof(a); // :)
However, by the time the array decays into a pointer, sizeof will give the size of the pointer and not of the array.
int a[5];
int * p = a;
sizeof(p); // :(
As you have already smartly pointed out main receives the length of the array as an argument (argc). Yes, this is out of necessity and is not redundant. (Well, it is kind of reduntant since argv is conveniently terminated by a null pointer but I digress)
There is some reasoning as to why this would take place. How could we make things so that a C array also knows its length?
A first idea would be not having arrays decaying into pointers when they are passed to a function and continuing to keep the array length in the type system. The bad thing about this is that you would need to have a separate function for every possible array length and doing so is not a good idea. (Pascal did this and some people think this is one of the reasons it "lost" to C)
A second idea is storing the array length next to the array, just like any modern programming language does:
a -> [5];[0,0,0,0,0]
But then you are just creating an invisible struct behind the scenes and the C philosophy does not approve of this kind of overhead. That said, creating such a struct yourself is often a good idea for some sorts of problems:
struct {
size_t length;
int * elements;
}
Another thing you can think about is how strings in C are null terminated instead of storing a length (as in Pascal). To store a length without worrying about limits need a whopping four bytes, an unimaginably expensive amount (at least back then). One could wonder if arrays could be also null terminated like that but then how would you allow the array to store a null?
The array decays to a pointer when passed.
Section 6.4 of the C FAQ covers this very well and provides the K&R references etc.
That aside, imagine it were possible for the function to know the size of the memory allocated in a pointer. You could call the function two or more times, each time with different input arrays that were potentially different lengths; the length would therefore have to be passed in as a secret hidden variable somehow. And then consider if you passed in an offset into another array, or an array allocated on the heap (malloc and all being library functions - something the compiler links to, rather than sees and reasons about the body of).
Its getting difficult to imagine how this might work without some behind-the-scenes slice objects and such right?
Symbian did have a AllocSize() function that returned the size of an allocation with malloc(); this only worked for the literal pointer returned by the malloc, and you'd get gobbledygook or a crash if you asked it to know the size of an invalid pointer or a pointer offset from one.
You don't want to believe its not possible, but it genuinely isn't. The only way to know the length of something passed into a function is to track the length yourself and pass it in yourself as a separate explicit parameter.
As stated by #Will, the decay happens during the parameter passing. One way to get around it is to pass the number of elements. To add onto this, you may find the _countof() macro useful - it does the equivalent of what you've done ;)
First, a better usage to compute number of elements when the actual array declaration is in scope is:
sizeof array / sizeof array[0]
This way you don't repeat the type name, which of course could change in the declaration and make you end up with an incorrect length computation. This is a typical case of don't repeat yourself.
Second, as a minor point, please note that sizeof is not a function, so the expression above doesn't need any parenthesis around the argument to sizeof.
Third, C doesn't have references so your usage of & in a declaration won't work.
I agree that the proper C solution is to pass the length (using the size_t type) as a separate argument, and use sizeof at the place the call is being made if the argument is a "real" array.
Note that often you work with memory returned by e.g. malloc(), and in those cases you never have a "true" array to compute the size off of, so designing the function to use an element count is more flexible.
Regarding int main():
According to the Standard, argv points to a NULL-terminated array (of pointers to null-terminated strings). (5.1.2.2.1:1).
That is, argv = (char **){ argv[0], ..., argv[argc - 1], 0 };.
Hence, size calculation is performed by a function which is a trivial modification of strlen().
argc is only there to make argv length calculation O(1).
The count-until-NULL method will NOT work for generic array input. You will need to manually specify size as a second argument.
This is a old question, and the OP seems to mix C++ and C in his intends/examples. In C, when you pass a array to a function, it's decayed to pointer. So, there is no way to pass the array size except by using a second argument in your function that stores the array size:
void func(int A[])
// should be instead: void func(int * A, const size_t elemCountInA)
They are very few cases, where you don't need this, like when you're using multidimensional arrays:
void func(int A[3][whatever here]) // That's almost as if read "int* A[3]"
Using the array notation in a function signature is still useful, for the developer, as it might be an help to tell how many elements your functions expects. For example:
void vec_add(float out[3], float in0[3], float in1[3])
is easier to understand than this one (although, nothing prevent accessing the 4th element in the function in both functions):
void vec_add(float * out, float * in0, float * in1)
If you were to use C++, then you can actually capture the array size and get what you expect:
template <size_t N>
void vec_add(float (&out)[N], float (&in0)[N], float (&in1)[N])
{
for (size_t i = 0; i < N; i++)
out[i] = in0[i] + in1[i];
}
In that case, the compiler will ensure that you're not adding a 4D vector with a 2D vector (which is not possible in C without passing the dimension of each dimension as arguments of the function). There will be as many instance of the vec_add function as the number of dimensions used for your vectors.
int arsize(int st1[]) {
int i = 0;
for (i; !(st1[i] & (1 << 30)); i++);
return i;
}
This works for me :)
length of an array(type int) with sizeof:
sizeof(array)/sizeof(int)
Best example is here
thanks #define SIZE 10
void size(int arr[SIZE])
{
printf("size of array is:%d\n",sizeof(arr));
}
int main()
{
int arr[SIZE];
size(arr);
return 0;
}

How to check if "set" in c

If I allocate a C array like this:
int array[ 5 ];
Then, set only one object:
array[ 0 ] = 7;
How can I check whether all the other keys ( array[1], array[2], …) are storing a value? (In this case, of course, they aren't.)
Is there a function like PHP's isset()?
if ( isset(array[ 1 ]) ) ...
There isn't things like this in C. A static array's content is always "set". You could, however, fill in some special value to pretend it is uninitialized, e.g.
// make sure this value isn't really used.
#define UNINITIALIZED 0xcdcdcdcd
int array[5] = {UNINITIALIZED, UNINITIALIZED, UNINITIALIZED, UNINITIALIZED, UNINITIALIZED};
array[0] = 7;
if (array[1] != UNINITIALIZED) {
...
You can't
There values are all undefined (thus random).
You could explicitly zero out all values to start with so you at least have a good starting point. But using magic numbers to detect if an object has been initialized is considered bad practice (but initializing variables is considered good practice).
int array[ 5 ] = {};
But if you want to explicitly check if they have been explicitly set (without using magic numbers) since creation you need to store that information in another structure.
int array[ 5 ] = {}; // Init all to 0
int isSet[ 5 ] = {}; // Init all to 0 (false)
int getVal(int index) {return array[index];}
int isSet(int index) {return isSet[index];}
void setVal(int index,int val) {array[index] = val; isSet[index] = 1; }
In C, all the elements will have values (garbage) at the time of allocation. So you cannot really have a function like what you are asking for.
However, you can by default fill it up with some standard values like 0 or INT_MIN using memset() and then write an isset() code.
I don't know php, but one of two things is going on here
the php array is actually a hash-map (awk does that)
the php array is being filled with nullable types
in either case there is a meaningful concept of "not set" for the values of the array. On the other hand a c array of built in type has some value in every cell at all times. If the array is uninitialized and is automatic or was allocated on the heap those values may be random, but they exist.
To get the php behavior:
Implement (or find a library wit) and use a hashmap instead on an array.
Make it an array of structures which include an isNull field.
Initialize the array to some sentinal value in all cells.
One solution perhaps is to use a separate array of flags. When you assign one of the elements, set the flag in the boolean array.
You can also use pointers. You can use null pointers to represent data which has not been assigned yet. I made an example below:
int * p_array[3] = {NULL,NULL,NULL};
p_array[0] = malloc(sizeof(int));
*p_array[0] = (int)0;
p_array[2] = malloc(sizeof(int));
*p_array[2] = (int)4;
for (int x = 0; x < 3; x++) {
if (p_array[x] != NULL) {
printf("Element at %i is assigned and the value is %i\n",x,*p_array[x]);
}else{
printf("Element at %i is not assigned.\n",x);
}
}
You could make a function which allocates the memory and sets the data and another function which works like the isset function in PHP by testing for NULL for you.
I hope that helps you.
Edit: Make sure the memory is deallocated once you have finished. Another function could be used to deallocate certain elements or the entire array.
I've used NULL pointers before to signify data has not been created yet or needs to be recreated.
An approach I like is to make 2 arrays, one a bit-array flagging which indices of the array are set, and the other containing the actual values. Even in cases where you don't need to know whether an item in the array is "set" or not, it can be a useful optimization. Zeroing a 1-bit-per-element bit array is a lot faster than initializing an 8-byte-per-element array of size_t, especially if the array will remain sparse (mostly unfilled) for its entire lifetime.
One practical example where I used this trick is in a substring search function, using a Boyer-Moore-style bad-character skip table. The table requires 256 entries of type size_t, but only the ones corresponding to characters which actually appear in the needle string need to be filled. A 1kb (or 2kb on 64-bit) memset would dominate cpu usage in the case of very short searches, leading other implementations to throw around heuristics for whether or not to use the table. But instead, I let the skip table go uninitialized, and used a 256-bit bit array (only 32 bytes to feed to memset) to flag which entries are in use.

How to empty a char array?

Have an array of chars like char members[255]. How can I empty it completely without using a loop?
char members[255];
By "empty" I mean that if it had some values stored in it then it should not. For example if I do strcat then old value should not remain
members = "old value";
//empty it efficiently
strcat(members,"new"); // should return only new and not "old value new"
using
memset(members, 0, 255);
in general
memset(members, 0, sizeof members);
if the array is in scope, or
memset(members, 0, nMembers * (sizeof members[0]) );
if you only have the pointer value, and nMembers is the number of elements in the array.
EDIT Of course, now the requirement has changed from the generic task of clearing an array to purely resetting a string, memset is overkill and just zeroing the first element suffices (as noted in other answers).
EDIT In order to use memset, you have to include string.h.
Depends on what you mean by 'empty':
members[0] = '\0';
Don't bother trying to zero-out your char array if you are dealing with strings. Below is a simple way to work with the char strings.
Copy (assign new string):
strcpy(members, "hello");
Concatenate (add the string):
strcat(members, " world");
Empty string:
members[0] = 0;
Simple like that.
char members[255] = {0};
EDIT: Given the most recent edit to the question, this will no longer work as there is no null termination - if you tried to print the array, you would get your characters followed by a number of non-human-readable characters. However, I'm leaving this answer here as community wiki for posterity.
char members[255] = { 0 };
That should work. According to the C Programming Language:
If the array has fixed size, the number of initializers may not exceed the number of members of the array; if there are fewer, the remaining members are initialized with 0.
This means that every element of the array will have a value of 0. I'm not sure if that is what you would consider "empty" or not, since 0 is a valid value for a char.
Use bzero(array name, no.of bytes to be cleared);
You cannot empty an array as such, it always contains the same amount of data.
In a bigger context the data in the array may represent an empty list of items, but that has to be defined in addition to the array. The most common ways to do this is to keep a count of valid items (see the answer by pmg) or for strings to terminate them with a zero character (the answer by Felix). There are also more complicated ways, for example a ring buffer uses two indices for the positions where data is added and removed.
members[0] = 0;
is enough, given your requirements.
Notice however this is not "emptying" the buffer. The memory is still allocated, valid character values may still exist in it, and so forth..
I'd go with
members_in_use = 0;
By "empty an array" if you mean reset to 0, then you can use bzero.
#include <strings.h>
void bzero(void *s, size_t n);
If you want to fill the array with some other default character then you may use memset function.
#include <string.h>
void *memset(void *s, int c, size_t n);
In this case just members[0] = 0 works.
Disclaimer: I don't usually program in C so there may be any syntax gotcha in my examples, but I hope the ideas I try to express are clear.
If "emptying" means "containing an empty string", you can just assign the first array item to zero, which will effectively make the array to contain an empry string:
members[0] = 0;
If "emptying" means "freeing the memory it is using", you should not use a fixed char array in the first place. Rather, you should define a pointer to char, and then do malloc / free (or string assignment) as appropriate.
An example using only static strings:
char* emptyString="";
char* members;
//Set string value
members = "old value";
//Empty string value
member = emptyString
//Will return just "new"
strcat(members,"new");
You can use the following instruction:
strcpy_s(members, "");

Resources