일반적으로 포인터 를 이해하는 데 문제가 있다고 생각합니다. 이 코드의 논리를 따를 수없는 것 같습니다.
typedef struct StackRecord
{
int Capacity;
int TopOfStack;
int* Array;
}*Stack;
다음 구조에서 * Stack 은 typedef로 인해 단순히 Stack을 명시하여 StackRecord 구조 유형의 주소를 수신하도록 선언되었습니다.
그러나 아래 코드는 StackRecord 구조 유형 의 주소에 대한 다른 수신자를 반환 합니다. 주소를 반환하지 않는 이유는 무엇입니까? 그러나 오히려 동일한 유형의 포인터를 자체에 반환합니까?
Stack CreateStack(int MaxElements)
{
Stack S;
if (MaxElements < MinStackSize)
{
printf("Error : Stack size is too small");
return 0;
}
S = (Stack)malloc(sizeof(struct StackRecord));
if (S == NULL)
{
printf("FatalError : Out of Space!!!");
return 0;
}
S->Array = (int*)malloc(sizeof(char)* MaxElements);
if (S->Array == NULL)
{
printf("FatalError : Out of Space!!!");
return 0;
}
S->Capacity = MaxElements;
MakeEmpty(S);
return S;
}
typedef를 제거 하면 믿거 나 말거나 조금 더 명확해질 수 있습니다 .
struct StackRecord
{
int Capacity;
int TopOfStack;
int* Array;
};
/**
* Return a pointer to a new, dynamically allocated instance
* of struct StackRecord
*/
struct StackRecord *CreateStack(int MaxElements)
{
struct StackRecord *S;
if (MaxElements < MinStackSize)
{
printf("Error : Stack size is too small");
return 0;
}
S = malloc(sizeof *S); // no need for cast, sizeof *S is same as sizeof (struct StackRecord)
if (S == NULL)
{
printf("FatalError : Out of Space!!!");
return 0;
}
/**
* Allocate the memory for the Array member of
* the new stack record instance.
*/
S->Array = malloc( sizeof *S->Array * MaxElements );
if (S->Array == NULL)
{
printf("FatalError : Out of Space!!!");
return 0;
}
S->Capacity = MaxElements;
MakeEmpty(S);
return S;
}
게시 한 코드에서는 Stack
기본적으로 struct StackRecord *
. 이 함수는 struct StackRecord
using 의 새 인스턴스를 만들고 malloc
해당 레코드의 내용을 초기화 한 다음 해당 새 인스턴스에 대한 포인터를 반환합니다.
malloc
호출 에 대한 참고 사항 -C에서는의 결과를 캐스팅 할 필요가 없으며 malloc
그렇게하는 것은 일반적으로 나쁜 습관 1로 간주됩니다 . 또한, 피연산자하는 sizeof
타입의 이름 일 필요는 없습니다 - 그것은 표현 될 수 의 당신은 할당 할 유형. IOW, 다음과 같은 선언이 주어지면
T *p;
모두 sizeof (T)
와 sizeof *p
같은 일을 않음 - 표현 *p
유형이 있습니다 T
. 따라서 malloc 호출의 일반적인 형식은 다음과 같이 작성할 수 있습니다.
T *p = malloc( sizeof *p * N );
또는
T *p;
...
p = malloc( sizeof *p * N );
작성하기 쉽고 유지하기가 쉽습니다.
p = (T *) malloc( sizeof (T) * N );
<폭탄>
typedef 뒤에 유형의 포인터를 숨기는 것은 좋지 않습니다. 특히 해당 유형의 사용자가 자신이 포인터 유형을 다루고 있음 을 알아야 할 때 더욱 그렇습니다 . 결과를 malloc
to에 할당 S
한다는 것은 포인터 유형 S
이어야 함 을 의미 합니다 . 의 ->
멤버에 액세스 하기 위해를 사용 S
한다는 것은 또는 유형에 대한 포인터 S
여야 함을 의미 합니다 . 이 때문에 이 점에 유의하는 포인터입니다, 그것은 형식 정의 뒤에 그 pointerness을 숨길 이해되지 않는다. 마찬가지로 사용자가 유형 의 -ness를 알고 있어야 한다면 typedef 뒤에 -ness를 숨기면 안됩니다 .struct
union
S
struct
struct
추상화는 강력한 도구이지만 원본 코드와 같은 부분적 (누수) 추상화는 모든 사람에게 삶을 더 혼란스럽게 만듭니다 (직접 발견했듯이).
</ rant>
void *
C가하는 방법과 다른 포인터 타입을. 그러나 C ++를 작성하는 경우 malloc
어쨌든 사용해서는 안됩니다 .이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다