programing

C의 포인터: 앰퍼샌드와 아스타리스크를 사용하는 경우

goodcopy 2022. 8. 10. 21:33
반응형

C의 포인터: 앰퍼샌드와 아스타리스크를 사용하는 경우

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★는 알고 있다& 및 변수 주소입니다.*포인터 변수 앞에 사용하면 포인터가 가리키는 개체의 값을 얻을 수 있습니다.그러나 배열, 문자열 또는 변수의 포인터 복사본을 사용하여 함수를 호출할 때는 다르게 작동합니다.이 모든 것 안에서 논리적인 패턴을 보는 것은 어렵다.

로 하면 요?& ★★★★★★★★★★★★★★★★★」*

포인터와 값이 있습니다.

int* p; // variable p is pointer to integer type
int i; // integer value

를 「」가 붙은 합니다.*:

int i2 = *p; // integer i2 is assigned with integer value that pointer p is pointing to

을 합니다.&:

int* p2 = &i; // pointer p2 will point to the address of integer i

편집: 어레이의 경우 포인터와 같이 취급됩니다.그것들을 포인트로 생각한다면, 당신은 그것을 사용할 것이다.*한 것과 그 을 얻기 더, 더 일반적인 은 '나중에', '나중에', '나중에', '나중에', '나중에', '나중에', '나중에', '나중에', '나중에', '나중에', '나중에', '나중에'를 사용하는 것입니다[]★★★★★★★★★★★★★★★★★★:

int a[2];  // array of integers
int i = *a; // the value of the first element of a
int i2 = a[0]; // another way to get the first element

두 번째 요소를 가져오려면:

int a[2]; // array
int i = *(a + 1); // the value of the second element
int i2 = a[1]; // the value of the second element

그...[]는 특수 연산자입니다.*오퍼레이터는 다음과 같이 동작합니다.

a[i] == *(a + i);  // these two statements are the same thing

간단히 말하면

  • &주소란 C와 같이 파라미터 변수를 수정하는 함수의 자리 표시자에서는 파라미터 변수가 값별로 전달되고 앰퍼샌드 수단이 참조로 전달되는 것을 알 수 있습니다.
  • *포인터 변수의 참조 해제를 의미합니다.즉, 포인터 변수의 값을 가져옵니다.
int foo(int *x){
   *x++;
}

int main(int argc, char **argv){
   int y = 5;
   foo(&y);  // Now y is incremented and in scope here
   printf("value of y = %d\n", y); // output is 6
   /* ... */
}

줍니다.foo

int foo(int x){
   x++;
}

int main(int argc, char **argv){
   int y = 5;
   foo(y);  // Now y is still 5
   printf("value of y = %d\n", y); // output is 5
   /* ... */
}

여기 디레퍼런스를 사용하는 그림이 있습니다.

int main(int argc, char **argv){
   int y = 5;
   int *p = NULL;
   p = &y;
   printf("value of *p = %d\n", *p); // output is 5
}

위는 주소의 취득 방법을 나타내고 있습니다. y 변수에 했습니다.p그럼 참조를 해제하겠습니다. p「」를 .* .p discriptions.*p.

어레이나 기능을 다룰 때는 패턴이 있습니다.처음에는 조금 알기 어려울 뿐입니다.

어레이를 취급할 때는 다음 사항을 기억해 두면 편리합니다.대부분의 컨텍스트에서 어레이식이 표시될 때 이 식의 유형은 암묵적으로 "N-element array of T"에서 "point to T"로 변환되고 그 값은 어레이의 첫 번째 요소를 가리키도록 설정됩니다.이 입니다.& ★★★★★★★★★★★★★★★★★」sizeof연산자 또는 선언에서 이니셜라이저로 사용되는 문자열 리터럴일 경우.

따라서 어레이 식을 인수로 사용하여 함수를 호출하면 해당 함수는 어레이가 아닌 포인터를 받습니다.

int arr[10];
...
foo(arr);
...

void foo(int *arr) { ... }

때문에, Ethernet을 사용하지 않습니다.&"%s"의 "%scanf():

char str[STRING_LENGTH];
...
scanf("%s", str);

변환에 , 「 」는scanf()char *의 값str 이는 )에됩니다.str* 「」,*scanf ★★★★★★★★★★★★★★★★★」*printf기능 등)을 참조해 주세요.

어레이 수 .& operator: operator: operator:

int arr[N];
...
foo(&arr);

void foo(int (*p)[N]) {...}

이러한 코드는 그다지 일반적이지 않습니다.함수 선언에서 배열 크기를 알아야 하며 함수는 특정 크기의 배열에 대한 포인터에서만 작동합니다(T의 10 요소 배열에 대한 포인터는 T의 11 요소 배열에 대한 포인터와는 다른 유형입니다).

&은 "" "T" N-element 배열에 포인터"입니다.T (*)[N]T *[N]타입에 「」 「」 「」)입니다.T *

함수 및 포인터를 다룰 때 기억해야 할 규칙은 다음과 같습니다.인수의 값을 변경하여 호출 코드에 반영하려면 수정하는 포인터를 전달해야 합니다.어레이는 작업에 약간의 번거로움을 주지만, 우선 일반적인 케이스부터 다루도록 하겠습니다.

C는 모든 함수 인수를 값별로 전달합니다.formal 파라미터는 실제 파라미터 값의 복사본을 수신하고 formal 파라미터의 변경은 실제 파라미터에 반영되지 않습니다.일반적인 예는 스왑 기능입니다.

void swap(int x, int y) { int tmp = x; x = y; y = tmp; }
...
int a = 1, b = 2;
printf("before swap: a = %d, b = %d\n", a, b);
swap(a, b);
printf("after swap: a = %d, b = %d\n", a, b);

다음과 같은 출력이 표시됩니다.

스왑 전: a = 1, b = 2스왑 후: a = 1, b = 2

「」x ★★★★★★★★★★★★★★★★★」y은 사물과 됩니다.a ★★★★★★★★★★★★★★★★★」b 「」로 .x ★★★★★★★★★★★★★★★★★」y되지 않다a ★★★★★★★★★★★★★★★★★」ba ★★★★★★★★★★★★★★★★★」b포인터를 스왑 함수에 전달해야 합니다.

void swap(int *x, int *y) {int tmp = *x; *x = *y; *y = tmp; }
...
int a = 1, b = 2;
printf("before swap: a = %d, b = %d\n", a, b);
swap(&a, &b);
printf("after swap: a = %d, b = %d\n", a, b);

이제 출력은 다음과 같습니다.

스왑 전: a = 1, b = 2스왑 후: a = 2, b = 1

기능에서는 '바꾸다'의 x ★★★★★★★★★★★★★★★★★」y, 의 「」입니다.x ★★★★★★★★★★★★★★★★★」y 가리키다기입처*x 쓰는 x. ;에서는 갱신하고 있지 않습니다.x자체로는 '를 알 수 있다'에서 를 알 수 있습니다.x해당 위치의 값을 업데이트합니다.

이것은 포인터 값을 수정하는 경우에도 마찬가지입니다.

int myFopen(FILE *stream) {stream = fopen("myfile.dat", "r"); }
...
FILE *in;
myFopen(in);

다음 입력 변수 stream아니라stream 포인트, 즉 변경stream의 값에 영향을 미치지 in 조작을하려면 , 포인터를 합니다 포인터를 건네주셔야 합니다.

int myFopen(FILE **stream) {*stream = fopen("myFile.dat", "r"); }
...
FILE *in;
myFopen(&in);

다시 말하지만, 어레이는 작업에 약간의 번거로움을 줍니다.배열 식을 함수에 전달하면 함수가 받는 것은 포인터입니다.어레이 첨자가 정의되어 있기 때문에 어레이에서 사용하는 것과 동일한 방법으로 포인터에서 첨자 연산자를 사용할 수 있습니다.

int arr[N];
init(arr, N);
...
void init(int *arr, int N) {size_t i; for (i = 0; i < N; i++) arr[i] = i*i;}

어레이 오브젝트는 할당되지 않을 수 있습니다.즉, 다음과 같은 작업은 할 수 없습니다.

int a[10], b[10];
...
a = b;

어레이에 대한 포인터를 다룰 때 주의해야 합니다.

void (int (*foo)[N])
{
  ...
  *foo = ...;
}

작동하지 않습니다.

, 꽤 도 있어.*/C에서 됩니다.

if*는 이미 됩니다.중 합니다.하다

  • a)*그의 값에 할 수 이타입인 , 또는 된 경우).*★★★★★★★★★★★★★★★★★★」
  • b)*연산자의 있기 이 에는 다른 .이 경우 왼쪽에는 다른 변수가 있어야 합니다.*

if*이치이것은 해당 변수가 포인터임을 의미합니다.

int int_value = 1;
int * int_ptr; //can point to another int variable
int   int_array1[10]; //can contain up to 10 int values, basically int_array1 is an pointer as well which points to the first int of the array
//int   int_array2[]; //illegal, without initializer list..
int int_array3[] = {1,2,3,4,5};  // these two
int int_array4[5] = {1,2,3,4,5}; // are identical

void func_takes_int_ptr1(int *int_ptr){} // these two are identical
void func_takes_int_ptr2(int int_ptr[]){}// and legal

if&이치일반적으로 이 변수는 해당 유형의 변수에 대한 참조임을 의미합니다.

if&는 이미 변수 를 반환합니다.

또한 어레이를 함수에 전달할 때는 어레이가 0 종단 cstring(char 어레이)과 같은 경우를 제외하고 어레이의 어레이 크기도 항상 전달해야 합니다.

나는 모든 단어에 대한 설명을 훑어보고 있었고 대신 구조를 위해 뉴사우스웨일스 대학의 비디오를 보았다.입니다.주소가 있는 셀이 있으면x 값 " " "7 값의 하는 간접적인 , 「」7&7으로 주소에서 할 수 .x*x...(cell: x , value: 7) == (cell: &7 , value: *x) 다른 보면, '하다' 입니다.John 7th seat . .*7th seat 가리키다John ★★★★★★★★★★★★★★★★★」&John 주다addresscontractions의 7th seat이 간단한 설명은 나에게 도움이 되었고 그것이 다른 사람들에게도 도움이 되기를 바란다.여기를 클릭해 주세요.이 가능합니다.여기를 클릭해 주세요.

다음으로 다른 예를 제시하겠습니다.

#include <stdio.h>

int main()
{ 
    int x;            /* A normal integer*/
    int *p;           /* A pointer to an integer ("*p" is an integer, so p
                       must be a pointer to an integer) */

    p = &x;           /* Read it, "assign the address of x to p" */
    scanf( "%d", &x );          /* Put a value in x, we could also use p here */
    printf( "%d\n", *p ); /* Note the use of the * to get the value */
    getchar();
}

추가 기능: 포인터를 사용하기 전에 항상 초기화하십시오.그렇지 않은 경우 포인터는 모든 것을 가리키며, 운영체제는 사용자가 소유하고 있지 않은 메모리에 액세스할 수 없도록 하기 때문에 프로그램이 중단될 수 있습니다.하지만 간단히 말하면p = &x;포인터에 특정 위치를 할당합니다.

당신은 좀 혼란스러운 것 같아요.당신은 포인터에 관한 좋은 튜토리얼/책을 읽어야 합니다.

튜토리얼은 처음에 매우 유용합니다(명확하게 설명).& ★★★★★★★★★★★★★★★★★」*Kenneth Reeek의 "Pointers in C"라는 책을 읽는 것을 잊지 마세요.

「 」의 & ★★★★★★★★★★★★★★★★★」*매우 명확합니다.

예제:

#include <stdio.h>

int main(){
  int x, *p;

  p = &x;         /* initialise pointer(take the address of x) */
  *p = 0;         /* set x to zero */
  printf("x is %d\n", x);
  printf("*p is %d\n", *p);

  *p += 1;        /* increment what p points to i.e x */
  printf("x is %d\n", x);

  (*p)++;         /* increment what p points to i.e x */
  printf("x is %d\n", x);

  return 0;
}

포인터 변수 또는 함수 파라미터를 선언할 때는 *:

int *x = NULL;
int *y = malloc(sizeof(int)), *z = NULL;
int* f(int *x) {
    ...
}

NB: 선언된 각 변수에는 고유한 *가 필요합니다.

값의 주소를 취득하는 경우는, & 를 사용합니다.포인터의 값을 읽거나 쓰려면 *를 사용합니다.

int a;
int *b;
b = f(&a);
a = *b;

a = *f(&a);

어레이는 보통 포인터처럼 취급됩니다.함수에 배열 매개 변수를 선언할 때도 마찬가지로 쉽게 포인터임을 선언할 수 있습니다(같은 의미).배열을 함수에 전달하면 실제로 첫 번째 요소에 포인터를 전달하는 것입니다.

함수 포인터는 규칙을 잘 따르지 않는 유일한 것입니다.& 를 사용하지 않고 함수의 주소를 취득할 수 있습니다.또한 * 를 사용하지 않고 함수 포인터를 호출할 수 있습니다.

사실, 당신은 완전히 이해했으므로 더 이상 알 필요가 없습니다:-)

다음 비트를 추가합니다.

  • 2개의 연산은 스펙트럼의 반대쪽 끝에 있습니다. &를 합니다.「 」 。*는 주소를 지정하여 변수(또는 내용)를 제공합니다.
  • 포인터를 함수에 넘길 때 포인터에 대한 어레이의 "수정"이 이루어집니다.
  • 는, 간접즉, 복수의 )을 할 수 (즉, 「인접」, 「인접」).char **p p입니다.char.

다른 방식으로 작동하는 것에 대해서는, 실제로는 그렇지 않습니다.

  • 어레이는 이미 언급했듯이 함수에 전달될 때 포인터(어레이의 첫 번째 요소)로 저하됩니다.크기 정보는 유지되지 않습니다.
  • 으로 끝나는 C자, 0자)을 나타내는 .\0의 문자의 문자입니다.
  • 변수의 주소를 함수에 전달할 때 포인터를 참조 해제하여 변수 자체를 변경할 수 있습니다(일반적으로 변수는 값(배열 제외)으로 전달됩니다).

네 게시물이 편집된 것 같은데...

double foo[4];
double *bar_1 = &foo[0];

에 대해서는, 을 참조해 주세요.&어레이 구조의 시작 주소를 얻을 수 있습니까?와 같다

Foo_1(double *bar, int size){ return bar[size-1]; }
Foo_2(double bar[], int size){ return bar[size-1]; }

같은 일을 할 겁니다

요점을 이해하는 것은 처음에는 복잡하지만, 여러분은 많은 연습과 연습을 해야 합니다.첫 번째 반복에서 이해하기를 기대하거나 설명을 읽고 이해했다고 생각하기를 기대하지 마십시오. 왜냐하면 당신은 이해하지 못했을 가능성이 매우 높기 때문입니다.

이론적인 이해뿐만 아니라 Stanford CS107의 이 코스를 따라 연습하는 것이 좋습니다.적어도 포인터가 설명되는 첫 번째 세 가지 레슨을 따르세요.

스탠포드 CS107 by Jerry Cain

하나의 매우 있는 는 '하다'입니다.gdb예를 들어, 비단뱀과 같은 인터랙티브 쉘을 가지고 있습니다.★★★★★★★★★★★★★★★★ gdb을 사용하다

 (gdb) x pp.name
0x555555555060 <_start>:        0x8949ed31
(gdb) x &pp.name
0x7fffffffdc38: 0x55555060
(gdb) p &pp.name
$4 = (char **) 0x7fffffffdc38
(gdb) p *pp.name
$5 = 49 '1'

언급URL : https://stackoverflow.com/questions/2094666/pointers-in-c-when-to-use-the-ampersand-and-the-asterisk

반응형