나는 종종 C 및 C ++ 코드에서 다음과 같은 규칙을 봅니다.
some_type val;
val = something;
some_type *ptr = NULL;
ptr = &something_else;
대신에
some_type val = something;
some_type *ptr = &something_else;
처음에는 이것이 범위의 맨 위에 모든 지역 변수를 선언해야했던 시절부터 남은 습관이라고 가정했습니다. 그러나 나는 베테랑 개발자의 습관을 너무 빨리 무시하지 않는 법을 배웠습니다. 그렇다면 한 줄로 선언하고 나중에 할당해야 할 합당한 이유가 있습니까?
답변
씨
C89에서 모든 선언 은 범위 ( { ... }
) 의 시작 부분에 있어야 했지만이 요구 사항은 빠르게 떨어졌습니다 (먼저 컴파일러 확장과 표준이 있음).
C ++
이 예제는 동일하지 않습니다. 기본 some_type val = something;
생성자를 val = something;
호출 한 다음 operator=
함수 를 호출하는 동안 복사 생성자를 호출합니다 . 이 차이는 종종 중요합니다.
버릇
어떤 사람들은 변수를 먼저 선언하고 나중에 한 지점에서 선언하고 다른 지점에서 정의를 사용하여 코드를 다시 포맷하는 경우 나중에 변수를 선언하는 것을 선호합니다.
포인터에 관해서는, 어떤 사람들은 포인터로 무엇을 하든지 NULL
또는 nullptr
에 대한 모든 포인터를 초기화하는 습관을 가지고 있습니다 .
답변
질문 C와 C ++에 동시에 태그를 달았지만이 언어에서는 답이 크게 다릅니다.
먼저, 질문 제목의 문구가 잘못되었습니다 (또는 더 정확하게는 질문 자체와 관련이 없음). 두 예제 모두에서 변수는 한 줄에 동시에 선언되고 정의 됩니다. 예제의 차이점은 첫 번째 변수에서 변수가 초기화되지 않거나 더미 값으로 초기화 된 다음 나중에 의미있는 값 이 할당 된다는 것입니다 . 두 번째 예에서 변수는 즉시 초기화 됩니다.
둘째, C ++ 언어에서 @nightcracker가 그의 답변에서 언급 했듯이이 두 구성은 의미 상 다릅니다. 첫 번째는 초기화에 의존하고 두 번째는 할당에 의존합니다. C ++에서 이러한 작업은 오버로드 가능하므로 잠재적으로 다른 결과를 초래할 수 있습니다 (비록 동일한 초기화 및 할당의 오버로드를 생성하는 것은 좋지 않습니다).
원래 표준 C 언어 (C89 / 90)에서 블록 중간에 변수를 선언하는 것은 불법이므로 블록의 시작 부분에 초기화되지 않은 (또는 더미 값으로 초기화 된) 변수가 선언 된 후 의미있는 변수가 할당 될 수 있습니다 나중에 의미있는 값을 사용할 수있게됩니다.
C99 언어에서는 블록 중간에 변수를 선언하는 것이 좋습니다 (C ++에서와 같이). 첫 번째 접근 방식은 선언 시점에서 이니셜 라이저를 알 수없는 특정 상황에서만 필요합니다. (이것은 C ++에도 적용됩니다).
답변
“로컬 선언”시대에 남은 오래된 습관이라고 생각합니다. 따라서 귀하의 질문에 대한 답변으로 : 아니요 좋은 이유가 있다고 생각하지 않습니다. 나는 그것을 직접하지 않습니다.
답변
나는에서 그것에 대해 뭔가 말했다 내 대답 에 Helium3하여 질문을 .
기본적으로 변경된 내용을 쉽게 볼 수있는 시각적 도구라고합니다.
if (a == 0) {
struct whatever *myobject = 0;
/* did `myobject` (the pointer) get assigned?
** or was it `*myobject` (the struct)? */
}
과
if (a == 0) {
struct whatever *myobject;
myobject = 0;
/* `myobject` (the pointer) got assigned */
}
답변
다른 답변은 꽤 좋습니다. C에는 이것에 관한 몇 가지 역사가 있습니다. C ++에는 생성자와 할당 연산자 사이에 차이가 있습니다.
아무도 추가 요점에 대해 언급하지 않았습니다. 선언을 변수 사용과 분리하여 유지하는 것이 때로는 더 읽기 쉽습니다.
시각적으로 말하자면, 코드를 읽을 때 변수의 유형 및 이름과 같은 더 평범한 인공물은 당신에게 튀어 나와 있지 않습니다. 그것은 당신이 일반적으로 가장 관심이 있고, 쳐다 보는 데 많은 시간을 할애 하는 진술 이므로 나머지를 한눈에 보는 경향이 있습니다.
동일한 유형의 공간에서 일부 유형, 이름 및 할당이 진행되는 경우 약간의 정보 과부하가 발생합니다. 또한, 내가 일반적으로 살펴 보는 공간에서 중요한 것이 진행되고 있음을 의미합니다.
말하기에는 다소 직관적이지 않을 수 있지만 소스가 더 수직 공간을 차지하게하면 더 좋을 수 있습니다. 나는 이것이 좁은 수직 공간에서 엄청난 양의 포인터 산술 및 할당을 수행하는 잼으로 채워진 줄을 작성해서는 안되는 이유와 유사하다고 생각합니다. 언어가 그러한 것들을 피할 수 있다고해서 그렇게해야한다는 의미는 아닙니다. 항상. 🙂
답변
C에서, 이것은 C ++에서와 달리 함수가 시작될 때 변수가 함수 본문의 어느 곳에서나 선언 될 수있을 때와 같이 함수 시작시 선언되어야했기 때문에 표준 관행이었습니다. 포인터가 가비지 없음을 가리 키도록하기 때문에 포인터가 0 또는 NULL로 설정되었습니다. 그렇지 않으면 내가 생각할 수있는 중요한 이점이 없으므로 누군가가 그렇게 할 수 있습니다.
답변
변수 정의 지역화 및 의미있는 초기화에 대한 장점 :
-
변수가 코드에 처음 나타날 때 습관적으로 의미있는 값이 할당되면 (같은 관점에서 또 다른 관점 : 의미있는 값이 유효 할 때까지 모양을 지연시키는 경우) 실수로 의미가 없거나 초기화되지 않은 값 으로 사용될 가능성은 없습니다 ( 조건문, 단락 평가, 예외 등으로 인해 실수로 일부 초기화가 우회되는 경우 쉽게 발생할 수 있음)
-
더 효율적일 수있다
- 초기 값 설정의 오버 헤드를 피합니다 (기본 구성 또는 NULL과 같은 일부 센티넬 값으로 초기화)
operator=
때로는 효율성이 떨어지고 임시 객체가 필요할 수 있습니다.- 때때로 (인라인 함수의 경우) 옵티마이 저가 일부 / 모든 비 효율성을 제거 할 수 있음
-
차례로 변수 범위를 최소화하면 범위에서 동시에 평균 변수 수가 최소화 됩니다 .
- 그것은하게 쉽게 정신적으로 추적하는 범위에서 변수, 그 변수에 영향을 줄 수있는 실행 흐름과 문 및 가치의 수입을
- 최소한 복잡하고 불투명 한 객체 의 경우 프로그램의 리소스 사용량 (힙, 스레드, 공유 메모리, 설명자) 이 줄어 듭니다.
-
정의에서 변수 이름을 반복하지 않고 초기 의미있는 할당에서 때때로 더 간결합니다.
-
참조와 같은 특정 유형 및 객체를 원할 때 필요
const
변수 정의 그룹화를위한 인수 :
-
때로는 여러 변수 유형을 고려하는 것이 편리하고 간결 합니다.
the_same_type v1, v2, v3;
(이유가 유형 이름이 너무 길거나 복잡하기 때문에
typedef
때로는 더 좋을 수도 있습니다) -
때로는 일부 작업에 관련된 변수 세트 및 유형을 강조하기 위해 사용법과 독립적으로 변수를 그룹화하는 것이 바람직합니다.
type v1;
type v2;
type v3;
이것은 유형의 공통성을 강조하고 복사 붙여 넣기,
//
주석 달기 등 을 용이하게하는 줄 당 변수를 고수하면서 변경하기가 조금 더 쉽습니다 .
프로그래밍의 경우와 마찬가지로 대부분의 상황에서 한 가지 실습에는 분명한 경험적 이점이있을 수 있지만, 다른 한 가지 실습은 실제로 몇 가지 경우보다 훨씬 더 나을 수 있습니다.