const 변수를 사용하여 C에서 배열 크기를 선언할 수 있습니까?
다음 코드가 에러를 발생시키는 이유는 무엇입니까?
const int a = 5;
int b[a]={1,2,3,4,5};
또, 「const」키워드를 지정하지 않고 위의 코드를 컴파일 하려고 했을 때에도, 같은 에러가 발생했습니다.
int a = 5;
int b[a]={1,2,3,4,5};
그것은 왜 그럴까?내가 여기서 하고 있는 실수는 무엇인가?
그리고 또 다른 질문입니다.상수가 코드의 실제 값으로 대체되는 경우, 예를 들어 변수 const int x = 5를 선언하면 변수 x에 대해 RAM에 할당된 메모리가 없지만 ROM의 상수 변수 영역에는 값 5가 유지되고 x가 코드 내에 나타나는 모든 곳에서 값 5로 단순히 대체된다는 것을 알 수 있습니다.하지만 언제 이런 일이 일어날까요?컴파일 시간?부팅 시간?전처리 시간?
PS: 임베디드 C(마이크로컨트롤러 등에서 동작)를 말하는 것이지 데스크톱에서 동작하는 C를 말하는 것은 아닙니다.따라서 임베디드 시스템에는 반드시 ROM(Flash, EEPROM...)이 있습니다.그러면 어떻게 될까요?
식식사는,const
읽기 전용의 오칭입니다. const
될 수 . 를 들어, 변수 값을 해도 문제 . 예를 들어, 선언하는 것은 완벽하게 괜찮습니다.
const volatile int timer_tick_register; /* A CPU register. */
읽을 수 있고 읽을 때마다 다른 값을 얻을 수 있지만 쓸 수는 없습니다. 취급하고 있습니다.const
정규화된 개체가 어레이 크기에 적합하지 않은 상수 표현식입니다.
주요 : VLA 2 2 2 :enum
매크로( 「」)
익명으로 enum
:
enum { N = 5 };
int is[N];
예를 들어 다음과 같습니다.
#include <stdio.h>
enum { N = 5 };
char is[N];
int main(void) {
printf("%ju\n", sizeof(is));
}
열거형 멤버는 상수 표현식이기 때문에 작동합니다. 열거형 멤버는 ANSI-C의 배열 크기일 수 있습니까?
매크로 사용 시:
#define N 5
int is[N];
의 enum
는 s라고 하는 것입니다.enum
에는 범위가 있으며 컴파일 스텝의 일부이기 때문에 오류 메시지가 개선될 수도 있습니다.
" " " " " " " " " " " " " " " " " )을 더 잘 할 수 입니다.#define N 1
»#define N 1u
을(를) 사용하는 동안,enum
는 일부 구현 정의 유형에 고정되어 있습니다.항상 size of(enum) == size of(int)입니까?하지만 이 경우에는 크게 문제가 되지 않습니다.
Ubuntu 21.04, GCC 10.3.0에서 테스트 ,gcc -ggdb3 -O0 -std=c99 -Wall -Wextra -pedantic -o main.out main.c
.
VLA를 회피하는 이유
- C89에는 없고, C11에서는 옵션입니다.
- 오버헤드가 발생할 수 있습니다.가변 길이 어레이 사용에 대한 오버헤드가 있습니까?(조금씩)
그것은 단순히 언어의 한계일 뿐이다.정적으로 바인드된 어레이의 크기는 일정한 식이어야 하며, 불행히도 C에서는 문자 그대로의 상수 또는sizeof
표현 같은 것, 그러나 a는 아니다.const
변수syslog 변수.
(Simon이 지적한 바와 같이 C99 이후 런타임 바운딩 어레이 또는 "가변 길이 어레이"도 존재하며, 그 크기는 모든 변수의 값으로 지정할 수 있습니다.하지만 그건 다른 동물이야.)
에서는 . C++에서는 이 다릅니다.static const int
표현이며, C++11을 도 합니다.constexpr
"컴파일 시 합리적으로 결정될 수 있는" 값을 가진 더 많은 것들을 포함하는 상수 표현을 훨씬 더 일반적으로 사용할 수 있도록 합니다.
아마도 언급할 가치가 있을 것이다, 여기서 당신은 사용할 수 있다.
int b[] = {1, 4, 5};
다수의 요소가 필요한 경우
size_t sz = sizeof(b)/sizeof(b[0]);
상수, 플래시 또는 RAM을 저장할 위치를 결정하는 것은 툴 체인에 달려 있다고 생각합니다.
편집: Wikipedia에서 C11이 가변 길이 어레이를 옵션 기능으로 격하한 것을 읽어 보십시오. (Doh!투고의 전반부는 그다지 유용하지 않을 수 있지만 후반부는 다른 질문에 대한 답변입니다.
Kerrek SB의 투고에 덧붙여, C99(ISO/IEC 9899:1999)는 가변 길이 어레이의 개념을 채용하고 있습니다.이 규격은 다음과 같은 예를 제시합니다.
#include <stddef.h>
size_t fsize3(int n)
{
char b[n+3]; // variable length array
return sizeof b; // execution time sizeof
}
sizeof
연산자는 다음과 같이 확장됩니다.
sizeof 연산자는 피연산자의 크기(바이트 단위)를 산출합니다.이 값은 식 또는 괄호로 둘러싸인 형식의 이름입니다.크기는 오퍼랜드의 유형에 따라 결정됩니다.결과는 정수입니다.피연산자의 유형이 가변 길이 배열 유형인 경우 피연산자가 평가되고 그렇지 않은 경우 피연산자는 평가되지 않으며 결과는 정수 정수입니다.
또 다른 좋은 예는 위키피디아에서 찾을 수 있다.
정적으로 선언된 배열은 가변 길이 배열이 될 수 없습니다.
다른 질문들에 대해서:
Q: 코드에서 상수가 실제 값으로 대체되는 것은 언제입니까?
상수가 상수 변수인 경우, 상수는 "대체"되지 않고 항상 메모리 영역으로 액세스할 수 있습니다. 연산자 "Address-of"가&
여전히 변수와 함께 작업해야 합니다.단, 변수 주소가 사용되지 않으면 "대체"되어 메모리가 할당되지 않습니다.C:
구현에서는 휘발성이 없는 const 객체를 읽기 전용 영역에 배치할 수 있습니다.게다가 주소가 전혀 사용되지 않는 경우에는, 실장에서는, 그러한 오브젝트에 스토리지를 할당할 필요가 없습니다.
다음 질문...
Q: RAM에는 변수x에 대해 메모리가 할당되어 있지 않지만 ROM의 상수 변수 영역에는 값 5가 할당되어 있습니다.
이것은 시스템에 따라 다릅니다.ROM 가 있고, 컴파일러가 ROM 의 위치를 알고 있는 경우는, ROM 에 배치되어 있는 경우가 있습니다.ROM이 없는 경우 컴파일러(링커)의 유일한 선택지는 RAM입니다.
Q: x는 코드에 x가 표시될 때마다 값 5로 대체됩니다.하지만 언제 이런 일이 일어날까요?컴파일 시간?부팅 시간?전처리 시간?
앞에서 설명한 바와 같이, 이는 상수가 어떻게 사용되는지에 따라 달라집니다.const 변수의 주소가 전혀 사용되지 않고 컴파일러가 충분히 영리하다면 컴파일러는 컴필레이션 시에 사용합니다.그렇지 않으면 "치환"은 발생하지 않으며 메모리 내의 위치가 있는 값입니다.이 경우 메모리 내의 변수는 링크 시에 배치됩니다.전처리 중에는 발생하지 않습니다.
언급URL : https://stackoverflow.com/questions/18848537/can-a-const-variable-be-used-to-declare-the-size-of-an-array-in-c
'programing' 카테고리의 다른 글
rand() + rand()는 왜 음수를 생성합니까? (0) | 2022.08.14 |
---|---|
접속 거부 오류의 원인은 무엇입니까? (0) | 2022.08.14 |
생성된 이벤트의 워치 속성과 $watch 메서드의 차이(Vue) (0) | 2022.08.14 |
fork()에 의해 작성된 프로세스 간에 메모리를 공유하려면 어떻게 해야 합니까? (0) | 2022.08.14 |
v-expansion-panel-content에 대한 동적 콘텐츠 (0) | 2022.08.14 |