Two-dimensional array parameter passing | value passing

Source: Internet
Author: User
Tags array example

First, let's go:
How do I pass parameters in an array like the following in a function? That is to say, how to ensure that the types of the virtual participation parameters are consistent.

Char str_arr [3] [10] = {"yes", "no", "uncertain "};
Char * str_array [] = {"yes", "no", "unsure "};

Function prototype:
Void func1 (char (* A) [10])
Void func2 (char **)

Call:
Func1 (str_arr );
Func2 (str_array );
What if str_arr is passed into func2? The compiler will warn that when passing parameter 1 (which belongs to 'function2'), it will convert between incompatible pointer types. That is, the type of the virtual participation parameter is inconsistent.

Similarly, str_array cannot be passed into func1.

We provide a complete test procedure:

***************/
# Include <stdio. h>
Void func1 (char (* A) [10])
{
Int I;
For (I = 0; I <3; I ++)
Printf ("% s/n", a [I]);
}

Void func2 (char **)
{
Int I;
For (I = 0; I <3; I ++)
Printf ("% s/n", * (a + I ));
}

Int main ()
{
Char str_arr [3] [10] = {"yes", "no", "uncertain "};
Char * str_array [] = {"yes", "no", "unsure "};
Char * STR [3] = {"A", "B", "C"};/* the two expressions have the same effect */
Func1 (str_arr );
Func2 (str_array );
Return 0;
}
/****************** End *******************/
Running result:
[Root @ localhost ansi_c] # GCC test. c
[Root @ localhost ansi_c] #./A. Out
Yes
No
Uncertain
Yes
No
Unsure
[Root @ localhost ansi_c] #
If
Func1 (str_arr );
Func2 (str_array );
Changed:
Func1 (str_array );
Func2 (str_arr );
What will happen?
[Root @ localhost ansi_c] # GCC test. c
Test. C: In the 'main' function:
Test. C: 22: Warning: conversion between incompatible pointer types when passing parameter 1 (which belongs to 'function1 ')
Test. C: 23: Warning: transfer between incompatible pointer types when passing parameter 1 (which belongs to 'func2 ')

The correct values of the two arrays should be as follows:
Char str_arr [3] [10] = {"yes", "no", "uncertain "};
Char * str_array [] = {"yes", "no", "unsure "};
Char (* pA) [10] = str_arr;
Char ** P = str_array;
Pa and P are the same type.

Of course, if the parameter is not passed, there will be no such troubles in the main () function.
******************** ****/
# Include <stdio. h>
Int main ()
{
Char str_arr [3] [10] = {"yes", "no", "uncertain "};
Char * str_array [] = {"yes", "no", "unsure "};
Char * STR [3] = {"A", "B", "C "};
Int I;
For (I = 0; I <3; I ++)
Printf ("% s/n", str_arr [I]);
For (I = 0; I <3; I ++)
Printf ("% s/n", str_array [I]);
Return 0;
}
/*************************************/
Running result:
[Root @ localhost ansi_c] # GCC test1.c
[Root @ localhost ansi_c] #./A. Out
Yes
No
Uncertain
Yes
No
Unsure
[Root @ localhost ansi_c] #

This shows that before passing parameters, the main () function knows that they are both two-dimensional arrays. For the above two function prototypes:
Function prototype:
Void func1 (char (* A) [10])
Void func2 (char **)
What are the differences between the two parameter passing methods? What are the requirements for real parameters?

The above only throws a problem. The topic here is to figure out the mysteries of passing parameters in two-dimensional arrays, rather than proposing a solution to this problem.
We will start from the basics later.

Let's take a look at how we talk about this part in the teaching material,
Tan haoqiang's two-dimensional array in C programming is passed as a parameter. The original Article is as follows (slightly changed, please forgive me ):

[Start with the original article]

The two-dimensional array name can be used as the real parameter or form parameter. when defining the form parameter array in the called function, you can specify the size of all dimensions or omit the size description of the first dimension. For example:
Void func (INT array [3] [10]);
Void func (INT array [] [10]);
Both of them are valid and equivalent, but the two-dimensional or higher-dimensional sizes cannot be omitted. the following definition is invalid:
Void func (INT array [] []);

Because the starting address of the array is passed from the real parameter, it is stored in the memory according to the array arrangement rules (stored by row), without the partition and column. If the column number is not specified in the form parameter, the system cannot determine how many rows and columns should be. It cannot specify only one dimension rather than the second dimension. The following statement is incorrect:
Void func (INT array [3] []);

The dimension of the real parameter array can be greater than that of the form parameter array. For example, the real parameter array is defined:
Void func (INT array [3] [10]);
The parameter array is defined:
Int array [5] [10];
At this time, the form parameter array only takes part of the real parameter array, and the rest does not work.

[End of original article]

That is to say, the parameter passing through a multi-dimensional array must specify the size of the second or higher dimension. The size of the first dimension can be omitted.
Like int array [3] [4], if you want to transmit parameters, the function prototype can be any of the following three types:
Void func (int A [3] [4])
Void func (int A [] [4])
Void func (INT (* A) [4])
When calling: func (array );

At the same time, the textbook also said that if the parameter does not describe the number of columns, the compiler cannot determine the number of rows and columns. Can I
What if array name array of int array [3] [4] is passed to void func (INT **?
See the following:
/**********************************/
# Include <stdio. h>
Int main ()
{
Int array [3] [4];
Int ** P = array;
}
**********************************/
Root @ localhost ansi_c] # GCC test2.c
Test2.c: In the 'main' function:
Test2.c: 5: Warning: incompatible pointer type Initialization
[Root @ localhost ansi_c] #

Although the array name of int array [3] [4] is essentially a second-level pointer, it is not the same as a general second-level pointer because it also contains array-related information, so in the main function:
Char str_arr [3] [10] = {"yes", "no", "uncertain "};

For (I = 0; I <3; I ++)
Printf ("% s/n", str_arr + I );

It can be addressable by subscript, skipping 10 bytes each time. Let's look at how the compiler processes Arrays:
For the array int P [m] [N];
If you want to obtain the value of P [I] [J] (I> = 0 & I <M & 0 <= J & J <n ),
The compiler addresses this way:
P + I * n + J;

Let's look at another example:
/******************* Two-dimensional array parameter passing ************** ***************/
# Include <stdio. h>
Void fun (int * a, int M, int N)
{
Int I, J;
For (I = 0; I <m; ++ I)
{
For (j = 0; j <n; ++ J)
{
Printf ("% d", * (a + I * n + j ));
}
Putchar ('/N ');
}
}

Void func (int * a, int M, int N)
{
Int I, J;
For (I = 0; I <m * n; ++ I)
{
Printf ("% d", a [I]);
}
Putchar ('/N ');
}

Int main ()
{
Int A [3] [3] =
{
{1, 1, 1 },
{2, 2, 2 },
{3, 3, 3}
};
Fun (int *) A, 3, 3 );
Func (& A [0] [0], 3, 3 );
Func (int *) A, 3, 3 );
Return 0;
}

* ******************* End ******************* ***********/
[Root @ localhost ansi_c] # GCC test4.c
[Root @ localhost ansi_c] #./A. Out
1 1 1
2 2 2
3 3 3
1 1 1 2 2 3 3 3
1 1 1 2 2 3 3 3
[Root @ localhost ansi_c] #

Let's look at the key points,
Array:
Int A [3] [3] =
{
{1, 1, 1 },
{2, 2, 2 },
{3, 3, 3}
};
Function prototype and call:
Prototype:
Void fun (int * a, int M, int N)
{
.............
Printf ("% d", * (a + I * n + j ));
.............
}
Call:
Fun (int *) A, 3, 3 );

Another function is:
Prototype:
Void func (int * a, int M, int N)
{
.............
Printf ("% d", a [I]);
.............
}
Call:
Func (& A [0] [0], 3, 3 );
Func (int *) A, 3, 3 );
We found that both methods can be executed normally. We forcibly converted a second-level pointer into a first-level pointer and passed it in the function to simulate the addressing method of the compiler array: * (a + I * n + J ).

Let's take a look at the two-dimensional character array example:
/****************** Two-dimensional character array ***************** **************/

# Include <stdio. h>
Void F (char ** A, int N)
{
Int I;
Printf ("% C/N", * (char *) A + 0 ));
Printf ("% C/N", (char *) A) [N]);
Puts ("------------ OK ");

For (I = 0; I <3; I ++)
Printf ("% s/n", (char *) A + I * n );
}
Int main ()
{
Char str_arr [3] [10] = {"yes", "no", "uncertain "};

F (char **) str_arr, 10 );
Return 0;
}
/**************** End ********************** ***/
Running result:
[Root @ localhost ansi_c] #./A. Out
Y
N
------------ OK
Yes
No
Uncertain
[Root @ localhost ansi_c] #
Forced type conversion is also done here, and converted to character pointer,
Printf ("% s/n", (char *) A + I * n ); the address of each string is the address of the characters 'y', 'n', and 'U' in the array,
Printf ("% C/N", * (char *) A + 0); the characters are arranged in sequence in the array. You can use * (char *) A + I) or (char *) A) [I.
Of course, this program can also be changed to this way, without the second-level pointer:
/*************************************** **************************/
# Include <stdio. h>
Void F (char * a, int N)
{
Int I;
Printf ("% C/N", * (a + 0 ));
Printf ("% C/N", (a) [N]);
Puts ("------------ OK ");

For (I = 0; I <3; I ++)
Printf ("% s/n", A + I * n );
}
Int main ()
{
Char str_arr [3] [10] = {"yes", "no", "uncertain "};

F (char *) str_arr, 10 );
Return 0;
}
/*************************************** **************************/
In the final analysis, we need to convert it into a level-1 pointer.

The following is a summary:

Passing parameters in an array
Array:
Int array [4] [10];
Function prototype:
Void func1 (int A [] [10]);
Void func2 (INT (* A) [10]);
Void func3 (int * P, int Col, int row );
Function call:
Func1 (array );
Func2 (array );
Func3 (int *) array, 4, 10 );

Errors:
Int arr [] [10];
Int ** P = arr;
This method is incorrect.
It should be
INT (* P) [10] = arr;
Similarly, arr cannot be passed to fun (INT ** P)

In addition, the array will be downgraded to a pointer after passing the parameter, for example:
# Include <stdio. h>
Void test (char a [] [2])
{
Int size = sizeof (a); // 4
}
Int main (void)
{
Char A [3] [2] = {'A', 'B', 'C', 'D', 'E', 'F '};
Int size = sizeof (a); // 6
Test ();
Return 0;
}

Source: http://hi.baidu.com/d_life/blog/item/912062ef1fd363e9ce1b3e2a.html

 

Function prototype: a dynamic two-dimensional array is required.
Void func1 (INT ** P, int row, int column)
{
}
Call:
Int main ()
{
Int M, N;
Int ** B;
Cin> m;
Cin> N;
B = new int * [m];
For (INT I = 0; I <m; I ++)
{
B [I] = new int [N];
};
Func1 (B, m, n );
Return 0;
}

I am used to defining a large block without using a pointer array (in this case, the number of rows in each row is the same ): for example, if there is a w * H matrix (H array with a length of W), you can directly define a float pointer: Float * pfbuffer; then the dynamic allocation size pfbuffer = new float [w * H]; this buffer must call Delete pfbuffer after use; to release. you pass this float pointer, and after passing the number of rows and columns, if you want to access column X of row y, you just need to calculate where it is, int ADDR = y * w + X; it is its "Address". If you want to access it, you can use pfbuffer [ADDR] directly. In fact, this is all done during image processing, because such address access is clear, reading is not inconvenient, and most of the time, we use a large number of matrices, with few columns. This is just my opinion.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.