//아스키 코드 값이 가장 큰 문자 출력하기
#include<stdio.h>
#include<string.h>
void main(void)
{
char *str_p, *n_p;
char str[100];
int i, n[100]={0}, max; //숫자 배열은 아스키 코드 비교를 위해 사용
str_p = str; //str_p 포인터 변수가 str 문자 배열의 주소를 저장함으로써 str을 가리키게 함
n_p = n; //n_p 포인터 변수가 int형 배열 n의 주소를 가짐으로써 n을 가리키게 함
printf("str 입력: ");
gets(str); //gets 함수로 문자열을 받아야 공백을 포함하여 배열에 저장 가능
for (i = 0; str[i]!='\0'; i++) //문자열 끝인 null이 아닐 때까지 반복
{
n[i] = str_p[i] + 0; //0을 더함으로써 숫자인 아스키코드 값으로 변환
}
max = n_p[0];
for (i = 1; n[i]; i++) //n[i] != NULL인 동안 반복
{
if (n_p[i] > max)
{
max = n_p[i];
}
}
printf("아스키코드 값이 가장 큰 문자: %c\n", max);
}
주의할 점!
1) 포인터 변수에 배열 주소 대입할 때,
배열의 주소를 저장하는 것이므로
str_p = &str;
이 아닌
str_p = str;
이라고 써야 한다!
왜냐하면 배열의 이름 자체가 배열의 시작 주소이기 때문
2) n 배열의 원소에서 max 값을 찾으려고 for문을 사용할 때,
for문을 끝내기 위한 조건식에서 n의 개수로 구하면 안 된다!
즉, n이 int형 배열이므로 n의 원소 개수 변수를 num이라 할 때
num = sizeof(n) / sizeof(int);
로 원소의 개수를 구하면, n의 크기를 100으로 줬기 때문에 원하는 원소의 개수를 얻을 수 없게 된다.
(*동적 메모리 할당을 하지 않았기 때문에 배열의 크기를 임의로 정해준 것이기 때문에)
*동적 메모리 할당: 필요한만큼 배열의 크기를 정해서 메모리에 할당한 후 프로그램이 끝나기 전 해제한다. 메모리 낭비를 방지할 수 있다.
따라서 아직 동적 메모리 할당을 배우지 않아서 배열의 크기를 임의로 정해서 수행하는 경우에는,
n[100] = {0};
으로 처음에 n을 0으로 모두 초기화한 후,
for문에서 조건식을 n[i] != NULL로 주면
원소가 NULL이 아닌 동안, 즉 0이 아닌 동안 반복문 내의 문장을 수행하고,
원소가 NULL이 되면 반복문을 빠져나오게 된다.
#include<stdio.h>
#define MAX 10
void main(void)
{
int arr[50] = { 0 }, i, j, k, temp;
int *num = arr;
for (i = 0; i < MAX; i++)
{
printf("n[%d] 입력: ", i);
scanf("%d", num + i);
}
printf("\narr[%d] = { ", MAX);
for (i = 0; i < MAX; i++)
{
if (i == MAX - 1)
{
printf("%d }\n\n", num[i]);
}
else
{
printf("%d, ", num[i]);
}
}
for (i = 0; i < MAX - 1; i++)
{
printf("%2d번째: { ", i + 1);
for (j = i + 1; j < MAX; j++)
{
if (arr[i] > arr[j])
{
temp = num[i];
num[i] = num[j];
num[j] = temp;
}
}
for (k = 0; k < MAX; k++)
{
if (k == MAX - 1)
{
printf("%d }\n", *(num + k));
}
else
{
printf("%d, ", *(num + k));
}
}
}
}
한 번 정렬이 될 때마다, 이와 같은 선택 정렬의 경우
가장 작은 수를 찾아서 바꾸는 수와 찾은 가장 수를 바꾸는 한 번의 정렬이 이루어진 후에
arr의 상태를 출력해야 하므로
바꾸는 for문이 끝난 후에 arr를 출력하는 for문을 작성하면 된다.
#include<stdio.h>
int main(void)
{
int b[] = { 2,3 };
int *p = &b;
printf("%p\n", p); //&b[0]
printf("%d\n", *p); //b[0]
printf("%d\n", *p + 1); //간접 참조 연산자 *가 산술 연산자 +보다 우선순위가 높으므로 *p가 되고, *p에 1을 더함 (b[0] 값에 1을 더함)
printf("%d\n", *p++); //++이 후위연산자이므로 먼저 *p를 반환한 후, p++해서 p가 &b[1]을 가짐(p가 b[1]을 가리킴)
printf("%p\n", p); //&b[1]
printf("%d\n", (*p)++); //괄호가 있으므로 *p 반환 후 *p의 값 1 증가 b[1] 출력
printf("%p\n", p); //&b[1]
printf("%d %d\n", b[0], b[1]);
}
연산자 우선순위☆
*p + 1
간접 참조 연산자 *가 산술 연산자 +보다 연산자 우선순위가 더 높으므로 먼저 *p가 읽힌다.
따라서 *p에 1을 더한 값이 반환된다.
*p++
먼저 *p의 값을 반환한 후, p++을 수행한다.
이것은 만약 x = *p++; 이라고 하면,
x = *p;
p++;
이 두 문장과 같은 의미이다.
먼저 값을 대입한 후 주소를 증가시키는 것
(*p)++;
괄호는 연산자 우선순위가 가장 높다.
따라서 *p에 괄호가 있으므로
*p++과 다르게 *p 값을 1 증가시키는 것을 의미한다.
추가로,
*(p++);
이거는 p++에 괄호가 있으므로 주소를 먼저 증가시키고,
p가 가리키는 곳의 값을 의미한다.
C 스터디 과제 4 (0) | 2019.05.06 |
---|---|
C 스터디 과제 03 (0) | 2019.04.09 |
C 스터디 과제02 (0) | 2019.04.04 |
C 스터디 과제01 (0) | 2019.04.04 |