Executive summary:
int a[17];
size_t n = sizeof(a)/sizeof(a[0]);
Full answer:
To determine the size of your array in bytes, you can use the sizeof
operator:
int a[17];
size_t n = sizeof(a);
On my computer, ints are 4 bytes long, so n is 68.
To determine the number of elements in the array, we can divide the total size of the array by the size of the array element. You could do this with the type, like this:
int a[17];
size_t n = sizeof(a) / sizeof(int);
and get the proper answer (68 / 4 = 17), but if the type of
a changed you would have a nasty bug if you forgot to change
the sizeof(int) as well.
So the preferred divisor is sizeof(a[0]) or the equivalent sizeof(*a), the size of the first element of the array.
int a[17];
size_t n = sizeof(a) / sizeof(a[0]);
Another advantage is that you can now easily parameterize the array name in a macro and get:
#define NELEMS(x) (sizeof(x) / sizeof((x)[0]))
int a[17];
size_t n = NELEMS(a);
Answer from Mark Harrison on Stack OverflowExecutive summary:
int a[17];
size_t n = sizeof(a)/sizeof(a[0]);
Full answer:
To determine the size of your array in bytes, you can use the sizeof
operator:
int a[17];
size_t n = sizeof(a);
On my computer, ints are 4 bytes long, so n is 68.
To determine the number of elements in the array, we can divide the total size of the array by the size of the array element. You could do this with the type, like this:
int a[17];
size_t n = sizeof(a) / sizeof(int);
and get the proper answer (68 / 4 = 17), but if the type of
a changed you would have a nasty bug if you forgot to change
the sizeof(int) as well.
So the preferred divisor is sizeof(a[0]) or the equivalent sizeof(*a), the size of the first element of the array.
int a[17];
size_t n = sizeof(a) / sizeof(a[0]);
Another advantage is that you can now easily parameterize the array name in a macro and get:
#define NELEMS(x) (sizeof(x) / sizeof((x)[0]))
int a[17];
size_t n = NELEMS(a);
The sizeof way is the right way iff you are dealing with arrays not received as parameters. An array sent as a parameter to a function is treated as a pointer, so sizeof will return the pointer's size, instead of the array's.
Thus, inside functions this method does not work. Instead, always pass an additional parameter size_t size indicating the number of elements in the array.
Test:
#include <stdio.h>
#include <stdlib.h>
void printSizeOf(int intArray[]);
void printLength(int intArray[]);
int main(int argc, char* argv[])
{
int array[] = { 0, 1, 2, 3, 4, 5, 6 };
printf("sizeof of array: %d\n", (int) sizeof(array));
printSizeOf(array);
printf("Length of array: %d\n", (int)( sizeof(array) / sizeof(array[0]) ));
printLength(array);
}
void printSizeOf(int intArray[])
{
printf("sizeof of parameter: %d\n", (int) sizeof(intArray));
}
void printLength(int intArray[])
{
printf("Length of parameter: %d\n", (int)( sizeof(intArray) / sizeof(intArray[0]) ));
}
Output (in a 64-bit Linux OS):
sizeof of array: 28
sizeof of parameter: 8
Length of array: 7
Length of parameter: 2
Output (in a 32-bit windows OS):
sizeof of array: 28
sizeof of parameter: 4
Length of array: 7
Length of parameter: 1
C Program Length of Array
List input in C and length argument - Code Golf Meta Stack Exchange
Total size of a linked list in C - Stack Overflow
How to find the length of an array
How do you find the length of an array in C?
Why is `sizeof` used to determine the length of an array in C?
What is the length of an empty array in C?
Videos
The following code prints 40, but I expect the output to be 10. Any ideas why?
Not for all languages
I estimate 15% of my Python golfs with list input could be shortened by taking in its length, if that were allowed. Hundreds of golfs in mainstream languages could be improved by mechanically replacing "len(l)" or similar with an input parameter.
These submissions strongly suggest that golfers wouldn't guess this to be allowed without knowing the rule specifically. This is a hidden rule of the worst kind -- broadly useful, unexpected, and likely to make golfs more boring on average.
I'm sympathetic to the problems languages like C have with cumbersome input processing, especially as they already have many disadvantages. Golfing languages can be designed around such issues, but C is stuck with them.
But, I want to avoid the trend of giving all languages an easy extra workaround because one language really wants it. The result is a laundry list of liberties with input that go beyond taking it conveniently and naturally for the language, to doing parts of the golfing task in the input format, justified by citing obscure meta threads about other languages.
I'd rather say that this is a property of C that golfers need to deal with, or that a C-specific rule be made. Either one would be better than changing the rules for all languages.
This is an interesting indication of the way PPCG has changed since the early days. I remember when a lot of questions included the length as a separate input and people commented with requests to make it optional because their high-level languages didn't need it.
In most high-level languages an array is effectively a struct with a pointer and a length. I don't see that there's any point to creating a standard struct template. However, it does seem perfectly reasonable to interpret "array" in a question as meaning "pointer and length, as encapsulated in your language". In the case of C the simplest "encapsulation"* is as two variables.
* Yes, I get the point that it's not really encapsulation if you can split them up, hence the scare quotes. But such pedanticism is not the point here.
You usually go through the list until you reach the tail item while counting in the meanwhile, code should be something like that:
int listLength(struct Data_Struct* item)
{
struct Data_Struct* cur = item;
int size = 0;
while (cur != null)
{
++size;
cur = cur->Next;
}
return size;
}
Mind that complexity of this operation is linear with the size of the list, so it's O(n) and it's quite inefficient. You could store size somewhere and update with list insertions and deletes to avoid any overhead and being able to calculate it in a constant time O(1).
EDIT: Didn't notice you wanted size of the whole data included into the list. In your case you can keep the same approach used for calculating the length but instead that adding 1 for every element you should add the total length of strings:
size += strlen(Name)+strlen(Task)+strlen(Pos);
Mind that since data inside your list element if of type char* the effective size of the Data_Struct is just 4 pointers, that's why you need to use a support function like strlen, otherwise you can't get real dimension of the strings.
Which is the difference?
sizeof(Data_Struct) == 16
because the Data_Struct type contains 4 pointers, three for pointers to char and one for the next element in the list
sizeof(Name) == sizeof(Task) == sizeof(Pos) == 4
because these variables are of type pointer to char, so they are pointer, no concrete value, and it's usually 4 bytes (I'm assuming a 32 bit architecture)
strlen(Name) == length in chars of the string
because the function works exactly to calculate the length of a string.
Once you allocate memory for a node (using malloc) you should be able to do sizeof(yourDataType). So to get the total size of the linked list you traverse the list and get the count of nodes:
Total Size Of Linked List = SizeOf(One Node) * Count Of Nodes
For instance:
int getCountOfList()
{
Node* temp = head; //assign a temp node to the head of the list
int count=0;
while(temp) {
count++;
temp = temp->next; //move to next node
}
return count;
}
Then you take that count and multiply by size:
size = getCountOfList * sizeof(mydatatype);
This will give you the size of the actual linked list but becareful as the linked list node has pointer elements which in and of themselves can allocate memory as well. This will need to be accounted for...
For instance, one of those char* elements within the node could malloc some more space and use up some memory.
If you actually need the entire size of the list including allocated elements for all other char* pointers for example, you simply:
1)Traverse the list and look into each node
2)For each node you check if the elements of each node point to any other allocation (for instance char* data may allocate 50 characters to store). If it isn't null you get the length of the string + 1 (for terminating char) and you multiply that by sizeof(char) (for this example)
3)You do that for each node and store that size, then move to next node
4)You take the SUM of all of these char* (in this case) for each node and accumulate for the entire list.
5)Once you have that simply add this sum that will give you the size of all nodes.
Then total size becomes:
SizeOfAllNode + (SizeOf(dataType) * CountOfNodes)
I googled it and found (sizeof(a)/sizeof(a[0])) but in my use this always ended up being 4, what is an alternative way or how can i fix this method.
Code : https://pastebin.com/raw/7Qdw1fmz
C arrays do keep track of their length, as the array length is a static property:
int xs[42]; /* a 42-element array */
You can't usually query this length, but you don't need to because it's static anyway – just declare a macro XS_LENGTH for the length, and you're done.
The more important issue is that C arrays implicitly degrade into pointers, e.g. when passed to a function. This does make some sense, and allows for some nice low-level tricks, but it loses the information about the length of the array. So a better question would be why C was designed with this implicit degradation to pointers.
Another matter is that pointers need no storage except the memory address itself. C allows us to cast integers to pointers, pointers to other pointers, and to treat pointers as if they were arrays. While doing this, C is not insane enough to fabricate some array length into existence, but seems to trust in the Spiderman motto: with great power the programmer will hopefully fulfill the great responsibility of keeping track of lengths and overflows.
A lot of this had to do with the computers available at the time. Not only did the compiled program have to run on a limited resource computer, but, perhaps more importantly, the compiler itself had to run on these machines. At the time Thompson developed C, he was using a PDP-7, with 8k of RAM. Complex language features that didn't have an immediate analog on the actual machine code were simply not included in the language.
A careful read through the history of C yields more understanding into the above, but it wasn't entirely a result of the machine limitations they had:
Moreover, the language (C) shows considerable power to describe important concepts, for example, vectors whose length varies at run time, with only a few basic rules and conventions. ... It is interesting to compare C's approach with that of two nearly contemporaneous languages, Algol 68 and Pascal [Jensen 74]. Arrays in Algol 68 either have fixed bounds, or are `flexible:' considerable mechanism is required both in the language definition, and in compilers, to accommodate flexible arrays (and not all compilers fully implement them.) Original Pascal had only fixed-sized arrays and strings, and this proved confining [Kernighan 81].
C arrays are inherently more powerful. Adding bounds to them restricts what the programmer can use them for. Such restrictions may be useful for programmers, but necessarily are also limiting.