주 함수에서 argc와 argv의 이름을 바꾸는 것이 안전합니까?


82

많은 프로그램에서 여러 인수와 문자열 배열에 표준 이름을 사용합니다. 주 함수의 프로토 타입은 다음과 같습니다 int main(int argc, char *argv[]);.. 하지만 이러한 변수에 대해 사용자 지정 이름을 선택하면 뭔가 깨질까요?

int main(int n_of_args, char *args[]);

컴파일러의 맥락에서 모든 것이 정상입니다. 이러한 변수는 주 함수에 대해 지역적이므로 이름이있을 수 있습니다. 그리고 간단한 코드가 완벽하게 빌드되고 실행됩니다. 그러나 이러한 이름은 전처리기에 의해 사용될 수 있습니다. 그렇다면 이러한 인수의 이름을 바꾸는 것이 안전합니까?

추신 개인적으로 나는이 이름이 매우 비슷하고 한 글자 만 다르기 때문에 나쁘다고 생각합니다. 그러나 모든 사람들은 어떤 이유로 든 그것들을 사용합니다.


21
예, 완전히 안전합니다.
David Hoelzer

55
모든 대답이 말했듯이 네, 안전합니다. 하지만 그러지 마세요. 모두가 알고 argc하고 argv있습니다. n_of_argsargsC ++ 또는 C를 모르는 사람에게 명확 수 있습니다 -하지만 청중이 아니다.
Keith Thompson

4
당신 이것을 있습니다 , 이것을 할 충분한 이유가 아닙니다. 모두가 그게 뭔지 알고 있고, 그렇게되기를 기대합니다.
SergeyA

10
질문이 정확히 "내가 사용자 정의 이름을 선택하면 무언가를 깨뜨릴 수 있을까"라면, 정확한 대답은 "예, 잘 정착 된 전통을 깨뜨릴 것입니다."입니다.)
Frax

12
그냥 뒤집으세요! .. 그리고 바로 시작부터 당신은 직업 안정을위한 토대를 마련하고 있습니다 :)
yano

답변:


121

예, 유효한 변수 이름을 사용하는 한 안전합니다. 그들은 지역 변수이므로 범위가 main기능을 넘어 가지 않습니다 .

C 표준 의 섹션 5.1.2.2.1에서 :

프로그램 시작시 호출되는 함수의 이름은 main. 구현은이 함수에 대한 프로토 타입을 선언하지 않습니다. 반환 유형 int및 매개 변수없이 정의되어야합니다 .

int main(void) { /*  ... */ }

또는 두 개의 파라미터들 (여기로 언급 argc하고 argv, 어떤 이름이 사용될 수있다하더라도, 그들은 선언 된 함수에 국부적으로 )

int main(int argc, char *argv[]) { /* ...   */ }

또는 동등한 것; 또는 다른 구현 정의 방식으로

즉, argc및 이외의 다른 것을 argv사용하면 이러한 매개 변수의 일반적인 이름에 익숙한 코드를 읽는 다른 사람들이 혼동을 일으킬 수 있습니다. 명확성의 측면에서 실수하는 것이 좋습니다.


38

이름 argc과는 argv실제로 C ++ 표준 이전의 C에 ++ (11)에 의해 위임되었다. 다음과 같이 명시되어 있습니다.

모든 구현은 main에 대한 다음 정의를 모두 허용해야합니다.

int main ()

int main ( int argc , char * argv [])

과에 대한 요구 사항을 논의하기 위해에 갔다 argcargv.

따라서 기술적으로 다른 이름을 사용하는 프로그램은 표준을 준수하지 않았으며 컴파일러는이를 거부 할 수있었습니다. 물론 실제로 그렇게 한 컴파일러는 없습니다. comp.std.c ++ 또는 이 C ++ 03 초안 표준 의 섹션 3.6.1 에서이 스레드를 참조하십시오 .

이것은 거의 확실히 단순한 감독이었고 C ++ 11에서 변경되었습니다.

모든 구현은

  • () 반환 int
  • ( int, 포인터에 대한 포인터 char) 반환 의 함수int

main(8.3.5) 의 유형으로 . 후자의 형식에서는 설명을 위해 첫 번째 함수 매개 변수가 호출 argc되고 두 번째 함수 매개 변수가 호출됩니다 argv.


29

물론이 매개 변수의 이름 을 원하는대로 안전하게 바꿀 수 있습니다.

 int main(int wrzlbrnft, char* _42[]) {
 }

이름은 모래에 기록됩니다. 최종적으로 컴파일 된 코드에는 영향을주지 않습니다.


중요한 것은 선언과 정의의 매개 변수 유형이 실제로 일치한다는 것입니다.

main()함수 의 서명 은 본질적으로 다음과 같이 선언됩니다.

 int main(int, char*[]);

구현에서 실제로 사용해야하는 경우 이름을 지정해야합니다. 어떤 이름이 사용되는지는 앞에서 언급했듯이 실제로 관련이 없습니다.


5
당신이 그것을 넣을 때 단지 일부 식별자 만이 "모래에 기록"됩니다. 함수 이름은 확실히 아닙니다.
Steve Cox

1
@SteveCox "함수 이름은 확실히 아닙니다." 결국 그들은 그렇습니다. 모래 입자의 단지 숫자 - P ...
πάντα ῥεῖ

3
좋아하지만 진지하게. 컴파일 후에도 객체 코드에는 여전히 함수 이름이 있습니다. 그렇지 않으면 작동하지 않을 것입니다 연결
스티브 콕스

4
@ πάνταῥεῖ : 특별히 제거하지 않는 한 함수 이름은 최종 실행 파일에 남아 있습니다.
Nick Matteo

1
@Kundor : 윈도우에 연결 한 후, 모든 비 특수 기능은 이름을 유지하지 않습니다
대니

15

예. 안전하고 이상해 보이지만 아무 것도 깨지지 않습니다.


7

예, 다른 이름을 사용하는 것이 안전합니다.

개인적으로 나는 그것을 추천하지 않을 것이다. 전통 argc적이고 argv널리 알려져 있고 당신의 코드로 작업 할 수있는 다른 모든 C 프로그래머에게 친숙하다. 장기적으로 자신의 특별하고 다른 이름을 사용하면 자신의 이름을 더 좋아하기 때문에 독자들 사이에 훨씬 더 많은 혼란과 좌절감을 줄 것입니다.

"로마에있을 때 로마인처럼하십시오."


그러나 다른 이름 glutInit(&argc, argv)을 사용해야 하는 매우 명백한 시나리오는 거의 없습니다. 악명 높은 시나리오는 GLUT를 초기화 하는 것입니다. SO 링크
user3078414

@ user3078414 흥미로운 예이지만 변수의 이름이 무엇인지에 대해 어떻게 말하는지 모르겠습니다. 다른 질문의 예에 따라 int dummyargc = 1; char *dummyargv[1] = {(char*)"Something"}; glutInit(&dummyargc, dummyargv);.
Steve Summit

감사합니다, @ steve-summit. 일부 API 문서는 잘못된 것이므로이 스레드는 argc argv기여하는 답변과 마찬가지로 명명 규칙 을 강조하는 데 가장 유용 합니다. 나는 가급적 다른 이름을 사용하는 예제로 내 의견을 넣었습니다. 여기에 SO 링크가 있습니다
user3078414

5

예, 원하는대로 이름을 바꿀 수 있습니다. 그것들은 단순히 함수 매개 변수 이름이며 그 이상은 아닙니다.


3

모두가 기술적 인 C ++ 규칙을 잘 다루었다고 생각합니다. 대답은 '예'입니다. 전통과이 특정 기능이 특별하고 상징적이라는 사실을 제쳐두고,이 기준에 따라 변하지 않는 유효한 포인트를 포함합니다.

종종 나는 선택의 철학이 거의 논의되지 않는다고 느낍니다. 그래서 이것이 시작하도록 요청 된 이유에 대해 중요하다고 느끼기 때문에이 문제에 대한 관점을 제공하고 싶었습니다.

이 질문은 일반적으로 코드에서 영어를 표현하는 선택을 포함합니다. 특히 짧은 손이 비슷한 모양의 텍스트를 표시하는 경우 짧은 손 설명에 귀찮은 것 같습니다. 그러나 귀하의 예에서 argn을 n_of_args로 변경하면 한 가지 유형의 속기 만 실제 값 추가없이 다른 형태의 속기로 변경됩니다 : 설명 또는 기타 가시적 속성.

단어 '숫자'가 문자 'n'으로 대체되었습니다.

짧은 손 방지 철학을 통해 짧은 손 이름을 변경하는 경우 다음과 같은 것이 더 적절 해 보일 수 있습니다.

main (int argumentCount, char ** argumentVector)

저는 항상 두 가지에 대해 생각합니다. 이름을 지정하는 것은 무엇인지 및 / 또는 묵시적인 용도로 지정하는 것입니다. 벡터라는 속성이 이중 간접 **에 의해 암시되기 때문에 그것을 argumentVector라고 부르는 것은 나에게 중복됩니다. 따라서 코드 작성 방법에 대한 더 나은 긴 손은 ** 인수입니다.

어떤 사람들은 argumentCount라는 변수가 int로 선언되고 Count는 음수가 될 수 없지만 음의 int {unsigned is better}를 가질 수 있다고 말합니다.

다시 말하지만, 그것이 무엇이며 어떻게 사용되는지는이 해석에서 작용합니다. 백작이라면 절대 음수가 아닐 것이라고 생각합니다. 결국, 당신은 어떻게 -2 개의 사과 수를 가질 수 있습니까? 당신은 사과 두 개를 빚지고 있습니다. 숫자라면 음의 경우가 가능할 것으로 예상합니다. 이것이 당신에게 추가 단어 'of'가 중요한 이유입니다. 즉, 컬렉션에서 참조하는 숫자는 컬렉션 자체의 속성이 아니라 특정 항목을 의미합니다. 즉 : argumentsNumber = 5는 numberOfArguments가 아닌 특정 인수를 의미합니다.

main (int maxArgumentsIndex, char ** arguments).

이것은 모호성을 제거합니다. 이를 색인이라고 부르면 부정적 대소 문자의 모호성을 제거하고 그것이 무엇인지, 추가로 사용 방법을 설명합니다. 또한 최대 값이 절대 값이고이 값을 수정하는 코드를 작성하는 것이 이상하게 느껴질 것임을 영어 표현으로 암시합니다 (const 여야 함). '인수'는 복수형이고 그것이 무엇인지, 이미 어떻게 사용되어야하는지 설명하기 때문에 여기서 의미가 있습니다. 인덱스가 Count / NumberOf의 -1이기 때문에 이런 방식으로 해석하는 것도 위험 할 수 있습니다. 5 개의 인수는 4의 maxIndex를 산출합니다 !!

다른 모든 기능과 나는 완전히 사용합니다.

void function (const unsigned int maxArgumentsIndex, const char ** arguments)

모든 상황이 긴 설명자를 사용해야하는 것은 아닙니다. 실제로 Vec3f, Matrix, Quaternion 등과 같은 수학 수업을 작성하는 경우에는 짧은 손이 더 가독성을 제공하기도합니다. . 부동 소수점 x, y, z vrs. float xComponent 등.

나는이 모든 것이 스타일 선택이라는 것을 이해하지만 선택을 의식하는 것은 장기적으로 정말 도움이 될 것입니다. 나는 노련한 프로그래머가 배열이 복수형으로 작성되지 않았을 때 신경 쓰이는 것을 보장하지만 다시, main은 존재의 특별한 산문입니다.)


2

C 표준에 따라 이름을 바꿀 수 있습니다. 내가 이해했듯이 C 언어에서 기본 키워드 / 유형 / 토큰 이름은 목적 / 사용법으로 정의되었으므로 동일한 방식으로 정의 된 이름입니다.

argc --> argument count

argv --> argument vector

사용 측면에서도 의미가 있으므로 원하는 이름으로 변경할 수 있습니다. Reserved names

GCC에서 프로그램 실행 main은 그의 매개 변수에 의존하지 않는 함수 이름으로 시작됩니다 .

마이크로 컨트롤러 용 독립 실행 형 프로그램을 작성할 때 이름에 대해 신경 쓸 필요가 없습니다. main대신 고유 한 이름 을 정의 name하고 어셈블리 entry_point를 변경하여 함수를 가리킬 수 있습니다. 컨트롤러 컴파일러와 사전 정의 된 컨트롤러 소스 코드의 가용성에 따라 다릅니다. Code-warrior의 Freescale 컨트롤러에서이 작업을 수행했습니다.

내 노트 :

코드의 가시성과 가독성을 높이려면 공통 표준 / 코드 스타일을 따르는 것이 좋습니다.


0

컴파일러에 관한 한 안전합니다.

이것이 야기 할 수있는 유일한 문제는 혼란입니다. 코드를 읽는 사람들은이 두 변수가 표준 이름을 가질 것으로 기대합니다. 다음과 같이 할 수도 있습니다.

int main(int foo, char ** bar)
{
    int argc;
    float argv;

그러나 나는 이것이 얼마나 나쁜 습관이 될 것인지 말할 필요가 없다고 생각합니다.


-1

변수 이름이 마음에 들지 않으면 매크로 #define으로 대체하지 않는 것이 좋습니다 .

#define yourCounterName argc
#define yourVectorName  argv 

위험을 감수하지 않고 "깨끗한 솔루션"을 생성합니다.


그것들은 상수가 아니라 대체 일뿐입니다.
David Dunham
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.