I was trying to write the code for storing multiplication table in array.
First I wrote the following code.
#include<stdio.h>
void Multiplication(int arr[][10], int num,int size);
int main(){
int arr[3][10];
Multiplication(&arr[0],2,3);
Multiplication(&arr[1],7,3);
Multiplication(&arr[2],9,3);
for(int i=0;i<3;i++){
printf("\n\nMultiplication Table of %d\n\n",arr[i][0]);
for(int j=0;j<10;j++){
printf("%d * %d = %d\n",arr[i][0],j,arr[i][j]);
}
}
return 0;
}
void Multiplication(int arr[][10], int num, int size){
for(int j=0;j<size;j++){
for(int i=0;i<10;i++){
arr[j][i] = num * (i+1);
}
}
}
When I was checking whether there is any reduntant part, I removed a little bit of pieces.
#include<stdio.h>
void Multiplication(int *arr, int num,int size);
int main(){
int arr[3][10];
Multiplication(arr[0],2,3);
Multiplication(arr[1],7,3);
Multiplication(arr[2],9,3);
for(int i=0;i<3;i++){
printf("\n\nMultiplication Table of %d\n\n",arr[i][0]);
for(int j=0;j<10;j++){
printf("%d * %d = %d\n",arr[i][0],j,arr[i][j]);
}
}
return 0;
}
void Multiplication(int *arr, int num,int size){
for(int i=0;i<10;i++){
arr[i] = num * (i+1);
}
}
Now, I noticed that &arr[0] and arr[0] are behaving same? I wanna know why is it so?
The following is the question asked:
I noticed that &arr[0] and arr[0] are behaving same? I wanna know why is it so?
We have
int arr[3][10];
arr[0] is a int[10], which is to say an array of 10 int values.
But it's being treated as a pointer. When an array is treated as a pointer, it produces a pointer to the first element of the array. So this means arr[0] is automatically converted to a int* pointing to the first element of the first row of arr when necessary.
&arr[0] means &(arr[0]). It produces a int(*)[10] (a pointer to an array of 10 int values) pointing to the first row of arr.
To recap,
arr[0] is a int[10] which degrades to a int*.
It points to the first element of the first row of arr.
&arr[0] is a int(*)[10].
It points to the first row of arr.
So, arr[0] is NOT equivalent to &arr[0], contrary to your assertion.
And this lack of equivalence is why you had to change from &arr[0] when you when you had int arr[][10] (which means int (*arr)[10] a parameter), to arr[10] when you had int *arr as the parameter.
The both programs are incorrect.
You declared a two dimensional array
int arr[3][10];
So expressions like this arr[0], arr[1], arr[2] have the array type int[10]. That is they produce the first "row", the second "row" and the third "row" of the two-dimensional array.
In the first program you are calling the function Multiplication like
Multiplication(&arr[0],2,3);
Multiplication(&arr[1],7,3);
Multiplication(&arr[2],9,3);
and within the function there are two nested loops
void Multiplication(int arr[][10], int num, int size){
for(int j=0;j<size;j++){
for(int i=0;i<10;i++){
arr[j][i] = num * (i+1);
}
}
}
according to the argument specified for the parameter size the function deals with a two dimensional array with three elements (rows) of the array type int[10] using a pointer to the first element of the array. As a result for the argument expressions &arr[1] and &arr[2] there is an access to the memory beyond the original two dimensional array.
You may consider these calls
Multiplication(&arr[0],2,3);
Multiplication(&arr[1],7,3);
Multiplication(&arr[2],9,3);
like
Multiplication( arr, 2, 3 );
Multiplication( arr + 1, 7, 3 );
Multiplication( arr + 2, 9, 3 );
The array designator arr is implicitly converted to a pointer to its first element (row) of the type int ( * )[10].
As you are setting only one "row" within the array then the function can be declared and defined the following way
void Multiplication(int arr[][10], int num ){
for(int j=0;j < 10;j++){
( *arr )[j]= num * (j+1);
}
}
and called like
Multiplication( arr, 2 );
Multiplication( arr + 1, 7 );
Multiplication( arr +2, 9 );
Of you want to set elements of a sub-array then the function can be defined the way it is defined initially but called like
Multiplication( arr, 2, 3 );
Multiplication( arr + 1, 7, 2 );
Multiplication( arr +2, 9, 1 );
In the second program the function is declared like
void Multiplication(int *arr, int num,int size){
for(int i=0;i<10;i++){
arr[i] = num * (i+1);
}
}
and you are calling it like
Multiplication(arr[0],2,3);
Multiplication(arr[1],7,3);
Multiplication(arr[2],9,3);
But within the function the parameter size is not used. There is used the magic number 10. And the passed argument 3 does not make a sense.
You should declare the function like
void Multiplication(int *arr, int num,int size){
for(int i=0;i<size;i++){
arr[i] = num * (i+1);
}
}
and call it like
Multiplication(arr[0],2,10);
Multiplication(arr[1],7,10);
Multiplication(arr[2],9,10);
Related
This question already has answers here:
Difference between "pointer to int" and "pointer to array of ints"
(8 answers)
Closed 4 years ago.
I read about (*ptr)[5] that it can point to a 5-element integer array. What this means?
It can be used when you want to go through a 2-d or a higher dimensional array.
For example you have this 2-d array:
int a[3][4] = {
1,2,3,4,
5,6,7,8,
9,0,1,6
};
A normal *ptr will go through each of the elements in the array.
If this array's base address is : 1000. Then the next address it will go to on increment would be 1002, 1004, 1006. Taking sizeof(int) => 2.
What (*ptr)[5] would do is to jump to the next 5th element and then point to it.
In the example taken above, if I want to jump on the very starting of each 1-d array in it, I would simply use (*q)[4] and jump to the next 4th element and just not the very next one.
So if you want to display the elements of this array you can do this in two ways:
Using normal *ptr
void display(int *q, int row, int col){
int i, j;
for(i=0; i<row; i++){
for(j=0; j<col; j++){
printf("%d ", *(q + i*col + j));
}
printf("\n");
}
}
Using (*ptr)[4]
void show(int (*q)[4], int r, int col){
int i, j, *p;
for(i=0; i<r; i++){
p = q+i;
for(j=0; j<col; j++){
printf("%d ", *(p+j));
}
printf("\n");
}
}
int (*q)[5] means that q is a pointer to an array of 5 integers. To understand better let us use this pointer to an array of 5 integers.
void main()
{
int a[][5] = {
1,2,3,4,5,
6,7,8,9,10,
11,12,13,14,15
};
int *p;
int (*q)[5];
p = *a;
printf("%d %d\n",p,q);
p++;
q++;
printf("%d %d\n",p,q);
}
Output:
65500 65500
65502 65510
To begin with, both p and q contain the same address 65500. However, on incrementing p it points to an array of 5 integers.Hence on incrementing p it points to the next integer,
whereas q starts pointing to the next 1-D array of 5 integers. Pointer to the array is very useful while passing a 2D array to functions.
I can't understand why my program only prints the first number in the array.
it seems it loops only once and then something breaks the loop. The output is 232.
#include <stdio.h>
int main( int argc, char* argv[]){
int sum_arr(int arr[]);
int arr[5]={232,44,3,4,5};
printf("%d\n",sum_arr(arr));
return 0;
}
sum_arr(int arr[]){
int i,sum=0,sizeofarr=sizeof(arr)/sizeof(arr[0]);
for(i=0;i<=(sizeofarr-1);i++){
sum+=arr[i];
}
return (sum);
}
sizeofarr = sizeof(arr) / sizeof(arr[0]);
This trick to calculate the size of an array doesn't work. Because in the function, arr decays to a pointer, not an array.
To fix the problem, pass the size explicitly.
Change the code the following way
#include <stdio.h>
nt main( int argc, char* argv[])
{
int sum_arr( int arr[], size_t n );
int arr[5] = { 232, 44, 3, 4, 5 };
printf( "%d\n", sum_arr( arr, sizeof( arr ) / sizeof( *arr ) ) );
return 0;
}
int sum_arr( int arr[], size_t n )
{
int i = 0, sum = 0;
for ( ; i < n ;i++ )
{
sum += arr[i];
}
return ( sum );
}
The problem with your code is that an arrray passed as an argument is implicitly converted to a pointer to its first element. So inside function sum_array you used sizeof( int * ) / sizeof( int ) that for your system is equal to 1.
Take into account this quote from the C Standard (6.3.2.1 Lvalues, arrays, and function designators)
3 Except when it is the operand of the sizeof 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. If the array object
has register storage class, the behavior is undefined.
Remember, in C when pass an array as an argument to a function, actually you're passing a pointer to an array.
Since the size of a pointer and an int is 4 or 8, you'll be getting sizeof(int *)/sizeof int (4/4=1 for 32-bit machines and 8/4=2 for 64-bit ones) which is 1 or 2.
In conclusion, array names in a C program are (in most cases) converted to pointers.One exception is when we use the sizeof operator on an array. If arr was converted to a pointer in this contest, sizeof(arr) would give the size of a pointer and not of the actual array, which would be rather useless, so in that case a means the array itself.
In my program the array passed in the function is converted to a pointer. Then, sizeof(arr) in the sum_arr function gives the size of a pointer and not of the actual array.
This program should be execute in this way:
#include <stdio.h>
#define SIZEOFARR(arr) (sizeof(arr)/sizeof(arr[0]))
int main(){
int sum_arr(int arr[],int size);
int arr[5]={232,44,3,4,5};
printf("The sum of the array is: %d\n",sum_arr(arr,SIZEOFARR(arr)));
return 0;
}
int sum_arr(int arr[],int size){
int i,sum=0;
for(i=0;i<size;i++){
sum+=arr[i];
}
return (sum);
}
#include<stdio.h>
#include<conio.h>
float smallest(int arr[],int k,int n);
void sort(int arr[],int n);
void main()
{
int arr[20],i,n,j,k;
clrscr();
printf("\nEnter the number of elements in the array: ");
scanf("%d",&n);
printf("\nEnter the elements of the array");
for(i=0 ; i < n ; i++)
{
printf("\n arr[%d] = ",i);
scanf("%d",&arr[i]);
}
sort(arr,n);
printf("\nThe sorted array is: \n");
for(i=0 ; i < n ; i++)
printf("%d\t",arr[i]);
getch();
}
int smallest(int arr[],int k,int n)//smallest function
{
int pos=k,small=arr[k],i;
for(i=k+1;i<n;i++)
{
if(arr[i]<small)
{
small=arr[i];
pos=i;
}
}
return pos;
}
void sort(int arr[],int n)//sorting function
{
int k,pos,temp;
for(k=0 ; k < n ; k++)
{
pos=smallest(arr,k,n);
temp=arr[k];
arr[k]=arr[pos];
arr[pos]=temp;
}
}
In the above program the sort function is being called from main but the return type of sort is void and it still returns the sorted array. As after sorting the array the function should return the sorted array back to the calling function to print the sorted array but the program runs perfectly. How is that happening?
When you declare
int arr[20];
you can say "arr is an array of 20 integers". But arr is a pointer to an integer as well, pointing to the first integer in a row of 20. So de-referencing *arr is an integer, the same as arr[0] in fact.
This means when you pass arr to a function you only pass a pointer to that function. The function in this case works on the (copied) pointer. But this very pointer points exactly to the same memory as your original arr declared in main(). And that's the reason why manipulating arr in sort() is in fact manipulating arr in main().
When passing an array as a parameter, this
int smallest(int arr[],int k,int n)
means exactly the same as
int smallest(int *arr,int k,int n)
For example
#include<iostream>
void printArray(int data[])
{
for(int i = 0, length = sizeof(data); i < length; ++i)
{
std::cout << data[i] << ' ';
}
std::cout << std::endl;
}
int main()
{
int data[] = { 5, 7, 8, 9, 1, 2 };
printArray(data);
return 0;
}
You will see that only the first 4 elements of the array are printed. The sizeof(data) returns a value of 4! That happens to be the size of the pointer used to pass the array to printArray().
First the array does not get copied. The pointer to the first element of the array is copied
First, there is no connection between any function argument what is, or is not passed using a return statement with an expression according to the function's return type.
While it is true that all parameter passing in C is by value - copy the value to a "local parameter variable" - nothing is assumed about what is to happen at the memory location a pointer is referencing. So, a function can make any changes in the calling environment, even without returning a value.
As to parameters declared as being aType name[]. this is merely syntactic sugar for const aType* name.
I was writing a program to concatenate two arrays in C. I am allocating memory for a third array and using memcpy to copy the bytes from the two arrays to the third. The test output is:
1 2 3 4 5 0 0 0 0 0
Is there anything wrong with this approach?
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int *array_concat(const void *a, int an,
const void *b, int bn)
{
int *p = malloc(sizeof(int) * (an + bn));
memcpy(p, a, an*sizeof(int));
memcpy(p + an*sizeof(int), b, bn*sizeof(int));
return p;
}
// testing
const int a[] = { 1, 2, 3, 4, 5 };
const int b[] = { 6, 7, 8, 9, 0 };
int main(void)
{
unsigned int i;
int *c = array_concat(a, 5, b, 5);
for(i = 0; i < 10; i++)
printf("%d\n", c[i]);
free(c);
return 0;
}
memcpy(p + an*sizeof(int),...
this second memcpy, you are trying to add 5 * sizeof(int) to an int pointer, p. However, when you add to a pointer, it already knows that it has to deal with sizeof(type), so you don't have to tell it.
memcpy(p + an,...
Remove the multiplication *sizeof(int) from the 1st argument of memcpy. Keep it in the argument of malloc and the 3rd argument of memcpy.
This is because p + an points to an int which is an ints to the right from p -- that is, the int which is an*sizeof(int) bytes to the right from p.
p is a pointer to int. When you add an integer to a pointer to an int, the compiler multiplies the integer by the size of an integer. The net result is to multiply by the size of an integer twice: what you're getting is "p + an*sizeof(int)" is p + (number of elements in a) * (number of bytes in an int) * (number of bytes in an int).
memcpy(p + an*sizeof(int), b, bn*sizeof(int));
should be:
memcpy(p + an, b, bn*sizeof(int));
You should remove sizeof(int) from second memcpy where you use pointer arithmetic (+).
Compiler doing this by itself depending on type of pointer.
you should see the definition of the memcpy, which copy's n "bytes" from the src to the dst area. so,you just need to times sizeof(int) only for the 3rd argument. and for "c", it's a pointer of int type, so, it does know that "+an" means move p forward to the an+1 int position.
Merging can be done by sorting the elements of the elements which are going to be merged code for merging two arrays
#include<stdio.h>
void sort(int arr[],int size){ // sorting function
int i,j,temp;
for(i=0;i<size;i++){
for(j=i;j<size;j++){
if(arr[i]>arr[j]){
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
}
int main(){
int a[10],b[10],c[10];
int n,i,k=0,j=0;
printf("Enter the size of the array:");
scanf("%d",&n);
for(i=0;i<n;i++){
printf("Enter the element of array A at index %d:",i); //input array A
scanf("%d",&a[i]);
}
sort(a,n);
for(i=0;i<n;i++){
printf("Enter the element of array B at index %d:",i); //Input array B
scanf("%d",&b[i]);
}
sort(b,n);
for(i=0;i<(n+n);i++){ // merging the two arrays
if(a[k]<b[j]){
c[i] = a[k];
k++;
}
else{
c[i] = b[j];
j++;
}
}
printf("Merged Array :\n");
for(i=0;i<(n+n);i++){
printf("c -> %d ",c[i]);
}
return 0;
}
Reference C program to Merge Two Arrays after Sorting
How do I write a function to search for an element in two dimensional array: if exists returns 1, otherwise returns no?
#include <stdio.h>
int search(int a[3][3],int x);
int main ()
{
int Array[3][3]; // array of size 3*3
int i,j; //counters i,j
int result,number;
for(i=0;i<3;i++)
{
printf("\n");
for(j=0;j<3;j++)
{
printf(" Array[%d][%d]= ",i,j);
scanf("%d", &Array[i][j]); //Fill The 3*3 array
}
}
printf("Enter The number you want:>");
scanf("%d",&number);
result=search(Array,number);
if(search(Array,number))
printf("Number exists\n");
else
printf("Number does not exists\n");
return 0;
}
int search(int a[3][3],int x){
int i,j;
for(i=0;i<3;i++){
for(j=0;j<3;j++){
if (x==a[i][j])
return 1;
return 0;
}
}
}
is this right ??
No, it's not. You need to move the return 0; out of the two for loops, and have it be the last statement in search.
No. The return 0; statement should be placed on the line before the very last closing brace.
Your program is not running because the search algorithm returns 1 if and only if the search element is in array[0][0], otherwise it returns zero and you think that the element doesn't exists. All you need to do is return 0 after traversing the full multi-dimensional array.
You can look into above answers. They have given good solutions.
No because your return 0; is inside the for loops.
I think what you want is that :
#include <stdio.h>
int search(int a[3][3],int x);
int main ()
{
int Array[3][3]; // array of size 3*3
int i,j; //counters i,j
int result,number;
for(i=0;i<3;i++)
{ printf("\n");
for(j=0;j<3;j++)
{
printf(" Array[%d][%d]= ",i,j);
scanf("%d", &Array[i][j]); //Fill The 3*3 array
}
}
printf("Enter The number you want:>");
scanf("%d",&number);
result=search(Array,number);
if(result)
printf("Number exists\n");
else
printf("Number does not exists\n");
return 0;
}
int search(int a[3][3],int x)
{
int i,j;
for(i=0;i<3;i++)
{
for(j=0;j<3;j++)
{
if (x==a[i][j])
return 1;
}
}
return 0;
}
Jon gave you the answer you need, but there are some details to be aware of.
C's treatment of arrays is such that the search function doesn't receive a 3x3 array of int; rather, it receives a pointer to a 3-element array of int. From the C language standard, draft n1256:
6.3.2.1 Lvalues, arrays, and function designators
...
3 Except when it is the operand of the sizeof 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. If the array object has register storage class, the behavior is undefined.
Thus, when you call result = search(Array, number);, the type of the expression Array is implicitly converted from a 3-element array of 3-element arrays of int (int [3][3]) to a pointer to a 3-element array of int (int (*)[3]). In the context of a function parameter declaration, T a[] and T a[n] are synonymous with T *a. You could change the function prototype to
int search(int (*a)[3], int x)
and it would behave exactly the same.
One consequence of this is that search can operate not just on 3x3 arrays, but on any Nx3 array. You've written your function to assume that a is always 3x3; if you want to be able to handle arrays of different numbers of rows, you would need to pass in a separate parameter to specify the number of rows in the array:
int search(int (*a)[3], size_t rows, int x)
{
size_t i, j;
for (i = 0; i < rows; i++)
for (j = 0; j < 3; j++)
if (a[i][j] == x)
return 1;
return 0;
}
int main(void)
{
int fiveRowArray[5][3] = {{ 1, 2, 3}, { 4, 5, 6}, { 7, 8, 9},
{10,11,12}, {13,14,15}};
int twoRowArray[2][3] = {{ 1, 2, 3}, { 4, 5, 6}};
int number;
printf("Gimme a number: ");
fflush(stdout);
scanf("%d", &number);
if (search(array, sizeof fiveRowArray / sizeof *fiveRowArray, number))
printf("Number exists in fiveRowArray\n");
else
printf("Number does not exist in fiveRowArray\n");
if (search(array, sizeof twoRowArray / sizeof *twoRowArray , number))
printf("Number exists in twoRowArray \n");
else
printf("Number does not exist in twoRowArray \n");
return 0;
}
The sizeof arr / sizeof *arr expression calculates the number of elements in the array by getting the total array size in bytes (sizeof arr) and dividing that by the number of bytes in an individual array element (sizeof *arr or sizeof arr[0]). Note that this only works for expressions of array type; it will not work for pointers that are being treated as arrays (such as the expression a in the search function).
If you want to handle different numbers of rows and columns, you'll have to take a different approach:
int search(int *a, size_t rows, size_t cols, int x)
{
size_t i, j;
for (i = 0; i < rows; i++)
for (j = 0; j < cols; j++)
if (a[i * cols + j] == x)
return 1;
return 0;
}
int main(void)
{
int fiveByThree[5][3] = {...};
int twoByFour[2][4] = {...};
...
if (search(&fiveByThree[0][0],
sizeof fiveByThree / sizeof *fiveByThree,
sizeof fiveByThree[0] / sizeof *fiveByThree[0],
number))
...
if (search(&twoByFour[0][0],
sizeof twoByFour / sizeof *twoByFour,
sizeof twoByFour[0] / sizeof *twoByFour[0],
number))
...
}
In this case, we explicitly pass a pointer to the first element in each array, so instead of receiving a pointer to an array of int, search receives a simple pointer to int, which we treat as a 1D array, and compute the offset manually as i * cols + j. This code assumes that all elements in the 2D array are contiguous.
Edit
Note that in C99, you can have what are called Variable Length Arrays (VLAs), where the array dimension can be specified by a runtime variable rather than a constant expression; this allows us to write the prototype as
int search(size_t rows, size_t cols, int arr[rows][cols], int x)
and not mess with pointers.