배열이란? 같은 형의 변수를 여러 개 만드는 경우에 사용
<index, data> 쌍의 집합
배열이 가능한 연산
연산들의 예시는 아래와 같다.
int list[6]; // create
list[0] = 100; // set
value = list[0]; //get
각 변수들에 해당하는 메모리 주소는 아래와 같다.
변수 | 메모리 주소 |
---|---|
list[0] | 기본주소: base |
list[1] | Base + 1*sizeof(int) |
: | : |
list[n] | Base + n*sizeof(int) |
list[0]이 base라고 한다면 list[1]은 Base + 1 x sizeof(int)이다.
그 이유는 배열이 int형이므로 하나의 index에 해당되는 data는 4 Bytes이기 때문이다.
만약, list[2]라면 list[0]과 2칸 차이니까 Base + 2 x sizeof(int)이다.
list와 같이 배열명은 가장 첫번째 메모리 주소와 같은 의미임을 잊지 말자.
구조체란? 타입이 다른 데이터를 하나로 묶는 방법
이와 반대로, 배열은 타입이 같은 데이터들을 하나로 묶는 방법
구조체의 선언과 구조체 변수의 생성
struct studentTag {
char name[10];
int age;
double gpa;
};
struct studentTag s;
strcpy(s.name, "Choi");
s.age = 25;
s.gpa = 4.5;
s.name을 s.age와 s.gpa처럼 대입연산자를 사용하고 싶다면
구조체를 선언할 때 char name[10]
대신에 char *name
으로 선언하면 된다. 여기서 name의 자료형은 char형을 가리키는 포인터 타입이다.
매번 구조체를 선언할 때마다 struct studentTag s
와 같이 쓰기에는 너무 길기 때문에 구조체를 정의할 때 struct 앞에 typedef를 적어 별칭을 사용할 수 있다.
typedef struct studentTag {
char name[10];
int age;
double gpa;
} student;
student s = {"Choi", 25, 4.5 };
포인터란? 다른 변수의 주소를 가지고 있는 변수
배열명은 사실상 포인터와 같은 역할을 한다. 컴파일러가 배열의 이름을 배열의 첫번째 주소로 대치한다.
포인터의 예시는 아래와 같다.
char a = 'A';
char *p;
p = &a;
여기서 마지막 줄은 a라는 변수에 해당되는 주소를 p에 넣는다는 의미이다.
만약 p가 가리키는 곳에 있는 값 즉,주소 100번지에 있는 값을 바꾸고 싶다면 아래와 같이 하면 된다.
*p = 'B';
포인터의 초기화
int i;
int *ptr = &i;
char *ptr = (char *)malloc(100);
char *ptr = "korea";
char A[100];
char *ptr = A;
char A[100];
char *ptr = &A[0];