사실, 나는 심지어 다차원 배열 문제를 단지 typedef
로 풀지 않는 것을 제외하고는 에릭과 같은 결론에 도달했습니다.
호기심에서, 나는 OP의 작업 버전을 적어 보려고했다. 마침내 나는 내 코드 (Eric Postpischils 응답 외에)를 제시하고자합니다.내가 VS2013에서 해결하려고 문제가 있었다 작업을 도착하기 전에
#include <stdio.h>
#include <stdarg.h>
#define BOARDSIZE 10
#define NCOLS BOARDSIZE
#define NROWS BOARDSIZE
typedef char Board[NROWS][NCOLS];
typedef char (*PBoard)[NCOLS];
void showBoardVariadic(int nArgs, ...)
{
va_list ap;
va_start(ap, nArgs);
/* Attention! VLAs are an optional feature of C11. */
PBoard boards[nArgs];
for (int i = 0; i < nArgs; ++i) {
boards[i] = va_arg(ap, PBoard);
}
/* print the 2D arrays side-by-side */
for (int row = 0; row < NROWS; ++row) {
for (int i = 0; i < nArgs; ++i) {
if (i) putchar('\t');
for (int col = 0; col < NCOLS; ++col) {
printf(" %c", boards[i][row][col]);
}
}
putchar('\n');
}
va_end(ap);
}
int main()
{
Board playerBoard;
Board opponentBoard;
/* initialize boards */
for (int row = 0; row < NROWS; ++row) {
#ifdef CHECK /* for checking */
/* insert some pattern in col 0 for checking */
playerBoard[row][0] = 'a' + row;
opponentBoard[row][0] = 'A' + row;
for (int col = 1; col < NCOLS; ++col) {
playerBoard[row][col] = opponentBoard[row][col] = '~';
}
#else /* productive code */
for (int col = 0; col < NCOlS; ++col) {
playerBoard[row][col] = opponentBoard[row][col] = '~';
}
#endif /* 1 */
}
showBoardVariadic(2, playerBoard, opponentBoard);
/* done */
return 0;
}
:
그래서, 일부 손보는 후 나는이 작업 버전
testVarArgMDimArray.c
을 얻었다. 너무 슬퍼 – VS2013은
VLAs을 지원하지 않습니다. 그러므로 나는 그것을 염두에 두어야 만했다.
내 의견에서 이미 권장했듯이 char*
대신 char
을 보드 요소로 선택했습니다. 나는 char*
도 해결할 수 있었지만, char*
은 OP에서 "우발적 인"선택 일 수 있다고 생각합니다.
typedef char Board[NROWS][NCOLS];
더 중요한 두 번째 아마도 :
typedef char (*PBoard)[NCOLS];
는 함수 매개 변수의 배열은 항상 기억
에릭의 생각에 따라, 나는 2D 보드 배열의 형태를 만들어 포인터로 컴파일. C는 배열을 인수로 전달하지 않습니다. 따라서 유형이 Board
인 함수를 호출하면 PBoard
유형의 인수가 수신됩니다.
괄호는 *PBoard
–입니다. 따라서 PBoard
은 배열에 대한 포인터입니다. 당신이 그들을 제거하는 경우 포인터의 배열을 대신 – 큰 차이가 무엇을 의도하지 않습니다.
이것을 숙달하면 showBoardVariadic()
의 내용이 다소 쉽게됩니다.
이
PBoard boards[nArgs];
va_arg
와 할당은 단순히 :
는
boards[i] = va_arg(ap, PBoard);
보드에 대한 액세스는 단순히 :로
보드의 배열이 선언이 힘
printf(" %c", boards[i][row][col]);
놀랍지 만이 경우 배열에 대한 포인터는 배열 배열처럼 동작합니다. 단지 다른 유형입니다. (예 : 당신은 다른 유형을 적용 할이 경우로 PBoard
와 sizeof
을 사용할 수 없습니다.)
을 모든 보드 요소는 개발이 상태에서 같은 내용을 포함, 나는 보드 인덱싱에 문제가 주목 될 수 있는지를 두려워했다 . 따라서 나는 컬럼의 각 첫 번째 요소가 다른 문자를 가져 오는 대체 초기화를 구현했습니다. playerBoard
'a' + row
의 경우 opponentBoard
'A' + row
의 경우. 이 테스트 할당은 매크로 CHECK
을 정의하여 활성화됩니다. 내 테스트 세션에서, 나는 한번도 -D CHECK
으로 컴파일했다.
btw. 내가 왜 NROWS
과 NCOLS
을 도입했는지 궁금하다면이 답을 쓰는 동안 OP에서 같은 크기를 가지고 우연히 행과 열을 어딘가에 뒤집 었는지 알지 못한다는 것을 깨달았습니다. 따라서 나는 물건을 분리하고 NROWS
≠ NCOLS
으로 테스트했습니다. Phew – 여전히 제대로 작동했습니다.
하지 적어도 마지막으로, Cygwin에서 내 샘플 세션 (I 윈도우 10에있어로) :
$ gcc --version
gcc (GCC) 6.4.0
$ gcc -std=c11 -D CHECK -o testVarArgMDimArray testVarArgMDimArray.c
$ ./testVarArgMDimArray
a ~ ~ ~ ~ ~ ~ ~ ~ ~ A ~ ~ ~ ~ ~ ~ ~ ~ ~
b ~ ~ ~ ~ ~ ~ ~ ~ ~ B ~ ~ ~ ~ ~ ~ ~ ~ ~
c ~ ~ ~ ~ ~ ~ ~ ~ ~ C ~ ~ ~ ~ ~ ~ ~ ~ ~
d ~ ~ ~ ~ ~ ~ ~ ~ ~ D ~ ~ ~ ~ ~ ~ ~ ~ ~
e ~ ~ ~ ~ ~ ~ ~ ~ ~ E ~ ~ ~ ~ ~ ~ ~ ~ ~
f ~ ~ ~ ~ ~ ~ ~ ~ ~ F ~ ~ ~ ~ ~ ~ ~ ~ ~
g ~ ~ ~ ~ ~ ~ ~ ~ ~ G ~ ~ ~ ~ ~ ~ ~ ~ ~
h ~ ~ ~ ~ ~ ~ ~ ~ ~ H ~ ~ ~ ~ ~ ~ ~ ~ ~
i ~ ~ ~ ~ ~ ~ ~ ~ ~ I ~ ~ ~ ~ ~ ~ ~ ~ ~
j ~ ~ ~ ~ ~ ~ ~ ~ ~ J ~ ~ ~ ~ ~ ~ ~ ~ ~
$ gcc -std=c11 -o testVarArgMDimArray testVarArgMDimArray.c
$ ./testVarArgMDimArray
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
$
typedef
– 매우 영리 에릭 ...
당신은 문제가 무엇인지 언급하지 않은 . 컴파일러 오류 메시지? 추락? 'va_arg'에서 잘못된 값이 왔습니까? –
배열을 인수로 전달할 수 없습니다. 항상 포인터를 전달합니다. 배열을 함수 매개 변수로 쓰면 컴파일러는이를 포인터로 읽습니다. 이 점을 염두에두고,'va_arg (ap, char * [] [BOARDSIZE])'에 대해 나쁘다고 생각합니다. 대신 포인터를 읽고 나중에 배열 유형으로 캐스팅하려고합니다. (아니, 사실 나는 또 다른 해결책을 찾으려고 노력할 것이다. var args는 매혹적이지만 멀티 딤 배열과 결합하여 ...) – Scheff
흠 ...'char * boards [numArgs] [BOARDSIZE] [BOARDSIZE]'는 'char *'의 -dim 배열. 귀하의 의견에 따르면, 당신은 대신 2D 배열에 대한 포인터의 배열을 원한다. (나는이 다중 - 희미한 배열 쓰레기를 싫어한다. 그것은 그것을 마스터해야하지만 실제로는 생산적인 가치가 없다.) 단일 희미한 배열과 명시적인 "다중 -dim indexing "은 쉽고 견고하며 유지 보수가 훨씬 쉽습니다.) – Scheff