C ++에서 함수 선언 후에 세미콜론 ( ';')이 필요하지 않습니까?


174

나는 최근에 중간 프로그래밍 테스트를 받았고 내가 잘못한 질문 중 하나는 다음과 같습니다.

함수 선언 후에 세미콜론 ( ';')이 필요하지 않습니다.

참 또는 거짓.

나는 "false"를 선택했다 (그리고 내가 미쳐 가고 있다고 생각하기 때문에 내가 틀렸다면 수정하십시오), 함수 선언 은 정의하기 전에 (코드 상단에) 작성하므로 컴파일러는 함수를 알 수 있습니다 호출하기 전에 호출하면 함수 정의 가 함수 전체를 구성하는 것입니다.

즉,

선언:

int func();

정의:

int func() {
  return 1;
}

이것에 대한 대답이 거짓이 아니어야합니까?


41
정의는 또한 선언이다. 그러나 나는 당신의 대답이 옳았다 고 말할 것입니다.

216
까다로운 질식 문제이며 잘 프로그래밍하는 사람의 능력과는 관련이 없습니다.
phonetagger

40
나는 항상 두 가지 부정적인 결과를 혼란스럽게 만드는 질문을 찾습니다. 내 생각에, 그러한 질문은 학생들을 여행하도록 설계되었습니다. 다음과 같은 방식으로 질문을 구성 할 수없는 이유는 다음과 같습니다. "함수 선언 후 항상 세미콜론 ( ';')이 필요합니다. 참 또는 거짓." : /
Algirdas Preidžius

18
@phonetagger이 모든 혼란은 질문이 얼마나 나쁜지 보여줍니다.
François Andrieux

34
Hanlon 's Razor 는 시험의 저자가 "선언"과 "정의"를 혼합 한 것으로 제안합니다.
Sneftel 2019

답변:


161

한 단계에서 함수를 선언하고 정의하는 상황이있을 수 있습니다 (예 : 함수 정의 지점에 함수 정의를 포함시키는 경우). 그래서 기술적으로 나는 사실이 정확 가정합니다. 그러나 질문은 당신이 한 것처럼 대답했을 것입니다.


10
나는 당신이 준 이유 때문에 진실이 맞지 않다고 주장합니다. 세미콜론이 필요한 경우가 있으면 거짓입니다 (또는 사실이 아닙니다). 진실은 나에게 절대적입니다. 필요한 경우가 분명한 경우에는 말할 수 없습니다.
I Funball 2019

16
@IFunball 좋은 논증. 어리석은 자연 언어. 문장;로 읽을 수 있습니다 "A 세미콜론 ( '') 함수 선언 후 필요하지 않습니다" "A 세미콜론 ( ';')되지 않는 (적) 함수 선언 후 필요"또는 (A 세미콜론 "로 ';' )는 항상 함수 선언 후에 필요 하지 않습니다 ". 진술을 참 또는 거짓으로 한정할지 여부는 해석 선택에 달려 있습니다. 엄격히 말해서 그 질문은 불분명하므로 명확한 대답이 없습니다.
피터-복원 모니카

6
@IFunball 더 이상의 맥락과 언어 변호사라는 진술이없는 "선언"은 일반적으로 "정의되지 않은 선언"을 의미하는 것으로 이해되기 때문입니다. 그 질문은 불공평했다.
궤도에서 가벼움 레이스

2
테스트 할 내용을 알고있는 사람에게 불명확 한 모든 시험 문제는 버그가 있습니다.
Nat

2
영어에 정의되지 않은 행동 조항을 추가해야 할 것 같습니다.
Nick Mertin

147

"정의는 선언이기도합니다"이외에 다음은 합법적 인 C ++입니다.

int f(), g();

이 두 가지 기능을 선언 f하고 g, 인수없이와의 리턴 타입 모두 int, 그러나의 정의는 f세미콜론 (즉시) 다음되지 않습니다. 마찬가지로 이것은 합법적입니다.

int f(), i = 42;

그러나 실제로 이러한 경우 세미콜론을 완전히 생략하는 것은 허용되지 않으므로 다음 세미콜론없이 선언의 예로 사용 된 경우 다소 놀라운 것입니다. 실제로 다음은 불법입니다.

void *p, f() {}

(단순한) 함수 선언 이외의 함수 정의 는 다른 선언 또는 정의와 동일한 type-specifier에 결합 될 수 없습니다 . (이것이 합법적이라면 a void *p와 a 모두를 정의 할 것 void f() {}입니다.)

어쨌든 이것은 중간 프로그래밍 테스트에 있어서는 안되는 "gotcha"유형의 질문 인 것 같습니다.

(오, 그런데 실제로와 같은 코드를 작성하지 마십시오 int f(), i = 42;.)


2
typedef를 사용하여 함수 유형을 정의한 다음이를 사용하여 한 번에 많은 함수를 선언 할 수도 있습니다. 예를 들어 typedef int fooProc(int); fooProc a,b.c.d.e;플로피 드라이브 기반 컴파일러의 표준 헤더가 왜 그렇게하지 않았는지 잘 모르겠습니다. 헤더 파일이 훨씬 작고 처리 속도가 빠를 수 있다고 생각했기 때문에 하루입니다.
supercat 2019

또한 int f(int(&g)(),int(*h)()){return g()+h();}여기에는 세 개의 함수 선언이 있으며 그중 하나는 괄호로 묶이고 다른 하나는 쉼표로, 다른 하나는 괄호로 묶습니다.
David Hammen

1
@DavidHammen : 그 이외의 함수를 엄격하게 선언하지는 않습니다 int f(stuff). 함수의 범위 내에서도 함수에 대한g 유형 참조 의 자동 변수이며 functionh대한 포인터 입니다.
Peter Cordes 2019

83

다른 답변과 의견은 이것이 끔찍하고 오도되고 잘못 작성된 질문 인 여러 가지 방법을 제시합니다. 그러나 아직 아무도 확인하지 않은 또 다른 문제가 있습니다. 질문은 ~이야:

함수 선언 후에 세미콜론 ( ';')이 필요하지 않습니다. 참 또는 거짓.

자, 함수 선언을 보자.

int func();       /* */
/*           ^       */
/*           |       */
/* That whitespace is "after the function declaration". */

그 모든 것이 선언 입니다. 선언이되지 int func()다음; . 선언 int func();다음에 공백이옵니다.

따라서 질문은 : 선언 후에 세미콜론이 필요한가 ? 당연히 아니지. 선언에는 이미 세미콜론이있어 종료되었습니다. 선언 후 세미콜론은 의미가 없습니다. 반대로 함수 선언 후int func(); ; 세미콜론 이됩니다 .

이 질문은 거의 확실하게 "참 또는 거짓 : 함수 선언의 마지막 토큰은 항상 세미콜론"이라는 질문을하도록 의도되었지만 퀴즈 작성자가 문제에 대해 명확하게 생각하지 않았기 때문에 그들이 쓴 질문은 아닙니다.

내 조언은 프로그래밍 언어 퀴즈를 완전히 피하는 것입니다. 그들은 꽤 끔찍하다.


우리가 주제에있는 동안 재미있는 사실. C #에서는 다음이 모두 합법적입니다.

class C {}
class D {};
struct E {}
struct F {};

C #에서 클래스 또는 구조체 선언은 사용자의 판단에 따라 세미콜론으로 끝나거나 끝나지 않을 수 있습니다. 이 이상한 작은 기능은 C / C ++ 프로그래머가 C #에 온다는 점에서 형식 선언이 무의미한 세미콜론으로 끝나는 기능을 제공합니다. 디자인 팀은이 습관을 가지고 그들을 처벌하고 싶지 않았습니다. :-)


의견은 긴 토론을위한 것이 아닙니다. 이 대화는 채팅 으로 이동 되었습니다 .
Samuel Liew

25

다음과 같이 함수를 선언 할 수도 있습니다.

int func(){
    return 1;
}

그 진술은 매우 모호하다. 정답은 다음과 같아야합니다. 함수 선언 방법에 따라 다릅니다.

어쨌든, 나는 거짓도 선택했을 것입니다. 아마도 누군가에게 질문을보고 할 수 있습니다.


3
어쨌든, 개인적인 수준으로 물건을 넣지 마십시오. 중요한 것은 함수 선언-정의의 작동 방식을 이해 했으므로 너무 걱정하지 말고 최소한 질문을 확인하고 계속 진행하십시오.
Luca Corsini

11
물론. 솔직히, 나는 내가 틀렸던 것보다 질문을 잘못함으로써 함수 선언 정의에 대해 더 많이 배웠다.
로건

1
@Logan은 너무 걱정하지 않습니다. 필요한 함수를 작성하고 읽는 방법을 알고 있다면 나는 개인적으로 다음과 같은 질문을 싫어한다. 1. 잘 정의되지 않았다. 2. 구문에 대한 이론적 지식을 테스트한다. 나에게 그것은 근육 기억과 같습니다. 각 숫자를 쉽게 입력 할 때 키로 넘어갈 수는 있지만, 어떤 키를 눌러야하는지에 대한 테스트를
해보면

2
... 공통 구문 (예 : 함수)을 작성하는 것은 두 번째 특성이 될 것입니다. 언어를 바꾸었기 때문에 엉망이 될 때, 지능과 구문 강조는 빠르고 효율적인 솔루션을 만듭니다. 더 유용한 것에 시간과 에너지를 투자하십시오.
bolov

20

함수 선언 후에 세미콜론 ( ';')이 필요하지 않습니다.

참 또는 거짓.

맞습니다 . 선언 후에 세미콜론이 필요하지 않습니다. 어떤 정의도 따르지 않습니다. 성명서도 마찬가지입니다.

7 장 [dcl.dcl]의 구문에서 지정한 것처럼 많은 종류의 선언은 세미콜론으로 끝나야합니다. 그러나 그 후에 두 번째를 쓸 필요는 없습니다.


1
에릭 리퍼 트는 이미이 점을 논박했다. 나는 모든 upvotes가 그것을 간과하게 만들었다 고 생각한다. 투표를 해주세요.
Marc van Leeuwen

"X는 항상 참 : 참 또는 거짓?" "거짓"이라는 답을 얻게 될 것입니다. 도대체 어디서나 세미콜론을 가질 필요 는 없다 . 컴파일러는 여러분의 프로그램을 불평하고 컴파일을 거부 할 수 있지만, 그것은 세상의 끝이 아닙니다. 나는 그것을 근본적인 필요 라고 부르지 않을 것이다 . ;)
Quuxplusone

@Quuxplusone 컴파일러가 프로그램을 거부하면 프로그램에 함수 선언이 없습니다 :)
Ben Millwood

6

이것은 우리가 함수를 선언하거나 정의하고 있는지에 달려 있습니다. 함수를 선언하는 경우 세미콜론 ( ;) 을 포함해야 하며 함수를 정의하는 경우 세미콜론이 필요하지 않습니다.

선언은 다음과 같습니다 :

int add(int, int);

정의는 다음과 같습니다.

int add(int a, int b)
{
    // ...
}

10
이 답변의 문제점은 정의와 선언이 상호 배타적이라는 것을 암시합니다. 실제로 모든 정의는 선언입니다. 정의는 선언의 하위 집합입니다.
MSalters

6

나는 거의 모든 다른 답변에 동의하지만 질문이 매우 모호하다고 말하고 귀하의 답변이 기술적으로 정확하다고 말하면 다른 관점을 제시 할 수 있습니다.

이것이 내가 항상 전화 한 방법입니다.

void func();  // The function prototype

...

void func()
{
    // The function definition
}

질문 이이 용어를 염두에두고 있다고 가정합니다.

정의와 선언은 내 눈에 같은 개념입니다. "x = y를 정의합니다"== "x = y를 선언합니다".

물론 함수 프로토 타입 (위)과 함수의 실제 정의에는 큰 차이가 있습니다.


나에게 프로토 타입은 내가 배운 방법 (당신이 틀렸다고 말하지는 않음)을 기반으로 한 선언이지만, 프로토 타입이 인수의 수와 유형을 지정하거나 무효화 할 것으로 기대하지만, 나는 당신이 그것을 생략 할 것으로 기대한다 간결하게.
David S

David S : 물론, 여기에는 인수의 수와 유형도 포함되지만 간결성을 위해 생략했습니다 (실제 함수 선언에는 인수가 없음에 유의하십시오). 그러나 전체 함수 선언을 프로토 타입이라고 말하면 실제로 동의하지 않습니다. Wikipedia는 "함수 프로토 타입 또는 함수 인터페이스는 함수의 이름 및 형식 서명 (arity, 데이터 형식의 매개 변수 및 반환 형식)을 지정하지만 함수 본문을 생략하는 함수의 선언입니다."
Opifex 2019

@DavidS : C ++에서 함수 선언은 항상 프로토 타입 (또는 정의) void func();이며 정확히 같습니다 void func(void);. 이것은 컴파일러와 args에 대해 아무 것도 알려주지 않는 C 와 매우 다르며 void func();와는 다릅니다 void func(void);. 나중에 프로토 타입이나 정의를 사용하는 것이 좋습니다. 그렇지 않으면 호출자가 기본 arg 프로모션을 적용해야합니다 (예 : float-> double 및 좁은 정수 유형을 arg에 적용하는 int것과 같은 규칙).
Peter Cordes

사과를 드려서 C와 관련된 것을 보았고 언어의 변화에 ​​주목하지 않았습니다. 명확성을 위해 의견을 삭제하지는 않지만 철회 된 것으로 간주합니다.
David S

6

당신이 취한 질문에 "직접적으로"대답하지 않는 것이 유감입니다. 예를 들어 다음과 같이 작성할 수 있습니다.

int func()  /* My function */ ;

아니면 쓸 수 있습니다 :

int func()
int a = 42;

첫 번째 경우 세미콜론은 선언 바로 뒤에 있지 않지만 괜찮습니다.

두 번째 경우에는 세미콜론 "후"선언이 있지만 바로 뒤에는 없습니다.

에릭 리퍼는 그의 대답에 맞는 아이디어를 가지고 있다고 생각 합니다.

"문장 종료 후 영어로 마침표가 있어야 하는가?"와 같습니다. 아마도, 문장은 이미 끝에 마침표가 있습니다 (그렇지 않으면 문장이 아닐 것입니다). 따라서 문장 뒤에 마침표가 없어야합니다 .


4
좋은. 추가 문장으로 그 문장을 끝내기. 난 당신이 무슨 짓을했는지 참조.
David S

2
int func() int a=42;컴파일하지 않습니다. 다른 쉼표가 아닌 쉼표가 필요합니다 int. 이 전날에 게시 된 @Arne의 답변을 참조하십시오. 이 답변에서 유일한 새로운 것은 영어 문장과 비슷한 마지막 단락입니다.
Peter Cordes

1
나는 두 번째 예제가 컴파일되었다고 말하지 않았다. 나는 선언이 "후"에 세미콜론이 필요하다는 말이 애매 모호하다고 지적했다. 내 예제에는 선언 후 세미콜론이 있었지만 컴파일 되지 않았습니다 .
Nick Gammon

1
오류 메시지에서도 이와 동일한 문제가 발생합니다. C #에서 가장 좋아하는 예는 " params 매개 변수는 공식 매개 변수 목록의 마지막 매개 변수 여야합니다 "입니다. 이제 대신 "프로브가 gloob 목록의 마지막 gloob이어야합니다"라고 가정합니다. 이것이 의미합니까? (1) 모든 질문 끝에는 정확히 하나의 frob가 있습니다. 모든 질문에는 끝에 정확히 하나의 물음표가 있습니다. (2) gloob 목록에는 여러 개의 frob가있을 수 있지만 하나 이상의 frob가있는 경우 , 짝수의 숫자는 02468의 수를 가질 수 있지만 마지막 항목은 마지막이어야합니다.
Eric Lippert

... (3) gloob 목록에는 frob가 없거나 하나있을 수 있으며, 하나가 있으면 끝이됩니까? 문맥을 모른다면 (1)이 가장 합리적인 설명이라고 생각하지만 "params parameter"의 경우 (3)이 올바른 설명입니다. 프로그래밍 언어 요소에 대한 많은 비공식적 설명에는 기술 편집자 친구가 "COIK"라고 ​​부르는 속성이 있습니다. 자료를 아직 완전히 이해하지 못했다면, 그 내용에 대한 설명은 쓸모가 없지만, 이미 완전히 이해했다면 설명이 필요하지 않습니다!
Eric Lippert

4

;프로토 타입에만 사용할 수 있습니다 .


4

까다로운 질문이지만, 다음과 같은 의미의 선언 이라는 단어를 사용 했습니다.

int example();

이 경우에도 마찬가지입니다.

그들이 구현 이라는 단어를 사용했다면 그것은 틀렸을 것입니다.


2

세미콜론 (;)은 컴파일러에게이 세미콜론 (;) 뒤에 새 명령문이 시작된다는 것을 알리는 데 사용됩니다.

따라서 세미콜론 (;)은 함수 선언 중에 만 필요하다고 생각합니다. 나에 따르면, 대답은 맞을 것입니다.


그러나 선언은 진술이 아닙니다.
HolyBlackCat

그러나 함수 선언 후 컴파일러를 사용하여 새로운 코드 줄을 실행하고 있습니다. 그래서 새로운 코드 라인을 실행하기 전에 이전 코드 라인이 끝나는 곳을 알아야 컴파일러가 네이티브 코드를 생성 할 수 있다고 생각합니다 (예 : 0101).
Jatinder

2

main () 전에 함수가 정의 된 경우 :

  • 함수가 이미 정의되어 있으므로 세미콜론이 필요하지 않습니다

main () 뒤에 함수가 정의 된 경우 :

  • 해당 함수의 프로토 타입을 작성하고 컴파일러에게 함수가 종료되었음을 알리기 때문에 세미콜론이 필요 합니다.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.