i have my length function to calculate the length of array, but it is giving two excess garbage numbers(negative). It must return 6 but it returns 8 due to garbage values.
#include<stdio.h>
int length(int *arr) {
int _length = 0;
while (*arr) {
_length++;
arr++;
}
return _length;
}
int main() {
int arr[] = {2, 1, 3, 4, 5, 6};
printf("%d\n", length(arr));
return 0;
}
You need some manner of termination condition. while (*arr) assumes that the array ends with zero which isn't the case, so you simply can't have a loop like that.
The size of this array is known at compile time so there's no need to calculate anything in run-time.
(sizeof arr / sizeof *arr) gives you the number of items in the array, as long as you place that code in the same scope as the array declaration.
Also, using that sizeof trick (which is an idiomatic way of determining the size) inside a function-like macro is a common solution:
#include <stdio.h>
#define length(arr) (sizeof(arr)/sizeof(*arr))
int main() {
int arr[] = {2, 1, 3, 4, 5, 6};
printf("%zu\n", length(arr));
return 0;
}
Related
When I use this code in the main() function, the size (or length) of the array is calculated correctly:
#include <stdio.h>
int main(void)
{
int arr[] = {2, 5, 9, 8, 4, 5, 1, 2, 8, 5};
int length = sizeof(arr) / sizeof(arr[0]);
printf("The number of elements in the array is %d\n", length);
return 0;
}
Output:
The number of elements in the array is 10
But when I do the same thing by using a function, then the output is wrong:
#include <stdio.h>
int sizeTeller(int array[]);
int main(void)
{
int arr[] = {2, 5, 9, 8, 4, 5, 1, 2, 8, 5};
printf("The number of elements in the array is %d\n", sizeTeller(arr));
return 0;
}
int sizeTeller(int array[])
{
int len;
return (len = sizeof(array) / sizeof(array[0]));
}
Output:
The number of elements in the array is 2
Can you please explain this to me that why this is so? I prefer to keep all the codes in functions that's why I tried the same here but the output went wrong.
This is because, like for many other casesNOTE, when arrays are passed as a function argument, they decay to the pointer to the first element of the array. Hence, in the called function, the received parameter type is a pointer, not an array.
So, in case of
int sizeTeller(int array[])
{
int len;
return (len = sizeof(array) / sizeof(array[0]));
}
is equivalent as
int sizeTeller(int* array)
{
int len;
return (len = sizeof(array) / sizeof(array[0])); // sizeof (int *) / sizeof (int)
}
Solution: If you need to pass an array as a function argument, and need to know it's size, you need to calculate the size in the caller and pass that as another argument to the called function.
NOTE:
Quoting C11, chapter 6.3.2.1/P3
Except when it is the operand of the sizeof operator, the _Alignof operator, or the unary & operator, or is a string literal used to initialize an array, an expression that has type 'array of type' is converted to an expression with type 'pointer to type' that points to the initial element of the array object and is not an lvalue. [....]
I have an array int arr[5] = {10, 2, 3, 5, 1}, and I want to pass in the last 4 elements (basically from index 1 to index4) into an argument as an array (so: [2, 3, 5, 1]). Is there a way to do this very simply (like how in Ruby you would be able to do arr[1..4]), or would I have to use a for loop?
You can manually increment the pointer by 1:
your_function(arr + 1)
Pointer arithmetic in C implicitly accounts for the size of the elements, so adding 1 will actually add 1 * sizeof(int)
For a closer analogue to array slicing from other languages, try this function:
int *slice_array(int *array, int start, int end) {
int numElements = (end - start + 1)
int numBytes = sizeof(int) * numElements;
int *slice = malloc(numBytes);
memcpy(slice, array + start, numBytes)
return slice;
}
It makes a slice of the array between the given start and end indices. Remember to free() the slice once you're done with it!
Answer
Given you current code:
int arr[5] = {10, 2, 3, 5, 1};
You can duplicate the range 1..4 by:
int arr_dup[4];
memcpy(arr_dup,arr+1,sizeof(int)*4);
Remember that your function definition should be a pointer, example:
void a_function(int *arr_arg); //Call via a_function(arr_dup);
Explanation
Arrays in c implemented as pointers (aka variables that hold memory addresses).
If you do arithmetic on the pointer, it will advance to the respective element. Example:
ptr + 1 //Next Element
ptr - 1 //Previous Element
#include <stdio.h>
#include <stdlib.h>
void my_function(int arr_size, int *arr)
{
int i;
for(i=0; i < arr_size; i++)
{
printf("[%d]:%d\n", i, arr[i]);
}
}
int main(int argc, char **argv)
{
int arr[] = { 10, 2, 3, 5, 1 };
(void)my_function(4, &arr[1]); /* TODO > use more flexible indexing */
return EXIT_SUCCESS;
}
I think you can use memcpy,memcpy can copy data byte to byte.In memmory,our data is binary,so even int is 4 bytes,we can copy it byte to byte.
int dst[4];
memcpy(dst,&arr[1],size(int) * 4);
I'm learning C, and tried writing a function that, given an array of integer, returns the length of the array. Here is my code:
#include <stdio.h>
int length_of_array(int array[])
{
int length = 0;
int i = 0;
while (array[i] != '\0') {
length += 1;
i += 1;
}
return length;
}
int main()
{
int test_array[] = {1, 2, 3, 4, 5};
printf("%d\n", length_of_array(test_array));
return 0;
}
However, when I compile this code and run it, I says that the length of the array passed in is 14. Does anyone know what could be the problem here?
Strings in C are NUL-terminated. Arrays are not (unless you explicitly do it yourself). The size of array is just the size of array: if allocated as a constant, you can find out the size with sizeof operator. If all you have is a plain pointer, you need to remember the size - there is no way in C to get it once you forget it.
#include <stdio.h>
int main() {
int test_array[] = {1, 2, 3, 4, 5};
int *test_ptr = test_array;
printf("%lu\n", sizeof(test_array) / sizeof(*test_array)); // correct
printf("%lu\n", sizeof(test_ptr) / sizeof(*test_ptr)); // incorrect
return 0;
}
I'm working in C, and am attempting to replicate the length member function that other languages (ie: C++) use to determine the length of an array or possibly vector of data. Is this something I can accomplish in C, or do I have to fall back onto examples like this:
int arraySize = sizeof(array) / sizeof(array[0]);
In general, in C, you use arrays as they are: a contiguous set of multiple pieces of data of the same type. You are generally expected to keep track of array sizes, along with the size of individual members, yourself.
In C++, for example, you have access to the Vector class, which encapsulates and handles all this record keeping for you.
In C, you would be expected to know exactly how big the array is. This is especially important in the case of pointer decay. Your initial example...
int arrayOfInts[6] = {1, 2, 3, 4, 5, 6};
int sizeOfArray = sizeof(arrayOfInts) / sizeof(int); // Success; Returns "6"
This works in this case, but it will fail if you were to pass the array to a function expecting an array of integers (as a pointer) as a function argument.
#include <stdio.h>
int getArraySize(int* arr);
int main(void) {
int arrayOfInts[6] = {1, 2, 3, 4, 5, 6};
int sizeOfArray = getArraySize(arrayOfInts);
return 0;
}
int getArraySize(int* arr) {
int ret;
ret = sizeof(arr) / sizeof(int); // FAILS, returns the size of a pointer-to-int, not the size of the array
return ret;
}
There are two ways to handle this: static definitions, or careful dynamic memory management.
// CASE 1: Trivial case, all arrays are of a static fixed size
#include <stdio.h>
#define ARR_SIZE (6)
int getArraySize(int* arr);
int main(void) {
int arrayOfInts[ARR_SIZE] = {1, 2, 3, 4, 5, 6};
int sizeOfArray = getArraySize(arrayOfInts);
return 0;
}
int getArraySize(int* arr) {
return ret ARR_SIZE;
}
// CASE 2: Managing sizes with dynamic allocation
#include <stdio.h>
#define ARR_SIZE (6)
int main(void) {
int sizeOfArray = ARR_SIZE;
int* arrayOfInts = malloc(sizeOfArray*sizeof(int));
if (arrayOfInts != NULL) {
// Success; initialize
int i;
for (i=0; i<sizeOfArray; i++) {
arrayOfInts[i] = i;
}
return 0;
} else {
// Failed; abort
sizeOfArray = 0;
return (-1);
}
}
If this is possible:
#include <stdio.h>
#include <process.h>
#define SIZE 5
void PassingArray(int arr[])
{
int i=0;
for(i=0 ; i<SIZE ; i++)
{
printf("%d, ", arr[i]);
}
printf("\n");
}
main()
{
int myIntArray[5] = {1, 2, 3, 4, 5};
PassingArray(myIntArray);
system("PAUSE");
}
Then why the following is illegal?
#include <stdio.h>
#include <process.h>
#define SIZE 5
int ReturningArray()[]
{
int myIntArray[5] = {1, 2, 3, 4, 5};
return myIntArray;
}
main()
{
int myArray[] = ReturningArray();
system("PAUSE");
}
You're not returning an int, but you're returning the array. This is the same value as &myIntArray[0]. int ReturningArray()[] is not a valid function prototype.
There's multiple reasons why this doesn't work.
The first is simply that it's prohibited by the language - the return type of a function shall not be an array (it also can't be a function).
The second is that even if you were allowed to declare ReturningArray as you do, you could never write a valid return statement in that function - an expression with array type that is not the subject of the unary & or sizeof operators evaluates to a pointer to the first element of the array, which no longer has array type. So you can't actually make return see an array.
Thirdly, even if we somehow had a function returning an array type, you couldn't use that return value as the initialiser of an array variable - the return value would again evaluate to a pointer to the first element of the array: in this case a pointer to int, and a pointer to int isn't a suitable initialiser for an array of int.
There are several problems with this code.
You are placing the brackets at the wrong place. Instead of
int ReturningArray()[]
it should be
int* ReturningArray()
You are returning a local variable. Local variables only exist during the execution of the function and will be removed afterwards.
In order to make this work you will have to malloc the int array and return the pointer to the array:
#include <stdio.h>
#include <malloc.h>
#define SIZE 5
int* ReturningArray()
{
int *myIntArray = (int *)malloc(SIZE * sizeof(int));
myIntArray[0] = 1;
myIntArray[1] = 2;
myIntArray[2] = 3;
myIntArray[3] = 4;
myIntArray[4] = 5;
return myIntArray;
}
int main(void)
{
int i;
int* myArray = ReturningArray();
for(i=0;i<SIZE;i++) {
printf("%d\n", myArray[i]);
}
free(myArray); // free the memory again
system("PAUSE");
return 0;
}
PassingArray is legal, but it does not pass an array. It passes a pointer to the first element of an array. void PassingArray(int arr[]) is a confusing synonym for void PassingArray(int *arr). You can't pass an array by value in C.
ReturningArray is not allowed, you can't return an array by value in C either. The usual workaround is to return a struct containing an array:
typedef struct ReturnArray {
int contents[5];
} ReturnArray;
ReturnArray ReturningArray()
{
ReturnArray x = {{1, 2, 3, 4, 5}};
return x;
}
Arrays are second-class citizens in C, the fact that they can't be passed or returned by value is historically related to the fact that they can't be copied by assignment. And as far as I know, the reason for that is buried in the early development of C, long before it was standardized, when it wasn't quite decided how arrays were going to work.
You can't return array from a function, but It is possible that you can declare a function returning a (reference in C++) or pointer to array as follows:
int myIntArray[] = {1, 2, 3, 4, 5};
int (*ReturningArray())[sizeof(myIntArray)/sizeof(int)] {
return &myIntArray;
}