전역 변수로 결정된 크기로 배열을 만들 수 없는 이유는 무엇입니까?
왜 레어사는이유하용를이▁the유▁why이▁does.a
글로벌 변수에 의해 초기화되지 않음size
?
#include<stdio.h>
int size = 5;
int main()
{
int a[size] = {1, 2, 3, 4, 5};
printf("%d", a[0]);
return 0;
}
컴파일 오류는 다음과 같이 표시됩니다.
변수 크기의 개체가 초기화되지 않을 수 있습니다.
제 말에 따르면, 어레이는 다음과 같이 초기화되어야 합니다.size
.
그리고 (가능하다면) 글로벌 변수를 사용하는 것을 고집한다면 어떤 대답이 있을까요?
C99, 6.7.8/3에서:
초기화할 엔티티 유형은 크기를 알 수 없는 배열이거나 가변 길이 배열 유형이 아닌 개체 유형이어야 합니다.
6.6/2:
런타임이 아닌 변환 중에 상수 식을 평가할 수 있습니다.
6.6/6:
정수 상수 식은 정수 유형을 가져야 하며 정수 상수, 열거 상수, 문자 상수, 결과가 정수 상수인 식의 크기 및 캐스트의 직접 피연산자인 부동 상수인 피연산자만 있어야 합니다.
6.7.5.2/4:
크기가 정수 상수 식이고 요소 유형의 크기가 알려진 상수인 경우 배열 유형은 가변 길이 배열 유형이 아니며, 그렇지 않으면 배열 유형은 가변 길이 배열 유형입니다.
a
는 가변 유형을 있는데, 는 변수길 사유용합다 때문입니다. 이유:size
정수 상수 식이 아닙니다.따라서 이니셜라이저 목록을 가질 수 없습니다.
C90에는 VLA가 없기 때문에 코드가 불법입니다.
C++에는 VLA도 없지만, 당신은 그것을 만들 수 있습니다.size
a const int
C에서는 C++을 할 수 const int
ICE의 변수입니다.C에서는 할 수 없습니다.
아마도 당신은 의도하지 않았을 것입니다.a
길이가 가변적이므로 필요한 것은 다음과 같습니다.
#define size 5
만약 당신이 정말로 의도했다면.a
다양한 길이를 가지려면 다음과 같은 작업을 수행할 수 있습니다.
int a[size];
int initlen = size;
if (initlen > 5) initlen = 5;
memcpy(a, (int[]){1,2,3,4,5}, initlen*sizeof(int));
또는 다음과 같습니다.
int a[size];
for (int i = 0; i < size && i < 5; ++i) {
a[i] = i+1;
}
하지만 size != 5의 경우 "해야 할" 일을 여기서 말하기는 어렵습니다. 가변 길이 배열에 고정 크기의 초기 값을 지정하는 것은 정말 말이 되지 않습니다.
이니셜라이저를 제공하는 경우 컴파일러에 배열 크기를 알려줄 필요가 없습니다.컴파일러는 초기화하는 요소의 수에 따라 크기를 파악합니다.
int a[] = {1,2,3,4,5};
의 전체 를 바이트 단위로 .sizeof(a)
의 원소 .sizeof(a[0])
:
int size = sizeof(a) / sizeof(a[0]);
컴파일러는 main()이 제어를 받을 때까지 크기 값이 여전히 5라고 가정할 수 없습니다.기존 C 프로젝트에서 참 상수를 사용하려면 다음을 사용합니다.
#define size 5
size
는 변수이며, C에서는 이와 같은 변수 크기의 배열을 선언할 수 없습니다(편집: C99에서는 이러한 배열을 초기화하지 않고 선언할 수 있습니다).크기가 변수인 배열을 생성하려면 malloc를 사용하거나 크기를 상수로 만듭니다.
컴파일러가 C99 호환되지 않는 것 같습니다...말이 나와서 말인데, 어떤 컴파일러를 사용하고 계십니까?GCC인 경우 '-std=c99' 스위치를 통과해야 합니다. C99 이전 컴파일러를 사용하는 경우 해당 명령문은 불법입니다. 그렇다면 다음을 수행하십시오.
본전에서inta[5]={1,2,3,4,5};printf("%d",a[0];반환 0;}
C99 이전 표준 컴파일러에서는 변수 대신 상수를 사용합니다.
편집: C99 표준에 대한 자세한 내용은 여기에서 확인할 수 있습니다...그리고 여기..
컴파일러는 배열을 선언하는 동안 배열의 크기를 알아야 합니다.배열의 크기는 선언 후에도 변하지 않기 때문입니다.배열의 크기를 변수에 넣으면 프로그램이 실행될 때 해당 변수의 값이 변경될 것이라고 상상할 수 있습니다.이 경우 컴파일러는 이 배열에 추가 메모리를 할당해야 합니다.이 경우 어레이가 스택에 할당된 정적 데이터 구조이기 때문에 이 작업을 수행할 수 없습니다.이것이 도움이 되기를 바랍니다.
일반적으로 변수에 의해 크기가 결정된 배열을 생성할 수 없는 것과 동일한 이유로 전역적으로 변수 크기의 배열을 생성할 수 없습니다.그 이유는 C++이 수동 메모리 관리를 가능하게 하기 때문인데, 솔직히 말해서 우리가 이 언어를 배우는 이유이고, 메모리를 할당할 때 우리는 두 가지 유형의 장점과 단점과 우리가 그것으로 무엇을 할 수 있는지를 염두에 두어야 합니다.
스택 메모리는 문자 그대로 스택 데이터 구조를 구현합니다.크기가 고정되어 있고(제가 알기로는 몇 메가바이트), 어떤 데이터라도 스택에 넣으면 맨 위로 밀어넣습니다.스택은 제한된 시간 동안만 존재해야 하는 범위의 변수에 완벽하게 적합합니다. 즉, 스택이 }을(를) 보는 즉시 사라집니다.스택은 모든 변수를 그룹화하는 단위로 함수를 사용하며, 함수(메인 포함)를 호출할 때마다 이 함수가 사용하는 총 메모리 양, 즉 할당하는 모든 변수의 합계를 푸시합니다.이 전체 크기를 스택 프레임이라고 하며 일정해야 합니다.그렇지 않으면 스택에서 어레이를 동적으로 할당하는 경우:
int size;
scanf("%d", %size);
int array[size];
어레이와 해당 스택 프레임에 대응하여 얼마나 많은 공간을 예약해야 하는지 알 수 없으므로 이 작업은 금지된 작업입니다.그러나 다음과 같이 상수 및 상수 식을 사용하여 초기화할 수 있습니다.
constexprt int getSize(int n){
return n * 2; //This can be anything, I just multiplied to get arbitrary value.
}
const int size = 45;
int constantArray[size]; //Works
int constantExpressionArray[getSize(2)]; //Also works
상수가 작동하는 이유는 항상 동일하고 알려진 크기를 보장하며, 메모리 공간을 차지하지 않고 컴파일러가 모든 상수 호출을 각각의 값으로 대체하기 때문입니다.상수 표현식은 컴파일 시간에 실행되는 함수이기도 합니다. 즉, 모든 값을 알고 있어야 합니다. 그런 다음 결과(항상 동일해야 함)를 호출에 대입하면 두 경우 모두 배열 크기가 동일해집니다(첫 번째는 45개, 두 번째는 4개).
실행할 때마다 크기가 동일한 배열을 사용하려면 동적으로 할당해야 합니다.
int* dynamicArray = new int[variableSize];
또는 사용std::vector
:
std::vector<int> dynamicArray(variableSize);
후자의 경우 설정됩니다.variableSize
크기 조정을 위해 초과해야 하는 어레이의 길이를 나타내는 용량입니다.책임감 있게 사용하면 단순히 그 아래의 어레이를 사용하게 되고 메모리를 동적으로 할당하고 기능 간에 점프를 함으로써 부과되는 성능 저하만 겪게 됩니다.
#include<stdio.h>
/* int size=5; */
#define size 5 /* use this instead*/
/*OR*/
int a[size]={1,2,3,4,5}; /* this*/
int main()
{
int a[size]={1,2,3,4,5};
printf("%d",a[0]);
return 0;
}
int size
는 것을 의미합니다.size
변수이고 C는 변수를 허용하지 않습니다.size
배열
VS2008을 사용하고 있습니다.
const int size=5;
허용한다
int a[size]={1,2,3,4,5};
언급URL : https://stackoverflow.com/questions/2427336/why-cant-i-create-an-array-with-size-determined-by-a-global-variable
'code' 카테고리의 다른 글
네트워크 어댑터를 재설정하는 명령/Powershell 스크립트 (0) | 2023.08.21 |
---|---|
화면 밖으로 확장되는 구속조건 레이아웃 내부의 Wrap_content 뷰 (0) | 2023.08.21 |
플렉스 컨테이너의 텍스트가 IE11에서 랩되지 않음 (0) | 2023.08.21 |
Javascript를 사용한 부분적인 포스트백 (0) | 2023.08.21 |
Swift UI에서 16진수 색상 사용 (0) | 2023.08.21 |