C언어 컴파일(compile)에 대한 생각 고찰 그리고 이해
포인터, 주소연산자, 참조연산자, 포인터 변수에 대한 생각 정리
자바개발을 하다 C를 해보려 하니 포인터 개념이 생겨 생각에 정리를 할겸 혼자 되뇌이며 몇자 적어 본다.
int a, b가 있는데 값을 대입하기 위해선 a = b 이렇게 하면된다
그런데 이말인 즉 *&a = *&b 란 뜻이다
&는 주소연산자이며 포인터를 뜻하고 &a하면 int형 변수 a를 가르키는 포인터이다
한마디로 a가 어디있는지 주소를 나타내는 것이다.
*는 참조연산자로서 기억공간을 사용하기 위해 사용되고 &앞에 *& 이렇게 붙이면 당연히 &가 가르키는 주소의 값을 *이걸로 가져다 쓰겠다는 의미이다.
다시 말해서 *&a는 int형 a의 주소에 있는 값을 가져온다는 의미이다.(포인터에 참조연산자를 사용하면 포인터가 가리키는 기억공간의 저장된 값을 사용할 수 있다.)
따라서, a = *&b로도 사용할 수 있다는 말이다.
그렇다면 이러한 &(주소연산자)를 저장할 순없을까?
일반적으로 선언된 int a 와같은 변수에는 값을 저장하는 것이지 주소를 저장할 수는 없다.
하지만 참조 연산자로 변수를 선언하게 되면 이러한 주소 값을 저장할 수 있다.
int *a (포인터변수 선언) 이렇게 말이다.
저장 방법은 int a, *b; a=10; *b=&a; 이렇게 하면된다.
포인터는 포인터가 가르키는 자료형의 크기와 관계없이 모두 4바이트이다. 따라서 포인터변수의 크기도 모두 4바이트이다.(근데 컴파일러에 따라 달라질 수 있음)
하지만 이렇게 크기가 같다고 해도 형변환이 되는것은 아니다. int형 포인터 변수에 저장된 주소를 double형 포인터 변수에 저장 못함
하지만 강제 형변환은 됨
int *ip;
double db=6.5;
ip = &db; <--하면 에러가 나지만
ip = (int *) &db <-- 이렇게 강제 형변환 하면 문제 없음
정리하자면 포인터는 주소값을 의미함 즉, 상수인 것이고
포인터 변수는 하나의 기억공간이며 번듯한 이름이 있는 변수인 거다.
포인터와 포인터 변수는 모두 특정 기억공간을 가리키는 역할을 하므로 두 가지 모두 참조 연산자를 사용하면 그들이 가리키는 기억 공간을 참조할 수 있다!
그러나 분명한 차이점은 포인터는 상수이므로 가리키는 대상을 결코 바꿀 수 없고, 포인터변수는 다른 주소값을 저장하면 얼마든지 가리키는 대상을 바꿀 수 있다.
c언어 다중포인터 이해 및 간단한 사용 방법
C언어 포인터 변수를 사용한 다양한 배열 표현 방법
1. 배열명을 사용한 배열 표현
: aa[0];
2. 배열명을 사용한 포인터 표현
: *(aa+0);
3. 배열명을 저장한 포인터 변수를 사용한 포인터 표현
: int *ap = aa;
ap+0;
4. 배열명을 저장한 포인터 변수를 사용한 배열 표현
: int *ap = aa;
ap[0];
* 배열요소는 참조하는 기본 방식이 포인터 계산에 의한 것이므로 계산 결과가 같다면 표현 형태는 얼마든지 바뀔 수 있음
예) *(ary) == *ary == *(ary+0)
ary[1] == *(ary+1) == *(1+ary) == 1[ary]
인라인(inline) 함수와 매크로(macro)
예를 들어 아래와 같이 SQUARE라는 매크로를 만들어 사용할 경우,
#define SQUARE(x) ((X)*(X)) int main(void) { std::cout << SQUARE(5) << std::endl; return 0; }
실제 프로그램 실행 시 main 함수의 SQUARE를 사용하게 될 경우 define된 주소로 점프 하여 실행 후 다시 원래로 돌아온다.
하지만 인라인 함수의 경우 전처리이기 아래와 같이 사용 하게 되면, 컴파일 시 인라인 함수가 코드 안에 삽입 되기 때문에 실제 main함수에서 SQUARE를 사용 시 삽인된 코드가 바로 실행 되기 때문에 속도도 빠르고 효율적이다.
inline int SQUARE(int x) { return x*x; } int main(void) { std::cout << SQUARE(5) << std::endl; return 0; }
C 형변환 문자형을 숫자형으로, 숫자형을 문자형으로
1. 문자형을 숫자형으로
atoi,atol,atof는 문자열을 숫자로 바꾸어 주는 함수이다.
사용하기 위해서 stdlib.h 이 헤더를 호출해야 한다.
include <stdlib.h>
-. atoi는 ascii to integer --> 문자열을 int형
-. atol은 ascii to long --> 문자열을 long형
-. atof는 ascii to float --> 문자열을 double형으로 바꾸어 준다.
앞에 -가 올 경우도 그대로 출력해 주고 문자나 띄어쓰기를 만나면 그 전까지의 숫자를 모두 바꾸어 준다.
또 시작하자마자 문자를 만날 경우 0을 반환한다.
#includeint main() { char buf1[10], buf2[10]; int num1, num2; memset(buf1, 0x00, sizeof(buf1)); memset(buf2, 0x00, sizeof(buf2)); sprintf(buf1, "20"); sprintf(buf2, "30"); num1 = atoi(buf1); num2 = atoi(buf2); printf("num1 + num2 = %d \n", num1+num2); return 0; }
2. 숫자형을 문자형으로
-. itoa : integer 값을 2진, 8진, 10진, 16진 문자열로 변환합니다.
-. ltoa : long 값을 2진, 8진, 10진, 16진 문자열로 변환합니다.
-. ultoa : unsigned long 값을 2진, 8진, 10진, 16진 문자열로 변환합니다.
-. fcvt : 실수(고정 소수점:float) 값을 문자열로 변환합니다.
-. ecvt : 실수(부동 소수점:double) 값을 문자열로 변환합니다.
-. gcvt : 실수 값을 부호와 소수점을 포함하여 문자열로 변환합니다.
C언어
- C언어 컴파일(compile)에 대한 생각 고찰 그리고 이해 2016.07.28
- 포인터, 주소연산자, 참조연산자, 포인터 변수에 대한 생각 정리 2016.07.25
- c언어 다중포인터 이해 및 간단한 사용 방법 2016.07.25
- C언어 포인터 변수를 사용한 다양한 배열 표현 방법 2016.07.25
- 인라인(inline) 함수와 매크로(macro) 2016.07.25
- C 형변환 문자형을 숫자형으로, 숫자형을 문자형으로 2016.07.25