error C2057: expected constant expression이 발생하면서 계속해서 배열의 크기가 잡히지 않는 것 같습니다.
while(1)
{
cout << "제작할 배열의 크기를 결정해 주세요. (3~13의 홀수)\n";
cout << "배열의 크기 => ";
cin >> M;
if(M > 13)
cout << "크기 13 초과 입니다. 다시 입력하여 주십시오.\n";
else if(M < 3)
cout << "크기 3 미만 입니다. 다시 입력하여 주십시오.\n";
else if(M/2 == 0)
cout << "짝수 입니다. 다시 입력하여 주십시오.\n";
else
{
cout << "크기 M의 배열을 제작합니다.\n";
break;
}
}
int arr[M][M]={0}; // 전체 초기화(0으로)
이 코드에서 어떤 부분을 수정해야 배열의 전체 크기를 지정할 수 있는지 해결책을 알려주신다면 감사하겠습니다.
(아무래도 while문을 탈출하면서 M값이 사라지거나, M값이 상수로 처리가 되지 않아서 인것 같은데, 맞는 해석인지 모르겠습니다.)
ps. 아무래도 포인터를 사용해서 강제로 비상수를 상수로 전환한다 던지 하는 테크닉이 필요한 걸까요?
능력자분들의 도움을 구합니다.. 염치 없지만 죄송하게도 부탁드립니다.. (조교님이 답장을 안주시네요..)
================================>
1.
정적배열은 컴파일할때 그 숫자가 정해져있어야합니다. 저렇게 유동성이 있는 M이란 변수는 사용할수 없는것이지요.
그래서 동적배열이 있는겁니다.
C행 R열의 2차원 배열을 사용하고싶으시다면
int *mat = new mat[C*R];
로 정의후 x,y에 데이터를 넣으려면
mat[C*y + x] = data; 이런식으로 대입하시면 됩니다.
2.
일단 잘못된 부분은 int arr[M][M]={0}; 입니다.
C++ 은 안쓴지 꽤 오래 돼서 기억이 안나는데 배열을 이런식 동적할당하려면 C 에선 malloc 으로 할당해야 합니다.
레가테스 (가입:2011-12-12 방문:2058)
2013-03-17 00:59:25 추천/반대:1/0
말록으로 넣고 프리로 지워줘야 합니다
안그럼 데이터가 남아 부려요
3.
아 첫댓글 잘못적었네요
int *mat = new mat[C*R]; 가 아니라 int *mat = new int[C*R]; 에요~
글구 배열 다썼으면 deIete []mat;해주는것도 잊지마시구요
4.
C++을 사용하실 거라면 new와 d.elete를 사용해야 합니다.
new와 d.elete는 C++ 언어 자체에 정의된 문법인 반면, malloc과 free는 OS에서 제공하는 함수입니다. 따라서 전자는 설계와 구현의 괴리가 후자보다 덜합니다.
가령 pt = new C[10]은 type C를 위한 memory를 할당하고 할당된 영역의 pointer를 리턴합니다.
d.elete [] pt는 pt에 할당된 영역을 해제합니다.
반면 pt = malloc(sizeof(int))은 OS가 현재 user process의 virtual memory의 heap memory 영역에서 4 bytes의 memory를 할당하고, 그 start address를 리턴합니다.
free(pt)는 OS가 현재 user process의 virtual memory의 heap memory 영역에서 pt를 start address로 가지는 할당된 영역을 해제하도록 합니다.
전자의 경우 원래 의도한 바만 잘 포장되어 있지만, 후자는 과도하게 OS detail을 알 필요가 있습니다.
그리고 class를 사용할 때는 memory할당 후에 constructor를 호출해야 하고, 해제 후에 destructor를 호출해야 하는데, 전자는 이것을 자동으로 해 주지만 후자는 그렇지 않습니다. (물론 후자도 추가로 memory할당 없이 new를 사용하는 굉장히 보기 드문 문법을 사용하면 되긴 합니다.)
5.
그리고 상수와 비상수를 알고 계시는 것으로 보아 어느 정도 배운 것은 있어 보이는데, 코드와 질문 내용을 봐선 중요한 핵심을 뭔가 놓치고 있는 게 아닌가 생각됩니다.
6.
포인터와 동적 할당에 대해 공부하려면 heap memory에 대해 알아두는 게 좋습니다.
7.
- 정적인 배열선언은 컴파일 시 해석되어야 하므로 상수값이 들어가야 합니다.
- 동적인 배열을 사용하려면 여러가지 선택이 있습니다.
(1) vector 를 쓰거나 (가장 C++ 적인 방법이겠지만 STL 에 대해 배웠다면 )
(2) new/d.elete 혹은 new[] d.elete[] 를 쓰거나
(3) malloc/free 를 쓰거나 ( <cstdio> 헤더를 인클루드 한다. 단 클래스 타입이라면 생성자/소멸자를 호출안하게 되므로 new/d.elete 를 쓴다 )
- 또, 이중 배열의 관리를 위해 다음과 같은 전략이 있습니다. (new[] / d.elete[] 인 경우지만 vector 나 malloc 을 쓰는 경우도 유사함)
(1) 이중 포인터를 사용해서 int** array = new (int*[M]); for (int i=0; i<M; i++) array[i] = new int[M]; 와 같이 선언한다.
(단 해제시에도 for (int i=0; i<M; i++) d.elete [] array[i]; d.elete [] array; 처럼 각각의 int[M] 할당영역을 해제 후 , array 를 해제해줘야 한다.
(2) 스윗초코님처럼 이중배열처럼 사용하는 법 ( 이중포인터 관리가 귀찮고 불편한 점이 있으므로 사용이 쉽다.)
단, C*y + x 처럼 배열의 인자값계산을 잘 사용해야 한다.
8.
C99에 추가된 기능 중에 "가변 길이 배열(VLA: variable-length array)" 이라는 기능이 있어서 배열을 선언 할 때 malloc이나 new가 아닌 변수를 사용 하더라도 배열 생성이 가능합니다.
C99에 추가된 내용은 위키(http://ko.wikipedia.org/wiki/C99) 참고하세요.
다만 사용하시는 IDE가 VS6.0 이라고 하시니 지원을 안 할 듯 싶습니다.
(VS2012 에서도 가변길이배열을 지원하지 않는 듯 싶습니다.(http://msdn.microsoft.com/en-us/library/zb1574zs.aspx))
굳이 VS6.0을 사용해야되는 상황이 아니시라면 gcc 최신 버전을 다운 받으시면 다음과 같은 코드가 정상 동작 합니다.
#include <iostream>
using namespace std;
int main()
{
int input = 0;
cin >> input;
int vla[input];
for (int i = 0; i < input; i++) {
vla[i] = i;
}
for (int i = 0; i < input; i++) {
cout << vla[i];
}
return 0;
}
컴파일러 : g++ (GCC) 4.6.2
> g++ vla_cpp.cpp -o vla_cpp.exe
또는
#include <stdio.h>
int main()
{
int input = 0;
scanf("%d", &input);
int vla[input];
for (int i = 0; i < input; i++) {
vla[i] = i;
}
for (int i = 0; i < input; i++) {
printf("%d\n", vla[i]);
}
return 0;
}
컴파일러 gcc (GCC) 4.6.2
> gcc vla.c -o vla.exe -std=c99
http://lejewk.tistory.com/69
C++에서 2차원 동적할당하기.
#include<iostream> int main(){ using namespace std;
int i,a=5,b=5; int **pt = new int*[a]; //5행만큼 동적할당.
for (i=0; i<a; i++){ //열의 수만큼 각 행에 동적으로 메모리 공간을 할당함 */
pt[i] = new int[b]; }
for(i=0; i<a; i++){ delete [] pt[i]; //열에 해당하는 메모리공간 해제 } delete [] pt; //행에 해당하는 메모리 공간 해제
return 0; }
C와 비교해서 거의 달라진게 없다. 그리고 2차원 동적할당이라는게 어디에 쓰이는지 잘모르겟다능 ㄷㄷ; 그저 구조체에 할당하는것밖에는 잘모르겟다..; ㅋㅋㅋ
2차원 동적할당의 원리는 2차원 포인터에 행을 깔아놓고 그 행의 원소에 다시한번 동적할당을 하는건데
그림판 작이라 이해점;;ㅋ
마치 이런모양과도 같다.
원하는 만큼의 길이를 할당할수도있다. 으..; 이런 형태의 배열을 내가 1학년때 물어봤는데; 그땐 너무 몰랏다능;;
!! 중요한거는 비 정상적인.. 그러니까 꼭 저렇게 직사각형모양이 아니라 자기가 원하는만큼의 포인터배열을 할당시켜도