기능적으로 그리고 구문 적으로 말하자면 프로토 타입이있는 함수 int foo(void)
와 int foo(void *)
?
나는 예를 들어, 차이를 알고, int bar(int)
그리고 int bar(int *)
- 그 중 하나의 int를 찾고, 다른 하나는 int 형 포인터를 찾고 있습니다. void
같은 방식으로 작동 합니까 ?
foo(void)
와 foo()
.
기능적으로 그리고 구문 적으로 말하자면 프로토 타입이있는 함수 int foo(void)
와 int foo(void *)
?
나는 예를 들어, 차이를 알고, int bar(int)
그리고 int bar(int *)
- 그 중 하나의 int를 찾고, 다른 하나는 int 형 포인터를 찾고 있습니다. void
같은 방식으로 작동 합니까 ?
foo(void)
와 foo()
.
답변:
에서 소프트웨어 공학에 대한이 답변, 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*
은 명시 적이어야합니다. 캐스트는 정의상 명시 적 변환이므로 캐스트 명시 적 호출은 중복됩니다.
foo(void)
-매개 변수가없는 기능
foo(void *)
-하나의 기능 void *
파라미터로
무엇입니까 void *
? 지정된 유형이없는 데이터에 대한 포인터 일뿐입니다. 다른 포인터 유형으로 캐스트 가능
unsigned add(void *arr)
{
unsigned *uarr = arr;
return uarr[0] + uarr[1];
}
(type) vs. (type *)
때문에 커플 우주 에서 이것이 어떻게 예외인지 강조합니다 .