I'm bad at C pointers, I'm not sure how should I sort the whole array, the code below sorted the array row-wise only, with a warning "assignment discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]". This code sure works in Windows, not sure for other OSes. I am supposed to create a function called snake with 2D const int pointer array, and its size, m as inputs. I am not allowed to move or swap the contents within the array to be scanned, also the whole main function is not allowed to be edited. For example, the input for the whole program is
3
9 8 7
5 4 6
3 2 1
The correct output should be
1 2 3
6 5 4
7 8 9
Instead, I got this
7 8 9
4 5 6
1 2 3
And here is my code. There is a commented section in snake() because the assert function will fail if I uncomment it. I was trying to reverse the even rows (but the index starts from 0, so you can say odd rows also) after sorting.
#include <stdio.h>
#include <assert.h>
void snake(const int *ptr_array[100][100], int m){
int* p =NULL;
int temp;
for(int y=0;y<m;y++){
for(int k=0;k<m-1;k++){
for(int g=0;g<m-k-1;g++){
if(*ptr_array[y][g]>*ptr_array[y][g+1]){
p=(ptr_array[y][g]);
(ptr_array[y][g])=(ptr_array[y][g+1]);
(ptr_array[y][g+1]) = p;
}
}
}
}
// for(int h=1;h<m;h+=2){
// for(int g=0;g<m/2;g++){
// p = (ptr_array[h][m-g]);
// (ptr_array[h][m-g]) = (ptr_array[h][g]);
// (ptr_array[h][g]) = p;
// }
// }
}
int main()
{
int array[100][100], check[100][100];
const int *ptr_array[100][100];
int i, j, m;
scanf("%d", &m);
for (i = 0; i < m; i++){
for (j = 0; j < m; j++) {
ptr_array[i][j] = &(array[i][j]);
scanf("%d", &(array[i][j]));
check[i][j] = array[i][j];
}
}
snake(ptr_array, m);
for (i = 0; i < m; i++) {
for (j = 0; j < m; j++) {
assert(check[i][j] == array[i][j]);
assert((ptr_array[i][j] >= &array[0][0]) && (ptr_array[i][j] <= &array[99][99]));
printf("%d ", *(ptr_array[i][j]));
}
printf("\n");
}
return 0;
}
#include <stdio.h>
void snake(const int *ptr_array[100][100], int m){
int* p =NULL;
int* w=NULL;
int temp,l;
for(int y=0;y<m;y++){
for(int k=0;k<m;k++){
p = ptr_array[y][k];
l = k+1;
for(int g=y;g<m;g++){
while(l<m){
if(*p>*ptr_array[g][l]){
p=(ptr_array[g][l]);
(ptr_array[g][l])=(ptr_array[y][k]);
(ptr_array[y][k]) = p;
}
l++;
}
l=0;
}
}
}
for(int h=1;h<m;h+=2){
for(int g=0;g<=(m-1)/2;g++){
w = (ptr_array[h][m-1-g]);
(ptr_array[h][m-1-g]) = (ptr_array[h][g]);
(ptr_array[h][g]) = w;
}
}
}
Here is a program I have build :
int mynand(int a, int b);
int mynor(int a, int b);
int myxor(int a, int b);
int report(CallBack f , char *gates);
int main( )
{
CallBack myfunctions[] = {myand, myor, myxor, mynand, mynor};
char gatename[N][9+1] = {"AndGate" , "OrGate" , "XorGate" , "NandGate" , "NorGate"};
int i;
int size = sizeof(myfunctions)/sizeof(CallBack);
Name temp[N];
for(i=0; i<size; i++)
{
strcpy(temp[i].gates , gatename[i]);
temp[i].gatename=myfunctions[i];
}
for(i=0; i<size; i++)
{
printf("\n%s\n" , temp[i].gates);
report(temp[i].gatename,temp[i].gates);
}
return 0;
}
int myand (int a, int b)
{
return a * b;
}
int myor (int a, int b)
{
return a + b>0;
}
int mynand (int a, int b)
{
return !(a * b);
}
int mynor (int a, int b)
{
return !(a + b);
}
int myxor (int a, int b)
{
return a*(!(a*b)) + b*(!(a*b));
}
int report(CallBack f , char * gates)
{
int i , j;
for(i=0; i<2; i++)
{
for(j=0; j<2; j++)
{
printf("%d %d %d\n", i , j , f(i ,j));
}
}
printf("\n");
return 0;
}
This program it has as an output :
AND
0 0 0
0 1 0
1 0 0
1 1 1
OR
0 0 0
0 1 1
1 0 1
1 1 1
XOR
0 0 0
0 1 1
1 0 1
1 1 0
NAND
0 0 1
0 1 1
1 0 1
1 1 0
NOR
0 0 1
0 1 0
1 0 0
1 1 0
2)Ι want to modify the functions myand , myor , etc. In order to take for an input simple linked list with type Data elements and prove that it works properly by writing the right code in main. Here the given statements:
typedef struct data {
int value;
struct data * next; }
Data;
typedef Data * DataList;
int myandlst(DataList );
Data * createData( int value) {
Data * dataptr;
dataptr = malloc(sizeof (Data)); dataptr->value = value;
dataptr->next = NULL;
return dataptr;
}
void appendData(DataList *lstptr, Data *newptr) {
if (*lstptr==NULL) {
*lstptr = newptr;
return;
}
appendData( &((*lstptr)->next), newptr);
return;
}
I am trying to add two matrices using 2D arrays in C. Here I am passing the array name as a parameter, which I think is pass by reference. However, I cannot add the arrays. Something is fishy in the add function, I cannot add the arrays.
I even tried to pass the parameter using address of Operator, however arrays are pointer themselves so it got error. I tried passing with the name of array. I am stuck
#include<stdio.h>
void input(int*,int*);
void add(int*,int*,int*);
void display(int*);
int main()
{
int a[3][3],b[3][3],sum[3][3];
input(a,b);
add(a,b,sum);
display(sum);
return 0;
}
void input(int*a,int*b)
{
for(int i = 0;i<3;i++)
{
for(int j =0;j<3;j++)
{
printf("Enter the element at a[%d][%d]",i+1,j+1);
scanf("%d",((a+i)+j));
}
}
for(int i = 0;i<3;i++)
{
for(int j =0;j<3;j++)
{
printf("Enter the element at b[%d][%d]",i+1,j+1);
scanf("%d",((b+i)+j));
}
}
}
void add(int* a,int*b,int*sum)
{
for(int i =0;i<3;i++)
{
for(int j=0;j<3;j++)
{
*(sum[i]+j) = *(a[i]+j) + *(b[i]+j);//error at this line
}
}
}
void display(int* sum)
{
printf("The sum is:\n");
for(int i =0;i<3;i++)
{
for(int j =0;j<3;j++)
{
printf("%d ",(sum[i]+j));
}
printf("\n");
}
}
I got the following error
operand of '*' must be a pointer
However my operand is readily a pointer.
The problem is that the methods:
void input(int*, int*);
void add(int*, int*, int*);
void display(int*);
expected a pointer, however you are passing to them 2D arrays (statically allocated), namely int a[3][3], b[3][3], sum[3][3];. Therefore, as already pointed out in the comments, those 2D arrays will be converted to 'int (*)[3]'. Consequently, you need to adapt the signature of your methods to:
void input(int [][3], int [][3]);
void add(int [][3], int [][3], int [][3]);
void display(int [][3]);
and
void input(int a[][3], int b[][3]){
// the code
}
void add(int a [][3], int b [][3], int sum [][3]){
// the code
}
void display(int sum [][3]){
// the code
}
Alternatively, if you want to keep the int* as parameter then what you can do is to allocate the matrix as a single array and adapt your code accordingly
Here I am passing the array name as a parameter,which i think is pass
by refernece.However I cannot add the arrays.Something is fishy in the
add function,i cannot add the arrays
You can use int* or use int[][], but you need to write the program as required by each case. I will show you an example of both cases.
about your program
do not use void. It is in general a waste, sometimes an error. Return something.
write generically. Compare:
void display(int* sum)
{
printf("The sum is:\n");
for(int i =0;i<3;i++)
{
for(int j =0;j<3;j++)
{
printf("%d ",(sum[i]+j));
}
printf("\n");
}
}
with
void display_a(int s[][3], int l, const char* msg)
{
if( *msg != 0) printf("%s\n",msg);
for(int i =0;i<l;i++)
{
for(int j =0;j<3;j++)
{
printf("%d ", s[i][j]);
}
printf("\n");
}
printf("\n");
return;
};
In the second case you can use the same function to display ANY array s and also write a simple title. Note that in C you can omit all but the last dimension in the vector. In fact C does not have multidimensional array as e.g. FORTRAN has. And passing the number of lines and the message as parameters you have much more than just using as you wrote.
NEVER write
printf("Enter the element at a[%d][%d]",i+1,j+1);
scanf("%d",((a+i)+j));
always test the return of scanf(). scanf() is not meant to read from the keyboard. Use at least one space in every prompt. Is is far more confortable to the user.
Use constants to test your program. Avoid reading for the user as it will waste much time on testing.
An example
output
Using arrays
Matriz A at [1][1] 1
Matriz A at [1][2] 2
Matriz A at [1][3] 3
Matriz A at [2][1] 4
Matriz A at [2][2] 5
Matriz A at [2][3] 6
Matriz B at [1][1] 6
Matriz B at [1][2] 5
Matriz B at [1][3] 4
Matriz B at [2][1] 3
Matriz B at [2][2] 2
Matriz B at [2][3] 1
The 1st matrix:
1 2 3
4 5 6
The 2nd matrix:
6 5 4
3 2 1
The sum (using arrays) is:
7 7 7
7 7 7
Using pointers
Matriz A at [1][1] 2
Matriz A at [1][2] 3
Matriz A at [1][3] 4
Matriz A at [2][1] 5
Matriz A at [2][2] 6
Matriz A at [2][3] 7
Matriz B at [1][1] 7
Matriz B at [1][2] 6
Matriz B at [1][3] 5
Matriz B at [2][1] 4
Matriz B at [2][2] 3
Matriz B at [2][3] 2
The 1st matrix:
2 3 5
5 6 7
The 2nd matrix:
7 6 4
4 3 2
The sum (using pointers) is:
9 9 9
9 9 9
Using t1 t2
The t1 matrix:
1 2 3
4 5 6
7 8 9
The t2 matrix:
9 8 7
6 5 4
3 2 1
t1 + t2 (using pointers) is:
10 10 10
10 10 10
10 10 10
the code
this code uses all that I tried to explain, I believe. Pay attention to the way you write the code when using the pointers: you just use the address and displacement.No brackets are needed.
#include<stdio.h>
void add_a(int[][3],int[][3],int[][3],int);
void display_a(int[][3],int,const char*);
int input_a(int[][3], int, const char*);
void add_p(int*,int*,int*,int);
void display_p(int*,int,const char*);
int input_p(int*, int, const char*);
int main(void)
{
int t1[][3] =
{
{ 1,2,3 },
{ 4,5,6 },
{ 7,8,9 }
};
int t2[][3] =
{
{ 9,8,7 },
{ 6,5,4 },
{ 3,2,1 }
};
int a[3][3];
int b[3][3];
int sum[3][3];
printf("Using arrays\n\n");
input_a(a,2,"Matriz A");
input_a(b,2,"Matriz B");
display_a(a, 2, "The 1st matrix:");
display_a(b, 2, "The 2nd matrix:");
add_a( a,b,sum, 2 );
display_a(sum, 2, "The sum (using arrays) is:");
printf("Using pointers\n\n");
input_p((int*) a,2,"Matriz A");
input_p((int*) b,2,"Matriz B");
display_p( (int*) a, 2, "The 1st matrix:");
display_p( (int*) b, 2, "The 2nd matrix:");
add_p( (int*) a, (int*) b, (int*) sum, 2 );
display_p( (int*) sum, 2, "The sum (using pointers) is:");
printf("\nUsing t1 t2 \n\n");
display_p( (int*) t1, 3, "The t1 matrix:");
display_p( (int*) t2, 3, "The t2 matrix:");
add_p( (int*) t1, (int*) t2, (int*) sum, 3 );
display_p( (int*) sum, 3, "t1 + t2 (using pointers) is:");
return 0;
};
void add_a(
int a[][3],
int b[][3],
int sum[][3],
int l // lines
)
{
for(int i =0;i<l;i++)
for(int j=0;j<3;j++)
sum[i][j] = a[i][j] + b[i][j];
return;
};
void display_a(int s[][3], int l, const char* msg)
{
if( *msg != 0) printf("%s\n",msg);
for(int i =0;i<l;i++)
{
for(int j =0;j<3;j++)
{
printf("%d ", s[i][j]);
}
printf("\n");
}
printf("\n");
return;
};
int input_a(int a[][3], int l, const char* msg )
{
for(int i = 0;i<l;i++)
{
for(int j =0;j<3;j++)
{
printf("%s at [%d][%d] ", msg, i+1,j+1);
int res = scanf("%d",&a[i][j]);
if ( res != 1 ) return -1; // read nothing
}
};
return 0;
};
void add_p( int*a, int* b, int* sum, int l )
{
for(int i =0;i<l;i++)
for(int j=0;j<3;j++)
*(sum + i*l + j) = *(a + i*l + j) + *(b + i*l + j);
return;
};
void display_p(int* s, int l, const char* msg)
{
if( *msg != 0) printf("%s\n",msg);
for(int i =0;i<l;i++)
{
for(int j =0;j<3;j++)
printf("%d ", *( s + i*l + j) );
printf("\n");
};
printf("\n");
return;
};
int input_p(int* a, int l, const char* msg )
{
for(int i = 0;i<l;i++)
{
for(int j =0;j<3;j++)
{
printf("%s at [%d][%d] ", msg, i+1,j+1);
int res = scanf("%d", (a + i*l + j) );
if ( res != 1 ) return -1; // read nothing
}
};
return 0;
};
I have a matrix, and a struct with 2 int variables.
struct virus {
int gen;
int neighbours;
}
I want to initialize my full gen matrix with the 1 value. The problem is it doesn't work for the first column of the matrix.
I'll post down bellow the code.
Also when I tried to set my matrix as the virus struct it didn't work and I had to initialize a new matrix that I called b.
It's just a simple initialization and a printing.
#include <stdio.h>
struct virus {
int gen;
int neighbours;
};
void initGen(int n, int a[][100])
{
struct virus b[n][100];
int i,j;
for(i = 0; i < n; i++)
{
for(j = 0; j < n; j++)
{
b[i][j].gen = 1;
}
}
}
void printMatrixGen(int n, int b[][100])
{
struct virus a[n][100];
int i;
for(i = 0; i < n; i++)
{
int j;
for(j = 0; j < n; j++)
printf("%d\t", a[i][j].gen);
printf("\n");
}
}
int main(void)
{
int a[100][100], n;
n = 4;
initGen(n,a);
printMatrixGen(n,a);
return 0;
}
The output is the matrix
0 1 1 1
0 1 1 1
0 1 1 1
0 1 1 1
Instead of
1 1 1 1
1 1 1 1
1 1 1 1
1 1 1 1
Your code passes a wrong array. You need to change function signatures as follows:
void initGen(int n, struct virus a[][100]);
void printMatrixGen(int n, struct virus a[][100]);
After that, remove local declaration of struct virus b arrays, and use structs passed as parameters.
Finally, declare your struct array inside main, and pass it to both functions:
struct virus a[100][100];
int n = 4;
initGen(n, a);
printMatrixGen(n, a);
I have a 2D array, lets call it "A1".
A1[rows][cols].
later in my program I create another 2D array called "A2",
A2[new_rows][new_cols]
A2 is bigger than A1... is there any way for me to set A1 the same size & contents of A2?
Arrays are static in C, so unfortunately you cannot change the size of an array once you define it. You can, however, achieve what you speak of using dynamically allocated arrays (although, this isn't strictly the same as resizing an array since, when reallocating, you lose the reference to the original array). Start by creating two dynamically allocated arrays A1 and A2 using malloc. Next, use realloc to reallocate A1 to be the same size as A2. Finally, copy the contents of A2 to A1. This will effectively "resize" A1 to be the same size as A2 with the same contents as A2. Here is some sample code (you may use whatever populating method is right for you, I just used filler):
#include <stdio.h>
#include <stdlib.h>
int **make2DArray(int rows, int cols);
void populate2DArray(int **array, int rows, int cols);
void print2DArray(int **array, int rows, int cols);
int main(int argc, char **argv)
{
int i, j;
int rows = 2, cols = 3;
int newRows = 4, newCols = 7;
// Create two dynamic arrays.
int **A1 = make2DArray(rows, cols);
int **A2 = make2DArray(newRows, newCols);
// Populate the dynamic arrays (however you like).
populate2DArray(A1, rows, cols);
populate2DArray(A2, newRows, newCols);
// Print original arrays.
printf("A1 (before):\n");
print2DArray(A1, rows, cols);
printf("\nA2 (before):\n");
print2DArray(A2, newRows, newCols);
// Reallocate A1 to be same size as A2.
int **temp = realloc(A1, sizeof(int *) * newRows);
if (temp)
{
A1 = temp;
int *tempRow;
for (i = 0; i < newRows; i++)
{
tempRow = realloc(A1[i], sizeof(int) * newCols);
if (tempRow)
{
A1[i] = tempRow;
}
}
}
// Copy contents of A2 to A1.
for (i = 0; i < newRows; i++)
{
for (j = 0; j < newCols; j++)
{
A1[i][j] = A2[i][j];
}
}
// Print resized A1 (should be same as A2).
printf("\nA1 (after):\n");
print2DArray(A1, newRows, newCols);
printf("\nA2 (after):\n");
print2DArray(A2, newRows, newCols);
}
int **make2DArray(int rows, int cols) {
// Dynamically allocate a 2D array.
int **array = malloc(sizeof(int *) * rows);
if (array)
{
for (int i = 0; i < rows; i++)
{
array[i] = malloc(sizeof(int) * cols);
}
}
return array;
}
void populate2DArray(int **array, int rows, int cols) {
// Populate a 2D array (whatever is appropriate).
int i, j;
for (i = 0; i < rows; i++)
{
for (j = 0; j < cols; j++)
{
array[i][j] = i + j;
}
}
}
void print2DArray(int **array, int rows, int cols)
{
// Print a 2D array to the terminal.
int i, j;
for (i = 0; i < rows; i++)
{
for (j = 0; j < cols; j++)
{
printf("%d ", array[i][j]);
}
printf("\n");
}
}
The output to the following code will be:
A1 (before):
0 1 2
1 2 3
A2 (before):
0 1 2 3 4 5 6
1 2 3 4 5 6 7
2 3 4 5 6 7 8
3 4 5 6 7 8 9
A1 (after):
0 1 2 3 4 5 6
1 2 3 4 5 6 7
2 3 4 5 6 7 8
3 4 5 6 7 8 9
A2 (after):
0 1 2 3 4 5 6
1 2 3 4 5 6 7
2 3 4 5 6 7 8
3 4 5 6 7 8 9