source

두 번째 인수가 메인()인 char *argv[]와 char **argv의 차이

ittop 2023. 10. 14. 10:36
반응형

두 번째 인수가 메인()인 char *argv[]와 char **argv의 차이

코드 1

#include<stdio.h>

int main(int argc, char *argv[])
{
int j;
printf("%d", argv[1][0]);
return 0;
}

CODE 2

#include<stdio.h>

int main(int argc, char **argv)
{
int j;
printf("%d", argv[1][0]);
return 0;
}

CODE 1과 CODE 2는 모두 동일한 출력을 제공합니다.그러나 CODE 1과 CODE 2의 주함수의 논항 2는 다릅니다.포인터 배열은 컴파일 시 데이터 섹션 위에 작성됩니다.argv는 포인터 배열입니다.그런 다음 주 기능에서 인수를 문자의 포인터, 즉 **argv로 선언해야 합니다.CODE 1과 같이 선언하는 것이 어떻게 정확합니까?

는 것이 기본입니다.char** x그리고.char* x[]같은 것을 표현하는 두 가지 방법이 있습니다.둘 다 파라미터가 포인터 배열에 대한 포인터를 수신한다고 선언합니다.항상 다음과 같이 쓸 수 있습니다.

 char *parray[100];
 char **x;

 x = &parray[0];

x를 동일하게 사용합니다.

기본적으로 char* argv[ ]는 char 포인터의 배열을 의미하는 반면 char** argv는 char 포인터에 대한 포인터를 의미합니다.

어느 배열에서나 배열의 이름은 배열의 첫 번째 요소에 대한 포인터입니다. 즉, 첫 번째 요소의 주소를 포함합니다.

따라서 아래 주어진 코드에서 문자 배열 x에서 x는 첫 번째 요소인 '1'을 가리키는 포인터입니다.그래서 캐릭터를 가리키는 거지.

배열 배열에서 포인터 첫 번째 요소인 x를 배열합니다. x는 그 자체로 문자를 가리키는 포인터입니다.그래서 다른 포인터를 가리키는 겁니다.

따라서 x는 char*이고 ar는 char**입니다.

어떤 기능에서 무엇인가를 받는 동안, 기본적인 규칙은 당신이 받고 있는 것의 종류를 말해야 한다는 것입니다.따라서 단순히 char**를 받고 싶다고 말하거나 char*arr[]라고 말할 수도 있습니다.

우선 복잡한 생각을 할 필요가 없습니다.우리는 단순히 알고 있습니다, 우리는 char*의 배열을 받고 있습니다.이거 몰라요?그래서 우리는 그것을 받고 사용합니다.

두 번째 경우는 간단합니다, arr는 char**라고 위에서 설명했듯이, 이것을 그대로 타입대로 넣어서 안전하게 받을 수 있습니다.이제 시스템은 우리가 받은 것의 종류를 알게 되었고, 우리는 단순히 배열 주석을 사용하여 다음 요소에 접근할 수 있게 되었습니다.즉, 어레이의 시작 주소를 받았기 때문에 다음 요소로 확실히 이동할 수 있습니다. 유형을 알고 있듯이 어레이에 무엇이 포함되어 있고 어떻게 더 사용할 수 있는지 알고 있습니다.촤에 대한 포인터가 포함되어 있다는 것을 알고 있기 때문에 합법적으로 접근할 수도 있습니다.

void func1(char* arr[])
{
    //function body
}
void func2(char** arr)
{
    //function body
}

int main()
{
    //x, y and z are pointer to char
    char x[3]={'1', '2', '3'};
    char y[3]={'4', '5', '6'};
    char z[3]={'7', '8', '9'};

    //arr is pointer to char pointer
    char* arr[3]={x, y, z};

    func1(arr);
    func2(arr);
}

그들은 완전히 똑같습니다.C11 표준의 §5.1.2.2.2항 상태:

할 때 의 이름은 됩니다입니다.main 시 이 구현에서 이 기능에 대한 프로토타입이 없음을 선언합니다..int매개변수 없음:

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

두 로 )를 사용합니다(에 참조:argc그리고.argv어떤 할 수 이 , 입니다.

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

또는 이와 동등한 방법,10) 또는 다른 구현 정의 방식.

10) 그리하여int된 typedef다로 할 수 있습니다.int , 의 .argv라고 쓸 수 .char ** argv,

분명히 두 선언이 일치하도록 하려는 의도가 있습니다.또한 이 규칙은 §6.7.6.3/7에 설명되어 있습니다.

매개변수를 "유형 배열"로 선언하는 것은 "유형에 대한 적격 포인터"로 조정해야 하며, 여기서 유형 한정자(있는 경우)는 다음과 같이 지정됩니다.[그리고.]배열 유형 파생의...

[EDIT] 댓글 작성 당시 GCC 사용 아마도 GCC 7.2

배열을 선언하기

char array[]

당신이 다음 코드를 가질 수 없다는 것을 의미하는 상수를 만듭니다.

char array[] = "hello";
array = "hey";

비록 두번째 문자열이 더 작고 적합해야 하지만 이 오류가 발생합니다.

오류: 배열 유형 'char[6]'을(를) 할당할 수 없습니다.

이 가지고 있다면**argv다를 쓸수 .

main(int argc, char **argv)
{
    char **other_array;
    /*
     * do stuff with other_array
     */
    argv = other_array;
}

이 가지고 있다면*argv[]그리고나서

main(int argc, char *argv[])
{
    char **other_array;
    /*
     * do stuff with other_array
     */
    argv = other_array;
}

이 경고를 드립니다.

경고: 'char **'에서 'constchar **'에 할당하면 중첩된 포인터 유형의 한정자가 삭제됩니다.

으로는 입니다.const

언급URL : https://stackoverflow.com/questions/27213580/difference-between-char-argv-and-char-argv-for-the-second-argument-to-main

반응형