C/C++ 기초 강의 요약 (섹션3)
#include <stdio.h>
int main(){
int a[5];
a[0]=2;
a[1]=3;
a[2]=7;
a[3]=6;
a[4]=8;
for (int i=0;i<=4;i++){
printf("%d\n", a[i]);
}
}
배열(Array)
이름 뒤에 []대괄호를 붙이고 그 안에 원하는 숫자를 넣는다. 그럼 메모리상에 연속된 공간에 자리가 원하는 숫자만큼의 자료 자리가 생긴다.
그 안에 그 숫자만큼의 데이터를 저장할 수 있다.
int arr[5]={3,1,4,1,5};
와 같이 {}중괄호 안에 쉼표로 구분하며 값을 적으면서 대입할 수도 있다.
int a[i]와 같이 정의를 했다면 그 배열을 사용하거나 값을 대입할때는 메모리에 저장될때 0부터 시작되기 때문에 []대괄호 안의 숫자는 0~i-1사이의 숫자를 넣어야한다.
#include <stdio.h>
int main(){
//array
int arr[]={3,1,4,1,5,6,1,2,4,6,7};
for(int i=0;i<sizeof(arr)/sizeof(int);i++){
printf("%d\n", arr[i]);
}
}
아까와 달리 arr배열을 정의할때 대괄호[] 안이 비어있다. 이처럼 비워진 상태로 정의를 하게 되면 대입된 값의 갯수만큼 자동으로 메모리에 할당한다.
근데 여기서 문제가 되는건 따로 배열 크기를 설정을 안했기 때문에 for문을 돌릴때 넣을 값을 모르게된다. 그래서 사용하는게 저번에 배운 sizeof()다.
모두가 알다시피 int는 4바이트다. 그럼 arr[]은 대입된 값이 총 11개이므로 4*11=44바이트. sizeof(arr)=44인것이다. 그걸 sizeof(int)로 나누면 11, 이렇게 sizeof()를 사용하여 대체할 수 있다.
#include <stdio.h>
int main(){
int arr[1000];
int n;
printf("입력할 숫자의 개수 : ");
scanf("%d", &n);
for(int i=0;i<n;i++){
scanf("%d", &arr[i]);
}
for(int i=n-1;i>=0;i--){
printf("%d\n", arr[i]);
}
}
입력할 숫자의 개수(n)를 사용자로부터 입력받고 그 수를 사용하여 int arr[n], 이렇게 정의하면 오류가 발생하게 된다. 컴파일러는 그 n값을 입력받기 전에 메모리에 arr[]의 메모리를 할당시켜야 하기 때문이다. 그래서 위의 코드처럼 arr[1000]으로 먼저 선언을 하고 입력할 숫자의 개수를 따로 받아 for문에서는 그 수를 사용하면 된다. 위의 코드는 입력받은 수를 배열에 저장하고 입력받은 순서의 반대로 다시 출력하는 프로그램의 코드이다.
#include <stdio.h>
int main(){
int n;
int arr[100];
scanf("%d", &n);
for(int i=0;i<n;i++){
scanf("%d", &arr[i]);
}
int max=arr[0];
for(int i=1;i<n;i++){
if(max<arr[i]) max=arr[i];
}
printf("%d\n", max);
}
#include <stdio.h>
int main(){
int n;
int arr[100];
scanf("%d", &n);
for(int i=0;i<n;i++){
scanf("%d", &arr[i]);
}
int min=arr[0];
for(int i=1;i<n;i++){
if(min>arr[i]) min=arr[i];
}
printf("%d\n", max);
}
위부터 차례대로 최댓값을 출력, 최솟값을 출력하는 코드이다.몇 개의 수를 입력할건지 입력을 받고 그 입력값을 n에 저장한다.
각각 max와 min을 arr배열의 첫번째 값 arr[0]으로 초기화 시키고 차차 그 후의 수와 비교를 거치며 값을 계속 초기화한다. i가 n-1이 되었을때 비교는 끝나고 그 결과 max는 arr배열의 최댓값을, min은 arr배열의 최솟값을 갖고있게 된다.
#include <stdio.h>
int main(){
int n;
int arr[100];
scanf("%d", &n);
for(int i=0;i<n;i++){
scanf("%d", &arr[i]);
}
int cnt=0;
for(int i=0;i<n;i++){
if(arr[i]%2==0){
cnt++;
}
}
printf("짝수의 개수 : %d\n", cnt);
}
앞은 그 전과 같이 arr배열에 값을 입력 받고 그 배열의 값을 하나하나씩 지나가며 if(짝수?)라면 cnt의 값을 1씩 더해서, for 문이 끝났을때 cnt는 짝수의 개수를 갖고있게 된다.
#include <stdio.h>
int main(){
int arr[3][4]={
{1,2,3,4},
{5,6,7,8},
{9,10,11,12}
};
for(int i=0;i<3;i++){
for(int j=0;j<4;j++){
printf("%d ", arr[i][j]);
}
printf("\n");
}
}
다차원 배열 이전에 정의했던 배열은 1차원 배열이였다. 그냥 숫자가 쭈우우욱 일렬로 저장되는.. 다차원 배열은 배열을 다차원으로 정의할 수 있게 해준다.위의 코드를 보자. arr[i]처럼 정의하던 아까와 달리 그 뒤에 중괄호[]가 하나 더 붙으면서 3X4크기의 int 배열을 만들었다.
//파스칼의 삼각형
#include <stdio.h>
int main(){
int p[10][10];
for(int i=0;i<10;i++){
for(int j=0;j<=i;j++){
if(j==0||i==j){
p[i][j]=1;
}
else{
p[i][j]=p[i-1][j-1]+p[i-1][j];
}
}
}
for(int i=0;i<10;i++){
for(int j=0;j<=i;j++){
printf("%d ",p[i][j] );
}
printf("\n");
}
}
파스칼의 삼각형을 다차원 배열과 for문으로 구현하는 코드다. 규칙으로는 j=0일때 혹은 i=j일때 p[i][j]는 1이다. 또 앞의 조건이 성립하지 않는다면 p[i][j]=p[i-1][j-1] + p[i-1][j]이다.
#include <stdio.h>
int main(){
char arr[]="Hello, world!";
printf("%d\n", sizeof(arr)/sizeof(char));
}
문자열 문자로 된 배열을 의미
위의 코드를 실행했을때 arr은 14바이트를 메모리에 할당한다. 그런데 Hello, world!을 세보면 아무리 세봐도 13개다. 그런데 왜 14바이트를 메모리에 할당했을까. "Hello, world!"은 {'H','e','l','l','o',' ', 'w','o','r','l','d','!','\0'}과 같다. 보면 알겠지만 {}로 정의했을때에는 뒤에 \0이라는게 포함된걸 알 수 있다. *\0은 nul문자로 문자열의 끝을 알린다. *
<string.h>
#include <stdio.h>
#include <string.h>
int main(){
char str[100]="Hello";
int len=strlen(str);
printf("%d", len);
}
새롭게 include된 string.h에는 여러 문자열 관련 함수가 정의되어 있다.
strlen 문자열의 길이를 반환하는 함수다.
#include <stdio.h>
#include <string.h>
int main(){
char str[]="Hello";
char str1[100];
strcpy(str1,str);
printf("%s\n", str1);
}
strcpy strcpy함수는 괄호() 안에 첫번째 문자열에 두번째 문자열을 복사하는 함수다. 위의 코드를 실행해보면 Hello가 출력되므로 복사가 되었음을 알 수 있다.
#include <stdio.h>
#include <string.h>
int main(){
char str[100]="Hello ";
strcat(str, "World!");
printf("%s \n", str);
}
strcat 문자열을 뒤에 이어붙이는 함수다. 첫번째 인자로 주어진 str문자열에 두번째로 주어진 인자인 "World!"가 이어붙게 되어 위의 코드를 실행해보면 Hello World!가 출력된다.
#include <stdio.h>
#include <string.h>
int main(){
char str[]="sample";
char str1[]="simple";
int cmp=strcmp(str,str1);
printf("%d\n", cmp);
}
strcmp 주어진 두 개의 문자열을 비교하는 함수다. 첫번째로 주어진 문자열이 두번째 문자열보다 사전순으로 앞에 있다면 -1, 그 반대라면 1, 두 문자열이 같다면 0을 반환한다.
<포인터>
#include <stdio.h>
int main(){
int a=20;
int *ptr_a;
ptr_a=&a;
printf("a의 값 : %d\n", a);
printf("a의 주소값 : %d\n", &a);
printf("ptr_a에 저장된 값 : %d\n", ptr_a);
printf("ptr_a이 가리키는 변수의 값 : %d\n", *ptr_a);
}
포인터 변수의 주소를 저장하는 변수
위의 코드를 설명해보자면, a라는 변수를 선언하고 그와 동시에 20이라는 값으로 초기화했다.
그 밑에서 ptr_a라는 이름의 포인터를 선언했다. 그리고 ptr_a에 &를 사용해서 a의 주소값인 &a를 대입했다.
밑에 4개의 printf를 실행해면 20,
,
,20 이 출력됐다. a의 주소값과 ptr_a의 값은 같았고, 그로써 ptr_a가 가리키는건 변수 a가 되었다. 그 결과 *를 사용해 ptr_a가 가리키는 변수의 값을 출력해보면 a의 값과 같은 20이 출력된다.
#include <stdio.h>
int main(){
int a=10;
int b=20;
int *ptr;
ptr=&a;
printf("ptr이 가리키는 변수에 저장된 값 : %d\n", *ptr);
ptr=&b;
printf("ptr이 가리키는 변수에 저장된 값 : %d\n", *ptr);
}
ptr이라는 포인터를 선언하고 ptr=&a로 a의 주소값을 대입시켰다. 그리고 *ptr의 값을 출력해보면 ptr이 가리키는 변수인 a의 값인 10이 나오게 된다.
그 후에 ptr=&b로 b의 주소값을 ptr에 대입시켰다. 그 결과 *ptr의 값을 출력해보면 ptr이 가리키고 있는 변수인 b의 값인 20이 출력되는걸 알 수 있다.
#include <stdio.h>
int main(){
int a=10;
int *ptr;
ptr=&a;
*ptr=20;
printf("%d\n", a);
}
ptr=&a로 a의 주소값을 대입시켰다. 그 후 *ptr=20으로 ptr이 가리키는 변수의 값을 20으로 변환시켰다. 여기서 ptr의 값은 바뀌지 않는다.
ptr에 저장된 값은 a의 주소값이기 때문이다. a의 주소값에 들어있는 데이터의 값이 바뀐것이지 주소값은 바뀌지 않는다. 그래서 위의 코드를 실행했을때 20이 출력되는걸 알 수 있다.
#include <stdio.h>
int main(){
int a=10;
int *ptr;
ptr=&a;
int **ptr_ptr;
ptr_ptr=&ptr;
printf("a=%d\n", a);
printf("&a=%d\n", &a);
printf("ptr=%d\n", ptr);
printf("&ptr=%d\n", ptr);
printf("ptr_ptr=%d\n", ptr_ptr);
printf("*ptr_ptr=%d\n", *ptr_ptr);
}
ptr이라는 포인터를 선언하였고 ptr에 a의 주소값을 대입했다. 그리고 ptr_ptr라는 이름의 더블포인터를 선언해 ptr의 주소값을 대입했다.
정리를 해보면 ptr은 a라는 변수를 가리키는 포인터이고, ptr_ptr은 a라는 변수를 가리키고 있는 포인터인 ptr을 가리키고 있는 더블 포인터다. 그 결과 위의 코드를 실행해보면 &a와 ptr과 *ptr_ptr의 값이 같은 것을 알 수 있으며 **ptr_ptr의 값은 a변수와 같은 10이다.
#include <stdio.h>
int main(){
int a=10;
int *ptr_a=&a;
printf("ptr_a의 값 : %d\n", ptr_a);
printf("ptr_a+1의 값 : %d\n", ptr_a+1);
}
위의 코드를 실행해보면 차이가 4가 나는 숫자가 출력이 된다. 그 이유는 무엇일까? ptr_a가 가리키고 있는 변수 a는 int형이다. int형은 알다시피 4바이트이다. 그래서 ptr_a+1은 a변수가 차지하고 있는 메모리 그 다음 메모리의 주소를 갖게 되는 것이다. ptr_a가 갖고있는 주소는 a변수가 갖고있는 메모리의 맨 첫번째 칸의 주소이기 때문에 ptr_a+1은 ptr_a 값보다 4가 큰 값을 갖게 되는 것이다.
#include <stdio.h>
int main(){
int arr[10]={1,2,3,4,5,6,7,8,9,10};
for(int i=0;i<10;i++){
printf("%d ", arr[i]);
}
printf("\n");
for(int i=0;i<10;i++){
printf("%d ", *(arr+i));
}
printf("\n");
for(int *ptr=arr; ptr<arr+10;ptr++){
printf("%d ", *ptr);
}
printf("\n");
printf("%d\n", *ptr_a);
}
앞서 말한것과 같이 arr+i는 &arr[i]과 같다. 여기서 주목해야하는건 3번째 for문이다.
for문의 괄호()안에서 ptr라는 이름의 포인터를 선언하고 거기에 arr[0]의 주소를 대입했다. 그러고나서 ptr++를 하며 출력한 결과 위 두 개와 출력값이 같다. ptr+=1은 아까 말한것처럼 주소값을 4바이트씩 이동하기 때문이다.
#include <stdio.h>
int main(){
int arr[3]={1,2,3};
int (*ptr_arr)[3];
ptr_arr=&arr;
}
int (*ptr_arr)[3] 은 길이가 3인 int형 배열을 가리키는 포인터를 정의
그리고 ptr_arr에 &arr을 대입해주면 *ptr_arr[3]은 arr[3]을 가리킨다.
#include <stdio.h>
int main(){
int arr[3]={1,2,3};
int (*ptr_arr)[3];
ptr_arr=&arr;
for(int i=;i<3;i++){
printf("%d\n",(*ptr_arr)[i]);
}
}
위의 (*ptr_arr)[i]를 출력해보았다.
#include <stdio.h>
int main(){
int arr[2][3]={{1,2,3}, {4,5,6}};
int(*ptr)[3]=arr;
//1.ptr[i]==arr[i]
//2.ptr[i][j]==arr[i][j]
for(int i=0;i<2;i++){
for(int j=0;j<3;j++){
printf("%d ", ptr[i][j]);
}
printf("\n");
}
}
배열 포인터 배열을 가리키는 포인터
선언은 int(*ptr)[i] 이런식으로 한다.
ptr[i]와 arr[i]는 같아졌기 때문에 밑의 for문에서 arr[i][j]와 같은 기능을 하는 ptr[i][j]를 사용할 수 있다.
#include <stdio.h>
int main(){
int arr[4] ={1,2,3,4};
int *ptr[4];
for(int i=0;i<4;i++){
ptr[i]=&arr[i];
}
for(int i=0;i<4;i++){
printf("%d ", *ptr[i]);
}
printf("\n");
}
포인터 배열 포인터들이 배열된 것
int *ptr[4]로 4칸의 포인터 배열을 만들었다. 다음 for문을 통하여 각각의 ptr[i]에 arr[i]의 주소를 대입시키고 있다.
그 후 그 밑의 for문에서 *ptr[i]로 출력을 한다. ptr[i]는 주소값이기 때문!
#include <stdio.h>
int main(){
char strings[3][10]={"Hello","World","Guntak"};
char *p_str[3];
for(int i=0;i<3;i++){
p_str[i]=strings[i];
})
for(int i=0;i<3;i++){
printf("%s \n", strings[i]);
}
}
strings[3][10]을 선언하고 동시에 초기화 했다. 그리고 p_str이라는 이름의 크기가 3인 배열을 선언했다. for문을 사용해 각각의 p_str[i]에 strings[i]를 대입했다.이제 p_str[i]과 strings[i]는 같은 표현이다.
마지막 for문처럼 %s인자에 strings[i]를 주면 %s가 알아서 strings[i]를 앞에서부터 훑으며 \0이 나오면 그만둔다.
<종합문제>
Q1.100개 이하의 정수를 입력받아 첫 줄에 짝수 번째 숫자들을 순서대로 출력하고 다음 줄에 홀수 번째 숫자들을 순서대로 추력하는 프로그램을 만들어 보세요.
/*
100개 이하의 정수를 입력받아 첫 줄에 짝수 번째 숫자들을 순서대로 출력하고
다음 줄에 홀수 번째 숫자들을 순서대로 추력하는 프로그램을 만들어 보세요.
*/
#include <stdio.h>
#include <string.h>
int main(){
int n;
int num[102];
printf("입력할 숫자의 개수를 입력하세요 >> ");
scanf("%d", &n);
printf("숫자를 입력하세요 >>");
for(int i=0;i<n;i++){
scanf("%d", &num[i]);
}
for(int i=0;i<n;i++){
if(i%2==1){
printf("%d ", num[i]);
}
}
printf("\n");
for(int i=0;i<n;i++){
if(i%2==0){
printf("%d ", num[i]);
}
}
}
Q2. 다음 코드의 출력값을 써보시오.
30
10
10
Q3.printf("%d \n", arr);이 100을 출력했다고 했을때의 출력값 예상
112 1
116 5
120 9
124 2
Q4. 10*10 이하의 정수형 이차원 배열을 입력받아 그 배열의 각 행의 요소의 합을 출력하는 프로그램을 만들어보세요.
#include <stdio.h>
int main(){
int arr[11][11];
int n,m;
scanf("%d %d", &n, &m);
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
scanf("%d", &arr[i][j]);
}
}
int sum=0;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
sum+=arr[i][j];
}
printf("%d\n", sum);
sum=0;
}
}
Q5.주어진 코드의 결과값 예상
100
100
100
100
100
0
100
0
Q6.주어진 코드의 결과값 예상
100
104
112
112
136
댓글
이 글 공유하기
다른 글
-
C/C++ 기초 강의 요약 (섹션7)
C/C++ 기초 강의 요약 (섹션7)
2020.03.27 -
C/C++ 기초 강의 요약 (섹션4)
C/C++ 기초 강의 요약 (섹션4)
2020.03.27 -
C/C++ 기초 강의 요약 (섹션2)
C/C++ 기초 강의 요약 (섹션2)
2020.03.27 -
C/C++ 기초 강의 요약 (섹션1)
C/C++ 기초 강의 요약 (섹션1)
2020.03.25