HomeAboutMeBlogGuest
© 2025 Sejin Cha. All rights reserved.
Built with Next.js, deployed on Vercel
장지원 페이지/
🗑️
Trash
/
장지원, JANG JIWON
장지원, JANG JIWON
/C언어/
Week3

Week3

2023.07.11 to 2023.07.17

 
 

1. 알고리즘

여러가지 알고리즘들
 

개념

 
  1. 가장 큰 수 찾는 프로그램
 
  1. 선택 정렬 프로그램
 
  1. 등수 매기기 프로그램
 
  1. 50보다 큰 수를 세는 프로그램
 

2. 포인터

포인터
 
임베디드 시스템? → 이 시스템에서 C언어의 기계어적 성질이 활용됨?
이 기계적인 성질의 중심이 되는게 포인터임
 

개념

 
포인터는 메모리 주소와 연관되어 있음
 
  1. 메모리 주소란?
int a;란 문장이 실행되면, 공간이 만들어지는게 아님 → 공간들 중 일부를 a라는 변수에 할당해 주는 것
a = 10;이란 문장이 실행되면서 아까 a에 할당 된 공간에 10이라는 숫자가 저장되는 것임
 
  1. 컴퓨터의 저장 공간
4GB, 8GB이런 거 있을 거야 → 4GB는 값을 저장할 수 있는 1byte의 공간이 40억 개 있다는 뜻 → 한 번에 40억 개의 공간 쓸 수 있다 이런 걸 의미하는 듯
컴퓨터는 1바이트 단위로 공간을 할당해줌
→ char는 1바이트이므로 이러한 공간 1개를 할당해주면 될 것, int는 4개, double은 8개 할당해주면 됨
이런식으로 공간을 할당 받은 후 변수에 값을 저장하면 할당 받은 공간에 값이 저장되게 됨
 
메모리 공간을 구분하는 번호로써 ‘주소(adress)’도 사용 됨
 
밑의 사진에서 변수 a에는 1000~1003번지 공간이 할당된 것이고, 변수 b에는 1004~1011번지 주소가 할당된 것이라 이해할 수 있음
 
notion image
 
  1. 변수와 주소
어떤 변수에 대해 그 변수가 할당된 공간의 주소를 알아내는 연산자 → &
&a 라고 하면 a가 할당된 주소를 알 수 있음
 
만약 a에 할당된 공간의 주소가 여러 개라면 그 중 가장 작은 값이 결과 값이 됨
 
밑의 예시에서 a가 1000~1003번지에 할당 되어있는 것을 확인할 수 있음
→ 이 때 &a로 변수 a의 주소를 알아보면 1000이 되고, printf를 통해 a와 &a를 출력 시켜 보면 a의 저장되어 있는 값이 8과 a의 주소인 1000이 출력되는 것을 확인할 수 있음
 
notion image
 
이렇게 &연산자를 통해 변수의 주소를 얻을 수 있으며, 이 주소를 어딘가에 저장할 수 있음
→ 이 때 주소를 저장하려면, 또 다른 변수가 필요하겠지? → 이 때 사용하는 즉, 주소를 저장할 수 있는 변수를 포인터라고 함 (주소 변수 = 포인터이다 라고 생각해도 될 듯?)
 
  1. 포인터 선언
포인터 선언은 *을 이용해서 할 수 있음
예를 들어, int*c;라고 하면, 포인터 c가 만들어짐 → 이 변수 c에는 int형 변수의 주소를 저장할 수 있음
 
notion image
 
위 그림에서 a, b는 변수 선언 (각각 int와 double형이므로 4칸과 8칸을 할당 시켜줌)
c, d는 포인터 선언 (포인터는 보통 4바이트의 크기를 가지고 있음 → 그러므로 각각 4칸을 할당 시켜줌)
 
&a는 위에서 보았듯이 a의 주소 중 가장 작은 값 (=1000)을 의미함 → 1000이라는 주소가 c에 저장되게 됨 (1000이라는 값이 포인터 c에 할당된 공간에 저장됨)
마찬가지로 포인터 d에는 1004 주소가 저장됨
→ 이런 말 되~~게 헷갈린다.. 잘 이해하자 ..
 
  1. 간접 지정 연산자
&는 변수가 할당된 공간의 주소를 알아낼 수 있는 연산자 → 이와 반대되는 역할을 하는 연산자도 있음 간접 지정 (또는 역참조) 연산자 *임
 
밑의 그림을 통해 자세히 설명함
notion image
 
*c = 8; 이라는 문장이 있음
포인터 c에는 전에 변수 a의 주소 즉, 1000을 넣어 두었으므로 포인터 c에 저장된 주소가 가르키는 공간은 1000~1004번지임
*c는 c에 저장된 주소가 가르키는 공간, 1000~1004번지의 ‘공간’을 의미함
(즉, &는 주소, *은 주소의 공간을 의미한다고 이해하면 될 듯)
 
*c = 8이라는 문장은 결국 a = 8 이라는 문장과 같은 의미를 가지게 됨
 
⇒ 정리하자면, 포인터에는 어떤 변수의 주소를 저장할 수 있음
그런데, 간접 지정 연산자를 이용하면 그 주소가 가르키는 공간에 접근 가능하고, 따라서 그 공잔에 값을 저장하거나 그 공간의 값을 읽는 것이 가능함 → 조금 더 저급 언어적 측면을 활용할 수 있다(?)
원래 변수에 직접적으로 값을 저장하거나 읽지 않아도, 포인터를 이용해서 간접적으로 값을 저장하거나 읽을 수 있음
 
  1. 포인터의 그림 표현
우리는 변수에 주소를 예측할 수 없음. 변수가 어느 주소 공간에 할당될지는 컴파일러나 운영체제가 결정하는 것이라서 프로그램은 그 주소를 알 수 없음
 
따라서 보통 밑의 그림처럼 표현함
밑의 그림은 “포인터 c가 변수 a를 가르키고 있다.” 라고 설명함
 
notion image
 
 
 
위 예제를 통해 말로써 해석해보자
  • 첫 번째, 두 번째 줄은 변수와 포인터들을 정의하고 있는 문장
  • 네 번째 줄에서는 변수 a의 주소가 포인터 p에 저장됨 (포인터 p가 변수 a를 가르키고 있다)
  • 다섯 번째 줄에서는 p가 가르키는 공간(a가 할당 받은 공간)에 8이 저장됨 (a에 8이 저장됨)
  • 쭉쭉쭉 실행되어서 최종적으로 20이 print되게 됨
 
  1. 포인터의 자료형
포인터에도 자료형이 있음
포인터가 가르키는 대상이 int형이면 int형 포인터, double형이면 double형 포인터라고 부름
‘포인터의 자료형은 (int*, double*) 이런식으로 끝에 *을 붙임으로써 표기함
int*형, double*형 이라고 부름 (정확한 명칭은 int형 포인터형, double형 포인터형임)
 
당연하지만 포인터 자료형이 같을 때만 저장 가능함
밑 예시 참고
 
notion image
 
 
함수와 포인터
 

개념

 
swap 예제
 
다음은 swap이란 함수를 호출해서 x, y값을 서로 바꾸어주는 코드임
→ 하지만 실행해보면 바뀌지 않는 다는 것을 확인할 수 있음
C언어에서 함수는 ‘호출’에 따라 동작하기 때문임
함수를 호출하면 인자에서 매개 변수로 값이 복사 될 뿐 어떤 연결이 생기는 것은 아님
이를 해결하기 위해 포인터를 이용할 수 있음
 
(++ 그냥 깨달은 점.. input, output 없으면 stdio.h 헤더 파일 불러오지 않아도 될 듯)
 
 
이런식으로 포인터를 사용하면 주소를 이용해서 간접적으로 변수 x와 y의 값을 바꿀 수 있음
 
해석은 밑 그림 참조
notion image
 
 
C언어에서는 값에 의한 호출이라는 개념만 사용 됨
참조에 의한 호출 (인자에 있는 변수가 매개 변수와 서로 연결 되어서 매개 변수를 수정하면 인자에 있는 변수도 같이 수정되는 것)은 지원하지 않고 있음
가끔 참조에 의한 호출이 필요할 때가 있는데, 그 때 포인터를 이용함 (그렇다고 해서 이게 참조에 의한 호출이 되는 것은 아님. 단지 참조에 의한 호출의 형태를 만들어주고 있는 것)
 
++ scanf를 사용할 때 scanf(”%d”, &a)라고 씀
 
scanf는 입력 값이 두 번째 인자 &a에 저장 됨
즉, scanf 함수 내에서 변수 a의 값을 바꾸는 것임
원래 함수는 인자 내에 있는 변수의 값을 바꾸지 못함
but scanf는 인자로 &a를 받고 있기 때문에 이가 가능함
 
scanf 내에서는 (위의 swap 예시 참고) &a 주소를 받아서 매개 변수에 저장 한 뒤에 그 주소를 통해 변수 a값을 바꿔 줌
 
따라서 scanf(”%d”, a);로 적게 된다면 Segmentatuon fault 오류가 발생함 → 주소가 잘못 되었다는 오류임
a가 인자로 오게 되면 a에 저장된 값이 인자로 넘어갈 것
만약 0이 저장되어 있다면 (보통 변수가 생성되면 0이 들어가 있으므로)
0이 인자로 넘어갈 것이고 scanf 함수에서는 0이 주소인 줄 착각하고, 0번지 공간을 찾을 거임
→ 근데 0번째 공간은 보통 변수가 할당되는 곳이 아니므로 Error를 출력시킬 것임
 
++ 포인터를 이용해서 반환 값을 여러 개 저장할 수도 있음
 
 
위 예시처럼 합과 차를 모두 return 해주는 함수를 만들고 싶음
위 함수는 실제로 두 개의 반환값을 반환하는 건 아님 !! → 그러나 sum_diff 함수는 반환값을 두 개 return 해주는 것처럼 보임 (270p 질문)
 
즉 포인터를 이용해서 결과를 받을 변수의 주소를 넘김으로써, 함수가 계산한 결과를 함수를 부른 쪽의 변수에 간접적으로 저장한다는 것
 
 
 
 
 

3. 포인터와 배열

배열명
 
포인터와 배열의 관계에 대해서 배울 것
배열에 관련된 연산은 포인터 연산들임
 

개념

 
이 기호는 (↔) 양쪽이 완전히 동일하다는 뜻 : 결과값이 동일할 뿐만 아니라 의미도 같아서 컴파일러가 구별하지 않음
 
이 기호는 (==) 양쪽이 서로 동등하다는 뜻 : 현재의 결과 값은 같은데, 의미는 서로 다른 것이어서 컴파일러가 구별함
 

 
변수를 선언하면 메모리 공간이 그 변수에 할당 됨
그렇다면, 배열을 선언하면 어떻게 할당이 될까?
 
예를 들어 int a[5]; 라고 선언을 해주었다고 생각해보자
그러면, int형 변수 한 개에 해당하는 4바이트 공간이 다섯 개가 할당 되어야 할 것
 
C언어에서는 다음과 같이 할당 됨
a[0]이 7200~7203번지의 공간들에 할당이 되었다면, a[1]은 7204~7207번지에, a[2]는 7208~7211번지에 할당 되는 것임
 
각 배열의 주소를 구해보면, &a[0] = 7200, &a[1] = 7204 … 가 될 것
 
    배열명, 즉 a는 다음과 같은 의미를 가짐
    a ↔ &a[0], 즉 a는 배열의 ‘첫 번째 요소의 주소’라고 이해 할 수 있겠어!
     
    주의 할 것은 a는 포인터가 아니라는 것
    따라서 a =7;과 같은 문장은 성립하지 않아 → pa = a;와 같이 따로 변수에 저장해서 사용해야 함
     
    ++ a의 자료형은 int*형임 (포인터형)
     
    그러면 *a는 뭘까?
    *은 주소가 가르키는 그 공간을 구하는 연산자임 → 그러므로 *a는 a[0]임
    *a ↔ *(&a[0]) ↔ a[0]
     
    a+1은 a[1]의 주소인 7204임
    이유는, C언어에서 (포인터형+정수)는 (포인터형+정수*(포인터가 가르키는 대상의 크기))로 계산되기 때문임 → 여기서 +,*은 사칙 연산 기호로써의 덧셈과 곱셈을 의미함
    a+i ↔ &a[i]
    쉽게 이해하면, a에 정수를 더하면, 그 정수 개수 이후의 배열 요소를 가르킨다고 보면 될 듯
     
    그러면 *a+1은 뭘까?
    a[1]이 될 것임
    *(a+1) ↔ *(&a[i]) ↔ a[i]
     
    위를 활용한 예제는 다음과 같음
     
     
      배열 요소를 지정할 때 배열명을 적고 []의 사이에 첨자를 적기도 함
      이 첨자 또한 ‘연산자’임 → 이름은 배열 참조 (array reference) 연산자 라고 부를 수 있음
       
      notion image
      ** 이거 읽어보기 *
       
      지금까지 포인터형에 정수를 더하는 연산을 해보았음 → 음수를 더할 수도 있을 것임
       
      포인터형도 하나의 자료형 → 이것들간의 연산이 가능함 : 결과는 두 주소 사이에 들어가는 변수의 개수임
      포인터와 포인터 간의 뺄셈은 두 주소 사이에 대상이 몇 개 들어갈 건지 계산하는 것이기 때문에 !! (주의!)
      &a[3]-&a[1] = 2일 것
       
       
      1차원 배열과 포인터
       

      개념

       
      ‘배열명’ 파트에서 다루어 본 것은 배열명의 의미와 주소 연산자를 통해 배열 요소들을 접근하는 방법임
      이 절에서는 배열과 포인터의 관계 및 포인터를 이용해서 배열 요소들을 접근하는 방법에 대해서 다룰 것임
       
       
      1. 배열명과 포인터
      int a[5];에서 a는 a[0]을 가르키는 주소임
      따라서 a의 자료형은 int형 변수를 가르키는 주소이므로 int *형임 (즉, 포인터형)
       
      만약 int *b;라고 선언한다면, b의 자료형 또한 int *형 일 것임 (즉, 포인터형)
       
      따라서 a와 b의 자료형은 같게 되고, b에 a를 저장하는 것도 가능함 (a에 b를 저장하는 것은 안됨 → 왜냐면 a는 포인터가 아니니까!! a는 상수 혹은 기호로써 이해해야 함)
      이렇게 되면 b에는 a[0] 주소가 들어있는 것 ! b는 a[0]을 가르키게 됨
       
      밑의 그림과 같은 상황이 되는 것임
      notion image
       
      여기서 a와 b는 같은 대상을 가르키고 있음
      다만 a와 b가 동일하지는 않아
      왜냐면, a는 주소값이고, b는 이를 저장하기 위한 변수(포인터)이기 때문이지
       
      따라서 동일하지는 않으나 현재는 같은 값을 가진다는 의미로 a==b라고 표기할 수 있음
       
      위 ‘배열명’ 파트에서 했던 것과 같이 a+i ↔ &(a[i])임
      따라서 b+i == &(a[i])가 될 것 임
      쉽게 이해하면 b+i는 b가 가르키는 배열 요소에서 i개 이후의 배열 요소를 가르킨다고 이해하면 될 듯
       
      마찬가지로 *(a+i) ↔ a[i] 였음
      따라서 *(b+i) == a[i]가 될 것
       
      마지막으로 *(b+i) ↔ b[i]가 됨
      여기서 중요한 점은 []가 배열도 아닌 b에 대해 사용 되었다는 것임
      지금까지 다룬 내용들을 보면 배열명과 포인터를 거의 구분 없이 사용했다는 걸 알 수 있음
      예를 들어 포인터 b에 배열명 a를 대입하는 순간, a+i가 가르키는 a[i]를 b+i도 가르키고 있고, *(a+i)와 동일한 a[i]가 *(b+i)와도 동일함
      그러므로 원래 배열명 앞에 있어야 하는 []연산자가 포인터 앞에 오는 것도 허용해 주는 것임
      b = a라고 선언한 이후에는 포인터 b를 마치 배열 a인양 사용할 수 있음
       
      밑의 그림으로 정리할 수 있음
      notion image
       
       
      예시를 통해서 다시 확인할 수 있음
       
      밑 예시에서 sum1,sum2,sum3,sum4의 합 은 모두 같음
       
       
      1. 포인터를 이용한 다양한 배열 접근1
      포인터를 이용해서 배열 요소들을 접근하게 되면 일반적인 배열 요소를 접근할 때와는 다른 자유도가 생김
      이런 자유도는 포인터가 변수라는 사실에 기인함
       
      배열 a와 포인터 b에 대해, 배열명 a는 변수가 아님
      배열명은 어떤 기호로 이해해야 하며, 따라서 그 값을 바꿀 수 없음
      예를 들어서 a=a+1;과 같은 문장을 적으면 안되지만, b=b+1;과 같은 문장은 적을 수 있음
       
       
      위 예시는 밑과 같이 실행됨
       
      notion image
       
      첫 번째 b[1]은 *(b+1), 즉 b+1이 가르키는 변수를 의미함
      b+1은 a[1]을 가르키고 있으므로 이 문장에서는 a[1]에 3을 저장됨
       
      마찬가지로 c[2]에는 3이, a[3]에는 5가 저장되게 됨
       
      만약 인덱스가 음수라면?
      b[-1]=3을 마지막 줄에 추가하게 되면, a[1]에 3이 저장됨
       
      이를 이용하면, 위 예시 처럼 배열을 바꾸어 가면서 다룰 수도 있고, 배열의 중간에서 부터 배열의 처음인 양 다룰 수 있음
       
      1. 포인터를 이용한 다양한 배열 접근2
       
      이 때는 a[0]에는 3이, a[1]에는 4가 각각 저장되게 될 것임
       
      우리는 i = i+1을 ++i 또는 i++로 적을 수 있었음
      이를 통해 위 문장을 밑의 사진처럼 더 간결하게 적을 수도 있음
       
      notion image
       
      이를 밑의 예시처럼 응용해 볼 수도 있음
       
       
      이것을 실행하면 a[0]부터 a[4]까지의 합이 출력 될 것임
      ** b++는 후위 연산자 인 듯, 그니까 b[0]을 할당하고 b[1]이 되는 거임
      전위 연산자는 b[0+1]을 할당해줌 **
       
      notion image
      notion image
       
      위 사진은 코드의 진행을 나타냄
       
      이 때 (k)를 보면, b가 아무것도 가르키지 않는 것을 확인할 수 있음
      만약 a[4]의 주소가 7216이라면, b는 7220을 가르키고 있을 거임
      단 7220번지에는 어떤 변수가 있을 수도 있고, 없을 수도 있음
      이 때는 *b=3과 같이 b값의 값을 바꾸는 것은 위험함
      왜냐면 다른 변수가 바뀔 수도 있기 때문임
       
      위 코드를 좀 더 포인터 연산을 많이 하게 끔 바꾸고 싶으면 밑과 같이 작성하면 됨
       
       
       
      다시 보는 배열 매개 변수
       

      개념

       
      함수 파트에서 매개 변수가 배열인 경우에 대해서 다루어 봤음
      매개 변수가 배열일 때는 새로운 배열이 만들어지는 건 아니고, 인자에 오는 배열의 이름을 잠시 바꾸는 것이라 했음
      그렇기 때문에 배열의 매개 변수의 크기도 생략한다고 했음
      무엇보다 값에 의한 호출이란 개념에 맞지 않아 보이는 동작도 있었음
      매개 변수가 함수 일 때 함수 내에서 배열 매개 변수의 배열 요소 값을 바꾸면 인자로 건넸던 배열의 배열 요소 값이 바뀌었음
      (질문 : 그렇다면 C언어에서 매개 변수가 함수인 경우에는 참조에 의한 호출을 하는 건가? → ㄴㄴ 모두 값에 의한 호출임, 배열에서는 아닌 것 ‘처럼’ 보였던 것 )
       
      (여기서 값에 의한 호출이란 호출한 함수에서 전달한 인자의 값을 복사하여 피호출 함수의 입력 매개 변수의 초기 값을 설정하는 방식. 이러한 전달 방식에서는 호출한 곳의 인자와 피호출한 곳의 인자의 값은 같지만 메모리는 독립적임. C언어에서는 이런 값에 의한 호출 방식을 사용함
      밑의 글 참고)
       
       
      ** C언어에서 배열 매개 변수는 없다고 봐도 됨 **
      매개 변수 자리에 배열을 적어 놓으면 그 것은 포인터로 변환됨
      예를 들어 void f(int a[])라고 함수의 머리 부분을 구성하면, 컴파일러는 이것을 void f(int *a)라고 해석함
      즉 배열 a가 아니라 포인터 a라고 인식하는 거임
       
       
      지금까지 우리가 함수 내에서 다루었던 배열 매개 변수는 모두 배열을 가장한 포인터들이었음
       
      위 예시를 더 자세히 다루어보면
      프로그램이 main에서 시작하면 배열 b를 만들고 진행하다가 함수 f를 만남
      함수 f로 가보니 매개 변수가 배열 a임
      그러므로 매개 변수 자리에 int*a가 있는 것처럼 동작해서 포인터 a가 생성됨
      그 다음 인자가 매개 변수에 복사 됨
      f를 보니 인자가 배열명 b임
      이 때 배열명 b는 b[0]을 가르키는 주소임
      이 값이 매개 변수인 포인터 a에 복사됨
      자료형은 당연히 둘 다 int*형임
       
      함수 내부를 실행하려고 하니 첫 문장이 a[2]=3임
      포인터 a에 대해 a[2]는 *(a+2)아 동일함
      그리고 현재 a가 b[0]을 가르키고 있으므로 a+2는 b[2]를 가르킬 것임
      그러므로 a[2]는 바로 b[2]이고 a[2]=3이 실행되면 b[2]에 3이 저장됨
      그리고 return문을 통해 되돌아가게 됨
      → 읽어 보면 값에 의한 참조가 아니라는 걸 확인할 수 있음
      → 즉 변수가 배열이면 인자의 배열을 잠시 이름만 바꾸는 것이라 이해해도 됨
      → 정확하게 설명한다면 매개 변수가 포인터인 것
       
      그럼 함수에서 다루었던 예제를 다시 살펴보자
       
       
      main 함수에서 array_sum 함수를 만나 위로 올라가게 됨
      array_sum 함수의 매개 변수는 int a[]와 n임
      n은 값에 의한 참조를 할 것이고, int a[]는 포인터 int *a로 변환될 것
      n에는 5라는 값이 복사 됨
      포인터 a에는 배열명 b의 값, 즉 b[0]의 주소가 전달 됨, a는 b[0]을 가르키고 있는 것
       
      반복문을 마치면 b[0]부터 b[4]까지의 합 = 31이 저장되어 있을 것
      sum에 더하는 건 a[0]~a[4]인데, 실제로는 b[0]~b[4]가 더해지고 있음
      포인터 연산의 관계를 이용해 포인터 a를 마치 배열인 것 처럼 사용한 것임
      마치 b가 a로 이름이 바뀐 것 처럼 보임
       
      만약 array_sum(b+1,3)을 반환하라 하면
      b[1]~b[3]의 합이 반환 될 것임
       
      정리하면, 매개 변수가 배열이어도 여전히 값에 의한 호출임
      배열 매개 변수가 포인터 매개 변수로 변한 다음에 인자 배열의 주소가 복사되는 것임
      → 주소 값에 의한 호출이라고 이해하면 될까? : 이렇게 이해하는게 좋을 듯
      다른 블로그에서는 값에 의한 호출과 포인터에 의한 호출을 구분하고 있음
       
       
       
       
       
       
      다차원 배열과 포인터
       

      개념

       
      1차원 배열에서는 int a[5]라는 배열에 대해서 int *b를 선언한 뒤 b=a;라고 실행하면 마치 b가 배열인 것 처럼 사용 가능했음
      다차원 배열에서는 이가 쉽지 않아
       
      2차원 배열에서 int a[2][3]에 상응하는 포인터는 int (*b)[3]과 같이 선언함
      괄호를 빠트려서는 안되고, 두 번째 이후의 크기 부터는 서로 같아야 함
      위와 같이 포인터 b를 선언하면 b=a;라는 문장을 실행할 수 있고, 이 때 부터 b를 2차원 배열인 것 처럼 사용하면 됨
      이 때 부터는 a[0][1]과 b[0][1]이 같은 의미를 가짐
       
       
      함수의 매개 변수에서 2차원 배열 매개 변수를 int b[][3]과 같이 적지만, 컴파일러는 int (*b)[3]으로 해석해서 읽음
       
      n차원 배열에 대해서도 위와 마찬가지임
       
      [size1][size2]…[sizen] → (*변수 명)[size2]…[sizen]과 같이 선언해도 됨
       
       
      #include <stdio.h> int main(void){ int i, a[10]; int max, idx; for (i=0; i<10; i++){ scanf("%d", &a[i]); } max = a[0]; idx = 0; for (i=1; i<10; i++){ if (a[i] > max){ max = a[i]; idx = i; } } printf("%d %d\n", max, idx); }
      #include <stdio.h> int main(void){ int i, j, a[10]; int min, idx, tmp; for (i=0; i<10; i++){ scanf("%d", &a[i]); } for (i=0; i<9; i++){ min = 9999; for (j=i; j<10; j++){ if(a[j] < min) { min = a[j]; idx = j; } } tmp = a[idx]; a[idx] = a[i]; a[i] = tmp; } for (i=0; i<10; i++){ printf("%d\n", a[i]); } }
      #include <stdio.h> int main(void){ int i, j, a[10]; int b[10]; int cnt; for(i=0; i<10; i++){ scanf("%d", &a[i]); } for(i=0; i<10; i++){ cnt = 0; for(j=0; j<10; j++){ if(a[j] > a[i]){ cnt++; } } b[i] = cnt + 1; } for(i=0; i<10; i++){ printf("%d\n", b[i]); } }
      #include <stdio.h> int main(void){ int i, a[10]; int cnt; for (i=0; i<10l i++){ scanf("%d", &a[i]); } cnt = 0; for (i=0; i<10; i++){ if(a[i]>50){ cnt++; } } printf("%d\n", cnt); }
      int a,b,c; int *p,*q; p = &a; *p = 8; q = &b; *q = 12; p = &c; *p = a+*q; printf("%d\n", *p);
      void swap(int a, int b){ inr tmp; tmp = a; a = b; b = tmp; return; } int main(void){ int x, y; x = 8; y = 12; swap(x, y); ... }
      void swap(int *a, int *b); int tmp; tmp = *a; *a = *b; *b = tmp; return; } int main(void){ int x,y; x = 8; y = 12; swap(&x, &y); ... }
      void sum_diff(int a, int b, int *c, int *d){ *c = a+b; *d = a-b; return; } int main(void){ int x,y; int p,m; x=8; y=12; sum_diff(x,y,&p,&m); ... }
      int a[5]; int i, sum; for (i=0; i<5; i++) { scanf("%d", a+i) # &a[i]와 같기 때문에 & 안써준거임 } sum = 0; for (i=0; i<5; i++) { sum = sum + *(a+i); # *(a+i) = a[i]와 같은 의미 이므로 이렇게 적어준거임 } printf("%d\n", sum);
      int a[5], *b, i; int sum1=0, sum2=0, sum3=0, sum4=0; ... b = a; for (i=0;i<5;i++) { sum1 += a[i]; sum2 += *(a+i); sum3 += *(b+i); sum4 += b[i]; } printf("%d, %d, %d, %d\n, sum1, sum2, sum3, sum4);
      int a[5]; int c[4]; int *b; b = a; b[1] = 3; b = c; b[2] = 5; b = a + 2; b[1] = 5;
      int a[5]; int *b; b = a; *b = 3; b = b + 1; *b = 4;
      int a[5]. *b, i; int sum=0; ... b = a; for(i=0;i<5;i++) { sum += *b++; } printf("%d\n",sum);
      int a[5], *b; int sum = 0; ... for(b=a;b<a+5;) { sum += *b++; } printf("%d\n",sum);
      void f(int a[]){ a[2] = 3; return; } int main(void){ int b[5]; ... f(b); ... }
      #include <stdio.h> int array_sum(int a[], int n){ int i, sum; sum = 0; for(i=0; i<n; i++) { sum += a[i]; } return sum; } int main(void){ int b[5] = {10,2,3,7,9} printf("%d\n",array_sum(b,5)); return 0; }
      #include <stdio.h> int main(void){ int a[2][3]; int (*b)[3]; int i, j, sum1, sum2; b = a; for (i=0;i<3;i++){ for(j=0;j<3;j++){ b[i][j] = i*30+j*10; } } sum1 = 0; sum2 = 0; for (i=0;i<3;i++){ for(j=0;j<3;j++){ sum1 = sum1 + a[i][j]; sum2 = sum2 + b[i][j]; } } printf("%d %d\n", sum1, sum2); return 0; }