C언어 타입선언


C언어를 공부하며 코딩한지는 오래됐지만 생각보다 C언어 타입 선언의 읽기와 이해는 맨날 볼때마다 헷갈릴때가 있습니다. 


그래서 이번에 확실하게 정리하기 위해 포스팅을 해봅니다.



C언어의 타입선언 읽기 RULE


- 이름부터 무조건 읽어라. 그리고 이름 에서 가까운 순서로 읽으면 된다.


- 우선순위가 가장 높은것은 [] 배열연산자와, 함수연산자 ()는 먼저 읽어라.


ex:)


int *  (* myVar) [100];

 5 4   2     1       3


해석

=>myVar는 주소를 담는 포인터변수이며, 배열크기 [100]을 가르킬수있는애이며, 배열의 원소는 포인터 변수인데 int형인 자료를 가르키는 애로 쓰인다.


즉 그림으로 그려보면



자 한번에 너무 확 달린것같나요?

그럼 차근차근해보겠습니다. 


char (*arr1)[4]; 

==> arr1은 포인터변수로서 주소를 가지는데, 이변수는 배열의 크기가 [4]인애를 가르키고 그 배열은 char형 자료들로 채워져있다!


-> arr1은 2차원배열의 형태를 가질 수 있습니다.

arr1[임의의 크기][4]



비교) 

int *whoA[4];  // 포인터 배열.


whoA는 크기가 [4]인 배열인데, 포인터변수를(주소를) 가지고있으며, 그 주소는 int형을 가르킨다.



타입 선언 Reading skill


*

- 지금까지 읽은것의 타입은 주소(포인터변수)

- 앞으로 읽을것(다음에 나오는것은) 은, 그 주소(포인터변수)가 가리키는 대상의 자료형(타입)


[]

- 지금까지 읽은 것은 배열

- 앞으로 읽은 것은 배열의 원소하나의 자료형(타입)


()

-지금까지 읽은것은 함수이며 ()안에는 함수파라메터(이건 개발자가 구분해야됨)

- 앞으로 읽을것(다음에 나오는것은) 함수의 리턴타입.





char * (*test1) [10]

5     4 2 1       3


변수명은 test1이며, 자료형은 포인터이며, 그 포인터는 배열크기가 [10]인것을 가리키는데, 그배열은 원소는 포인터 변수인데, 그 포인터 변수는 char 자료형을 가리킨다.





int (* test2 [5] ) (int)

 5  3   1      2    4 


변수명은 test2이며, [5] 배열로써, 원소는 포인터변수인데 이포인터 변수가 가리키는 것은, 파라메터가 (int) 1개를가지며, 반환형이 int인 함수이다.



// 2의 경우 파라메터 변수를 생략할 수 있다. (*blabla)[10]...

char ( * myfunc ( char (*)[10]) ) [10];

5      3    1           2                4


이름이 myfunc이며, 파라메터로 2차원 배열을 가지며, 반환형은 포인터변수인데 이포인터 변수는, 배열의 크기가 [10]인것을 가르키며, 그배열은 char를 담고있다.












1. 꾸준히
매일 꾸준히 하는 것이 중요하다.
경력이 많은 프로그래머들도 몇달만 코딩을 안해도 감이 많이 떨어지는 것을 느낀다.

2. 반복
책의 내용을 잘 이해했다고 해서 하루아침에 프로그래밍을 잘할수 있는 것은 아니다.
이해한 내용을 바탕으로 수많은 반복연습을 통해서만 지식을 진정한 자신의 것으로 만들 수 있다.
처음 2~3번은 자세히 보고, 그 다음 부터는 하루에 10분간 10페이지를 훑어보는 식으로 반복하자.

3. 좋은코드를 많이 보고 따라한다.
이미 수많은 무림의 고수들이 여러문제들에 대한 코딩을 다 작성해 놓았다. 
새로운 방법으로 문제를 풀겠다고 도전하는 것은 헛수고일 확률이 크다.
"이럴때는 이렇게 하는 구나..."라는 것을 배우고 유사한 상황에서 활용하면 되는 것이다. 
여러분들이 해야할일은 이러한 경험들을 많이 쌓아 나가는 일이지, 기존과는 다른 새로운

코딩방식을 만들어 내는 것이 아니다.

좋은 코드는 보기에도 좋다. 잘정리되어 있고, 별로 특별한 것이 없다. 
프로그래밍의 각요소들을 잘이해하고, 각 요소들을 적재적소에 바르게 사용하면 되는 것이다. 
단지 소스의 라인수를 줄인다고해서 좋은 코딩이 아닌것이다. 
로직이 소스코드에 잘드러날수있게 쉽고 평범하게 작성하는 것이 좋은 코드인 것이다.


4. 기본에 충실
처음에 기본을 잘배워놓지 않으면, 그 이후에는 기회가 잘 없다. 
실무에서는 매일 개발하기 바쁘고, 새로운 기술 배우기 바쁘고...

배울것이 많다고 생각할지 모르나, 실제로 원리는 모두 같다고 해도 과언이 아니다.
하나를 깊이있게 파고들면 나머지는 다 여러분 손에 있을 것이다. 


5. 코드를 작성하기전에 순서도를 그린다.  
프로그래밍 = 로직설계 + 코딩"이다. 

새로운 기술이나
프로그램을 공부하는 것도 중요하지만, 어떤 과제가 주어졌을때 이를 잘 분석하고 설계하는
능력을 장기적으로 키워나가도록 노력해야할 것이다.


6. 주석을 가능한한 많이 적는다.

주석은 매우 유용하고도 중요한 요소이다. 
그럼에도 불구하고 많은 사람들이 이를 소홀히 한다.
자신이 작성한 코드도 몇일만 지나면 이해가 안되는 경우가 많다. 
적어도 이해하는데 시간이 걸린다. 
주석은 이러한 시간들을 절약해줄것이며, 보다 에러가 적은 코드를 작성하는데 도움을
줄 것이다. 특히 여러사람이 공동작업을 하는 경우에는 더욱 더 중요하다. 서로를 위해서...
작업과 관련된 가능한한 많은 정보를 주석에 담도록 하자. 


7. 작업일지를 작성한다.
오늘은 이렇게저렇게 해봤는데 잘안되었다... xxx.java의 코드를 이렇게 바꾸었다. 
몇시몇분에 xx로 백업받아놓았다... 라는 식으로 가능한한 자세히 적도록 한다.
 이렇게 함으로써 여러분들의 경험을 기록으로 쉽게 보관할수 있으며, 문제해결에 많은 도움이 된다.
GIT등의 형상관리툴을 이용하면 이런 작업일지를 작성하는데 편리할것이라 생각이 든다.


8. 자신의 소스를 가꾼다.
보통 코딩을 마치고 나면, 모든 것을 덮어두곤 한다. 원하는 결과를 얻었다고 거기서 그치지말고
이제 로직과 코드를 보다 효율적으로 개선할 방법이 없는지 고민해보자. 글을 써놓고 좋은 글로
만들기 위해 읽고 또 읽고 다듬듯이 코드를 다듬어보자. 여러분들의 코드를 구사하는 능력이 보다
향상되어가는 것을 느낄 수 있을 것이다.

여러분들을 위한 제안은 작은 프로그램을 만들어서 오랜기간동안 점차 발전시켜 나가는 것이다.
새로운 기능들을 하나씩 추가해가고, 기능을 발전시켜나가보자. 이과정을 통해서 여러분들의 실력
은 몰라보게 향상될 것이다.

9. 생각하라.
항상 머릿속에 한 가지 문제를 준비하라. 지하철을 기다리거나, 화장실에서 볼일 볼때 문제를 풀어
보자. 


10. 좋은 책을 선택한다.
공부를 시작할때 제일 먼저 하는 일은 아마도 책을 고르는 일일 것이다. 보통 책하나에 수십시간을
학습하게 되는데, 책을 잘못선택한 경우 수십시간과 노력을 허비하는 셈이다.
바른 책을 고르는 일은 쉬운일이 아니지만, 최소한 몇시간을 투자해서 최선의 선택을 하도록 노력
해야 수십시간을 허비하는 일이 없을 것이다.

책을 고르는 법은 여러가지가 있겠으나, 가장 중요한 것은 본인이다. 서점에서 같은 종류의 몇가지
책을 놓고 서로 비교해보면, 시간을 들인 만큼 보다 나은 선택을 할 가능성이 높아진다.

많은 컴퓨터 서적이 독자들의 선택을 어렵게 하고, 컴퓨터 업계 특성상 좋은책을 만들기 보다
빨리찍어서 파는 것이 더 중요해진 요즘. 독자들의 바른 선택이 보다 나은 책이 출판되는 것을
가능하게 한다는 것을 알았으면 한다.


'IT 최신 트렌드' 카테고리의 다른 글

당신을 위한 쿠팡 기획전  (0) 2020.03.14
웹 캐싱 서비스 with 프록시 서버  (0) 2017.07.09

들어가기 앞서

안드로이드 앱은, 자바의 멀티스레드 프로그래밍 모델을 준수해야합니다. 자바가 편하긴하지만 동시프로그램 처리, 데이터 일관성 유지, Task 시퀀스 설정등 복잡성이 증가하는 단점이 있습니다. 이는 개발자가 고려하여 최대한 복잡성은 줄이고 성능을 높일 수 있도록 구현해야할 것입니다.



스레드 기본사항

보통 안드로이드에서는, 하나의 스레드에서 실행하는 작업의 단위를 TASK라고 지칭합니다. 

스레드는 순차적으로 하나 또는 다수의 태스크를 실행할 수 있습니다.



실행

자바에서는 run method 안에서 태스크를 정의함으로 구현할 수 있다.


private class MyThreadTask implements Runnable{

   public void run(){

int j = 0; // 스레드에서의 지역스택에 저장됨.

   }

}


run() 메서드 안에서 호출되는 지역변수는 스레드의 지역 메모리 스택에 저장됩니다. 태스크의 실행은 Thread 객체생성과 start() 메서드 호출로 

실핼할 수 있습니다.


Thread myThread = new Thread(new MyThreadTask ());

myThread.start();


스레드의 지역데이터를 저장하는 전용메모리가 있습니다. 


CPU는 한번에 하나의 스레드 명령어를 처리할 수 있습니다.


스레드의 변경을 문맥교환, Context Switch라고 합니다.

하나의 프로세서에 동시에 실행되는 두개의 스레드를 코드와 그림으로 보시겠습니다.

Thread T1 = new Thread(new MythreadTask());

T1.start();

Thread T2 = new Thread(new MythreadTask());

T2.start();



스레드 T1 ------                   ------------

                        ||||(문맥교환시간)

스레드 T2                  ------                  -----


      시간


T1과 T2사이에는 CPU가 사용하는 문맥교환시간이 존재해서 T1이 끝나고 바로 T2가 실행되는게 아니라 약간의 문맥교환 오버헤드가 드는것을 확인하실 수 있습니다.(위에 |||| ) 




싱글 스레드 애플리케이션

각 앱은, 하나이상의 스레드를 가집니다. 또한, 사용자의 반응성을 고려해서 멀티스레드 환경으로 구현해야하는 경우도 존재합니다.



멀티스레드 애플리케이션

동작이 동시에 실행되는것으로 인식되도록 앱 코드를 여러코드 경로로 분할하는 애플리케이션입니다. 실행 스레드 수가 프로세서의 수를 초과하면 완벽한 동시성이 될수는 없습니다. 

멀티스레드는 필수적이긴하나 그에따른 복잡성 증가는 개발자가 풀어야 할 과제입니다.



자원소비증가

각 스레드는 지역변수등을 저장하는 전용 메모리영역을 할당받습니다. 프로세서 측면에서는 스레드 설정 및 해제, 문맥 교환에서 스레드를 저장하고 복원시, 오버해드가 생기게됩니다. 스레드가 많아질수록, 더많은 문맥교환이 일어나고 성능이 저하되게 됩니다.



복잡성 증가

코드를 분석하기 어려워집니다. 또한 실행에 불확실성을 가져다 줍니다.



데이터 불일치

두개의 스레드가 공유자원을 사용할 경우, 어떤 순서로 데이터를 접근하는지 알수없게됩니다. 하나의 공유변수를 두개의 스레드가 접근할때 경쟁조건에 노출되게 됩니다. 

그래서 공유변수에접근할때 다른스레드가 접근할수없도록, 원자영역을 만드는것이 필수적입니다. 자바에서 가장 동기화 메커니즘은 synchronized 키워드를 사용하면 되겠습니다.


ex_)

synchronized(this){

  sharedVal++;

}


+ Recent posts