compiler errors with multi dimensional arrays in c - c

This is the first time, when I'm using C. I have to do my numeric mathematics homework in C.
So I have problem using multi dimensional arrays. I don't now why I'm getting the following errors:
subscripted value is neither array nor pointer nor vector
subscripted value is neither array nor pointer nor vector
In function ‘inMatrix’:
error: subscripted value is neither array nor pointer nor vector|
In function ‘inVector’:|
error: subscripted value is neither array nor pointer nor vector|
In function ‘outVector’:|
error: subscripted value is neither array nor pointer nor vector|
In function ‘main’:|
error: incompatible type for argument 2 of ‘plu’|
note: expected ‘float (*)[(long unsigned int)(k)]’ but argument is of type ‘float’|
error: incompatible type for argument 3 of ‘plu’|
expected ‘float *’ but argument is of type ‘float’|
For example:
I don't know why it is complaining about the 'float *' when I didn't use a float pointer.Searching on google didn't return any results, so I don't know what the error is. I don't understand this error 'subscripted value is neither array nor pointer nor vector'.
What can I do? How can I rewrite my source code to get rid of these compiler errors?
Sorry for my poor English.
#include <stdio.h>
#include <stdlib.h>
void inMatrix(double matrix, int n)
{
int j, i;
for (i = 0; i < n; i++)
{
for (j= 0; j < n; j++)
{
scanf("%lf", &matrix[i][j]);
}
}
}
void inVector(double vektor, int n)
{
int k;
for (k = 0; k < n; k++)
{
scanf("%lf", &vektor[k]);
}
}
void outVector(double vektor, int n)
{
int k;
for (k = 0; k < n; k++)
{
printf("%.8lf", vektor[k]);
}
}
int plu(int k, float A[k][k], float b[k], float x[k])
{
int P[k];
int n, m, p, i, j;
int d=0;
int r=0;
int T=0;
float t=0;
float y[k];
//seged vektorok
for(n=1; n<k;n++)
{
x[n]=0;
y[n]=0;
}
// Permutaciós matrix
// permutation
for(i=1; i<k; i++)
{
P[i]=i;
}
// Rendezes
// sorting
for(d=1; d<k-1;d++)
{
p=0;
for(i=d; i<k; i++)
{
t=A[i][d];
if(t<0)
t=-1*t;
if(t>p)
{
p=t;
r=i;
}
}
//Ha szingularis
//If singular
if(p==0)
{
// printf("szingularis");
return 1;
}
//Matrix Csere
//Matrix change
T=P[r];
P[r]=P[d];
P[d]=T;
//matrix elem csere
//matrix value change
for(i=1; i<k; i++)
{
t=A[r][i];
A[r][i]=A[d][i];
A[d][i]=t;
}
for(i=d+1;i<k;i++)
{
A[i][d]=A[i][d]/A[d][d];
for(j=d+1; j<k; j++)
{
A[i][j]=A[i][j]-A[i][d]*A[d][j];
}
}
}
// Megoldas Vektorra
// Solve for Vector
for(n=1; n<k;n++)
{
t=0;
for(m=1;m<=n-1;m++)
{
t+=A[n][m]*y[m];
}
y[n]=b[P[n]]-t;
}
for(n=k-1;n>=1;n--)
{
t=0;
for(m=n+1; m<k;m++)
{
t+=A[n][m]*x[m];
}
x[n]=(y[n]-t)/A[n][n];
}
return 0;
}
int main()
{
//int i,j,k, num,value;
// d as numbers of dimmension
int d;
// Read dimension of array
scanf("%d", &d);
float matrix[d][d];
float vector[d];
inMatrix(matrix[d][d], d);
inVector(vector[d], d);
float resVector[d];
if(plu(d,matrix[d][d],vector[d], resVector[d])==1)
{
printf("szingularis");
}
else
{
outVector(resVector[d], d);
}
return 0;
}

Here, I've fixed the compiler errors for you.
I won't bother to explain in detail the errors as you clearly need to read a good book first.
#include <stdio.h>
#include <stdlib.h>
void inMatrix(int n,double matrix[n][n])
{
int j, i;
for (i = 0; i < n; i++)
{
for (j= 0; j < n; j++)
{
scanf("%lf", &matrix[i][j]);
}
}
}
void inVector(double vektor[], int n)
{
int k;
for (k = 0; k < n; k++)
{
scanf("%lf", &vektor[k]);
}
}
void outVector(double vektor[], int n)
{
int k;
for (k = 0; k < n; k++)
{
printf("%.8lf", vektor[k]);
}
}
int plu(int k, double A[k][k], double b[k], double x[k])
{
int P[k];
int n, m, p, i, j;
int d=0;
int r=0;
int T=0;
float t=0;
float y[k];
//seged vektorok
for(n=1; n<k;n++)
{
x[n]=0;
y[n]=0;
}
// Permutaciós matrix
// permutation
for(i=1; i<k; i++)
{
P[i]=i;
}
// Rendezes
// sorting
for(d=1; d<k-1;d++)
{
p=0;
for(i=d; i<k; i++)
{
t=A[i][d];
if(t<0)
t=-1*t;
if(t>p)
{
p=t;
r=i;
}
}
//Ha szingularis
//If singular
if(p==0)
{
// printf("szingularis");
return 1;
}
//Matrix Csere
//Matrix change
T=P[r];
P[r]=P[d];
P[d]=T;
//matrix elem csere
//matrix value change
for(i=1; i<k; i++)
{
t=A[r][i];
A[r][i]=A[d][i];
A[d][i]=t;
}
for(i=d+1;i<k;i++)
{
A[i][d]=A[i][d]/A[d][d];
for(j=d+1; j<k; j++)
{
A[i][j]=A[i][j]-A[i][d]*A[d][j];
}
}
}
// Megoldas Vektorra
// Solve for Vector
for(n=1; n<k;n++)
{
t=0;
for(m=1;m<=n-1;m++)
{
t+=A[n][m]*y[m];
}
y[n]=b[P[n]]-t;
}
for(n=k-1;n>=1;n--)
{
t=0;
for(m=n+1; m<k;m++)
{
t+=A[n][m]*x[m];
}
x[n]=(y[n]-t)/A[n][n];
}
return 0;
}
int main()
{
//int i,j,k, num,value;
// d as numbers of dimmension
int d;
// Read dimension of array
scanf("%d", &d);
double matrix[d][d];
double vector[d];
inMatrix(d,matrix);
inVector(vector, d);
double resVector[d];
if(plu(d,matrix,vector, resVector)==1)
{
printf("szingularis");
}
else
{
outVector(resVector, d);
}
return 0;
}
Your errors show that you don't understand the basics of C at all.
Take some time to review your concepts.

Well, I'm not totally clear on what your assignment was but lets look at the first function
I see you are trying to iterate through a square matrix of size n and read double-values from stdin into the matrix. The input parameter for this should not be (double, int). It should be (double*, int). A double* is an array of doubles. If you declare this function with just a double (like you did), then the program will allocate enough space for one double on the stack and your for-loop will be writing on important memory (and by that I mean it will most likely just crash) for array sizes bigger than one. Also, declaring it this way means the memory is found on the stack for this function call. This means that once the function is over, your array values you set are lost forever.
Instead, you need to declare it like:
void inMatrix(double* matrix, int n)
and pass in an array when you call it.
double myArray[16];
inMatrix(myArray, 4);
I hope this is helpful. Im not sure how much you understand about pointers/arrays.

Related

Error when passing 2D array to function in c

I am writing a program to calculate matrix multiplication but it does not work. When I debug and check each value of the array a and b in function printMatrixMultiplication (which are entered by user), GDB prints out "cannot perform pointer math on incomplete type try casting". (I have searched for it but I still don't get it.) The function only works when the input is predefined in main.
This is my code
#include <stdio.h>
void input(int m, int n, double a[m][n]);
void output(int m, int n, double a[m][n]);
void printMatrixMultiplication(int row_a, int col_a, double a[row_a][col_a], int row_b, int col_b, double b[row_b][col_b]);
int main()
{
int row_a, col_a, row_b, col_b;
// get value of matrix a
printf("row_a = ");
scanf("%d", &row_a);
printf("col_a = ");
scanf("%d", &col_a);
double a[row_a][col_a];
input(row_a, col_a, a);
// output(row_a, col_a, a);
// get value of matrix b
printf("row_b = ");
scanf("%d", &row_b);
printf("col_b = ");
scanf("%d", &col_b);
double b[row_b][col_b];
input(row_b, col_b, a);
// output(row_b, col_b, a);
printMatrixMultiplication(row_a, col_a, a, row_b, col_b, b);
//test
// double a[2][2]={1,2,3,4};
// double b[2][3]={1,2,3,4,5,6};
// printMatrixMultiplication(2,2,a,2,3,b);
return 0;
}
void input(int m, int n, double a[m][n])
{
int i, j;
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
scanf("%lf", &a[i][j]);
}
}
}
void output(int m, int n, double a[m][n])
{
int i, j;
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
printf("%.2f ", a[i][j]);
}
printf("\n");
}
}
void printMatrixMultiplication(int row_a, int col_a, double a[row_a][col_a], int row_b, int col_b, double b[row_b][col_b])
{
if (col_a != row_b)
{
return;
}
double res[row_a][col_b]; //this matrix store results
for (int i = 0; i < row_a; i++) //the values be stored line by line, this
{ //operation is controled by i and j loops.
for (int j = 0; j < col_b; j++) //the k loop helps calculate dot_product.
{
double dot_product = 0;
for (int k = 0; k < col_a; k++)
{
dot_product += a[i][k] * b[k][j]; //ERROR HERE
}
res[i][j] = dot_product;
}
}
output(row_a, col_b, res);
}
So, where does the error come from and how to fix it?
Irrelevant, but the function is not well implemented so if possible, I would really appreciate if anyone gives me a hint to improve it.
I am using GCC version 6.3.0.
It's typo in your code when reading matrix b.
Just replace:
input(row_b, col_b, a);
with
input(row_b, col_b, b);

Input matrix in C using function

I am trying to input a matrix of order p*q using a function I got some errors. how to get the input using a pointer it gives me a segmentation fault .
#include<stdio.h>
int read_matrix(int *x,int p,int q){
for(int i=0;i<p;i++){
for(int j=0;j<q;j++){
scanf("%d",*(x+i)+j);
}
}
return 0;
}
int main(){
int p,q;
printf("enter the order of the matrix");
scanf("%d%d",&p,&q);
int a[p][q];
read_matrix(a[q],p,q);
for(int i=0;i<p;i++){
for(int j=0;j<q;j++)
printf("%d",a[i][j]);
}
}
You have multiple problems and seem to misunderstand how arrays and pointers work. To begin with a[q] will be out of bounds if p <= q.
a[q] (if q is valid) is an array of q elements, which decays to a pointer to its first element. It's not any kind of pointer to the matrix itself.
And inside the read_matrix function when you do *(x + i) + j that is actually equal to x[i] + j which is a single int value, and not a pointer to an element in any array.
You need to pass the matrix itself to the function, and let it decay to a pointer to an array, and use that as a proper "array of arrays":
// Use variable-length arrays for the matrix argument x
// Declare it as a pointer to an array of q integer elements
// Note the changed order of arguments, it's needed because q must be declared
// before its used for the VLA
void read_matrix(int p, int q, int (*x)[q]) {
for (int i = 0; i < p; ++i) {
for (int j = 0; j < q; ++j) {
scanf("%d", &x[i][j]); // Use normal array indexing and address-of operator
}
}
}
int main(void) {
int p, q;
scanf("%d %d", &p, &q);
int a[p][q];
// Here a will decay to a pointer to its first element, &a[0]
// Since a[0] is an array of q elements, the type will be
// int (*)[q], exactly as expected by the function
read_matrix(p, q, a);
for (int i = 0; i < p; ++i) {
for (int j = 0; j < q; ++j) {
printf("%d ", x[i][j]);
}
printf("\n");
}
}
You are making things needlessly complicated with the pointer arithmetic. *(x+i)+j means x[i] + j*sizeof(int) which is not what you want.
Just do something like this instead:
#include<stdio.h>
void read_matrix(int x, int y, int matrix[x][y])
{
int count=0;
for(int i=0;i<x;i++)
for(int j=0;j<y;j++)
matrix[i][j] = ++count;
}
int main (void)
{
int x=3, y=2;
int matrix[x][y];
read_matrix(x,y,matrix);
for(int i=0;i<x;i++)
{
for(int j=0;j<y;j++)
printf("%d ",matrix[i][j]);
printf("\n");
}
}

Passing a 2d array to a function if I don't know the dimensions

I am trying to write a C function to add two arrays. The function should work with any array sizes and it should receive a reference to both arrays and the number of rows and the number of columns and it should return a pointer to the first element of the resulting array.
How would I do that? When I try to pass a two dimensional array to a function I get an error?
#include<stdio.h>
void function(int r, int c,int a[][]){
int i,j;
for(i=0;i<r;i++)
{
for(j=0;j<c;j++)
{
printf("%d, ",a[i][j]);
}
printf("\n");
}
}
int main(){
int array[2][2] = {{1,2},{4,5}};
function(2,2,array);
return 0;
}
Assuming C99, or C11 with an implementation that doesn't define __STDC_NO_VLA__, you could use the variable length array (VLA) notation and could write:
void function(int r, int c, int a[r][c])
{
for (int i = 0; i < r; i++)
{
for (int j = 0; j < c; j++)
printf("%d, ", a[i][j]);
putchar('\n');
}
}
Or something equivalent to that. The dimensions must be defined before they're used in the array specification.
If you don't have access to even a C99 compiler but only a C90 compiler, then you have to pass a pointer to the first element of the array and the sizes and you perform the array index calculation explicitly.
void function(int r, int c, int *a)
{
for (int i = 0; i < r; i++)
{
for (int j = 0; j < c; j++)
printf("%d, ", a[i * c + j]);
putchar('\n');
}
}
Now you call the function like this:
int main(void)
{
int array[2][2] = { { 1, 2 }, { 4, 5 } };
function(2, 2, &array[0][0]);
return 0;
}

matrix multipication in c

i know there are similiar questions but i tried the suggestions there and it still does not work, here my complete code;
#include <stdio.h>
#include <math.h>
void ludec(int N, double lu[N][N]){
double temp;
int k,i,j;
for(k=0;k<N;k++){
for(i=k+1;i<N;i++){
temp=lu[i][k]/=lu[k][k];
for(j=k+1;j<N;j++){
lu[i][j]-=temp*lu[k][j];
}
}
}
}
void matmul(int u,int m,int n,double p[u][m],double bb[m][n]){
double mul[u][n];
int ii,jj,kk;
for(ii=0;ii<u;ii++){
for(jj=0;jj<n;jj++){
mul[ii][jj]=0.0;
}
}
for(ii=0;ii<u;ii++){
for(jj=0;jj<n;jj++){
for(kk=0;kk<m;kk++){
mul[ii][jj]=mul[ii][jj]+p[ii][kk]*bb[kk][jj];
printf("la %f ii %d jj%d kk%d\n",mul[ii][jj],ii,jj,kk);
}
}
}
}
int main(void){
double lu[3][3]={{4.0,3.0,-2.0},{-1.0,-1.0,3.0},{2.0,-1.0,5.0}};
double a[3][3]={{4.0,3.0,-2.0},{-1.0,-1.0,3.0},{2.0,-1.0,5.0}};
double y[3][1];
double b[3][1]={{9.0},{-4.0},{6.0}};
double x[3][1];
int i,j,N=3;
double f=0;
ludec(N, lu);
y[0][0]=b[0][0];
for(i=1;i<3;i++){
for(j=0;j<i;j++){
f+=lu[i][j]*y[j][0];
}
y[i][0]=(b[i][0]-f);
f=0;
}
f=0;
x[2][0]=y[2][0]/lu[2][2];
for(i=1;i>=0;i--){
for(j=1+i;j<3;j++){
f+=lu[i][j]*x[j][0];
}
x[i][0]=(y[i][0]-f)/lu[i][i];
f=0;
}
printf("%f\n %f\n %f\n",x[0][0],x[1][0],x[2][0]);
for(i=0;i<3;i++){
for(j=0;j<3;j++){
printf("%f %d %d\n",lu[i][j],i,j);
}
}
double mul[3][1];
matmul(3,3,1,a,x);
for(i=0;i<3;i++){
for(j=0;j<2;j++){
printf("%f %d %d\n",mul[i][j],i,j);
}
}
return 0.0;
}
here is the part responsible by multiplication;
the problem is
i have to get 3*1 matrix as result in matrix multiplication, but it gives bigger matrix with alot of garbage elements i monitor the matrix multiplication by printf in the matmul function and it seems to work but when i do same out side the matmul function it gives garbage only some values are correct with a lot of useless wrong elements.
void matmul(int u,int m,int n,double p[u][m],double bb[m][n]){
double mul[u][n];
int ii,jj,kk;
for(ii=0;ii<u;ii++){
for(jj=0;jj<n;jj++){
mul[ii][jj]=0.0;
}
}
for(ii=0;ii<u;ii++){
for(jj=0;jj<n;jj++){
for(kk=0;kk<m;kk++){
mul[ii][jj]=mul[ii][jj]+p[ii][kk]*bb[kk][jj];
printf("la %f ii %d jj%d kk%d\n",mul[ii][jj],ii,jj,kk);
}
}
}
}
the problem is matmul function and i dont know why it does not work i already initialized the matrix with zeros. am i using void function property wrong?
i am very new to c hence there may be something i am doing wrong. the overall code is for lu decompositation, and i want to see wheter the code works or not by multiplying result with initial matrix.
this is the out put
mul is a local variable in matmul, thus the result is not visible to the calling function. You should modify the matmul function to take the result matrix as an argument:
void matmul(int u, int m, int n,
double mul[u][n], const double p[u][m], const double bb[m][n])
{
for (int i = 0; i < u; i++) {
for (int j = 0; j < n; j++) {
mul[i][j] = 0.0;
for (int k = 0; k < m; k++) {
mul[i][j] += p[i][k] * bb[k][j];
}
}
}
}
Invoke from main as
double mul[3][1];
matmul(3, 3, 1, mul, a, x);
And print the output vector:
for (i = 0; i < 3; i++) {
for (j = 0; j < 1; j++) {
printf("%f %d %d\n", mul[i][j], i, j);
}
}

Transpose matrix function in C, with function receiving and returning a 2D array

I need to create a function that takes a matrix and returns it transpose. The only requirement is that it directly returns a matrix, not just modifies it by reference. Here's what I've done so far:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define ROW 100000000
#define COL 100000000
int (*(f_MatTrans)(int mat[][COL], int r, int c))[COL];
int main(void)
{
int x[2][2]={1,2,3,4};
int (*a)[2];
a=f_MatTrans(x,2,2);
for(int i=0; i<2; i++)
{
for(int j=0; j<2; j++)
{
printf("X[%d][%d]=%d\n",i,j,x[i][j]);
printf("A[%d][%d]=%d\n",i,j,a[i][j]);
}
}
return 0;
}
int (*(f_MatTrans)(int mat[][COL], int r, int c))[COL]
{
int a[c][r];
for(int i=0; i<r; i++)
{
for(int j=0; j<c; j++)
{
a[j][i]=mat[i][j];
}
}
return a;
}
The purpose of this is to include the function on a library created by myself, just in case it is useful information.
The code in the question (when I read it) doesn't compile because the array x is not compatible with the function signature.
I'm not clear what the real constraints on your problem are. The easy way to do it in C99 or C11 is with VLA notation:
#include <stdio.h>
static void MatrixTranspose(int r, int c, int src[r][c], int dst[c][r])
{
for (int i = 0; i < r; i++)
for (int j = 0; j < c; j++)
dst[j][i] = src[i][j];
}
int main(void)
{
int x[3][2] = { { 0, 1 }, { 2, 3 }, { 4, 5 } };
int y[2][3];
MatrixTranspose(3, 2, x, y);
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 2; j++)
{
printf("X[%d][%d]=%d ", i, j, x[i][j]);
printf("Y[%d][%d]=%d\n", j, i, y[j][i]);
}
}
return 0;
}
Sample output:
X[0][0]=0 Y[0][0]=0
X[0][1]=1 Y[1][0]=1
X[1][0]=2 Y[0][1]=2
X[1][1]=3 Y[1][1]=3
X[2][0]=4 Y[0][2]=4
X[2][1]=5 Y[1][2]=5
My suspicion is that you are supposed to be doing something different (notationally more complex), but it is not yet clear what.
You cannot return a pointer to the local array, because that ceases to exist when the function returns. If you want your function to create the result array (not write to some other array that is passed into the function), you must use malloc() in these cases:
//The return type is actually `int (*)[r]`, but C doesn't like that.
int* f_MatTrans(int r, int c, int mat[][c]) {
int (*a)[r] = malloc(c*sizeof(*a));
for(int i=0; i<r; i++) {
for(int j=0; j<c; j++) {
a[j][i]=mat[i][j];
}
}
return *a;
}
Note that I changed the array types: If you declare mat as int mat[][COL], the number COL will be used to calculate the offset mat[1][0], which will be 100000000 integers after the first element in your case, while the array that you pass in only contains four integers. This is undefined behavior, and your program is allowed to format your harddrive if you do this.
Unfortunately, it is not possible for the type of the returned pointer to depend on the value of an argument to the function. That is why I changed the return type to a plain integer pointer, you must document that this is meant to be a pointer of type int (*)[r].
You would use the function above like this:
int main(void) {
int x[2][3]={1,2,3,4,5,6};
int (*a)[2] = (int (*)[2])f_MatTrans(2, 3, x);
for(int i=0; i<2; i++) {
for(int j=0; j<2; j++) {
printf("X[%d][%d]=%d\n",i,j,x[i][j]);
printf("A[%d][%d]=%d\n",i,j,a[i][j]);
}
}
free(a); //Cleanup!
return 0;
}

Resources