I'm a beginning programmer who is confused with passing a two dimensional array to a function. I think it may just be a simple syntax problem. I've looked for an answer, but nothing I've found seems to help, or is too far above my level for me to understand.
I identify the array and the function in the main function as, and after initializing it, attempt to call it:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
int const ROWS = 8;
int const COLS = 8;
int main(int argc, char** argv) {
char board[ROWS][COLS];
bool canReach(char board[][], int i, int j);
//initialize array
//values of i and j given in a for loop
canReach(board, i, j);
return (EXIT_SUCCESS);
}
While writing the function outside the main function, I defined it exactly the same as I did in the main function.
bool canReach(char board[][], int i, int j){
//Functions purpose
}
When I attempt to build the program, I'm given this error twice and the program does not build:
error: array has incomplete element type 'char[][]'
bool canReach(char board[][], int i, int j)
^
Please note that I'm trying to pass the entire array to the function, and not just a single value. What can I do to fix this problem? I would appreciate it if it didn't have to use pointers, as I find them quite confusing. Also, I've tried to leave out things that I thought weren't important, but I may have missed something I needed, or kept in things I didn't. Thank you for your time in helping out this starting programmer!
You can just pass arrays as function arguments with definition of their size.
bool canReach(char board[ROWS][COLS], int i, int j);
When the size is unknown, pointers are the way.
bool canReach(char* board, int i, int j);
You should know, that arrays != pointers but pointers can storage the address of an array.
Here is a demonstrative program
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
bool canReach( int n, int m, char board[][m] )
{
for ( int i = 0; i < n; i++ )
{
for ( int j = 0; j < m; j++ )
{
board[i][j] = 0;
}
}
return printf( "Hello SaarthakSaxena" );
}
int main( void )
{
const int ROWS = 8;
const int COLS = 8;
char board[ROWS][COLS];
canReach( ROWS, COLS, board );
return EXIT_SUCCESS;
}
Its output is
Hello SaarthakSaxena
Defining a function inside another function (here: main) is not allowed in C. That is an extension of some compilers (e.g. gcc), but should not be used.
You have to specify the dimension of the array. C arrays do not have implicit size information as in HLL.
It also is not a good idea to use const variables for array dimensions in C. Instead
#define ROWS 8
#define COLS 8
Assuming i and j are the indexes of an element in the array, you can use the signature:
bool canReach(size_t rows, size_t cols, char board[rows][cols],
size_t i, size_t j);
This allows to pass arrays of (run-time) variable size to the function. If the dimensions are guaranteed fixed at run-time:
bool canReach(char board[ROWS][COLS], size_t i, size_t j);
But only if using the macros above. It does not work with the const variables.
Both versions tell the compiler which dimension the array has, so it can calculate the address of each element. The first dimension might be omitted, but there is nothing gained and it would imhibit optional bounds checking (C11 option). Note the 1D-case char ca[] is just a special version of this general requirement you can always omit the left(/outer)most dimension.
Note I changed the types to the (unsigned) size_t as that is the appropriate type for array-indexing and will generate a conversion warning if properly enabled (strongly recommended). However, you can use int, but have to ensure no value becomes negative.
Hint: If you intend to store non-character integers in the array or do arithmetic on the elements, you should specify the signed-ness of the char types. char as such can be either unsigned or signed, depending on implementation. So use unsigned char or signed char, depending what you want.
Related
I have no idea what to do. Whenever I try to insert read_num[size] it does not work. My debugger shows the value as 0. I want to take a value for the size of the array from the user. Then I want to use the value in another file.
So what I want to do is, I will do a printf to ask the user to give a value so that I can pass it as the size of the array. I did and it didn't work. Then I decided to write a direct value [36]. But I want user to insert 36.
This is what I have tried:
main.c
int main(void)
{
int numbers[ARR_SIZE] = { 0 };
int size = 36; // I am doing directly but I want to take the value from the user but it just does not work.
double mean = 0;
double stddev = 0;
read_array(size);
}
file.c
int read_array(int a[36]) //placing 36 directly, I want it to be placed by the user
{
int num_read[36]; int i = 0; // I have no clue whats i am doing. I just want to pass the value from the user.
while (i < a)
{
printf("Enter number");
scanf_s("%d", &num_read[i]);
++i;
}
}
header file
#include <stdio.h>
#include <math.h>
#define ARR_SIZE 100
int read_array(int arr[ARR_SIZE]);
double calc_mean(int arr[], int size);
double calc_stddev(int arr[], int size);
void print_array(int arr[], int size);
In you main.c file you want to decide the value of size and use that value in a call to the function read_array().
You do so by calling read_array(size);, which makes sense to me.
Sadly your shown code lacks the details of whether or not you include your header file (and others). I assume that it does.
However, if what you are doing inside main() is actually what you want to do (I assume so), then the header file and the implementation of read_array() does not match that intention.
This int read_array(int arr[ARR_SIZE]), in your header and your implementation, means
"Dear compiler, this function takes an array (or a pointer to 100 consecutive ints)."
That does not match your plan of "I will give a single int as the parameter to the function."
To match that plan, use a prototype of int read_array(int a);.
The implementation code as shown should then work.
If you want the local array to actually be of the size given by the user and arriving via the parameter a, then change
int num_read[36]; to int num_read[a];.
However, I suspect that you then intend to return the array which you filled with input from the user.
That is neither possible with a prototype of int read_array(int a); nor with one of int read_array(int arr[ARR_SIZE]);. Both mean "This function will return a single int.".
I assume you will need help with that, but you need to ask a separate question on how to return a new array from a C function - or better first search StackOverflow for a duplicate.
To pass the size of the array to the function (it does not matter if it is defined in the same or another compilation units) you need to have an additional parameter to the function. There is no other way of doing it in C language
int *doSomethingWithArray(int *array, size_t size)
{
/* ... */
}
But I want user to insert 36.
The user can only enter something using I/O functions and has no access to the C code.
int *initArray(int *array, const size_t size)
{
for(size_t index = 0; index < size; index ++)
array[index] = rand();
return array;
}
int *printArray(int *array, const size_t size)
{
for(size_t index = 0; index < size; index ++)
printf("array[%3zu] = %d\n", index, array[index]);
return array;
}
int main(void)
{
size_t array_size;
srand(time(NULL));
if(scanf("%zu", &array_size) == 1) // user enters the size of the array
{
int array[array_size];
initArray(array, array_size);
printArray(array, array_size);
}
}
https://godbolt.org/z/xjh9qGcrz
I have the following 2d array of unsigned chars to store an image as values from 0 to 255:
unsigned char img[MAX_DIM][MAX_DIM];
And I have a function that takes a 2d int array as parameter:
void transpose(int m[][MAX_DIM], int h, int w);
How can I pass the char array to that function? I tried something like this but it doesn't work:
transpose((int (*)[MAX_DIM])img, h, w);
You could make a type-generic interface and implement two different transpose functions, one for 8 bit data and one for 32 bit data. Example:
#include <stdint.h>
#include <stdio.h>
void transpose_32 (size_t h, size_t w, uint32_t m[h][w]){ puts(__func__); }
void transpose_8 (size_t h, size_t w, uint8_t m[h][w]){ puts(__func__); }
#define transpose(m,h,w) _Generic(**(m), uint8_t: transpose_8, uint32_t: transpose_32)(h,w,m)
int main(void)
{
const size_t MAX_DIM = 10;
uint8_t img1[MAX_DIM][MAX_DIM];
uint32_t img2[MAX_DIM][MAX_DIM];
transpose(img1, MAX_DIM, MAX_DIM);
transpose(img2, MAX_DIM, MAX_DIM);
return 0;
}
I would like to point out a few things that might help you.
First, if you want to pass an array as a function parameter, don't specify the size in brackets because there is no need to. In fact, think it is wrong.
Second, when you want to typecast something to int as I guess you are trying at your third line of code, the expression is :
(int)charArray[] ;
and not
int charArray(*) [SIZE]
Third and most important, you cant typecast something that is non-arithmetic (char) to something that is (int). But what you can do is use the atoi function that converts an argument to int.
int atoi(const char *str);
Also, next time you want to pass an array to a function, you should prefer to reference it and pass the address of the array as a parameter and not the array with the content itself, because there is no way to return the whole array converted from the transpose function, even if you manage to process it the way you want.
I hope I helped even a little, but if your problem is not resolved, try posting the statement of your problem in order for us to be more able to help you.
I am attempting to write a C program which reads input from a text file and puts it into a 2D-array where Rows are lines and columns are characters.
However I am confused after reading the following article:
http://c-faq.com/aryptr/pass2dary.html
The function definition which I am thinking of is
int processArray(char **text) {
...
...
}
where I am attempting to pass in a pointer to a 2D array whose dimensions I don't know until runtime. I would like to be able to access the elements using two square brackets [] []
However in the link it says the following:
An intermediate pointer would have to be used when attempting to call
it with a two-dimensional array:
extern g(int **ipp);
int *ip = &array[0][0];
g(&ip); /* PROBABLY WRONG */
but this usage
is misleading and almost certainly incorrect, since the array has been
``flattened'' (its shape has been lost).
What is wrong with the above declaration?
How should you define an array to multiple dimensions?
Leaving aside VLAs you can use a simple pointer to point your matrix:
#include "stdio.h"
#define MAX_ROWS 2
#define MAX_COLS 2
void test (int *matrix, int col_max, int row_max)
{
for (int i=0; i<row_max; i++)
{
for (int j=0; j<col_max; j++)
{
printf("matrix[%d][%d]= %d\n", i, j, *(matrix+(i*col_max)+j) );
}
}
}
int main(void)
{
int matrix[MAX_ROWS][MAX_COLS] = { {1,2}, {3,4} };
test(&matrix[0][0], MAX_ROWS, MAX_COLS);
return 0;
}
I'm trying to understand what "best practice" (or really any practice) is for passing a multidimensional array to a function in c is. Certainly this depends on the application, so lets consider writing a function to print a 2D array of variable size. In particular, I'm interested in how one would write the function printArry(__, int a, int b) in the following code. I have omitted the first parameter as I'm not exactly sure what that should be.
void printArry(_____, int a, int b){
/* what goes here? */
}
int main(int argc, char** argv){
int a1=5;
int b1=6;
int a2=7;
int a2=8;
int arry1[a1][b1];
int arry2[a2][b2];
/* set values in arrays */
printArry(arry1, a1, b1);
printArry(arry2, a2, b2);
}
The easiest way is (for C99 and later)
void printArry(int a, int b, int arr[a][b]){
/* what goes here? */
}
But, there are other ways around
void printArry(int a, int b, int arr[][b]){
/* what goes here? */
}
or
void printArry(int a, int b, int (*arr)[b]){
/* what goes here? */
}
Compiler will adjust the first two to the third syntax. So, semantically all three are identical.
And a little bit confusing which will work only as function prototype:
void printArry(int a, int b, int arr[*][*]);
This is not really an answer, but extended comment to the OP's comment question, "well you can pass the array without knowing the number of rows with this, but then how will you know when to stop printing rows?"
Answer: generally, you can't, without passing the array size too. Look at this 1-D example, which breaks the array size.
#include <stdio.h>
int procarr(int array[16], int index)
{
return array[index];
}
int main (void)
{
int arr[16] = {0};
printf("%d\n", procarr(arr, 100));
return 0;
}
Program output (although all elements initialised to 0):
768
That was undefined behaviour and there was no compiler warning. C does not provide any array overrun protection, except for array definition initialisers (although such initialisers can define the array length). You have to pass the array size too, as in
#include <stdio.h>
int procarr(int array[16], size_t index, size_t size)
{
if (index < size)
return array[index];
return -1; // or other action / flag
}
int main (void)
{
int arr[16] = {0};
printf("%d\n", procarr(arr, 100, sizeof arr / sizeof arr[0]));
return 0;
}
Program output:
-1
I am trying to initialize an array of elements to a finite value in a c function.
one way i know is to use a for loop to initialize those values but I am wondering if there is a simple way? I know that they can be initialized during array declaration though but I wouldn't prefer that way.
ex:
int a[10];
void foo(void)
{
for (int i=0; i<10;i++)
{
a[i] = 10;
}
}
Thanks
For the special case, that it is an char/byte array you could use the memset function:
#include <string.h>
void * memset ( void * ptr, int value, size_t num );
Attention: Thoug an 'int' is passed to memset, the ptr will increase in char/byte steps. So it is not suitable for an int array!
But you could use memfill:
#include <publib.h>
void *memfill(void *buf, size_t size, const void *pat, size_t patsize);
See http://manpages.ubuntu.com/manpages/saucy/man3/memfill.3pub.html for details. But it is probably not everywhere available.