2010년/3월
3월 19일 소수구하기와 포인터 기본
뽀얀햄스터
2010. 3. 19. 17:02
프로그램 소수(prime number)구하기
#include<stdio.h>
int main()
{
int inum=3;
int iprime=2;
int icount;
int irecnt=1;
printf("소수 : 카운트 \n%d\t%d\n",iprime,irecnt); //출력하기
for(inum;100>inum;inum=inum+2)//홀수 구하기
{
for(iprime=2,icount=0;inum>=iprime;++iprime)//홀수 값 나눌 값 정하기
{
if(0==inum%iprime) //홀수 나누기 2부터~ 홀수까지
{
icount++; // 홀수 나누기 값이 0일경우 하나씩 증가.
if(inum==iprime) // 홀수 나누기 마지막값이 같을때
{
if(1==icount) //나누기 해서 나머지가 0인 갯수가 1번일때(소수)
{
irecnt++; // 소수 를 증가하는 카운트
printf("%d\t%d\n",inum,irecnt); // 출력
}
}
}
}
}
return 0;
}
---- 힘들었다. 그래도 성공~
포인터
<심볼 테이블>
Type | Name | Address |
int | iNum | 0012FF7C |
int *iP; <=== 포인터 변수 *(포인트 타입)
즉 한마디로 int형 포인터 라는것이다.
iP=(int*)0x77;
(int*)<==형변환
#include<stdio.h>
int main()
{
int inum;
int *iP;
//inum =0x77;
//iP= (int*)0x77;
inum=(int)&inum;
iP =&inum;
//*inum=0x88;
*iP=0x88;
*(int*)0x12FF7C = 0x99;
*(int*)0x12ff78 = 0x66;
printf("0x%X\n",inum);
printf("%X\n",&inum);
printf("0x%X\n",iP);
printf("%X\n",&iP);
return 0;
}
여기서 기본적으로 iP에 inum의 주소를 넣게 된다. 물론 넣기 위해서는 캐스팅을 해야하고 주소를 넣게 되면 *iP를 통해서 =0x88을 하게 되면 iP안에 있는 주소로 점프하고 0x88 을 넣게 된다. 이것은 inum에 들어가게 된다.
*(int*)0x12FF7C = 0x99; 추가로 0x12FF7C는 현재 상수이지만 캐스팅으로 (int *)로 주소처럼 바꾸어
두고 *으로 실행하게되면 0x12FF7C번지에 0x99가 저장된다.
심볼 테이블
메모리에 일단 기본적으로 거꾸로 1바이트 뒤집어서 저장이된다.
iP =&inum;순간 메모리에서 0x12FF7C가 저장되고
*iP=0x88; 실행해서 iP주소값 안에 들어가고 iP 안에
0x12FF7C가 들어가 있다. 그 주소로 찾아가서 0x88을 넣게 되고
0x12FF7C가 결국에는 iNum 주소가 되는것이다.
*(int*)0x12FF7C = 0x99;
*(int*)0x12ff78 = 0x66;
여기서 바로 포인터주소로 캐스팅하여 0x12FF7C는 기본적으로 상수이다
이걸 주소를 받아서 실행하기위해서 포인트int로 캐스팅해서 실행해서
0x99와 0x66이 들어가는걸 볼수 있다.
---------------------------------------------------------------------
#include<stdio.h>
int main()
{
unsigned int iNum;
unsigned int * uiP;
unsigned char * ucP;
iNum= 0x12345678;
uiP= &iNum;
ucP=(unsigned char *)&iNum;
printf("%X\n",iNum);
printf("%X\n",&iNum);
printf("%X\n",&uiP);
printf("%X\n",&ucP);
printf("[%02X][%02X][%02X][%02X]\n",*ucP,*(ucP+1),*(ucP+2),*(ucP+3));
printf("%08X\n",*uiP);
printf("%08X\n",*(uiP-1));
printf("%08X\n",*(uiP+1));
return 0;
}
다음소스는 포인터의 자료형에서 char와 int의 차이를 알게 해준다.
기본적으로 심볼테이블에의 모습이다 여기서 주소가 차례대로 넣어진다는것을 알수있다.
-메모리-
iNum= 0x12345678;
uiP= &iNum;
ucP=(unsigned char *)&iNum;
INum에 12345678이 들어가고 iNum의 주소가 uiP에 저장이 되며 ucP에 iNum의 주소를 넣으려고 하지만 unsigned char와 unsigned int 형의 형태가 틀리다 그래서 캐스팅을 통해서 맞춰준다.
가장중요한점~!!!!!!!! 포인터의 자료형은 이전에 포인터는 4바이트값이 들어간다. 하지만 나중에 출력하려고할때 자료형의 따라서 출력되는것이다 즉 char *로 지정할경우 입력으로 4바이트 주소가 들어가지만 나올때 1바이트씩나오게 된다. (결과값 참조)
-메모리의 저장타입-
빅엔디안과 리틀엔디안 프로그램의 값이 메모리에 저장하기 위해서는 우리가 사용하는 순서대로 넣게 되면 빅엔디안이다 즉 인텔 같은경우는 들어갈때 1바이트씩 거꾸로 들어가게 된다. 그래서 결론은 우리가 덧셈을 할때 1234+2334 할경우 일의자리부터 더하고 점점 자릿수를 올린다. 하지만 리틀엔디안을 사용할경우는 거꾸로 넣게 되면 이 산술부분이 버스통해서 CPU올때 바로바로 계산하면 된다 그리고 2345 || 9874중에서 어느숫자가 더 큰 논리부분에서는 2천과 9천인 앞의 자리수부터 보고 어느값이 큰것인지 구하게 될때는 빅엔디안으로 메모리에서 버스를 통해서 CPU로 올때 빅엔디안 편하다 개인용 컴퓨터 같은경우는 산술이 빨라서 게임같은 복잡적인것을 주로하기때문에 리틀엔디안을 많이 쓰고 슈퍼컴퓨터 같은 경우는 빅엔디안을 많이 쓴다.
-------------------------------------------
결과값
printf("[%02X][%02X][%02X][%02X]\n",*ucP,*(ucP+1),*(ucP+2),*(ucP+3));
printf("%08X\n",*uiP);
printf("%08X\n",*(uiP-1));
printf("%08X\n",*(uiP+1));
여기서 포인터의 타입형의 중요성을 보여주는 결과값이다. ucP는 char형태이다. 그리고 지금 ucP에서는 iNum의 주소값이 들어가 있다. 그리고 * 연산으로 실행할경우 iNum의 값인 12 34 56 78을 출력해야한다 하지만 char형태로 1바이트씩 출력할수 밖에 없기때문에 78이 먼저 출력된다.(78이 출력되는 이유는 리틀엔디안때문)그리고 *(ucP+1)로 1바이트씩 주소가 이동해서 주소값 12FF7D의 값이 출력된다. 그리고 마지막 printf("%08X\n",*(uiP-1)); 이경우는 uiP는 int형 포인터이다 그래서 저 -1값을 하게 되면 int 형이라서 4바이트씩 이동한다.(char는 1바이트씩)