목차
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 함수 , 계속 팔로우해주세요! ! ! ! !