Error while running code - makes pointer from integer without a cast - c

I'm trying to run my code but I get 5 errors and they're all of the same kind.
The first is:
note: expected 'int (*)[3]' but argument is of type 'int'
In, for example, this part of my code (it points out on the line where you see the word HERE
HERE-> int isNeighbourClose(int mat[N][M], int i, int j, int a, int b){
int m;
m=calcDistance(mat[i][j], mat[a][b]);
if(m<=1)
{
return 1;
}
return 0;
}
And the other is:
error: passing argument 1 of 'isNeighbourClose' makes pointer from integer without a cast
In, for example, this part of my code
int isCellExtreme(int mat[N][M], int i, int j){
int a, b;
int m;
for(a=-1;a<=1;a++)
{
if((i+a>=0) && (i+a<=N))
{
for(b=-1;b<=1;b++)
{
if((j+b>=0) && (j+b<=M))
{
if((a!=0)||(b!=0))
{
HERE-> m=isNeighbourClose(mat[N][M], i, j, i+a, j+b);
if(m)
{
return 0;
}
}
}
}
}
}
return 1;
}
I went over this a couple of times and can't find where the problem is. Any idea where I'm mistaken?
Thanks in advance.

When you pass mat[N][M] to isNeighbourClose, you're not passing a 2D array like you think you are. You're passing in the single element of mat at row N column M.
The function expects a 2D array, so pass the whole array:
m=isNeighbourClose(mat, i, j, i+a, j+b);
EDIT:
When you have a declaration like this:
int mat[N][M];
You're specifying the datatype and (in this case) the dimensions of the array, i.e. it says "mat is an array of N by M elements". This differs from an expression as mentioned above where mat is being used.

Related

Adding up matrices/ returning an array

I'm a begginer to C and I've got some problems with programming a function which would take two matrices, add them up and return the result as a third matrix. The fundamental problem is making a function return an array.
I found some solutions online on how to return an array by returning a pointer to the first element of the array, but couldn't apply it to my situation with two-dimensional array. I know how to add matrices in main function, but I need to break the program down into several functions.
Here is my code
float matrix_add(float matrixA[MAX_SIZE][MAX_SIZE], float matrixB[MAX_SIZE][MAX_SIZE], int column, int line)
{
float matrixRes[MAX_SIZE][MAX_SIZE];
for (int i=0; i<column; i++)
{
for (int j=0; j<line; j++)
{
matrixRes[i][j]=matrixA[i][j]+matrixB[i][j];
}
}
return matrixRes;
}
I've tried one of the solutions I've found online:
float *matrix_add(float matrixA[MAX_SIZE][MAX_SIZE], float matrixB[MAX_SIZE][MAX_SIZE], int column, int line)
{
static float *matrixRes[MAX_SIZE][MAX_SIZE];
for (int i=0; i<column; i++)
{
for (int j=0; j<line; j++)
{
*matrixRes[i][j]=matrixA[i][j]+matrixB[i][j];
}
}
return matrixRes;
But there are a few problems with it - I don't understand it, and the function still doesn't work - it returns false results and there is a warning in the compiler "return from incompatible pointer type".
Also, I'm not sure how to call it (maybe that's the problem with the solution I found?). I wanted to get some specific value from the array and called the function like this
matrix_add(matrixA, matrixB, column, line)[value][value]);
Where matrixA and B are some 2d arrays, column and line are integer variables. This returns an error (subscripted value is neither array nor pointer nor a vector)
Can you point me in the right direction and tell me how to make this function work (and explain the solution)? MAX_SIZE is predefined value (10) as in this assignment I'm supposed to use static memory allocation (but if you can help me by using dynamic allocation, that's fine)
The main function looks like this
int main()
{
int column_num[2], line_num[2];
float matrixA[MAX_SIZE][MAX_SIZE], matrixB[MAX_SIZE][MAX_SIZE];
scanf("%d", &column_num[0]);
scanf("%d", &line_num[0]);
matrix_load_val(matrixA, column_num[0], line_num[0]);
scanf("%d", &column_num[1]);
scanf("%d", &line_num[1]);
matrix_load_val(matrixB, column_num[1], line_num[1]);
}
for (int i=0; i<column_num[0]; i++)
{
for(int j=0; j<line_num[0]; j++)
{
printf("%0.5g\n", matrix_add(matrixA, matrixB, i, j));
}
}
matrix_load_val is a procedure which asks the user for values and puts them in a resultant matrix (it works for sure, tested)
Your attempt isn't too far off. You have a viable idea to declare a static array and "return it," but first we need to understand what that means.
In C, array types are strange beasts. You can't directly return an array of values like you can in other languages. Instead, you return a pointer. We say the array type decays to a pointer. For one-dimensional arrays, this isn't too scary:
float *get_array(void) {
static float my_array[2] = { 1, 2 };
return my_array;
}
float *result = get_array();
For multidimensional arrays, the decay is much trickier and uglier:
Note that when array-to-pointer decay is applied, a multidimensional array is converted to a pointer to its first element (e.g., a pointer to its first row or to its first plane): array-to-pointer decay is applied only once.
To return a pointer to a two-dimensional array, the syntax is:
float (*get_array(void))[2] {
static float my_array[2][2] = { { 1, 2 }, { 3, 4 } };
return my_array;
}
float (*result)[2] = get_array();
Applying this, we can tweak your code to make it work (some braces omitted for brevity):
float (*matrix_add(float matrixA[MAX_SIZE][MAX_SIZE], float matrixB[MAX_SIZE][MAX_SIZE], int column, int line))[MAX_SIZE]
{
static float matrixRes[MAX_SIZE][MAX_SIZE];
for (int i = 0; i < column; ++i)
for (int j = 0; j < line; ++j)
matrixRes[i][j] = matrixA[i][j] + matrixB[i][j];
return matrixRes;
}
However, a more idiomatic C pattern for this type of thing is to have the caller pass in a pointer to the output array. The function then populates this array. This is called an output parameter. This also eliminates the static variable and its associated issues (such as thread safety and subsequent calls clobbering the results of previous calls).
void matrix_add(
const float matrixA[MAX_SIZE][MAX_SIZE], /* "input parameter" */
const float matrixB[MAX_SIZE][MAX_SIZE], /* "input parameter" */
float matrixRes[MAX_SIZE][MAX_SIZE], /* "output parameter" */
int column,
int line)
{
for (int i = 0; i < column; ++i)
for (int j = 0; j < line; ++j)
matrixRes[i][j] = matrixA[i][j] + matrixB[i][j];
}
Notice we've also made the input parameters const to reflect the fact that the function doesn't modify those arrays. This makes it clear from the function's prototype which are the input and which are output parameters.
* I also took the liberty of reformatting a bit, and of changing i++ to ++i because it's a good habit, although it makes no difference in this particular case.
I recommend that you pass another matrix to the function which can be used to populate the result:
void matrix_add(float matrixA[MAX_SIZE][MAX_SIZE], float matrixB[MAX_SIZE][MAX_SIZE], float matrixRes[MAX_SIZE][MAX_SIZE], int column, int line)
{
for (int i=0; i<column; i++)
{
for (int j=0; j<line; j++)
{
matrixRes[i][j]=matrixA[i][j]+matrixB[i][j];
}
}
}
After you call matrix_add, matrixRes will have the results. This works because you're passing the address of matrixRes to matrix_add, that is, matrixRes is not local to matrix_add as in the case of column and line.

Passing an array to a function changes its values?

The intended result is the printing of the same values that we input, but the output is zero after the first row.
#include<stdio.h>
void display(int *q, int);
int main() {
int i,j,n;
int d[50][50];
printf("Input the order\t");
scanf("%d", &n);
for (i=0;i<=(n-1);i++) {
for (j=0;j<=(n-1);j++) {
scanf("%d", &d[i][j]);
}
}
display (d, n);
}
void display (int *q, int r) {
int i,j;
for (i=0;i<r;i++) {
for (j=0;j<r;j++) {
printf("%d\t", *(q + i*r + j));
}
printf("\n");
}
}
Your function is declared with a parameter of type int *. You are attempting to pass an argument of type int [50][50], which decays to pointer type int (*)[50]. These pointer types are incompatible. Language does not support implicit conversion from int (*)[50] to int. Your code is not a valid C program, and I'm sure your compiler told you about it.
A more meaningful thing to do would be to declare your function as
void display (int n, int q[n][n])
and access your array elements in a natural way as
q[i][j]
However, for that you will have to use true array sizes as n (i.e. 50 in your case). If you want to process a smaller sub-matrix of elements, you will have to pass its size separately.
But if you really want to use your "hack", you will have to use an explicit cast when calling your function
display ((int *) d, n);
and keep in mind that each row of your original array still contains 50 elements, as declared, regardless of the value of n. This means that inside your function you will have to use 50 as row size multiplier
void display (int *q, int r) {
int i,j;
for (i=0;i<r;i++) {
for (j=0;j<r;j++) {
printf("%d\t", *(q + i*50 + j));
}
printf("\n");
}
}
your display routine assumes that the 2D array is [n][n] whereas it is [50][50].
You have to pass the actual 2D array dimension alongside with n, the display routine cannot know the actual 2D array size.
You could declare your array dynamically like this:
printf("Input the order\t");
scanf("%d", &n);
int d[n][n];
and then avoid the warning
test.c:20:18: warning: passing argument 1 of 'display' from incompatible pointer type
display (d, n);
here by casting explicitly to 1D pointer (since you know the structure):
display ((int*)d, n);

Value is not an array nor pointer nor vector

I'm working on some C homework for class and I've been running into issues using arrays. Here is a sample of one of my functions that's having an error.
void multiply(int a, int size)
{
int i;
for(i = 0; i < size; i++){
a[i] = a[i] * 5;
printf("%d, ", a[i]);
}
printf("\n");
}
It returns the error: subscripted value is neither array nor pointer nor vector on lines 5 & 6 when I call for a[i]. I have a as an array with size 10, but each time I try and call an individual value in the array it doesn't want to work. I've tried searching it but none of the solutions really seems to work.
You should change your function to:
void multiply(int * a, int size)
Change your function header to:
void multiply(int* a, int size)
Othewise the function thinks a is an int not an int array

Unable to convert (int*) to int

I'm just trying to read the elements from a text file that has all the numbers and pass it as an argument to the "frequency()" function given below.However,It shows up an error saying that
"argument of type int is incompatible with argument of type (int*)" . I tried everything to convert (int*) to int but ended up miserably..below posted is my C code.
void main()
{
FILE*file = fopen("num.txt","r");
int integers[100];
int i=0;
int h[100];
int num;
int theArray[100];
int n,k;
int g;
int x,l;
while(fscanf(file,"%d",&num)>0)
{
integers[i]=num;
k =(int)integers[i];
printf("%d\n",k);
i++;
}
printf ("\n OK, Thanks! Now What Number Do You Want To Search For Frequency In Your Array? ");
scanf("\n%d", &x);/*Stores Number To Search For Frequency*/
frequency(k,n,x);
getch();
fclose(file);
}
void frequency (int theArray [ ], int n, int x)
{
int count = 0;
int u;
// printf("%d",n);
for (u = 0; u < n; u++)
{
if ( theArray[u]==x)
{
count = count + 1 ;
/*printf("\n%d",theArray[u]);*/
/* printf("\n%d",count);*/
}
else
{
count = count ;
}
}
printf ("\nThe frequency of %d in your array is %d ",x,count);
}
So the idea is that the elements read through "num.txt" are stored in an array 'k' and the same array has to be passed in the frequency function! However,in my case it is saying "argument of type int is incompatible with argument of type(int*).
frequency(k, n, x);
|
|
+---int ?
But
frequency (int theArray [ ], int n, int x)
|
|
+ accepts an int*
Call your function as
frequency ( integers, i, x );
You never initialized n and theArray in your main, simply declaring them will not magically pass them in other functions.
When you call the frequency function, you're passing in the int k as the first argument. I think it's worth correcting your statement that k is an array. It is not. You declare it as an int. This is where your type error is coming from because it expects an int * (because of the int[] argument).
Perhaps you mean to pass in integers instead of k?

Pointers for a beginner (with code)

I am doing my first ever homework assignment in C and I'm trying to grasp pointers. They make sense in theory, but in execution I'm a little fuzzy. I have this code, which is supposed to take an integer x, find its least significant byte, and replace y with that byte in the same location. GCC returns with:
"2.59.c:34:2: warning: passing argument 1 of ‘replace_with_lowest_byte_in_x’ makes pointer from integer without a cast [enabled by default]
2.59.c:15:6: note: expected ‘byte_pointer’ but argument is of type ‘int’"
And the same for argument 2. Would someone be so kind as to explain to me what is going on here?
#include <stdio.h>
typedef unsigned char *byte_pointer;
void show_bytes(byte_pointer start, int length) {
int i;
for (i=0; i < length; i++) {
printf(" %.2x", start[i]);
}
printf("\n");
}
void replace_with_lowest_byte_in_x(byte_pointer x, byte_pointer y) {
int length = sizeof(int);
show_bytes(x, length);
show_bytes(y, length);
int i;
int lowest;
lowest = x[0];
for (i=0; i < length; i++) {
if (x[i] < x[lowest]) {
lowest = i;
}
}
y[lowest] = x[lowest];
show_bytes(y, length);
}
int main(void) {
replace_with_lowest_byte_in_x(12345,54321);
return 0;
}
The function expects two pointers but you're passing integer(-constant)s. What you probably want is to put the numbers in their own variables and pass the addresses of those to the function: (in main):
int a = 12345, b = 54321;
replace_with_lowest_byte_in_x(&a, &b);
Note that you're still passing incompatible pointers.
The compiler is right, your replace_with_lowest_byte_in_x() expects two unsigned char *, but you pass two ints to it. Yes, the ints can be regarded as memory address, but it's dangerous, so there is a warning. &variable gives you the address of variable.

Resources