포인터
포인터란 주소의 주소입니다
오늘 길동이 집으로 모여, 그 길동이가 변수라고 생각하면 돼요.
야, 서울시 oo동 oo번지로 모여 이렇게 말할 수도 있습니다
c언어는 이렇게 주소를 사용할 수 있고 주소를 담을 수 있는 변수가 포인터입니다
(자바는 포인터를 처리하지 않습니다)
포인터는 주소이고, 주소를 담을 수 있는 변수를 포인터 변수라고 합니다.
- 포인터 변수를 선언할 때는 자료의 형을 먼저 쓰고 변수명 앞에는 *를 붙인다
- int *b; //b라는 변수는 이제 일반 숫자가 아닌 포인터(주소)를 담을 수 있는 정수형 변수이다
- char *c; //c라는 변수는 이제 포인터를 담을 수 있는 문자형 변수이다
- int a;는 기억 장소 어딘가에 가서 만들어진다, 주소를 알고 싶으면 &a로 알 수 있다
- int *b; int a; b = &a; //a의 주소를 포인터 변수인 b에 넣은 것이다
- int a = 100; //a가 있는 곳에 데이터 100이 저장됨
- b = &a; //b에 a의 주소가 저장됨
- 실행문에서 포인터 변수에 *를 붙이면 해당 포인터 변수가 가리키는 곳의 값을 말한다
- 즉 포인터 변수가 가리키고 있는 주소의 값이다.
- *b = *b + 10 //실행문이 가리키는 곳의 값에 10을 더한다. 4번지에 있는 값이 100이라면 110이 된다.
- 포인터 변수b가 가리키는 곳의 값을 바꾸면 해당 a의 값도 바뀐다
- 주소를 찍을땐 %p 이다
int a;
int *b;
a = 100; //4번지에 100 저장됨
b = &a; //4가 기억됨
b = *b + 10;//포인터 변수가 가리키는 곳의 값을 말할 때는 *를 붙인다, 즉 110이다
여기서 변수 a의 값은 20이었지만 가리키는 포인터 변수b가 30이 되어 a의 값도 30으로 변경되었다
배열
array, 말 그대로 나열 시킨 것인데 기억 장소에 형과 크기가 같은 것을 여러개 모아서 한번에 쓰는 것이다.
프로그램 하다보면 변수가 수백개 수천개 쓰일 때가 있다
ex. 한 반의 학생 40명일때 변수를 40개 써야한다
하지만 똑같은 형의 변수이니까 배열을 만들어서 위치만 가리키게 하는 것이다.
1차원 배열은 변수들을 일직선상의 개념으로 조합한 배열이다
자료형 변수형[개수]
- int a[5]
- 자료형 : 배열에 저장할 자료의 형을 지정한다
- 변수명 : 사용할 배열의 이름이므로 사용자가 임의로 정한다
- 개수 : 배열의 크기를 정한다
- 선언할 때 a에 5개라고 선언했으니까 정수 배열이고 5개의 요소를 갖는 배열이다
- 쓸 때는 0번지부터 쓴다, a[4] 라면 다섯번째 요소이다
- 배열은 반복문과 관련이 깊다
프로그램 자체가 사람이 어떻게 하면 쉽게 쓸까를 생각하고 만들었기 때문에 실제로는 어렵지 않다
반복분이 두개이면 한 반복문을 완료하면 다음 반복문을 수행한다 (for 다음에 for)
배열의 이름은 주소다, 주소를 이용해서 배열의 결과를 찍어본다.
- 메모리 어딘가에 변수 a, i, p가 생겼다
- 정수형은 4바이트이기 때문에 100번지라면 100 104 108 112 116…이렇게 증가한다
- p = a; //a는 배열이다, 배열은 주소다
- p는 정수를 담을 수 있는 포인터 변수이다. a의 주소를 p가 가리키게 된다 (100번지)
- 실행문에서 *는 그것이 가리키고 있는 곳의 값이다.
- p는 100이고 i는 0, *100은 10이다
- 포인터 변수는 포인터 단위(주소 단위)로 움직인다, 그래서 i가 증가하면 포인터 변수는 그 다음 번지를 가리킨다, 4바이트가 증가한다
- 즉 포인터 변수를 증가시키면 다음 번지를 가리킨다
- p는 계속 100번지를 가리키고 i가 증가하면서 다음 번지를 가리키므로 100번지 → 104번지 → 108 번지…
- 10 → 11 → 12…
- 포인터가 증가한다는 것은 그 자료형의 크기만큼 증가한다. 정수형이니까 4바이트씩 증가한다, 문자형이라면 1바이트씩 증가한다
2차원 배열
1차원 배열은 직선적인 구조인데
2차원 배열은 1차원 배열이 여러개 있는 것을 하나도 묶은 것이다(행과 열)
- 변수들을 평면, 즉 행과 열로 조합한 배열이다
- 자료형 변수명[행개수][열개수]
- int a[3][4] //3행 4열
0,0 | 0,1 | 0,2 | 0,3 |
1,0 | 1,1 | 1,2 | 1,3 |
2,0 | 2,1 | 2,2 | 2,3 |
안쪽 반복문 반복 → 바깥쪽 반복문 반복
i | j | k | 결과 |
0 | 0 | 1 | [0][0]=1 |
1 | 2 | [0][1]=2 | |
2 | 3 | [0][2]=3 | |
3 | 4 | [0][3]=4 | |
1 | 0 | 5 | [1][0]=5 |
1 | 6 | [1][1]=6 | |
2 | 7 | [1][2]=7 | |
3 | 8 | [1][3]=8 | |
2 | 0 | 9 | [2][0]=9 |
1 | 10 | [2][1]=10 | |
2 | 11 | [2][2]=11 | |
3 | 12 | [2][3]=12 |
사용자 정의 함수
말그대로 사용자가 만들어서 쓰는 함수이다, 필요한 기능을 만들어서 쓸 수 있다
(기본적으로 만들어져 있는 함수는 내장 함수이다)
- 프로그램은 위에서부터 밑으로 실행된다
- 프로그램은 main()을 만나야만 실행된다
- 즉 위에서부터 내려오는데 위에서 내가 만든 함수를 선언해놓고 아래에 정의하면 main()함수 안에서 사용할 수 있다
- 아래는 리턴 값이 없는 경우 -> 돌려주는 값이 없음
- 리턴 값이 있는 경우 -> 돌려주는 값이 있음
-
#include <stdio.h> void func(int i, int j); //내가 쓸 함수를 선언, 함수의 리턴값이 없으면 void //func 함수는 정수형 변수 i,j를 받는구나 main() { int a = 3, b = 12; func(a,b); //이 함수가 어딘가에 반드시 있어야 한다 printf("%d, %d", a,b); } void func(i, j) int i,j; { i*=3; j /=3; printf("%d, %d", i,j); //나를 부른 곳으로 돌아간다 } //정의한 함수는 리턴값이 없다 //9,4 //3,12가 출력된다
#include <stdio.h>
func(i,j); //앞에 void가 없다 = 리턴 값이 있다
main()
{
int a = 3, b = 12;
a = func(a,b);
printf("%d, %d", a,b);
}
func(i, j)
int i, j;
{
i *= 3;
j /= 3;
printf("%d, %d", i,j);
return i; //i 값을 돌려준다
//나를 부른 곳으로 돌아간다
}
//a=9, b=12
//리턴 값은 하나만 돌려줄 수 있다
//여러개를 돌려주려면 주소 값을 이용한다
값을 여러개 돌려줘야 하는 경우는 구조체를 만들거나 주소를 이용한다.
주소(포인터 변수)로 그곳의 값을 바꿔버리면 된다, 포인터를 사용한다
#include <stdio.h>
void func(int *i, int *j); //리턴값이 없고 포인터 변수를 두개 받는 함수
main()
{
int a=3, b=12;
func(&a, &b); //번지를 가리킨다
printf("%d, %d", a,b);
}
void func(i,j)
int *i, *j; //정수형 변수의 주소를 가진다
{
*i *= 3; //*i는 i변수가 가리키는 값, 여기에 3을 곱한다 = 9
*j /= 3; //*j는 j변수가 가리키는 값, 여기에 4를 나눈다 = 4
printf("%d, %d", *i, *j);
}
내장 함수
이미 정의가 되어 있는 함수이며, 헤더파일을 작성하고 사용한다
pow(x,y) | 거듭제곱 | pow(2,5)=32 |
sqrt(x) | 제곱근 | sqrt(25)=5 |
abs(x) | 절대값 | abs(-70)=70 |
strlen(a) | 문자열 길이 | strlen(”abcd”)=4 |
strcpy(a,b) | 문자 배열 복사 | |
strcmp(a,b) | 문자열 비교 | 같다면 0을, a가 크면 1을, b가 크면 -1을 반환한다 |
atoi(a) | 문자열->정수형 | atoi(”12”) → 12가 된다 |
atof(a) | 문자열→실수형 |
#include <stdio.h>
#include <string.h>
#include <math.h>
main()
{
printf("%f", pow(2,3));
printf("%f", sqrt(25));
printf("%f", abs(-32));
char a[] = "ad";
char b[] = "ac";
printf("%d", strcmp(a,b)); //1 (b가 크다)
srtcpy(a,b); //b를 a에 복사 -> ac가 된다
printf("%d", strcmp(a,b)); //0 (둘은 같다)
char c[]="123";
char d[] ="456";
printf("%d",atoi(c) + atoi(d)); //579
char e[]="12.3";
char f[] ="45.6";
printf("%f",atof(e) + atof(f)); //57.9
'컴퓨터 일반 > 프로그래밍언어론' 카테고리의 다른 글
프로그래밍언어 문제(2) (2) | 2024.10.21 |
---|---|
프로그래밍언어 문제(1) (0) | 2024.10.21 |
프로그래밍(3) 제어문 (1) | 2024.10.16 |
프로그래밍(2) C언어 연산자 (4) | 2024.10.16 |
프로그래밍(1) 순서도, C언어 기초 (3) | 2024.10.16 |