like how to convert an integer for example: 123 to an array: [1,2,3]
I know how to make a LinkedList in C but I'm struggling to understand how an ArrayList would be implemented in C - especially the addition and direct access parts
Videos
Save yourself some pain...
using System.Linq;
int[] ints = new [] { 10, 20, 10, 34, 113 };
List<int> lst = ints.OfType<int>().ToList(); // this isn't going to be fast.
Can also just...
List<int> lst = new List<int> { 10, 20, 10, 34, 113 };
or...
List<int> lst = new List<int>();
lst.Add(10);
lst.Add(20);
lst.Add(10);
lst.Add(34);
lst.Add(113);
or...
List<int> lst = new List<int>(new int[] { 10, 20, 10, 34, 113 });
or...
var lst = new List<int>();
lst.AddRange(new int[] { 10, 20, 10, 34, 113 });
There is also a constructor overload for List that will work... But I guess this would required a strong typed array.
//public List(IEnumerable<T> collection)
var intArray = new[] { 1, 2, 3, 4, 5 };
var list = new List<int>(intArray);
... for Array class
var intArray = Array.CreateInstance(typeof(int), 5);
for (int i = 0; i < 5; i++)
intArray.SetValue(i, i);
var list = new List<int>((int[])intArray);
A naive implementation of ArrayList in c, open to criticism and feedback to improve upon my implementation.
https://github.com/kingxcold/Array_list-in-c
You are returning a pointer to a stack memory location. That memory region is no longer valid once the function returns.
Also, instead of actually returning a pointer to the array, you are returning the first element in the array. The following code will return 1, not a pointer the array.
int array[] {1, 2, 3, 4};
return *array
You probably only need to make minimal changes your code to get it to work.
void** array = (void **) malloc(sizeof(void *) * array_size);
...
return array;
Just make sure that you release the memory that memory used for array when you are finished with it.
void **array = list_to_array(list);
// Use array
...
// Finished with array
free(array);
When you increase the pointer int* a by 1, it would actually increase it by sizeof(int), which is - on most systems, at least - 4.
So if
int* a = 0x40b8c438
then
a + 1
= ((void*) a) + sizeof(int)
= 0x40b8c43c
and
a + 2
= ((void*) a) + sizeof(int) * 2
= 0x40b8c440
In python, I would use a list to store some numbers than print all of them:x = [1, 2, 3, 4]
print(x) #output = [1, 2, 3, 4]
How should I do it in C with an array?
Another question: is an array similar to the python lists? If not, what type would be it?;
A definitely better than average effort.
No documentation
.h file deserves overall documentation. Consider users should be able to understand what these functions do without access to the .c file.
Bug: al_contains()
al_contains() returns 0 when data is not found or if data != 0.
Did OP want al_contains() to return the index when found?
Hide it
struct array_list definition not needed in .h file. Only its declaration needed. Research Information hiding
Unclear return
al_find() returns -1 when data not found, yet -1 is a valid data. Consider a different approach.
Use const
For functions that do not modify the state of the list:
Example:
//int al_is_valid_index(struct array_list *list, int index);
int al_is_valid_index(const struct array_list *list, int index);
Include first
In array_list.c,code #include "array_list.h" first to test that it does not rely on any <.h> files that it does not include itself.
Why 10?
Zero is a better choice for AL_INITIAL_CAPACITY.
Often the list are used, there are many empty ones. Zero is a natural choice.
If concerned about a lot of initial re-allocations, simply jump use to 10 when first needed.
Name space
Code uses al_... and array_list.... Use one,
static??
static const int AL_INITIAL_CAPACITY = 16; serves no purpose in the .h file.
Order?
With so many functions, consider alphabetizing the order in both .c and .h.
Mixed indexing types
Code using int and size_t for the array indexing and sizing type. Suggest size_t throughout.
Pedantic growth
Insure capacity + capacity / 2 does not overflow.
More functions
Consider:
A right-size function to reduce the allocation to the needed size.
With al_find() and al_find_last(), perhaps a find_next(... index) to pickup after al_find()?
Consider an apply function, one that applies a passed in function to every element of the array. I'd such this is a better way to print too and delete al_print().
int al_apply(struct array_list *list, void *state, int (*f)(void *state, size_t index, int data));
Consider al_sort(int (*cmp)(const void *e1, const void *e2)).
This is a problem:
list->array = realloc(list->array, sizeof(*(list->array)) * list->capacity);
If the allocation fails, then we have overwritten list->array with a null pointer, leaving no way to access the memory it was pointing to. That's a memory leak. Don't overwrite any values until we know our reallocation was successful:
size_t new_capacity = capacity + capacity / 2;
int *new_mem = realloc(list->array, sizeof *list->array * new_capacity);
if (!new_mem) { return false; } /* using <stdbool.h> */
list-array = new_mem;
list->capacity = new_capacity;