[C] 함수로 전달된 포인터

포인터를 함수의 인자로 받는 경우, 함수내에서 원본을 변경하는가.

내용이 너무 두서 없어서 포스트 전체를 수정합니다.

처음 의문이 든 부분은, 문자열을 가리키는 포인터를 함수로 넘겨주고 문자열을 변형하면 포인터의 값이 변하는가?라는것이었는데. 이는 사실 그리 어려운 문제가 아니다. 포인터는 메모리의 주소를 가리키는 타입의 변수이고 이는 사실 unsigned int 나 unsinged int64 등의 정수형과 비슷하게 숫자를(메모리 번지도 결국 숫자값이므로) 담는 변수이다.

그리고 함수에 선언된 인자는 함수 내부에서만 사용하는 지역변수이고, 표준 타입의 변수를 함수에 전달하면 그 값이 인자로 선언한 변수에 들어가는데, 이건 그냥 변수의 값이 인자에도 들어가는 것이므로 값이 복사되는 것이다. 따라서,

  • 함수 외부에서 특정한 구조체나 배열, 문자열에 대한 포인터를 저장한 변수 A가 있고 이를 함수의 인자로 넘기면
  • 함수의 인자 B는 A와 동일한 값을 갖는다. 다만 값이 같을 뿐, B가 A를 가리키는 포인터가 될 수는 없다.
  • A가 포인터라면 B도 포인터이므로, 이 포인터가 가리키는 곳의 값을 조작할 수는 있다. 이러한 조작은 함수의 종료 후에도 변경을 유지하게 된다.
  • B는 A의 사본으로서, 함수의 실행 중에만 유지되고 함수 실행 종료시점에 파괴된다. A에 들어있는 값 자체는 아무런 영향을 받지 않는다.

로 정리할 수 있겠다. 땅땅땅.

[Cocoa / Objective-C] NSString의 문자열 뒤집기, 글자를 정렬한 문자열 구하기.

프레임워크에 당연히 있는 기능일 줄 알았는데 없더라… 그래서 자작.

짤막한 설명

문자열 뒤집기는 C문자열로 바꾼다음 포인터를 쓰는게 제일 깔끔할 것 같아서 그렇게 했다. -UTF8String 메소드는 const char 타입 포인터를 리턴하는데, 이걸 char 형으로 강제캐스팅하는 게 찜찜해서 strcpy로 복사했는데, 어디서 이 함수도 상당히 나쁘다고 쓰지 말라더라. (다른 뭐를 쓰라던데 그게 기억이 안나서 그냥 씀)

malloc으로 할당한 메모리는 ARC의 관심밖이므로 철저히 free 해주는 나란 남자, 그런 남자…

문자열내 문자들을 사전순으로 정렬해주는 건 소인수 분해 따위나 할 때 쓸모가 있긴 있을텐데,  NSArraysortedUsingComparator: 메소드를 사용했다.  OSX에서는 코드 블럭( ^( ){ … } )을 쓰면 되는데 GNUStep에서는 이게 함수포인터를 쓰는 것 같더라. 아마 이 코드 그대로 쓰면 안될 듯. GNUStep의 정렬 메소드는 함수 포인터로 되어 있고 아예 메소드명이 달라서, NSSortDescriptor를 사용하는 방법으로 변경했다. 지난 번 버전의 코드는 여기에서 볼 수 있다.

함수 내에서 상당히 많은 autorelease 되는 NSString을 만들어낼 수도 있어서, 메소드 안쪽에 autoreleasepool 블럭을 설치해줬다.

 

C에서의 문자열 배열과 문자열 배열을 동적으로 할당하기

문자열의 배열을 2차원배열을 쓸 때의 문제점

C언어는 문자열을 다루는 자료형이 없다. 대신에  C에서 문자열은 널 문자로 끝나는 문자(char) 타입의 배열을 사용하여 저장한다.  만약 일련의 문자열 집합을 다루려면 문자열의 배열을 써야 할테다.  여러 개의 문자열을 배열에 담고 싶다면 이차원 배열을 쓰는 방법을 생각할 수 있는데,  이 경우 크기가 일정하게 고정된 영역을 여러 개 생성해야 하고, 만약 각 문자열의 길이가 제각각 다르다면 불필요하게 낭비되는 메모리가 제법 될 수 있다.

2차원 배열의 문자열 배열
2차원 배열을 사용하여 구성한 문자열 배열

메모리를 비롯하여, 부족한 하드웨어 자원을 알뜰 살뜰 아껴서 최대의 성능을 내기 위해 개발된 초기 C언어 관점에서 이러한 2차원 배열의 사용은 그리 추천하지 않는다. C에서의 문자열 배열과 문자열 배열을 동적으로 할당하기 더보기

[C] conio.h에 대해

conio.h 는 MS-DOS용 C컴파일러에 포함되어 있는 헤더파일로, 표준 C 라이브러리에는 포함되지 않고 있다. (따라서 여기서 정의한 함수를 표준 함수처럼 쓰면 다른 플랫폼에서는 심벌이 없다고 컴파일 되지 않는다.) 이 헤더에는 콘솔 입출력과 관련된 함수들이 정의되어 있다.

멤버 함수들

  • kbhit – 키보드가 눌려졌는지 확인
  • getch – 콘솔에서 버퍼나 에코(타이핑한 키가 화면에 표시)없이 한 개의 키 값을 입력 받음
  • getche – 콘솔에서 키보드 입력으로 한 개의 키 입력을 받음. 에코됨.
  • ungetch – 키보드 버퍼로 문자 1개를 넣음
  • cgets – 콘솔로부터 문자열을 직접 입력 받음
  • gscanf – 콘솔 입력으로부터 포매팅된 입력을 받음
  • cputs – 콘솔에 직접 문자열을 출력
  • cprintf –  포맷을 사용해 콘솔에 문자열을 출력
  • clrscr – 화면을 지움