전역 변수 선언이 이상합니다...

kknd345의 이미지

#include <stdio.h>

int end_row=3;
int end_column=4;
int totalMax=0;
int array[end_row][end_column];




void re_sum( int row, int column, int total)
{
	int count=0;
	total+= array[row][column];

	while(true)
	{
		if( row == end_row)
		{
			if( total > totalMax )
				totalMax=total;
			return;
		}

		else
		{
			if( count==0 )
			{
				count=1;
				re_sum( row+1, column-1, total);
			}
			else if( count == 1 )
			{
				count=2;
				re_sum( row+1, column, total);
			}
			else if ( count ==2 )
			{
				count=3;
				re_sum( row+1, column+1, total);
			}
			else 
				return;
		}
	}

}


void main()
{
	int i,j;
	for( i=0; i < 3;i++)
	{	
		for( j=0; j<4 ; j++)
		{
			re_sum(i,j,totalmax);
		}
	}

	printf("%d",totalmax);
}

C:\C문제\작업장\2proble\2.cpp(6) : error C2057: expected constant expression
C:\C문제\작업장\2proble\2.cpp(6) : error C2466: cannot allocate an array of constant size 0
C:\C문제\작업장\2proble\2.cpp(6) : error C2057: expected constant expression
C:\C문제\작업장\2proble\2.cpp(6) : error C2466: cannot allocate an array of constant size 0
C:\C문제\작업장\2proble\2.cpp(6) : error C2087: '<Unknown>' : missing subscript
C:\C문제\작업장\2proble\2.cpp(57) : error C2065: 'totalmax' : undeclared identifier

이런 에러가 발생하는데 이유를 모르겠습니다.

chonbj의 이미지

array[end_row][end_column]

함수의 인자로 변수값을 넣을 수 없습니다.

넣으실려면...

const int end_row=3;
const int end_column=4;

이런식으로 사용 하시구요

int totalmax=0; 의 대소문자가 틀렸네요...totalMax 로...

정말 좋은 자료가 많은 것 같군요

kknd345의 이미지

답변 고맙습니다 ^^.

그렇게 하니깐 풀리네요.

그런데 전역 변수 array[][]

가로 안에는 왜 const 고정된 값이 들어가야 하나요?

1%의 가능성이면 충분하다!
최선을 다하자!

지리즈의 이미지

저렇게 하면..
컴파일러가 초기에 메모리를 구성해 줍니다.
따라서 컴파일시에 메모리크기가 결정되기 때문에,
const를 사용해서.. 고정된 값을 쓰는 거지요.
(저같은 경우는 #define과 같은 전처리자를 사용합니다만)

프로그램 실행시
동적으로 어레이의 크기를 조정할 필요가 있을 경우에는
포인터+malloc등을 이용합니다.

There is no spoon. Neo from the Matrix 1999.

lsj0713의 이미지

지리즈 wrote:
저렇게 하면..
컴파일러가 초기에 메모리를 구성해 줍니다.
따라서 컴파일시에 메모리크기가 결정되기 때문에,
const를 사용해서.. 고정된 값을 쓰는 거지요.
(저같은 경우는 #define과 같은 전처리자를 사용합니다만)

프로그램 실행시
동적으로 어레이의 크기를 조정할 필요가 있을 경우에는
포인터+malloc등을 이용합니다.

이와 관련하여, C와 C++에 참으로 흥미로운 차이점이 있습니다.

#include <stdio.h>

int main(void)
{
    int a = 4;
    int arr[a];

    arr[0] = 1;

    printf("arr[0] = %d\n", arr[0]);

    return 0;
}

위의 코드는 C에서, 혹은 C++에서 옳은 코드일까요, 틀린 코드일까요?
어떤 온라인 컴파일러(?)를 이용해서 테스트해 봅시다.

http://www.comeaucomputing.com/tryitout/

C99에서:

Comeau C/C++ 4.3.3 (Aug  6 2003 15:13:37) for ONLINE_EVALUATION_BETA1
Copyright 1988-2003 Comeau Computing.  All rights reserved.
MODE:strict errors C99 

In strict mode, with -tused, Compile succeeded (but remember, the Comeau online compiler does not link). 

C++98에서:

Comeau C/C++ 4.3.3 (Aug  6 2003 15:13:37) for ONLINE_EVALUATION_BETA1
Copyright 1988-2003 Comeau Computing.  All rights reserved.
MODE:strict errors C++

"ComeauTest.c", line 6: error: expression must have a constant value
      int arr[a];
              ^

1 error detected in the compilation of "ComeauTest.c".

In strict mode, with -tused, Compile failed

C에서는 맞는 코드이고, C++에서는 틀린 코드입니다.

C99에서는 Variable Length Array 라는 놈이 새로이 추가되었습니다. 말 그대로 가변 길이 배열입니다. 즉 배열을 정의할 때 배열의 첨자로 변수를 사용하는 것이 가능합니다.

단, 질문자께서 맨처음 올리신 코드는 file scope VLA가 사용되었으므로 C99에서도 올바르지 않은 코드입니다.

6.7.5.2 Array declarators 

extern int n;
int A[n]; // invalid: file scope VLA
extern int (*p2)[n]; // invalid: file scope VM
int B[100]; // valid: file scope but not VM
void fvla(int m, int C[m][m]); // valid: VLA with prototype scope
void fvla(int m, int C[m][m]) // valid: adjusted to auto pointer to VLA
{
    typedef int VLA[m][m]; // valid: block scope typedef VLA
    struct tag {
        int (*y)[n]; // invalid: y not ordinary identifier
        int z[n]; // invalid: z not ordinary identifier
    };
    int D[m]; // valid: auto VLA
    static int E[m]; // invalid: static block scope VLA
    extern int F[m]; // invalid: F has linkage and is VLA
    int (*s)[m]; // valid: auto pointer to VLA
    extern int (*r)[m]; // invalid: r has linkage and points to VLA
    static int (*q)[m] = &B; // valid: q is a static block pointer to VLA
}

C++에서는 이와 반대로 틀린 코드입니다. 배열을 정의할 때 그 첨자로는 반드시
정수형 Constant expression이 들어가야 합니다.

5.19 Constant expressions 중에서...

정수형 상수 수식(integral constant expression)은 상수(literal), 열거형(enumerator), const variables, constant expression으로 초기화된 정수형 혹은 열거형 정적 데이터 맴버, 타입이 아닌 정수형 템플릿 파라메터, sizeof expression 중 하나이다.

위의 코드에서 배열의 첨자로 사용된 것은 const형도 아니고 정적 데이터 타입도 아니므로 에러가 나는 것은 당연합니다.

재미있는 것은 C(정확히는 C99)에는 VLA가 있는데 C++에는 없다는 것과, C의 문법에는 constant expression이 없는데 C++에는 있다는 것입니다. C에서는 배열을 선언할 때 첨자로 expression이 들어가지만 그것에 대해 정수형이어야 한다고 제한해 놓은 데 비해서, C++에서는 문법 차원에서 constant expression이 들어가야 한다고 제한하고 있습니다.

근데 이것이 어디에 쓸모가 있는 내용이냐고요? 그냥 재미일 뿐입니다. :-)

doldori의 이미지

lsj0713 wrote:

근데 이것이 어디에 쓸모가 있는 내용이냐고요? 그냥 재미일 뿐입니다. :-)

의미심장한 말씀이군요. Stroustrup은 C++을 만들 때 "A better C"로
생각했습니다. 그리고 C++이 C의 사실상의 수퍼셋(기술적으로는 아니더라도)
으로 남기를 바라는 것 같습니다. 표준이 개정되면서 두 언어 간의 차이가 점점
벌어지는 상황을 "악몽(nightmare)"라고 표현하더군요.
역사적인 이유로 인해 두 언어가 밀접한 관계를 갖고 있기는 한데, 앞으로도
지금과 같은 실용적인 수준의 호환성이 유지될지 궁금합니다. C와 C++
표준위원회 사이에 호환성을 위한 협조가 이루어지는지는 모릅니다만,
이를 포기하고 제갈길로 나가기로 결정한다면 오히려 C와 C++의 같은 점이
재미있는 얘깃거리가 되겠죠.
kknd345의 이미지

차이까지 설명해 주셔서 정말 고맙습니다.

다른 건 열심히 보니깐 이해를 하겠는데..

C99에서는 Variable Length Array 라는 놈이 새로이 추가되었습니다. 말 그대로 가변 길이 배열입니다. 즉 배열을 정의할 때 배열의 첨자로 변수를 사용하는 것이 가능합니다. 

단, 질문자께서 맨처음 올리신 코드는 file scope VLA가 사용되었으므로 C99에서도 올바르지 않은 코드입니다. 

이부분에서 같은 C인데 제가 쓴건 file scope VLA 라 안된다고 하셨는데..
file scope VLA 이게 무엇을 말하는 건가요?

1%의 가능성이면 충분하다!
최선을 다하자!

lsj0713의 이미지

kknd345 wrote:

이부분에서 같은 C인데 제가 쓴건 file scope VLA 라 안된다고 하셨는데..
file scope VLA 이게 무엇을 말하는 건가요?

VLA는 Variable Length Array의 약자이고, file scope라는 것은 파일 전체에서 사용될 수 있는 변수, 즉 전역변수라는 뜻입니다.

VLA 혹은 그에 의존하는(VLA에서 유도되는) 데이터형을 variably modified type, 즉 VM이라 하는데 VM은 반드시 block scope 혹은 function prototype scope를 가져야 합니다. 또한 static 혹은 extern 이 붙은 객체는 VLA가 될 수 없습니다.

block scope는 { } 내부를 뜻하고 function prototype scope는 다음을 뜻합니다.

void foo(int arg1, double arg2);

위 함수 선언의 파라미터 리스트 안의 범위를 function prototype scope라고 부릅니다. (함수 정의가 아닌 것에 주의!) 매개변수 리스트 안에 같은 이름이 두번 쓰이면 안되기에 생긴 분류입니다. 함수 정의에는 각각의 매개변수에 그냥 block scope가 적용됩니다.

progcom의 이미지

lsj0713 wrote:

C99에서는 Variable Length Array 라는 놈이 새로이 추가되었습니다. 말 그대로 가변 길이 배열입니다. 즉 배열을 정의할 때 배열의 첨자로 변수를 사용하는 것이 가능합니다.

(중략)

재미있는 것은 C(정확히는 C99)에는 VLA가 있는데 C++에는 없다는 것과, C의 문법에는 constant expression이 없는데 C++에는 있다는 것입니다. C에서는 배열을 선언할 때 첨자로 expression이 들어가지만 그것에 대해 정수형이어야 한다고 제한해 놓은 데 비해서, C++에서는 문법 차원에서 constant expression이 들어가야 한다고 제한하고 있습니다.

근데 이것이 어디에 쓸모가 있는 내용이냐고요? 그냥 재미일 뿐입니다. :-)

C++의 현행 표준은 98년에 완성되었고, C99는 그 이후에 나왔기 때문이지요. 즉, 현재의 C++ 표준(C++98)은 C89에 기반하고 있으니, C99에서 새로 추가된 개념은 존재하지 않는 거죠.
재미있지요?

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.