int* xp의미는

&int (int 크기의 실제 값[13]이 담긴 공간의 주소값 [0x0012FF44]) int* xp에 담음

 

일반 변수

포인터 변수

참조 변수

 

일반 변수는 / 기본적으로 메모리 주소를 1번 참조해서 실제 값을 가져온다.

C++ 포인터 변수명, 참조를 참조 변수명 >> ref >> value

C++ 참조 변수명, 참조 변수명 >> value

C# 객체 변수명, 참조 변수명 >> value

 

 

: C++ 에서, 일반적으로 array, vector 같은 컨테이너는 생성시, 변수명은 포인터다. (참조의 참조값이다.)

이를 함수내에서 참조 접근하려면, 정의시 *포인터 연산자를, 함수 내의 CRUD는 &주소 연산자로 접근한다.

일반 변수 타입도 같은 방법을 쓴다.

 

: C# 에서 array, list 같은 컬랙션은 참조다. object obj = new();

매개변수 array, list의 이름만 주면, 참조된다. 그냥. 주고. 그냥. 쓰면. 참조. 된다.

일반 변수는 다르다. 전달시 실행 객체 맴버라서, 다른 객체의 맴버가 아니라서 그런가 보다.

 

: 차이점은 C# 에서

1. 일반 변수는 ref, out으로 접근

2. thread 는 ref, out 조차 안됨

3. thread 에서 array, list 는 된다. 객체라서

 

당연한데, 당연하지 않다.

C#은 객체 참조라서, C++은 포인터라서 사용법이 다르다..

 

C++도 참조변수로 받으면 같을거 같다.

역시 C/C++ 이 더 편하다.

C++에서 포인터와 참조차이를 못 익혔다면, C#에서 참조와 일반 변수 차이를 짐작이나 했을까?

 


C# 쓰레드 실행시, 매개변수에 "리스트의 변수명(test)"만 명시해도, 잘 작동한다. 

static async Task Main(string[] args)
{
    List<int> test = new();

    add12(test);
    foreach (int item in test)
        Console.Write("{0} ", item);

    Console.WriteLine();

    await Task.Run(() => add34(test));
    foreach (int item in test)
        Console.Write("{0} ", item);
}

public static void add12(List<int> test)
{
    test.Add(1);
    test.Add(2);
}

public static void add34(List<int> test)
{
    test.Add(3);
    test.Add(4);
}

// 1 2
// 1 2 3 4

"일반 변수명(num)"은 안된다.

static async Task Main(string[] args)
{
    int num = 0;

    await Task.Run(() => assign9_no_ref(num));
    Console.Write("\n{0} ", num);

    await Task.Run(() => assign9_ref(ref num));
    Console.Write("{0} ", num);
}

public static void assign9_no_ref(int not_ref)
{
    not_ref = 9;
}

public static void assign9_ref(ref int num)
{
    num = 9;
}

// 0 9
ubiquitous4g