고급 포인터: 배열 포인터, 포인터 배열, 문자 포인터(매우 자세한 설명, Xiaobai는 한눈에 이해할 수 있습니다!!!!!!)

목차

I. 소개

2. 포인터 배열과 배열 포인터 판단 방법

1. 문자 그대로 받아들이기

2. 기호의 측면에서 이해 

3. 포인터 배열

1. 포인터 배열의 적용 

2. 포인터 배열의 입력

 4. 배열 포인터

다섯, 문자 포인터

1. 캐릭터 포인터의 활용

2. 문자포인터의 에러포인트

여섯, 상호 격려


I. 소개

포인터에 대한 사전적 이해를 했다면 현시점에서는 기본적인 포인터를 이해하고 쓸 수 있는 포인터에 머물고 있다는 것을 알게 될 것입니다 . 포인터. 문제 풀이, 거물 코드 읽기 등의 일상적인 관행에 이런 것들이 계속 나타나기 때문에이 지식은 항상 저를 괴롭 혔습니다.주의 깊게 조사한 후 적어서 여러분과 공유하겠습니다.

기본 사항을 잊은 경우 기본 포인터에 대한 이전 이해를 살펴볼 수 있습니다.

(295메세지) 포인터 기본 이해 (간단, 이해하기 쉬움, 초상세!!!)_sunny-ll's blog-CSDN blog

2. 포인터 배열과 배열 포인터 판단 방법

1. 문자 그대로 받아들이기

"배열 포인터 " 및 " 포인터 배열 ", 명사 중간에 " 의 "라는 단어를 추가하면 중심을 알 수 있습니다——

배열 포인터: 포인터 인데 어떤 포인터인가요? 배열에 대한 포인터입니다.

포인터 배열: 배열입니다 . 어떤 배열입니까? 포인터의 배열입니다.

2. 기호의 측면에서 이해 

우선 순위를 지정해야 합니다: ()>[]>*, 그래서:

      (*p)[n]: 우선 순위에 따라 괄호 안을 먼저 보고 p는 포인터이고 이 포인터는 1차원 배열을 가리키고 배열의 길이는 n이며 이것이 "배열 포인터"입니다. , 즉 배열 포인터 ;

     *p[n]: 우선순위에 따라 먼저 []를 보고 p는 배열이고 *와 결합하면 이 배열의 요소는 포인터 유형이며 총 n개의 요소가 있습니다. 이것은 "배열"입니다. of pointers", 즉 포인터 의 배열입니다 .

위의 두 가지 분석에 따르면 p가 무엇인지, 그러면 구문의 중심 단어, 즉 배열 "포인터"와 포인터 "배열"이 무엇인지 알 수 있습니다.

3. 포인터 배열

배열의 모든 요소가 포인터를 보유하는 경우 이를 포인터 배열이라고 합니다. 일반적인 형식은 다음과 같습니다.

유형 * 포인터 이름 [ ]

배열이고 배열의 요소는 모두 포인터이며 배열이 차지하는 바이트 수는 배열 자체의 크기에 따라 결정되며 각 요소는 포인터입니다. 

예: char *arr[]={"Sunday", "Monday"}, 두 개의 포인터가 저장됩니다. 첫 번째 포인터는 문자열 "Sunday"를 가리키고 두 번째 포인터는 문자열 "Monday"를 가리킵니다. 

포인터 배열의 가장 중요한 용도는 여러 문자열에 대한 작업을 수행하는 것입니다. 문자 포인터가 2차원 배열보다 빠르고 효율적이기 때문입니다.

 

1. 포인터 배열의 적용 

코드 예제 데모:

#include <stdio.h>
int main()
{
    //定义三个整型数组
	int a[5] = { 1,2,3,4,5 };
	int b[5] = { 6,4,8,3,1 };
	int c[5] = { 2,5,8,6,1 };
    //定义一个存放指向整型变量的指针的数组arr
    int* arr[] = { a,b,c };
    //通过接引用打印出三个一维数组的元素
	for (int i = 0; i < 3; i++)
	{
		for (int j = 0; j < 5; j++)
        {
		    printf("%d ", *(arr[i]+j));
	    }
        printf("\n");
    }
	return 0;
}

결과:

1 2 3 4 5

 6 4 8 3 1

 2 5 8 6 1

위에서 arr을 역참조하는 방법은 여러 가지가 있으며 모두 동일합니다. 예를 들어 보겠습니다. 

#include<stdio.h>
int main()
{
	int i = 0;
	int a[3][4] = { {1,2,3,4} ,{5,6,7,8} ,{9,10,11,12} };//定义一个二维数组
	int* pa[3];//定义一个指针数组
	for (i = 0; i < 3; i++)//给指针数组赋值
		pa[i] = a[i];
    printf("指针数组的内容为:\n");
	for (i = 0; i < 3; i++)//打印出指针数组的内容
	{
		int j;
		for (j = 0; j < 4; j++)
			printf("%d ", *(*(pa + i) + j));
		printf("\n");
	}
    //以下均为不同方式的解引用操作
    printf("不同解引用操作的结果为:\n");
	printf("%d,%d\n", a[1][1], *(pa[1] + 1));
	printf("%d,%d\n", a[1][1], *(*(pa+1) + 1));
	printf("%d,%d\n", a[1][1], (*(pa + 1))[1]);
	printf("%d,%d\n", a[1][1], pa[1][1]);
    return 0;
}

결과:

포인터 배열의 내용은 다음과 같습니다.

1 2 3 4 5
6 7 8
9 10 11 12

다양한 역참조 작업의 결과는 다음과 같습니다.

6,6
6,6
6,6
6,6

위의 예에서 역참조하는 방법은 여러 가지가 있으며 이에 상응하는 형식은 다음과 같습니다. 

*( pa[i] + j ) // 등선우 *( a[i] + j )

*( *(p+i) + j ) // 等了于 *( *(a+j) + j )

( *(p+i) )[ j ] // 等了于( *(a+i) )[ j ]

p[ i ][ j ] // 等了于 a[i][j]

중요: 포인터 배열은 문자열 배열 과 함께 사용할 수도 있습니다 . 다음 예를 참조하십시오. 

#include <stdio.h>
int main(){
    char *str[3] = {"lirendada","C语言","C Language"};
 
    printf("%s\n%s\n%s\n", str[0], str[1], str[2]);
    return 0;
}

데이트

c 언어

C 언어

참고: 문자열의 첫 번째 주소는 문자열 자체가 아니라 문자 배열 str에 저장되며, 문자열 자체는 다른 메모리 영역에 위치하며 문자 배열과 분리됩니다.

포인터 배열의 각 요소의 유형이 char *인 경우에만 위와 같이 포인터 배열에 값을 할당할 수 있으며 다른 유형은 할 수 없습니다.

2. 포인터 배열의 입력

포인터 배열에 문자열을 입력하는 방법은 무엇입니까?

1. 포인터는 초기화 중에 지정됩니다(예: char *p = "hello world!" 또는 char *p[3]={"aa", "abc", "ggdd"}) 2. 초기화 중에
적용 정의만 되고 초기화되지 않은 포인터는 메모리 공간을
가리키지 않기 때문에 포인터가 가리키는 위치에 값을 할당할 수 없습니다. 그렇기 때문에 포인터만 정의된 경우 Xalloc이나 new를 사용하여 초기화를 위한 공간을 신청합니다.

공간을 신청하다 

malloc 함수를 사용하여 포인터 배열을 위한 공간을 할당합니다.

malloc은 필요에 따라 프로그램에 할당할 수 있는 메모리 공간을 동적으로 무작위로 할당하는 방법입니다.
예: (char*)malloc(sizeof(char)*20) 은
20개의 문자 유형 데이터 크기에 대한 공간을 동적으로 할당하고 반환된 포인터 유형을 char 유형 포인터로 캐스트하는 것을 의미합니다.

공간을 여는 작업은 루프 문을 사용하여 수행할 수 있습니다(예: for char *p[10]; 적용 가능).

for( i=0 ; i<10 ; i++ ) 
{
   p[i] = ( char *) malloc ( sizeof ( char ) * N ); //为每个指针申请开设N字符的存储空间
}

C 언어를 사용하여 포인터 배열을 입력하고 출력합니다.

#include <stdio.h>
#include <stdlib.h>
int main(void)
{
    char* str[5] = {}; ///5为5个字符串,后面的大括号为初始化
    int i;
    for (i = 0; i < 5; i++)
    {///指针数组如果没有初始化赋值,则要申请空间,切记,否则会出错,这里的100为每个字符串的元素个数最多为100
        str[i] = (char*)malloc(100);
    }
    for (i = 0; i < 5; i++)
    {
        scanf("%s", str[i]); ///这里不用加& ,因为str本身是地址
        // gets(str[i]);
    }
    for (i = 0; i < 5; i++)
    {
        printf("%s ", str[i]);
        // puts(str[i]);
    }
    printf("\n");
    for (i = 0; i < 5; i++)
    {
        free(str[i]);///最后要free,逐个free
    }
    return 0;
}

 작업 결과:

포인터 배열의 적용 주제는 다음 기사를 참조하십시오.

(295개 메시지) 포인터 배열_Layne...'s Blog-CSDN Blog_Array of Pointers

요약: 위의 설명에 따르면 포인터 배열이 2차원 배열의 생성, 문자열의 입력 저장에 적용될 수 있음을  분명히 알 수 있습니다 . 일반 응용 프로그램에서는 실제로 문자열의 입력 저장에 더 많이 사용됩니다. 예를 들어, 제목은 길이를 비교하기 위해 5개의 문자열을 입력하고, 문자열을 사전순으로 연속 입력하고, 문자열을 정렬해야 하는데 이때 포인터 배열을 사용하면 매우 편리합니다! ! ! !

 4. 배열 포인터

대부분의 경우 배열 포인터는 2차원 배열의 생성 및 적용에 주로 사용됩니다. 유형은 다음과 같습니다.

int (*p)[4] = ; 

배열 a를 가리키는 포인터 p를 나타내며 배열 a의 각 행에는 4개의 요소가 있습니다.

괄호는 p 가 a에 포함된 각 1차원 배열의 유형인 *유형의 배열에 대한 포인터임을 나타냅니다 . 우선 순위는 추가해야 하는 것보다 높음 .naked 로 작성하면 p는 2차원 배열 포인터가 아니라 포인터의 배열이 됨을 이해해야 함 .int [4]

[]*()int *p[4]int *(p[4])

배열 이름 a도 표현식에서 p에 해당하는 포인터로 변환됩니다!

포인터 p를 사용하여 2차원 배열의 각 요소에 액세스하는 방법을 살펴보겠습니다. 위의 정의에 따르면:

1)  p배열 a의 시작 부분, 즉 행 0을 가리키고 한 p+1행 앞으로 이동하여 행 1을 가리킵니다.

2)  *(p+1)해당 주소의 데이터, 즉 첫 번째 행 데이터 전체를 가져오는 것을 나타냅니다. 데이터의 행이지만 1행의 0번째 요소가 아니라 여러 데이터라는 점에 유의하십시오. 코드 이해:

#include <stdio.h>
int main(){
    int a[3][4] = { {0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11} };
    int (*p)[4] = a;
    printf("%d\n", sizeof(*(p+1)));
    return 0;
}

   실행 결과: 16

   의미: 행에 4개의 int 정수가 있으므로 4*4=16은 행의 데이터를 나타냅니다.

3) *(p+1)+1은 첫 번째 행의 첫 번째 요소의 주소를 나타냅니다. 그것을 이해하는 방법?

*(p+1)은 단독으로 사용될 때 데이터의 첫 번째 행을 의미하며, 식에 배치될 때 데이터의 첫 번째 행의 첫 번째 주소, 즉 0번째 요소의 주소로 변환됩니다. 전체 행이 사용되기 때문에 첫 번째 행 데이터에는 실제 의미가 없으며 컴파일러는 이 상황이 발생할 때 행의 0번째 요소에 대한 포인터로 변환합니다.

4)  *(*(p+1)+1)첫 번째 행의 첫 번째 요소 값을 나타냅니다. 분명히 *를 추가하는 것은 주소에서 데이터를 가져오는 것을 의미합니다.

위의 결론에 따르면 다음과 같은 등가 관계를 쉽게 추론할 수 있습니다.

a+i == p+i
a[i] == p[i] == *(a+i) == *(p+i)
a[i][j] == p[i][j] == *(a[i]+j) == *(p[i]+j) == *(*(a+i)+j) == *(*(p+i)+j)

배열 포인터에 2차원 배열 적용:

#include <stdio.h>
int main(){
    int a[3][4]={0,1,2,3,4,5,6,7,8,9,10,11};
    int(*p)[4];
    int i,j;
    p=a;
    for(i=0; i<3; i++){
        for(j=0; j<4; j++) printf("%2d  ",*(*(p+i)+j));
        printf("\n");
    }
    return 0;
}

 작업 결과:

0 1 2 3 
 4 5 6 7 
 8 9 10 11

다섯, 문자 포인터

1. 캐릭터 포인터의 활용

(1) 단일 문자

 char  ch='w';
 char *p=&ch;
 //这里的p就是个字符指针 我们可以通过解引用p去改变ch中存的字符'w'。
 *p='s';

(2) 문자열


   const char* pstr="hello bit.";//这里是把一个字符串放到pstr指针变量里了吗? 
   printf("%s\n", pstr);

(2)의 경우
우선 "hello bit."는 상수 문자열이고 여기서 char*는 문자열의 첫 번째 문자의 주소, 즉 h의 주소를 저장합니다.

상수 문자열: 역참조로 변경할 수 없으므로 char* 포인터가 역참조 및 내용 변경을 제한하는 데 const를 사용해야 합니다.

요약: 상수 문자열의 첫 번째 문자 h의 주소는 포인터 변수 pstr에 저장됩니다.

2. 문자포인터의 에러포인트

코드 예:

#include <stdio.h>
int main()
{
    char str1[] ="hello bit.";
    char str2[] ="hello bit.";
    
    const char* str3="hello bit.";    
    const char* str4="hello bit.";
    
    if(str1==str2)
       printf("str1 and str2 are same\n");    
    else
       printf("str1 and str2 are not same\n");   
           
    if(str3==str4)
       printf("str3 and str4 are same\n");    
    else
       printf("str3 and str4 are not same\n");       
    return 0;
}

str1과 str2는 같지 않고 str3과 str4는 같은 이유는 무엇입니까?


우선, 예제 1에서 두 개의 if 비교는 모두 주소입니다.

str1과 str2 사이의 비교는 배열의 첫 번째 요소의 주소입니다. 배열이 메모리의 공간을 열어서 str1과 str2의 주소가 다르기 때문입니다.
str3 및 str4는 문자 포인터이며 문자열의 첫 번째 문자 주소를 비교합니다. 이 두 포인터에 저장된 내용은 "hello bit"입니다. 이들은 동일한 상수 문자열이며 메모리의 동일한 상수 문자열
은 하나의 사본으로 저장되므로 str3과 str4의 주소는 동일합니다.

여섯, 상호 격려

다음은 배열 포인터, 포인터 배열, 문자 포인터 에 대한 나의 이해입니다. 이해하지 못하거나 문제를 발견하는 친구가 있으면 댓글란에 알려주십시오. 동시에 계속해서 이해를 업데이트하겠습니다 . 콜백 포인터 qsort 함수 , 계속 팔로우해주세요! ! ! ! !

 

 

추천

출처blog.csdn.net/weixin_45031801/article/details/127381406