를 역 참조 나는 char **
문자 ** 포인터
내 혼란을 종료 하시겠습니까?
나는 char *
이 char에 대한 포인터이며 char *array[]
은 char 포인터의 배열이지만 정확히 char **
은 어떻게 처리합니까?
또한 dereferences라는 단어가 나왔을 때 포인터가 제거되었다고 생각하는 이유는 정확히 포인터를 역 참조하는 것이 무엇입니까? 포인터가 가리키는 값을 변경합니까? 포인터를 역 참조
덕분
를 역 참조 나는 char **
문자 ** 포인터
내 혼란을 종료 하시겠습니까?
나는 char *
이 char에 대한 포인터이며 char *array[]
은 char 포인터의 배열이지만 정확히 char **
은 어떻게 처리합니까?
또한 dereferences라는 단어가 나왔을 때 포인터가 제거되었다고 생각하는 이유는 정확히 포인터를 역 참조하는 것이 무엇입니까? 포인터가 가리키는 값을 변경합니까? 포인터를 역 참조
덕분
같은 메모리 할당 기능/조작자로부터 오는 포인터, 포인터가 가리키는 값에 액세스하는 수단 "역 참조". 다음의 선언을 가정
int a = 10;
int *p = &a;
여기서 두 변수의 가상 메모리 맵이다 :
Item Address 0x00 0x01 0x02 0x03 ---- ------- ---- ---- ---- ---- a 0x80001000 0x00 0x00 0x00 0x0A p 0x80001004 0x80 0x00 0x10 0x00
a
10. p
가 a
(0x80001000)의 어드레스를 포함하는 정수 값을 포함한다. a
부터 p
까지의 내용에 액세스하려면 p
의 간접 참조 연산자 *
을 참조하십시오. 따라서 식 *p
은 식 a
과 같습니다.
#include <stdlib.h>
#define N 20 // For this example, we will allocate 20 strings
#define LENGTH 10 // of 10 characters each (not counting 0 terminator)
...
char **arr = malloc(sizeof *arr * N);
if (arr)
{
size_t i;
for (i = 0; i < N; i++)
{
arr[i] = malloc(sizeof *arr[i] * (LENGTH + 1));
strcpy(arr[i], " ");
}
}
: 우리가
a = 16;
를 작성하는 것과 같은입니다
*p = 16;
을 썼다면 여기에 문자열 배열을 만들 형
char **
의 객체를 사용하는 방법을 보여주는 코드의 짧은 조각이다
줄 단위로 이동,
char **arr = malloc(sizeof *arr * N);
은 문자 (sizeof *arr
== sizeof (char *)
유형이 *arr
== char *
이므로)를 가리키는 데 충분한 N 개의 요소 블록을 할당하고 결과 포인터 값을 arr
에 할당합니다. IOW, arr
은 char
에 대한 첫 번째 포인터를 가리 킵니다. 따라서 char **
유형입니다. 당신은 선언과 함수 호출을 분리하는 경우, 그렇지 않은 것을 arr
점에, 우리는 arr
에 malloc
의 결과를 할당 할
char **arr;
...
arr = malloc(sizeof *arr * N);
과 같을 것이다합니다.
if (arr)
malloc
이 실패하는 것이 가능, 그래서 우리는 그것을 사용하기 전에 결과를 확인하고 싶습니다. malloc
이벤트가 실패하면 NULL 포인터 값을 반환합니다.(; sizeof (char)
는 항상 1이므로주의 *arr[i] == char
의 타입 때문에, sizeof *arr[i] == sizeof (char)
)
arr[i]
들어
{
size_t i;
for (i = 0; i < N; i++)
{
arr[i] = malloc(sizeof *arr[i] * (LENGTH + 1));
우리 LENGTH + 1 개 요소에 대해 충분히 큰 각각은 char
값을 저장하기에 충분히 큰 메모리 블록을 할당 결과를 arr[i]
에 할당하십시오.
각 문자열을 별도의 malloc
호출로 할당하므로 메모리에 인접하지는 않습니다. 여기에서 상기 코드의 가능한 결과 도시 다른 메모리 맵이다 ". *의 P1의 == C를, 즉 비 참조 P1은 우리 /로부터 판독 ℃로 쓸 수"
Item Address 0x00 0x01 0x02 0x03 ---- ------- ---- ---- ---- ---- arr 0x80001000 0xA0 0xCC 0x00 0x00 ... arr[0] 0xA0CC0000 0xA0 0xCC 0x20 0x00 arr[1] 0xA0CC0004 0xA0 0xCC 0x20 0x40 arr[2] 0xA0CC0008 0xA0 0xCC 0x21 0x28 ... arr[19] 0xA0CC0014 0xA0 0xCC 0x23 0x10 ... arr[0][0] 0xA0CC2000 ' ' ' ' ' ' ' ' arr[0][4] 0xA0CC2004 ' ' ' ' ' ' ' ' arr[0][8] 0xA0CC2008 ' ' ' ' 0x00 0x?? ... arr[1][0] 0xA0CC2040 ' ' ' ' ' ' ' ' arr[1][4] 0xA0CC2044 ' ' ' ' ' ' ' ' arr[1][8] 0xA0CC2048 ' ' ' ' 0x00 0x?? ...
포인터를 값을 포인트에 액세스하는 것을 의미한다. 예를 들어,
char c = 'c'; // This is a primitive value. You cannot dereference it.
char* p1 = &c; // A pointer to the address of c
char** p2 = &p1; // A pointer to the address of p1
/* Now, the following is true:
*p1 == c, i.e. dereferencing p1 allows us to read from/write to c.
*p2 == p1
**p2 == *(*p2) == *p1 = c - dereferencing p2 twice is c, too */
대신 C를 C에 대한 포인터를 사용하는 이유는 직접 포인터는 1 개 이상의 값에 액세스 할 수 있다는 것입니다. 이 예를 들면 다음과 같습니다.
char[4] str;
char c0 = 'a', c1 = 'b', c3 = 'c', c4 = '\0';
str[0] = c0; str[1] = c1; str[2] = c2; str[3] = c3;
str = "abc"; // Same as the above line
이제 두 번째 문자가 필요하다고 가정합니다. c1
으로 액세스 할 수 있습니다. 그러나 보시다시피,이 표기법은 정말 귀찮습니다. 또한 파일에서 문자열을 읽는 대신 파일에서 읽는다면 복잡한 작업을해야합니다. 대신, 우리는 첫 번째 요소는 인덱스 0, 두 번째 일을 가지고
str[1] /* or */ *(str+1)
주 쓰기 - 우리가 여기에 1을 사용하는 이유가 있습니다. char**
은 이것을 11까지 바꿉니다. 우리는 char 배열을 가지고 있습니다. 우리가 배열을 가지고 있다고 가정하고, 그것을 input
이라고하고, 그 안에있는 모든 문자열의 길이를 찾아야합니다. 이 방법은 다음과 같습니다.
int lensum(char **input) {
int res = 0;
while (*input) { // This loops as long as the value input points to is not 0.
char* p = *input; // Make a copy of the value input currently points to
while (*p != '\0') { // Loop while the copy does not point to a char '\0'
res += 1; // We found a character
p++; // Check next character in the next iteration
}
input++; // Check next string in the next iteration
}
return res;
}
포인터는 실제 값을 보유하는 대신 주소에 값을 저장하는 유형입니다.
char * p의 경우 한 번 할당하면 p에는 주소 A가 포함됩니다. 포인터를 역 참조한다는 것은 주소 A에 저장된 값을 액세스한다는 의미입니다. char *에 문자열을 저장할 수있는 이유는 다음과 같습니다. 할당 된 메모리는 연속적입니다. 따라서 A는 첫 번째 문자를 저장하는 주소이고 A + 1은 두 번째 문자를 저장하는 주소입니다.
char ** pp의 경우 char * 주소를 저장합니다. 이 주소 B를 호출하십시오. 따라서 dereferencing pp는 주소 B의 값을 액세스하는 것을 의미합니다.이 주소는 char * 일 수 있으며, 이는 문자열을 보유하게됩니다. 마찬가지로 B + 1 (실제로 B + sizeof (char *))은 다른 문자열 인 다음 값을 저장합니다.
pp를 두 번 다시 참조하면 (예 : ** pp) 주소 B의 값 (예 : A)에 액세스 한 다음 다시 한 번 참조 해제하여 다시 문자 A의 값을 가져 오는 것을 의미합니다.
정말 좋은 설명입니다. 감사. – jarryd
미안해, 내가 어쩌면 틀렸어.하지만 배정 후에 완전히 정리하려면 총 문자열 수와 자유 arr [i ]뿐만 아니라 전체 배열 free (arr)를 해제하는 것이 맞습니까? 아니면'자유 (arr)만으로 충분할까? '? –