This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Passing multidimensional arrays as function arguments in C
In C,
if I want a function to receive a 2-D array, can I use * notation for the function parameter
int (int my2dary[][10]); //This is what I do not want.
Yes, you pass a pointer to an array of int
int func(int (*my2dary)[10]);
and you call it
int a[5][10];
func(a);
Although, func doesn't know how many elements are in my2dary, so you must give a number too
int func(int n, int (*my2dary)[10]);
and call
int a[5][10];
func(5, a);
See How to interpret complex C/C++ declarations or The ``Clockwise/Spiral Rule''.
If your problem is that you don’t know the size of the array at compile time, you may want:
int func(int *array, int size)
{
int n,m;
...
array[m*size+n]; /* = array[m][n] if in the caller: int array[x][size]; */
}
Optionally (and very probably you need) you can pass a second size argument (x) to be able to test array boundary
Related
This question already has answers here:
Passing a matrix in a function (C)
(5 answers)
Closed 2 years ago.
I'd like to define a function that can process a matrix in a flexible way. That is, I need a function that can deal with matrices of any size.
My first try was to deal with the matrix as a pointer, in this way:
#include <stdio.h>
#include <stdlib.h>
#define MAX_L 10
#define MAX_C 10
void initializeMatrix(int *matrix, int lines, int columns){
int i,j,color;
for(i=0;i<lines;i++){
for(j=0;j<columns;j++){
*(matrix+i*columns+j) = rand()%10;
}
}
}
void printMatrix(int *matrix, int lines, int columns){
int i,j,color;
for(i=0;i<lines;i++){
for(j=0;j<columns;j++){
printf("%d\t",*(matrix+i*columns+j));
}
printf("\n");
}
}
int main(){
int x,y,i,color,count,finish;
int matrix[MAX_L][MAX_C];
initializeMatrix(matrix,MAX_L,MAX_C);
printMatrix(matrix,MAX_L,MAX_C);
return 0;
}
Is there any problem in working with matrices in this way? Is it a good practive?
Is there any problem in working with matrices in this way? Is it a good practice?
No.
void ...Matrix(int *matrix, int lines, int columns) expects an int *matrix. ...Matrix(matrix,MAX_L,MAX_C); does not convert matrix to a int *.
Save time, enable all warnings as your compiler should have told you this already.
The range of indices in C is [0...SIZE_MAX]. Consider size_t instead of int. Take care that size_t is an unsigned type.
With C99 and many compilers since, code can use a VLA declaration as suggested by #dbush.
// void printMatrix(int *matrix, int lines, int columns){
void printMatrix(size_t lines, size_t columns, const int matrix[lines][columns]) {
Use const when the reference object does not change.
You can make the size of each dimension a variable if you list the size parameters first, then use them in the array dimensions.
void initializeMatrix(int lines, int columns, int matrix[lines][columns]){
I'm new to programming and I don't really understand this question. Can some of you give me examples of what it means. How do I write a function where a is int values and n is the length?
I'm confused...
I'm not sure what your question is, as you haven't provided much information. However, a function in C is defined like this:
return_type function_name( parameter list ) {
body of the function
}
So, for this situation, we could say:
void arrayFunction( int a[], int n){
//do whatever you need to do with the function here
}
This may help you some.
Suppose you have an array of ints, as follows:
int arr[] = {2,3,4,5,6};
You can see that there are 5 elements inside above array arr. You can count them.
But it happens that when you pass the above arr to function, that function has no idea about how many elements arr contains. See below (incorrect) code snippet:
#include <stdio.h>
void display(int arr[]){
}
int main(void) {
int arr[] = {2,3,4,5,6};
display(arr);
return 0;
}
The function named 'display()' has no idea about how many elements arr has
Therefore you you need to pass the extra argument (the extra argument called 'n') to tell that called function about the number of elements inside arr. You need to tell this separately - the length of arr.
Now this becomes - as you said in your question - arr is int values and n is the length
Below is the correct code:
#include <stdio.h>
void display(int a[], int n){
//Now display knows about lenth of elemnts in array 'a'
// Length is 5 in this case
}
int main(void) {
int arr[] = {2,3,4,5,6};
display(arr, 5);
return 0;
}
Now, the function named 'display()' knows the length of array of int. This is the way you write code where you specify your array and its length.
More formally, this is because while passing array, it decays to a pointer and so the need arises to pass its length also alongwith it.
This question already has answers here:
returning multiple values from a function [duplicate]
(8 answers)
Closed 5 years ago.
If I have a function which calculates the minimum and maximum of an array would it be bad practice to include minimum and maximum in the function parameters so I can edit them while the function runs.
So I would have void minmax(array, int min, int max)
the min and max variables would be sent in as null and get changed when the function runs. Would this be ok or should I be using malloc to get an array and return the pointer instead?
Q: If I have a function which calculates the minimum and maximum of an array would it be bad practice to include minimum and maximum in the function paramiters
A: No, not at all. That's a perfectly reasonable thing to do.
Q: "So I would have void minmax(array, int min, int max)..."
A: Uh, no. That would NOT pass "min" and "max" back to the caller. Instead, you need something like:
void minman(int * array, int * min, int * max);'
For example:
int myarray[] = {1, 2, 3};
int min, max;
minman(myarray, &min, &max);
...
That's totally fine, except that you'll need min and max to be pointers. If they're just plain old int like you have there, the caller will never see the changes you make.
There is nothing wrong with a function returning values through parameters. Except the code you wrote will not work - change it like this:
void minmax(int *array, int *min, int *max)
Also see returning multiple values from a function.
This question already has answers here:
C sizeof a passed array [duplicate]
(7 answers)
Closed 4 years ago.
In the program below the length of the array ar is correct in main but in temp it shows the length of the pointer to ar which on my computer is 2 (in units of sizeof(int)).
#include <stdio.h>
void temp(int ar[]) // this could also be declared as `int *ar`
{
printf("%d\n", (int) sizeof(ar)/sizeof(int));
}
int main(void)
{
int ar[]={1,2,3};
printf("%d\n", (int) sizeof(ar)/sizeof(int));
temp(ar);
return 0;
}
I wanted to know how I should define the function so the length of the array is read correctly in the function.
There is no 'built-in' way to determine the length inside the function. However you pass arr, sizeof(arr) will always return the pointer size. So the best way is to pass the number of elements as a seperate argument. Alternatively you could have a special value like 0 or -1 that indicates the end (like it is \0 in strings, which are just char []).
But then of course the 'logical' array size was sizeof(arr)/sizeof(int) - 1
Don't use a function, use a macro for this:
//Adapted from K&R, p.135 of edition 2.
#define arrayLength(array) (sizeof((array))/sizeof((array)[0]))
int main(void)
{
int ar[]={1,2,3};
printf("%d\n", arrayLength(ar));
return 0;
}
You still cannot use this macro inside a function like your temp where the array is passed as a parameter for the reasons others have mentioned.
Alternative if you want to pass one data type around is to define a type that has both an array and capacity:
typedef struct
{
int *values;
int capacity;
} intArray;
void temp(intArray array)
{
printf("%d\n", array.capacity);
}
int main(void)
{
int ar[]= {1, 2, 3};
intArray arr;
arr.values = ar;
arr.capacity = arrayLength(ar);
temp(arr);
return 0;
}
This takes longer to set up, but is useful if you find your self passing it around many many functions.
As others have said the obvious solution is to pass the length of array as parameter, also you can store this value at the begin of array
#include <stdio.h>
void temp(int *ar)
{
printf("%d\n", ar[-1]);
}
int main(void)
{
int ar[]= {0, 1, 2, 3};
ar[0] = sizeof(ar) / sizeof(ar[0]) - 1;
printf("%d\n", ar[0]);
temp(ar + 1);
return 0;
}
When you write size(ar) then you're passing a pointer and not an array.
The size of a pointer and an int is 4 or 8 - depending on ABI (Or, as #H2CO3 mentioned - something completely different), so you're getting sizeof(int *)/sizeof int (4/4=1 for 32-bit machines and 8/4=2 for 64-bit machines), which is 1 or 2 (Or.. something different).
Remember, in C when pass an array as an argument to a function, you're passing a pointer to an array.If you want to pass the size of the array, you should pass it as a separated argument.
I don't think you could do this using a function. It will always return length of the pointer rather than the length of the whole array.
You need to wrap the array up into a struct:
#include<stdio.h>
struct foo {int arr[5];};
struct bar {double arr[10];};
void temp(struct foo f, struct bar g)
{
printf("%d\n",(sizeof f.arr)/(sizeof f.arr[0]));
printf("%d\n",(sizeof g.arr)/(sizeof g.arr[0]));
}
void main(void)
{
struct foo tmp1 = {{1,2,3,4,5}};
struct bar tmp2;
temp(tmp1,tmp2);
return;
}
Inside the function ar is a pointer so the sizeof operator will return the length of a pointer. The only way to compute it is to make ar global and or change its name. The easiest way to determine the length is size(array_name)/(size_of(int). The other thing you can do is pass this computation into the function.
This question already has answers here:
Why use an asterisk "[*]" instead of an integer for a VLA array parameter of a function?
(2 answers)
Closed 6 years ago.
While trying to implement a C11 parser (for educational purposes), I found that in C11 (p. 470) but also in C99 (p. 412) (thanks Johannes!), the direct declarator is defined as:
(6.7.6) direct-declarator:
direct-declarator [ type-qualifier-list? * ]
At first, I thought this was an error in the grammar (the type list shouldn't be optional). However, when I tried this out in my reference compiler (clang), I got an rather unexpected error:
int array[*] = { 1, 2, 3 };
// error: star modifier used outside of function prototype
So apparently, (in clang) this is called the star modifier.
I quickly learned that they can only be used in function signatures:
void foobar(int array[*])
However, they can only be used in the declaration. Trying to use it in a function definition results in an error as well:
void foobar(int array[*]) {
// variable length array must be bound in function definition
}
So as far as I can tell, the intended behaviour is to use [*] in the function declaration and then use a fixed number in the function definition.
// public header
void foobar(int array[*]);
// private implementation
void foobar(int array[5]) {
}
However, I have never seen it and I don't quite understand the purpose of it either.
What is its purpose, why was it added?
What's the difference with int[]?
What's the difference with int *?
What is its purpose, why was it added?
Purpose is seen when a variable length two dimentional array is used as a function parameter. The function
int foo(int n, int m, int a[n][m]) {...}
can be prototyped as any of the following
int foo(int , int, int [][*]);
int foo(int , int, int a[*][*]);
int foo(int , int, int (*a)[*]);
int foo(int n, int, int a[n][*]);
int foo(int , int m, int a[*][m]);
int foo(int , int m, int (*a)[m]);
int foo(int n, int m, int a[n][m]);
In case of two dimensional array, when used as function parameter, size of the second dimension can't be omitted. If the name of first variables in function prototype is omitted then it wouldn't be possible to specify the length (second dimension) of the array. The * gives the clue that the length of the array will be determined by the second parameter.
What's the difference with int[]?
What's the difference with int *?
In case of 1D array, for the function definition
int bar(int n, int a[n]} {...}
any of the following prototype is valid
int bar (int , int *);
int bar (int , int [*]);
int bar (int , int []);
int bar (int n, int a[]);
int bar (int n, int a[n]);
int bar (int n, int [n]);
In this case neither * nor n is necessary as compiler will treat both of int [*] and int [n] as int *. So, with one dimensional array you can't see much difference.
NOTE: When using variable length array as a function parameter, order of parameter is important. Order of parameters for first four prototypes of bar can be switched, but in latter two first parameter must not be the array itself.
int bar (int a[n], int n); //Wrong. Compiler has not yet seen 'n'.
The C rationale document for C99 says
A function prototype can have parameters that have variable length array types (§6.7.5.2) using a special syntax as in
int minimum(int, int [*][*]);
This is consistent with other C prototypes where the name of the parameter need not be specified.
What's the difference with int[]
What's the difference with int *.
I think it's simply that those types in a function prototype means "pointer", while a [*] in a non-top position (int[*] still equals int[] I think, in a function prototype) actually is valid and means array
// not recommended though: it is now unclear what the parameters
// mean to human callers!
void f(int, int [][*]);
void f(int n, int x[][n]) {
x[1][0] = 1;
}
int main() {
int a[2][1];
f(1, a);
printf("%d\n", a[1][0]);
}
As for the purpose, when indexing the array in the function definition, the compiler needs to know how many integers of the next index to skip when giving the first index (x[i] skips i * n integers in f above). But this information is not needed in the non-defining prototype declaration, hence it can be left out and replaced by *.