programing

몇 가지 수준의 조언을 얻을 수 있습니까?

goodcopy 2022. 8. 1. 21:49
반응형

몇 가지 수준의 조언을 얻을 수 있습니까?

( 「」 「」)*는일일 수수? ?? ???

다음 예를 들어 보겠습니다.

int a = 10;
int *p = &a;

마찬가지로 우리는

int **q = &p;
int ***r = &q;

기타 등등.

예를들면,

int ****************zz;

C합니다.standard 한하 、 sandard 하 、 정 standard다 standard standard standard standard 。

5.2.4.1 번역 제한

276 실장에서는 다음 제한 중 적어도1개의 인스턴스를 포함하는 프로그램을 번역 및 실행할 수 있어야 합니다.[...]

279 — 선언의 산술, 구조, 결합 또는 보이드 유형을 수정하는 12개의 포인터, 배열 및 함수 선언자(임의의 조합)

상한은 실장마다 다릅니다.

실제로 C 프로그램은 일반적으로 무한 포인터 방향 지정을 사용합니다.1개 또는 2개의 스태틱레벨이 공통입니다트리플 인다이렉션은 거의 없습니다.하지만 무한대는 매우 흔합니다.

무한 포인터 인다이렉션은 물론 직접 선언자가 아닌 구조체의 도움으로 실현됩니다.이것은 불가능합니다.또한 이 구조에 다른 데이터를 포함할 수 있는 구조가 필요합니다.이러한 데이터를 종료할 수 있는 다른 레벨에서 사용할 수 있습니다.

struct list { struct list *next; ... };

이제 당신은 가질 수 있다list->next->next->next->...->next 포인터 즉, 포인터 표시는 여러 개입니다.*(*(..(*(*(*list).next).next).next...).next).next★★★★★★★....next첫 으로 '에 'Noop'이라고할 수 .그래서 우리는 이것을 이 구조체의 첫 번째 멤버로 상상할 수 있습니다.***..***ptr.

이러한 거대한 표현보다는 루프를 통해 링크를 통과할 수 있고 구조를 쉽게 원형으로 만들 수 있기 때문에 여기에는 제한이 없습니다.

즉, 링크 리스트는 문제를 해결하기 위해 다른 수준의 간접을 추가하는 궁극적인 예가 될 수 있습니다.이는 푸시 조작마다 동적으로 링크 리스트가 이루어지기 때문입니다.:)

사람들이 말했듯이, "이론적으로" 제한은 없다.g++ 4.1.2로 실행해 보니, 최대 20,000 사이즈로 동작했습니다.컴파일이 느려서 더 높이려고 하지 않았어요. g것 ()size = 10할 수 ptr.cpp에서 확인할 수 있습니다.

g++ create.cpp -o create ; ./create > ptr.cpp ; g++ ptr.cpp -o ptr ; ./ptr

create.cpp

#include <iostream>

int main()
{
    const int size = 200;
    std::cout << "#include <iostream>\n\n";
    std::cout << "int main()\n{\n";
    std::cout << "    int i0 = " << size << ";";
    for (int i = 1; i < size; ++i)
    {
        std::cout << "    int ";
        for (int j = 0; j < i; ++j) std::cout << "*";
        std::cout << " i" << i << " = &i" << i-1 << ";\n";
    }
    std::cout << "    std::cout << ";
    for (int i = 1; i < size; ++i) std::cout << "*";
    std::cout << "i" << size-1 << " << \"\\n\";\n";
    std::cout << "    return 0;\n}\n";
    return 0;
}

이론상:

원하는 만큼 많은 수의 지시사항을 가질 수 있습니다.

실질적으로:

물론 메모리를 소비하는 것은 무제한일 수 없습니다.호스트 환경에서 사용 가능한 리소스로 인해 제한이 있습니다.따라서 실질적으로 구현이 지원할 수 있는 최대 한도가 있으며 구현은 이를 적절히 문서화해야 합니다.따라서 이러한 모든 아티팩트에서 표준에는 최대 한계가 지정되어 있지 않지만 하한은 지정되어 있습니다.

다음은 참고 자료입니다.

C99 표준 5.2.4.1 변환 제한:

: 선언의 산술, 구조, 결합 또는 보이드의 유형을 수정하는 12개의 포인터, 배열 및 함수 선언자(임의의 조합).

이것은, 모든 실장이 서포트할 필요가 있는 하한치를 지정합니다.각주에서는 표준에는 다음과 같이 기술되어 있습니다.

18) 가능한 한 일정한 번역 제한을 부과하지 않도록 합니다.

실제로 기능에 대한 포인터가 있으면 더 재미있습니다.

#include <cstdio>

typedef void (*FuncType)();

static void Print() { std::printf("%s", "Hello, World!\n"); }

int main() {
  FuncType const ft = &Print;
  ft();
  (*ft)();
  (**ft)();
  /* ... */
}

여기에 나와 있는 바와 같이 다음과 같은 이점이 있습니다.

아아아아아!
아아아아아!
! ★★★★★★★★★★★★★★★★★★★★★★!

또한 런타임 오버헤드가 발생하지 않으므로 원하는 만큼 쌓을 수 있습니다.컴파일러가 파일을 체크할 때까지 계속합니다.

모든 C++ 개발자들은 유명한 3성급 프로그래머에 대해 들어봤을 것이다.

그리고 위장해야 할 마법의 '침묵 장벽'이 있는 것 같아요

C2에서 인용:

삼성 프로그래머

C-프로그래머용 등급 시스템입니다.포인터가 간접적일수록(즉, 변수 앞에 "*"가 많을수록) 평판이 높아집니다.별 없는 C-프로그래머는 사실상 존재하지 않으며, 이는 사실상 모든 사소한 프로그램들이 포인터의 사용을 필요로 하기 때문입니다.대부분은 원스타 프로그래머입니다.옛날에는(음, 나는 젊기 때문에 적어도 옛날처럼 보인다) 가끔 3성급 프로그래머가 만든 코드를 발견하고 경외감에 떨곤 했다.어떤 사람들은 심지어 한 가지 이상의 간접적인 수준에서 함수 포인터가 포함된 3성 코드를 봤다고 주장하기도 했다.UFO처럼 진짜처럼 들리네요.

제한은 없습니다. 여기서 를 확인하십시오.

정답은 "지시 수준"이 무엇을 의미하느냐에 따라 달라집니다."단일 선언으로 몇 가지 수준의 간접성을 가질 수 있습니까?답은 '최소 12'입니다.

int i = 0;

int *ip01 = & i;

int **ip02 = & ip01;

int ***ip03 = & ip02;

int ****ip04 = & ip03;

int *****ip05 = & ip04;

int ******ip06 = & ip05;

int *******ip07 = & ip06;

int ********ip08 = & ip07;

int *********ip09 = & ip08;

int **********ip10 = & ip09;

int ***********ip11 = & ip10;

int ************ip12 = & ip11;

************ip12 = 1; /* i = 1 */

"프로그램이 읽기 어려워지기 전에 몇 가지 수준의 포인터를 사용할 수 있습니까?"라고 묻는다면 이는 취향의 문제이지만 한계가 있습니다.두 가지 수준의 간접(무언가에 대한 포인터)을 갖는 것은 일반적입니다.그 이상은 쉽게 생각하기 어렵다; 다른 대안이 더 나빠지지 않는 한 그렇게 하지 마라.

"실행 시 지정할 수 있는 포인터 리디렉션 수준 수"를 의미하는 경우, 제한은 없습니다.이 점은 각 노드가 다음 노드를 가리키는 순환 목록의 경우 특히 중요합니다.프로그램은 포인터를 영원히 따를 수 있습니다.

확인해보니 재미있을 것 같네요.

  • Visual Studio 2010(Windows 7 의 경우)에서는, 다음의 에러가 발생하기 전에, 1011 레벨을 설정할 수 있습니다.

    치명적인 오류 C1026: 파서스택 오버플로, 프로그램이 너무 복잡함

  • gcc(Ubuntu), 100k 이상*하드웨어가 한계인 것 같아요.

(변수 선언만으로 변경 가능)

템플릿 메타프로그래밍에서는 임의의 수의 *를 가진 타입을 생성할 수 있다는 점을 지적하고 싶습니다.정확히 무엇을 하고 있었는지 잊어버리고 있습니다만, 재귀적인 T* 타입을 사용하여 메타 조작을 하는 새로운 독자적인 타입을 만들 수 있다고 제안되고 있습니다.

템플릿 메타프로그래밍은 광기 상태에 빠지는 속도가 느리기 때문에 수천 개의 간접 수준을 가진 유형을 생성할 때 변명할 필요가 없습니다.예를 들어 기능적 언어로 템플릿 확장에 peano 정수를 매핑하는 편리한 방법입니다.

한이 없다.포인터는 내용이 주소인 메모리 청크입니다.
말씀하신 대로

int a = 10;
int *p = &a;

포인터에 대한 포인터도 다른 포인터의 주소를 포함하는 변수입니다.

int **q = &p;

여기서q다음 주소를 유지하는 포인터에 대한 포인터입니다.p그것은 이미 의 주소를 가지고 있다.a.

포인터에 대한 포인터는 특별히 특별한 것이 없습니다.
따라서 다른 포인터의 주소를 유지하는 폰터 체인에 제한이 없습니다.
즉,

 int **************************************************************************z;

허용됩니다.

2004년 MISRA C 표준의 규칙 17.5에서는 포인터 방향 전환의 레벨이 3을 넘지 않도록 하고 있습니다.

여기서 생각할 수 있는 질문은 두 가지가 있습니다.C 타입으로 얻을 수 있는 포인터 인다이렉션의 레벨과 단일 선언자에 넣을 수 있는 포인터 인다이렉션의 레벨입니다.

C 표준은 전자에 최대값을 부과할 수 있도록 허용하고 최소값을 부여한다.그러나 이는 여러 typedef 선언을 통해 회피할 수 있습니다.

typedef int *type0;
typedef type0 *type1;
typedef type1 *type2; /* etc */

따라서 이는 최종적으로 C 프로그램을 거부하기 전에 얼마나 큰/복잡하게 만들 수 있는지에 대한 개념과 관련된 구현 문제이며, 이는 매우 컴파일러에 따라 다릅니다.

실제 한계 같은 은 없지만 한계라는 것은 존재한다.모든 포인터는 보통 힙이 아닌 스택에 저장되는 변수입니다.스택은 보통 작습니다(일부 링크 중에 크기를 변경할 수 있습니다).예를 들어, 4MB 스택이 있다고 가정해 봅시다.이것은 매우 정상적인 크기입니다.또한 4바이트 크기의 포인터가 있다고 가정합니다(아키텍처, 타깃 및 컴파일러 설정에 따라 포인터의 크기가 동일하지 않습니다).

경우, 「 」4 MB / 4 b = 1024따라서 가능한 최대 수는 1048576이지만 스택에 다른 항목이 있다는 사실을 무시해서는 안 됩니다.

그러나 일부 컴파일러는 최대 수의 포인터 체인을 가질 수 있지만 스택사이즈 제한이 있습니다.따라서 무한 링크 중에 스택 크기를 늘리고 메모리를 처리하는 OS를 실행하는 무한 메모리를 가진 머신을 가지고 있으면 포인터 체인이 무제한이 됩니다.

「 」를 사용하고 int *ptr = new int;포인터를 힙에 넣습니다.이것은, 스택이 아니고, 힙 사이즈가 제한되는 일반적인 방법이 아닙니다.

편집:infinity / 2 = infinity머신의 메모리가 증가하여 포인터의 사이즈가 커지는 경우.억) 한 한)면 、 면면면면면면면 면면면면

포인터를 보관하는 장소에 따라 다릅니다.스택에 있는 경우 제한이 상당히 낮습니다.한 무더기로 저장하면 제한이 훨씬 높아집니다.

이 프로그램을 보세요.

#include <iostream>

const int CBlockSize = 1048576;

int main() 
{
    int number = 0;
    int** ptr = new int*[CBlockSize];

    ptr[0] = &number;

    for (int i = 1; i < CBlockSize; ++i)
        ptr[i] = reinterpret_cast<int *> (&ptr[i - 1]);

    for (int i = CBlockSize-1; i >= 0; --i)
        std::cout << i << " " << (int)ptr[i] << "->" << *ptr[i] << std::endl;

    return 0;
}

가 생성되고 에서첫 변수에 체인이 알 수 .number.

. BTW를 합니다.92K얼마나 깊이 들어갈 수 있는지 상상해 보세요.

언급URL : https://stackoverflow.com/questions/10087113/how-many-levels-of-pointers-can-we-have

반응형