programing

C는 왜 ->와 을 구별합니까?

goodsources 2022. 9. 1. 23:24
반응형

C는 왜 ->와 을 구별합니까?

좋아, 이건 심각한 문제는 아니지만, 한동안 날 괴롭혔어이 둘을 구별하는 이유가 있나요?->그리고..오퍼레이터?

물론, 현재의 규칙은 이다..구조물에 작용합니다.->는, 포인터 투 포인터(또는 조합)로 동작합니다.하지만 실제 작동 방식은 이렇습니다.허락하다s요소를 내포하고 있는 구조이다x, 그리고,ps같은 형태의 구조물에 대한 포인터입니다.

쓰시면

s->x

컴파일러는...의 방해가 되는 경고를 내뱉을 것이다.

s.x. 를 다시 입력하고 다시 컴파일해 주세요.

쓰시면

ps.x

컴파일러는...의 방해가 되는 경고를 내뱉을 것이다.

ps->x를 말하는 거군요.그것을 다시 입력하고 다시 컴파일하세요.

컴파일러는 이 두 가지 유형을 모두 알고 있기 때문입니다.s그리고.ps컴파일 시에는 올바른 연산자가 무엇인지 해석하는 데 필요한 모든 정보가 포함되어 있습니다.올바른 수정에 대한 모호함이 없다는 점에서 다른 경고(세미콜론 누락 등)와 다를 수 있습니다.

예를 들어 C1x 표준위원회에 상정된 제안서를 제시하겠습니다(ISO는 보수적인 성향을 띠고 있기 때문에 이 내용은 고려되지 않습니다).

표현식 lhs.rhs가 주어진 경우, lhs가 구조물 또는 결합 유형인 경우, 표현식은 rhs라는 이름의 lhs 요소를 참조해야 한다.lhs가 구조물에 대한 유형 포인터 또는 -union일 경우, 이는 (*lhs).rhs로 해석되어야 한다.

이렇게 하면 확실히 시간이 절약되고 사람들이 C를 쉽게 배울 수 있게 됩니다.[그리고 저는 C가 학습자가 학습한 것을 알 수 있을 만큼 충분히 가르쳤습니다.]->혼란스럽거나 짜증나는 것 중 하나입니다.

C가 비슷한 일을 하는 전례도 있습니다.예를 들어, 구현의 이유로 함수 선언은 항상 함수 포인터에 캐스팅되므로,f(x,y)그리고.(*f)(x,y)둘 다 효과가 있을 것이다f함수 또는 함수 포인터로 선언되었습니다.

그래서 제 질문은 이 제안이 뭐가 문제라는 거죠?두 사람 사이에 치명적인 모호성이 존재하는 예를 생각해 볼 수 있나요?ps.x그리고.s.x또는 왜 의무적인 구별을 유지하는 것이 다른 방법으로 유용한가?

네가 한 말에 미친 건 없는 것 같아.사용..구조에 대한 포인터가 작동하기 때문입니다.

그러나 나는 구조와 구조에 대한 포인터가 다르게 취급된다는 점이 좋다.

운영 상황에 대한 설명과 비용이 많이 드는 항목에 대한 단서를 제공합니다.

이 단편은 상당히 큰 기능의 중간에 있다고 가정해 보십시오.

s.c = 99;
f(s);

assert(s.c == 99);

현재로선 알 수 있다s구조입니다.모든 것이 복사되는 것을 알고 있습니다.f주장은 발포할 수 없다는 것도 알고 있습니다

사용하는 경우.구조에 대한 조언이 허락되면, 난 그 중 어떤 것도 알지 못할 것이고, 그 주장은 불붙을지도 모른다.f설정될 수 있다s.c(오류)s->c)을 다른 것으로.

또 다른 단점은 C++와의 호환성이 떨어진다는 것입니다.C++는 허용->클래스가 '좋아요' 포인터가 될 수 있도록 클래스가 오버로드됩니다.중요한 것은.그리고.->다르게 행동하다"New" C 코드 사용.C++ 코드로서는 아마 더 이상 받아들여지지 않을 것입니다.

확실히 애매모호하거나 제안을 할 수 없는 것은 아닙니다.유일한 문제는 다음과 같습니다.

p->x = 3;

아시겠지만p는 포인터입니다만, 허가하는 경우는, 다음과 같습니다.

p.x = 3;

이 상황에서는 실제로 알 수 없습니다.그러면 문제가 발생할 가능성이 있습니다.특히 나중에 포인터를 던져서 잘못된 수의 간접적 수준을 사용할 경우 문제가 발생할 수 있습니다.

(상대적인 C++와 대조적으로) C 프로그래밍 언어의 구별되는 특징은 비용 모델이 매우 명확하다는 입니다.화살표는 추가 메모리 참조가 필요하기 때문에 점은 화살표와 구별됩니다.또, C는 메모리 참조의 수를 소스 코드에서 명확하게 하기 위해서 매우 주의합니다.

그런 기능을 C언어 사양에 도입하고 싶다면 나머지 언어와 함께 "blend"하기 위해서는 "decay to pointer"라는 개념을 구조 유형으로 확장하는 것이 논리적인 방법입니다.당신은 함수와 함수 포인터로 사례를 만들었습니다.이렇게 동작하는 이유는 C의 함수 타입이 다음 경우를 제외하고 모든 컨텍스트에서 포인터 타입으로 감소하기 때문입니다.sizeof및 단항&연산자(어레이에 대해서도 같은 일이 일어납니다, BTW).

따라서 제안하신 것과 유사한 것을 구현하기 위해 "구조에서 포인터로 붕괴"라는 개념을 도입할 수 있습니다.이것은 C의 다른 모든 "붕괴"(즉 어레이에서 포인터로 붕괴 및 함수에서 포인트로 붕괴)와 완전히 같은 방식으로 동작합니다.구조 오브젝트 타입의 경우T식에서 사용되며, 그 유형은 즉시 입력으로 감소합니다.T*- 구조 객체의 선두에 대한 포인터 - 피연산자일 경우 제외sizeof또는 단항&일단 이러한 붕괴 규칙이 구조물에 도입되면, 다음을 사용할 수 있습니다.->연산자는 구조물에 대한 포인터가 있는지 또는 왼쪽에 구조물에 대한 포인터가 있는지에 관계없이 구조 요소에 액세스합니다.교환입니다..이 경우에는 완전히 불필요해질 수 있습니다(제가 뭔가를 빠뜨리지 않는 한).->유일한->.

이상, C언어의 정신에 입각해 실시한다면, 이 기능은 어떻게 보일까, 라고 다시 한 번복합니다.

하지만 (찰스가 말한 것에 동의하며) 구조물에 대한 포인터와 구조물에 대한 코드의 시각적 구별을 잃는 것은 그다지 바람직하지 않다고 생각합니다.

추신: 구조물에 대한 이러한 부패 규칙의 명백한 부정적인 결과는 "배열은 단지 끊임없는 지침일 뿐"이라고 믿는 현재의 신참들의 군대 외에, 우리는 "구조물들은 단지 지속적인 지침일 뿐"이라고 믿는 신참들의 군대를 갖게 될 것입니다.또한 Chris Torrek의 어레이 FAQ는 구조를 다루려면 약 1.5~2배 더 커야 합니다.

물론 다음과 같은 복잡한 경우가 있을 수 있습니다.

(*item)->elem

(일부 프로그램에서 있었던 일인데) 만약 당신이 이런 글을 쓴다면

item.elem

즉, Elem이 구조 항목의 요소인지, 항목이 가리키는 구조물의 요소인지, 반복자 항목이 가리키는 목록의 요소인지 등을 혼동할 수 있다.

그래서 구조물에 대한 포인터를 사용할 때 좀 더 명확하게 할 수 있습니다.

네, 괜찮습니다만, C가 정말로 필요로 하는 것은 전혀 아닙니다.

그것은 괜찮을 뿐만 아니라 모던한 스타일이다.Java와 Go는 둘 다 사용만 합니다..레지스터에 들어가지 않는 것은 모두 어느 정도 레퍼런스이기 때문에 적어도 함수 호출에 도달할 때까지는 사물과 포인터구별이 확실히 제멋대로입니다.

첫 번째 진화적 단계는 dmr이 한때 선호했던 것을 암시하는 역참조 연산자 포스트픽스를 만드는 것이었습니다.파스칼이 이렇게 하니까p^.field거기 있는 유일한 이유는->오퍼레이터는 타이핑을 해야 하는 것은 바보 같은 일이기 때문이다.(*p).field또는p[0].field.

그래, 잘 될 거야더 높은 수준의 추상화에서 작동하기 때문에 더 좋습니다.다운스트림 코드를 변경하지 않고 가능한 한 많은 변경을 할 수 있어야 합니다.그것은 어떤 의미에서 상위 레벨의 언어의 전체 포인트입니다.

나는 그것을 사용하는 것에 대해 주장해 왔다.()기능 호출의 경우[]어레이 서브스크립션이 잘못되었습니다.구현마다 다른 추상화 내보내기를 허용하지 않는 이유는 무엇입니까?

하지만 바꿀 이유가 별로 없어요.C 프로그래머들은 한 표현에서 한 문자를 저장하는 통사적 설탕 확장이 부족하다는 것에 대해 반발할 것 같지 않고, 만약 그것이 보편적으로 채택된다면 즉시 사용되지는 않을 것이기 때문에 어쨌든 사용하기 어려울 것이다.표준 위원회가 잘못되면 결국 빈 방에 설교를 하게 된다는 것을 기억하라.세계 컴파일러 개발자들의 자발적인 협력과 동의를 필요로 합니다.

C에게 정말로 필요한 것은 안전하지 않은 코드를 작성하는 데 조금 더 빠른 방법이 아닙니다.C에서 일하는 것은 상관없지만, 프로젝트 매니저는 자신의 신뢰성이 최악의 사람에 의해 결정되는 것을 싫어하고, C가 정말로 필요로 하는 것은 사이클론이나 Go와 같은 안전한 방언일 가능성이 있습니다.

현재 구문을 사용하면 코드가 포인터와 실제 개체 중 어느 쪽인지 알 수 있습니다.코드를 미리 모르는 사람이 더 잘 이해한다.

언급URL : https://stackoverflow.com/questions/1813865/why-does-c-have-a-distinction-between-and

반응형