This question already has answers here:
Why sizeof(param_array) is the size of pointer?
(8 answers)
Closed 9 months ago.
I am trying to find the smallest missing element of an array using function check, which has two arguments (n and array A). I can't understand why my function check is always returning one and the while loop is never closing.
#include <stdio.h>
bool check(int n, int A[])
{
for (int i = 0; i < sizeof(A); i++)
{
if(A[i] == n)
{
return 1;
}
}
return 0;
}
int main()
{
int A[] = {1, 3, 6, 4, 1, 2};
int n = 1;
while (check(n, A) == 1)
{
n++;
}
printf("%d is missing",n);
}
The compiler adjusts a parameter having an array type to pointer to the array element type.
So this function declaration
bool check(int n, int A[])
is equivalent to
bool check(int n, int *A );
And within the function the expression sizeof(A) is equivalent to the expression sizeof( int * ) and is equal to either 4 or 8 depending on the used system.
Thus this for loop
for (int i = 0; i < sizeof(A); i++)
invokes undefined behavior.
I know but still that's not why the while loop is never stopping.
Answering your above comment it seems that in the used system sizeof( int * ) is equal to 8 and the variable n is placed in memory after the array A as they defined in main
int A[] = {1, 3, 6, 4, 1, 2};
int n = 1;
As a result you get the infinite wile loop because in the for loop within the function the memory occupied by the variable n is checked and n is always equal to itself.
Thus the function always returns 1.
That is in the for loop the array is traversed as it has 8 elements like
int A[] = {1, 3, 6, 4, 1, 2, n, some_indeterminate_value };
Related
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;
}
This question already has answers here:
C input and out parameters of a function
(3 answers)
how to set a int value passed by parameter to a function and assign it to global so I can use outside of the function?
(3 answers)
Closed 4 years ago.
My task is to write a function which calculates sum of elements of array. which I did like so:
#include <stdio.h>
#include <stdlib.h>
int sum (int array[], int len){
int i;
int sum=0;
for (i=0; i<len; i++){
sum = sum + array[i];
}
return sum;
}
int main() {
int array[] = {9, 4, 7, 8, 10, 5, 1, 6, 3, 2};
int len = 10;
printf ("Sum: %d\n" , sum(array, len));
}
Output: Sum: 55
however, now I need to do the very same thing but differently. The Sum function should take 3 arguments, third one being a Pointer, return no value and still be able to call it in the main function to print out the sum again.
Any help would be appreciated.
P.S. Yes, it is part of homework.
The pointer will point to the integer variable that will receive the sum:
void sum (int array[], int len, int *result)
You call it from main giving a pointer to the result. I give no more; the rest is your homework.
This question already has answers here:
How to pass 2D array (matrix) in a function in C?
(4 answers)
Closed 6 years ago.
I've got this homework. Basically, what I have to do is complete the following code that returns the maximum element of a bidimensional array of 'r' rows and 'n' columns.
#include <stdio.h>
int max_element(int **A, int r, int n) {
// complete the code
int max;
max = a[0][0];
for (int i = 0; i < r; i++) {
for (int j = 0; j < n; j++) {
if (A[i][j] > max)
max = A[i][j];
}
}
return max; }
// implement a main() function to test the algorithm
int main() {
int A[2][3] = { {1, 0, 4}, {10, 3, 1} };
printf("%d\n", max_element(&A, 2, 3));
return 0; }
I have 1 warning:
passing argument 1 of 'max_element' from incompatible pointer type [-Wincompatible-pointer-types]
The console stopped working: a problem caused the program to stop working correctly...
Your max_element function is defined as such:
int max_element(int **A, int r, int n);
It takes a pointer to a pointer to int (int**) and you are feeding it this:
int A[2][3];
max_element(&A, 2, 3);
Do you expect the expression &A to yield a result of type int**? It will not. It will in fact yield a result of type int(*)[2][3]. That will not bind to int**. This is where the compiler warning kicks in. Those are incompatible pointers!!
You have a wider problem though. A 2D array is not int**. It has type int[][COLS]. You must specify the second number.
Change your function to be:
const int COLS = 3;
int max_element(int A[][COLS], int r, int n);
and then call as:
max_element(A, 2, 3);
Change the function prototype of max_element from:
int max_element(int **A, int r, int n)
To
int max_element(int A[][3], int r, int n)
This C-Faq thoroughly explains why. The gist of it is that arrays decay into pointers once, it doesn't happen recursively. An array of arrays decays into a pointer to an array, not into a pointer to a pointer.
And also, you should call max_element by max_element(A, 2, 3) instead of max_element(&A, 2, 3).
If a function is already declared as accepting a pointer to a pointer (as in your case), it is almost certainly meaningless to pass a two-dimensional array directly to it. An intermediate pointer would have to be used when attempting to call it with a two-dimensional array:
int max_element(int **A, int r, int n);
int *ip = &A[0][0];
max_element(&ip, 2, 3); /* PROBABLY WRONG */
but this usage is misleading and almost certainly incorrect, since the array has been flattened (its shape has been lost).
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);
int a[10];
int b[10];
memcmp(a, b, sizeof(int) * 10);
memcmp() only tells us which memory block is bigger/smaller since it just returns -1,0,+1.
Is there a way to know number of matching elements in a[] and b[] just after which the mismatch occurs.
Ex: a = {1, 2, 3, 4, 5, 6}
b = {1, 2, 4}
Here memcmp(a, b, sizeof(int)* 3) would return -1. I want to get 2 as answer
Is there a way we can get number of matching elements with help of memcmp or some similar inbuilt function
I assume you want a low level answer since you must have already rejected the easy way with a loop.
You could XOR the memory block a[0] to a[9] with b[0] to b[9]. The resulting memory will be a block of zeros if, and only if, the original arrays were equal. To get the number of matching elements, count the number of int blocks that have all zero bits.
You could do this blisteringly fast in assembler as the operations are so simple.
A for loop over the two arrays should suffice:
int a[10];
int b[10];
int aLen = sizeof(a)/sizeof(int); /* we can do this since arrays are declared on the stack */
int bLen = sizeof(b)/sizeof(int);
int currentContig = 0;
int maxContig = 0;
for (int aIdx = 0, int bIdx = 0; (aIdx < aLen) && (bIdx < bLen); ) {
if (a[aIdx] == b[bIdx]) {
currentContig++;
aIdx++;
bIdx++;
}
else if (a[aIdx] > b[bIdx]) {
currentContig = 0;
aIdx++;
}
else {
currentContig = 0;
bIdx++;
}
if (currentContig > maxContig) {
maxContig = currentContig;
}
}
fprintf(stdout, "longest contiguous match: %d\n", maxContig);
Please Try Like below
int matched_num=0;
while(a[matched_num]==b[matched_num])
matched_num++;
printf("%d",matched_num);
final printed value will be total number of matched element in both arrays.