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를 담고있다.












리팩토링 (Refactoring) 이란?



-소스코드 구조를 효율적으로 변경하면서, 기능이나 동작의 변화가 없도록 하는 작업.



Restructuring VS refactoring


-재구조화는 다시 설계를 하는 작업.

-리팩토링은 나름의 규칙을 가지고 수정하는 작업.
Þ일련의 작업 Process가 있음.

ex) Return을 빼고, 변수이름을 네이밍 룰에 맞추어 진행하며 함수이름을 변경



변수의 읽기 쓰기 분석 연습

int mySumVar = 0;


for(int i = 0; i<1024 ; i++)

  mySumVar mySumVar + i;


mySumVar 은 읽고 쓰며, i 읽기만 하고 있음을 알 수 있다.


읽고 쓰는 변수 => call by reference 으로 함수 추출 시 파라메터로 사용하면 됨.

읽는 변수 => call by value 으로 함수 추출시 파라메터로 사용하면 됨.

참고) 쓰는변수 => 함수 추출 시 return 을 쓰면 됨.




void MySubSumI(int I, int *mySumVar )

{

  sub(i, &mySumVar );

}


int mySumVar = 0;

for(int i = 0; i<1024 ; i++)

  MySubSumI(i, &mySumVar );





변수 제거 기법 알아 보기.

- 어떤 변수가 모두 read만 하거나 write만 하면 변수 제거가능!


- 당연히 알 수 있는 값을 또하나의 변수에 저장하는 변수제거 해보기

-> 원의 넓이, 사각형의 넓이등등


- 플래그 변수들 의심해볼 것!

for, while, if, switch 등의 반목문혹은 조건식에서의 플래그를 검토해볼 것




변수 제거 기법 – flag 변수 제거 방법

- 플래그 변수의 읽기접근을 모두 제거 가 가능한가 검토 해볼것!

-> 쓰기 접근만 남게되면 그 변수는 제거가능

-무조건 true, 혹은 false로 빠지지 않는지 검토해보기!
-> 조건식을 옮겨서 true/false 무조건 되는지검토 물론 코드로직은 동일해야함을 검토!


-플래그 변수 읽기대신, 다른 조건식을 대체할수있는 변수나 조건이있는지 검토할 것
만약 플래그와 같이 동시에 쓰기가 되는 변수가 있다면 그 변수를 이용해서 조건식으로 대체 하는 방법 사용.




플래그 변수 제거 해보기



char *getInputFromUserFile(File *myFile)

{

//입력값을 읽기 전, 읽는 중

int BEFORE = 0

int READING = 1

int my_word_flag = BEFORE;


char *word = nullptr;

int i = 0;

char inputC;


while (inputC = fgetc(myFile))

{

if (my_word_flag == BEFORE) //문자 읽기전

{

word = static_cast <char *>(malloc(sizeof(char)*WORD_SIZE));

my_word_flag = READING;

word[i++] = inputC;

}

else if (my_word_flag == READING) //문자읽는중

{

  word[i++] = inputC;

}

}

return nullptr;

}



아래는 답안입니다.
============>>>>>>>>

char *getInputFromUserFile(File *myFile)

{

char *word = nullptr;

int i = 0;

char inputC;

while (inputC = fgetc(myFile))

{

if (word == nullptr)

{

word = static_cast <char *>(malloc(sizeof(char)*WORD_SIZE));

word[i++] = inputC;

}

else

{

word[i++] = inputC;

}

 }

 return nullptr;

}


+ Recent posts