Related
I wrote this code :
#include <stdio.h>
void transpose(int *Al[]){
int x=0;
int z=0;
int k=1;
while (*Al[z] != "\0") {
int c=*Al[z];
if (c>x)
x=c;
z++;
}
printf("%d ",x);
for(int o=0;o<6;o++){
for(int i=0 ;i<x;i++ ) {
int *p = Al[i];
int l=*p;
if(k<l)
printf("%d ",*(p+k));
else
printf(" ");
}
k++;
printf("\n");
}
}
int main() {
int A[] = {5, -5, 14, 5, 2};
int B[] = {3, 6, 11};
int C[] = {4, 1, -3, 4};
int D[] = {6, 2, 7, 1, 8, 2};
int E[] = {2, 15};
int F[] = {3, 4, -2};
int *All[] = {A, B, C, D, E, F, NULL};
transpose(All);
}
The function gets an array that points to different array I need to print the arrays using pointers
the output should be :
-5 6 1 2 15 4
14 11 -3 7 -2
5 4 1
2 8
2
But this code doesn't print anything.
Also the arrays that it points at the first value is the size of the array.
I tried this :
void transpose(int *Al[]){
int x=0;
int z=0;
int k=1;
for(int o=0;o<5;o++){
for(int i=0 ;i<6;i++ ) {
int *p = Al[i];
int l=*p;
if(k<l)
printf("%d ",*(p+k));
else
printf(" ");
}
k++;
printf("\n");
}
}
It worked only I need to replace the five and six in the loop
Five is the biggest size of all he arrays -1 so I will know how many lines to print and six to how many arrays in All so I can know how many colums I should print. Is there a solution for this?
The condition in the while loop
while (*Al[z] != "\0") {
does not make a sense. The expression *Al[z] has the type int while the string literal "\0" has the type char *.
Also it is unclear why there is present the magic number 6 in this loop
for(int o=0;o<6;o++){
There is no need to calculate explicitly the number of columns because you have a sentinel value equal to NULL.
I can suggest for example the following solution
#include <stdio.h>
void transpose( int * Al[] )
{
int rows = 0;
for ( int **p = Al; *p != NULL; ++p )
{
if ( rows < **p ) rows = **p;
}
if ( rows ) --rows;
for ( int i = 0; i < rows; i++ )
{
for ( int **p = Al; *p != NULL; ++p )
{
if ( i + 1 < **p ) printf( "%2d ", *( *p + i + 1 ) );
else printf( " " );
}
putchar( '\n' );
}
}
int main(void)
{
int A[] = {5, -5, 14, 5, 2};
int B[] = {3, 6, 11};
int C[] = {4, 1, -3, 4};
int D[] = {6, 2, 7, 1, 8, 2};
int E[] = {2, 15};
int F[] = {3, 4, -2};
int *All[] = { A, B, C, D, E, F, NULL };
transpose( All );
return 0;
}
The program output is
-5 6 1 2 15 4
14 11 -3 7 -2
5 4 1
2 8
2
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
Need to make a function that can replace first n elements from array A with last n elements of array B.
arguments in function should be like (arrayA, arrayB, n)
Works like:
int A[ ] = {1, 2, 3, 4, 5};
int B[ ] = {6, 7, 8, 9, 10};
function name(A[ ], B[ ], 2)
Output:
int A[ ] = {9, 10, 3, 4, 5};
int B[ ] = {6, 7, 8, 1, 2};
void *mymemcpy(void *a, const void *b, size_t size)
{
unsigned char *ac = a;
const unsigned char *bc = b;
while(size--) *ac++ = *bc++;
return a;
}
void replace(void *a, const void *b, size_t nelem, size_t elemsize, size_t size_b)
{
const char *bc = b;
mymemcpy(a, b + (size_b - nelem) * elemsize, nelem * elemsize);
}
int main(void)
{
int a[] = {1,2,3,4,5,6};
int b[] = {1,2,3,4,5,6,7,8,9,0};
replace(a,b,3,sizeof(a[0]), sizeof(b)/sizeof(b[0]));
for(size_t index = 0; index < sizeof(a)/sizeof(a[0]); index++)
{
printf("%2d ", a[index]);
}
printf("\n");
}
I would not use it directly as your teacher probably will not believe you.
Here you are.
#include <stdio.h>
void swap_n( int *a, int *b, size_t n )
{
while ( n-- )
{
int tmp = *a;
*a++ = *b;
*b++ = tmp;
}
}
int main(void)
{
int a[] = { 1, 2, 3, 4, 5 };
int b[] = { 6, 7, 8, 9, 10 };
const size_t N1 = sizeof( a ) / sizeof( *a );
const size_t N2 = sizeof( b ) / sizeof( *b );
for ( size_t i = 0; i < N1; i++ )
{
printf( "%2d ", a[i] );
}
putchar( '\n' );
for ( size_t i = 0; i < N2; i++ )
{
printf( "%2d ", b[i] );
}
putchar( '\n' );
size_t n = 2;
swap_n( a, b + N2 - n, n );
for ( size_t i = 0; i < N1; i++ )
{
printf( "%2d ", a[i] );
}
putchar( '\n' );
for ( size_t i = 0; i < N2; i++ )
{
printf( "%2d ", b[i] );
}
putchar( '\n' );
return 0;
}
The program output is
1 2 3 4 5
6 7 8 9 10
9 10 3 4 5
6 7 8 1 2
Pay attention to that the argument n of the function swap_n shall be not greater than the number of elements in the array a and in the array b.
Using the function swap_n you can exchange any parts of the size n of two arrays. For example to exchange two elements third and fourth of the array a with second and third elements of the array b you could write
size_t n = 2;
swap_n( a + 2, b + 1, n );
In this case the program output will be
1 2 3 4 5
6 7 8 9 10
1 2 7 8 5
6 3 4 9 10
I need to Sum the 3D Array by using other function 'int ADD'. I want to pass the Array by using pointer and adding with pointer increase but I'm stuck at passing the Array. Here is my codes.
int(*pA)[COL][HIT] = A;
printf("Sum Of Array A : %d",ADD((*pA)[COL][HIT]);
system("pause");
}
int ADD(int(*pA)[COL][HIT])
{
int sum = 0;
for ((*pA)[COL][HIT] = 0; (*pA)[COL][HIT] < 10 * 7 * 6; (*pA)[COL][HIT]++)
{
sum = sum + (*pA)[COL][HIT];
}
return sum;
}
It seems what you need is something like the following shown in the demonstrative program.
#include <stdio.h>
#define N1 2
#define N2 3
#define N3 4
long long int add( int ( *a )[N2][N3], size_t n )
{
long long int sum = 0;
for ( int ( *p1 )[N2][N3] = a; p1 != a + n; ++p1 )
{
for ( int ( *p2 )[N3] = *p1; p2 != *p1 + N2; ++p2 )
{
for ( int *p3 = *p2; p3 != *p2 + N3; ++p3 ) sum += *p3;
}
}
return sum;
}
int main(void)
{
int a[N1][N2][N3] =
{
{
{ 1, 2, 3, 4 },
{ 1, 2, 3, 4 },
{ 1, 2, 3, 4 }
},
{
{ 1, 2, 3, 4 },
{ 1, 2, 3, 4 },
{ 1, 2, 3, 4 }
}
};
printf("Sum Of Array a : %lld", add( a, N1 ) );
return 0;
}
The program output is
Sum Of Array a : 60
Another approach is to reinterpret the 3D array as a 1D array. For example
#include <stdio.h>
#define N1 2
#define N2 3
#define N3 4
long long int add( int *a, size_t n )
{
long long int sum = 0;
for ( int *p = a; p != a + n; ++p )
{
sum += *p;
}
return sum;
}
int main(void)
{
int a[N1][N2][N3] =
{
{
{ 1, 2, 3, 4 },
{ 1, 2, 3, 4 },
{ 1, 2, 3, 4 }
},
{
{ 1, 2, 3, 4 },
{ 1, 2, 3, 4 },
{ 1, 2, 3, 4 }
}
};
printf("Sum Of Array a : %lld", add( **a, N1 * N2 * N3 ) );
return 0;
}
Your variable names are confusing, since you are using a pointer to a 2D array (a pointer to a table) consider using row and col instead of COL and HIT
You need to pass both dimensions (rows and cols) to the function and also the number of tables.
Call the function using
ADD(tables, rows, cols, A);
And the prototype of the function should be something like
int ADD(int tables, int rows, int cols, int (*pA)[rows][cols])
Then, in a loop:
for (int i = 0; i < tables; i++)
for (int j = 0; j < rows; j++)
for (int k = 0; k < cols; k++)
sum = sum + pA[i][j][k];
I have the following:
struct matrix {
int h;
int w;
int** data;
};
int m1[2][2] = {
{1, 2},
{3, 4}
};
int m2[3][3] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
struct matrix matrix1 = {2, 2, m1};
struct matrix matrix2 = {3, 3, m2};
This gives the error 'initialisation from incompatible pointer type'. What pointer type should I be using?
You may be interested in the variable length arrays of C99. This solution does not directly answer your question about how to initialize the structure with a properly typed data (one can't); but you can use a simple pointer to store the array's address and then cast to the variable length array pointer when using struct matrix.
The user side would just call functions like printFroMat() which receive a single argument of type struct matrix; the code inside these functions (so to speak, the library implementation) would perform the somewhat unsightly casts, as demonstrated. The typedef makes the cast perhaps a little more understandable because it demonstrates where the variable name in a declaration would go.
Note that the funny sizeof(m2)/sizeof(*m2) etc. are not strictly necessary, you can just say 3. But the sizeof expression automatically stays in sync with the actual matrix size, which quickly becomes a real asset.
You can pass "arrays" (in fact: still just addresses, but of a known array type) together with their dimensions as parameters to functions, and index them the normal way (below in printMatrix). Example:
#include<stdio.h>
#include<string.h>
struct matrix {
int h;
int w;
int *data; // first element of matrix
};
int m2[4][3] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9},
{10, 11, 12}
};
void printMatrix(int dim1, int dim2, int mat[][dim2] )
{
printf("Address of matrix: %p\n", (void *)mat);
for(int i1=0; i1<dim1; i1++)
{
for(int i2=0; i2<dim2; i2++)
{
printf("%d ", mat[i1][i2]);
}
putchar('\n');
}
}
void printFromMat(struct matrix mat)
{
printMatrix(mat.h, mat.w, (int (*)[mat.w])mat.data);
// or:
typedef int (*mT)[mat.w];
printMatrix(mat.h, mat.w, (mT)mat.data);
}
int main()
{
printMatrix( sizeof(m2) /sizeof(*m2), // number of highest-order elements
sizeof(*m2)/sizeof(**m2), // number of second-order elements per highest-order
m2 ); // address of the first sub-array
struct matrix mat = { sizeof(m2) /sizeof(*m2), sizeof(*m2)/sizeof(**m2), *m2 };
printFromMat(mat);
return 0;
}
Sample session:
$ gcc -std=c99 -Wall -o 2d-matrix 2d-matrix.c && ./2d-matrix
Address of matrix: 0x100402020
1 2 3
4 5 6
7 8 9
10 11 12
Address of matrix: 0x100402020
1 2 3
4 5 6
7 8 9
10 11 12
Address of matrix: 0x100402020
1 2 3
4 5 6
7 8 9
10 11 12
2d array is not a pointer to pointer.
How to use the void *.
#include <stdio.h>
struct matrix {
int h;
int w;
void *data;
};
int m1[2][2] = {
{1, 2},
{3, 4}
};
int m2[3][3] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
struct matrix matrix1 = {2, 2, m1};
struct matrix matrix2 = {3, 3, m2};
int main(void){
int i, j;
int (*matp)[matrix2.w] = matrix2.data;//Back from the void* to pointer to array
for (i=0; i<matrix2.h; i++){
for(j=0; j<matrix2.w; j++)
printf("%d ", matp[i][j]);
puts("");
}
printf("\n");
return 0;
}
A matrix, as you declared, is not a pointer to pointer. Use a simple pointer to point its element.
#include <stdio.h>
struct matrix {
int h;
int w;
int* data;
};
int m1[2][2] = {
{1, 2},
{3, 4}
};
int m2[3][3] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
struct matrix matrix1 = {2, 2, &m1[0][0]};
struct matrix matrix2 = {3, 3, &m2[0][0]};
int main(int argc, char **argv)
{
int i, j;
for (i=0; i<matrix2.h; i++)
for(j=0; j<matrix2.w; j++)
printf("%d ", matrix2.data[(i*matrix2.h)+j]);
printf("\n");
}
EDIT
To answer to the comment, you can use compound literal as below. In this way you could access it with [i][j]
#include <stdio.h>
struct matrix {
int h;
int w;
int** data;
};
int *m2[3] = {
(int[]){1, 2, 3},
(int[]){4, 5, 6},
(int[]){7, 8, 9}
};
struct matrix matrix2 = {3, 3, m2};
int main(int argc, char **argv)
{
int i, j;
for (i=0; i<matrix2.h; i++)
for(j=0; j<matrix2.w; j++)
printf("%d ", matrix2.data[i][j]);
printf("\n");
}
You may not initialize the structure such a way like
struct matrix matrix1 = {2, 2, m1};
struct matrix matrix2 = {3, 3, m2};
because there is no conversion from types int ( * )[2] and int ( * )[3] to type int **
I suggest to allocate memory for copies of the arrays dynamically.
The approach can look the following way as it is shown in the demonstrative program
#include <stdlib.h>
#include <stdio.h>
struct matrix
{
size_t h;
size_t w;
int **data;
};
int m1[2][2] =
{
{ 1, 2 },
{ 3, 4 }
};
int m2[3][3] =
{
{ 1, 2, 3 },
{ 4, 5, 6 },
{ 7, 8, 9 }
};
struct matrix init( size_t h, size_t w, int a[h][w] )
{
struct matrix matrix = { 0 };
matrix.data = malloc( h * sizeof( int * ) );
if ( matrix.data )
{
matrix.h = h;
matrix.w = w;
for ( size_t i = 0; i < h; i++ )
{
matrix.data[i] = malloc( w * sizeof( int ) );
if ( matrix.data[i] )
{
for ( size_t j = 0; j < w; j++ ) matrix.data[i][j] = a[i][j];
}
}
}
return matrix;
}
int main( void )
{
struct matrix matrix1 = init( 2, 2, m1 );
struct matrix matrix2 = init( 3, 3, m2 );
for ( size_t i = 0; i < matrix1.h; i++ )
{
for ( size_t j = 0; j < matrix1.w; j++ ) printf( "%d ", matrix1.data[i][j] );
printf( "\n" );
}
printf( "\n" );
for ( size_t i = 0; i < matrix2.h; i++ )
{
for ( size_t j = 0; j < matrix2.w; j++ ) printf( "%d ", matrix2.data[i][j] );
printf( "\n" );
}
printf( "\n" );
// free allocated arrays of matrix1 and matrix2
}
The program output is
1 2
3 4
1 2 3
4 5 6
7 8 9
You need also to write a function that will free the allocated memory for the structure.
The compiler must support variable length arrays.
I want to decrement a pointer to the last element of an array and check for the condition that if the value of the pointer was smaller than 5, do nothing and go to the next round of loop and if not, that is if the value is equal or bigger than 5, print the value. So, for the array in the example, I want only 6 to be printed, that is the first encounter of a value equal or bigger than 5. I tried the code below but while being compiled with no error, it doesn't print any value. I'd appreciate your comments on this.
#include<stdio.h>
//The is a C program to decrement an array from the last element to the first.
int x[11] = {5, 6, -4, -3, -2, -1, 4, 3, 2, 1, -2};
int *lastElem, count;
int main (void) {
lastElem = &x[10];
for (count = 0; count < 11; count++)
if (abs(*lastElem) < 5)
continue;
else
printf("%d\n", *lastElem--);
return 0;
}
There is a problem in your decrement logic. If the value is less than 5, you're missing the decremet.
check the below code.
#include<stdio.h>
//The is a C programme to decrement an array from the last element to the first.
int x[11] = {5, 6, -4, -3, -2, -1, 4, 3, 2, 1, -2};
int *lastElem, count;
int main (void) {
lastElem = &x[10];
for (count = 0; count < 11; count++)
{
if (*lastElem >= 5)
{
printf("%d\n", *lastElem);
break ;
}
lastElem--;
}
return 0;
}
EDIT:
As you modified your question to include the absolute value comparions, the changes are like below.
Note : When making some major changes [which will change the behaviour and output] to the original question asked, do make a note of that, and if possible, mention the edit properly.
#include<stdio.h>
#include <stdlib.h>
//The is a C programme to decrement an array from the last element to the first.
int x[11] = {5, -6, -4, -3, -2, -1, 4, 3, 2, 1, -2};
int *lastElem, count;
int main (void) {
lastElem = &x[10];
for (count = 0; count < 11; count++)
{
if ( abs(*lastElem) >= 5)
{
printf("%d\n", *lastElem);
break;
}
lastElem--;
}
return 0;
}
You never assign another address to lastElem than the inital value (that is the 10th element). Also, if you want to go backwards, set count to 10 and let it count to 0. In each loop you have to assign &x[count] to lastElem (or decrement it, as it is a pointer and the address will be decremented according to the object it points to).
The line printf("%d\n", *lastElem--); is not always executed it is only executed when abs(*lastElem) >= 5. This is how you should do it
#include<stdio.h>
//The is a C programme to decrement an array from the last element to the first.
int x[11] = {5, 6, -4, -3, -2, -1, 4, 3, 2, 1, -2};
int *lastElem, count, value;
int main (void)
{
lastElem = &x[10];
for (count = 0; count < 11; count++)
{
value = *(lastElem--);
if (value < 5)
continue;
printf("%d\n", value);
break;
}
return 0;
}
This will do it with continue.
Here is the only correct code among presented here in other answers that does the task.:)
In fact you need a program that searches backward an alement of an array that satisfies a given condition. And if there is such an element then to output it.
#include <stdio.h>
#include <stdlib.h>
int main( void )
{
int a[] = { 5, 6, -4, -3, -2, -1, 4, 3, 2, 1, -2 };
const size_t N = sizeof( a ) / sizeof( *a );
int *first = a, *last = a + N;
while ( first != last && ( unsigned int )abs( *( last - 1 ) ) < 5 ) --last;
if ( first != last ) printf( "%d\n", *--last );
return 0;
}
The output is
6
Below there is demonstrated a general approach for such tasks
#include <stdio.h>
#include <stdlib.h>
int * find_backward( const int a[], size_t n, int ( *predicate )( int ) )
{
const int *first = a, *last = a + n;
while ( first != last && !predicate( *( last -1 ) ) ) --last;
return ( int * )last;
}
int is_greater_or_equal_to_5( int x )
{
return 5 <= ( unsigned int )abs( x );
}
int main( void )
{
int a[] = { 5, 6, -4, -3, -2, -1, 4, 3, 2, 1, -2 };
const size_t N = sizeof( a ) / sizeof( *a );
int *target = find_backward( a, N, is_greater_or_equal_to_5 );
if ( target != a ) printf( "%d\n", *--target );
return 0;
}
Using this approach you can use any integer arrays (even with zero size) and any conditions that are set by means of predicates.
For example if you want to find the last element of an array that is divisible by 3 you can write
#include <stdio.h>
#include <stdlib.h>
int * find_backward( const int a[], size_t n, int ( *predicate )( int ) )
{
const int *first = a, *last = a + n;
while ( first != last && !predicate( *( last -1 ) ) ) --last;
return ( int * )last;
}
int divisible_by_3( int x )
{
return x % 3 == 0;
}
int main( void )
{
int a[] = { 5, 6, -4, -3, -2, -1, 4, 3, 2, 1, -2 };
const size_t N = sizeof( a ) / sizeof( *a );
int *target = find_backward( a, N, divisible_by_3 );
if ( target != a ) printf( "%d\n", *--target );
return 0;
}
The output is
3
Take into account that this function allows also to deal with constant arrays.:)