foo (void) vs foo (void *)


9

기능적으로 그리고 구문 적으로 말하자면 프로토 타입이있는 함수 int foo(void)int foo(void *)?

나는 예를 들어, 차이를 알고, int bar(int)그리고 int bar(int *)- 그 중 하나의 int를 찾고, 다른 하나는 int 형 포인터를 찾고 있습니다. void같은 방식으로 작동 합니까 ?


관련 질문에 대한 답변 : stackoverflow.com/a/1043209/434551 .
R Sahu


무엇보다 흥미로운 될 수있다 사이의 차이 foo(void)foo().
Maxim Egorushkin

답변:


10

에서 소프트웨어 공학에 대한이 답변, void 그것이 사용되는 방법 특별히에 따라 처리됩니다. 으로 C하고 C++, void표시하기 위해 사용 하는 데이터 타입의 부재를 반면 void *나타내는 데 사용되는 유형이없는 메모리의 일부 데이터 / 공간있는 점 포인터. void *자체적으로 역 참조 할 수 없으며 먼저 다른 유형으로 캐스트해야합니다. 이 캐스트는에 명시적일 필요는 없지만에 명시 적 C이어야합니다 C++. (우리는 malloc의 반환 값을 캐스팅하지 않는 이유입니다 void *.)


함수를 매개 변수로 사용하면 void 없는 것을 의미하며 허용되는 유일한 매개 변수입니다. 변수 유형처럼 void를 사용하거나 다른 인수를 포함하려고하면 컴파일러 오류가 발생합니다.

int foo(void, int);     //trying to use "void" as a parameter
int bar(void baz);      //trying to use "void" as an argument's type
main.c:1:8: error: 'void' must be the first and only parameter if specified
int foo(void, int);
       ^
main.c:2:14: error: argument may not have 'void' type
int bar(void baz);
             ^

다음과 같이 유형을 가진 변수를 선언하는 것은 불가능합니다 void.

int main(void) {
  void qux;         //trying to create a variable with type void
}
main.c:5:8: error: variable has incomplete type 'void'
  void qux;

void함수의 반환 값은 데이터가 반환되지 않음을 나타냅니다. 유형의 변수를 선언 할 수 void없으므로 void 포인터로도void 함수 의 반환 값을 잡을 수 없습니다 .

void foo(int i) { return; }

int main(void) {
  void *j;
  j = foo(0);

  return 0;
}
main.c:5:5: error: assigning to 'void *' from
      incompatible type 'void'
  j = foo(0);
    ^ ~~~~~~

타입리스 void *는 다른 경우입니다. void 포인터는 메모리의 위치에 대한 포인터를 나타내지 만 해당 포인터의 데이터 유형은 나타내지 않습니다. (이것은 C 에서 다형성을 달성 하는 데 사용됩니다 . qsort () 함수 .) 그러나 이러한 포인터는 실수로 잘못된 유형으로 캐스팅하기가 쉽기 때문에 사용하기 까다로울 수 있습니다. 아래 코드는에서 컴파일러 오류를 발생시키지 C않지만 정의되지 않은 동작을 발생시킵니다 .

#include <stdio.h>

int main(void) {
  double foo = 47.2;    //create a double
  void *bar = &foo;     //create a void pointer to that double
  char *baz = bar;      //create a char pointer from the void pointer, which
                        //is supposed to hold a double

  fprintf(stdout, "%s\n", baz);
}

그러나 다음 코드는 완벽하게 합법적입니다. void 포인터로 캐스트하거나 그로부터 캐스트하면 보유하는 값이 변경되지 않습니다.

#include <stdio.h>

int main(void) {
  double foo = 47.2;
  void *bar = &foo;
  double *baz = bar;

  fprintf(stdout, "%f\n", *baz);
}

47.200000

함수 매개 변수로서, void *전달하는 포인터의 데이터 유형을 알 수 없으며 해당 메모리 위치에있는 모든 것을 올바르게 처리하는 것은 프로그래머의 책임입니다. 리턴 값으로서, 리턴 void *되는 자료의 유형이 알려지지 않았거나 유형이 없으며 프로그램에 의해 처리되어야 함을 나타냅니다.

int quux(void *);   //a function that receives a pointer to data whose type is not known, and returns an int.
void *quuz(int);    //a function that receives an int, and returns a pointer to data whose type is not known.

void함수 프로토 타입의 tl; dr 은 "데이터 없음"을 의미하고 리턴 값이 없거나 매개 변수 void *가 없음을 나타냅니다. 포인터의 데이터를 사용하려면 포인터를 다른 유형으로 캐스트해야합니다.


void * ... must be cast to another type first, but may be done so without an explicit cast.C ++에서는 그렇지 않습니다. C ++에서 변환 양식 void*은 명시 적이어야합니다. 캐스트는 정의상 명시 적 변환이므로 캐스트 명시 적 호출은 중복됩니다.
eerorika

C / C ++ 차이점을 반영하여 업데이트되었습니다. 알려 주셔서 감사합니다!
닉 리드

4

foo(void) -매개 변수가없는 기능

foo(void *) -하나의 기능 void * 파라미터로

무엇입니까 void *? 지정된 유형이없는 데이터에 대한 포인터 일뿐입니다. 다른 포인터 유형으로 캐스트 가능

unsigned add(void *arr)
{
   unsigned *uarr = arr;
   return uarr[0] + uarr[1];
}

필수 답변이므로 가장 좋습니다. void 는 실제로 유형이 아니기 (type) vs. (type *)때문에 커플 우주 에서 이것이 어떻게 예외인지 강조합니다 .
로베르토 Caboni

2

기능적으로 구문 적으로 말하자면 프로토 타입이 int foo (void) 인 함수와 int foo (void *) 사이에 차이가 있습니까?

차이점이 있습니다.

int foo(void) 인수를받지 않는 함수를 선언합니다.

int foo(void *)유형의 단일 인수를 허용하는 함수를 선언합니다 void*.

C ++에서는 int foo(void)에 해당합니다 int foo().

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.