반응형

아래는 문자열 뒤집기, 배열 뒤집기를 작동시키는 C언어 코드이다.

 

예를들어 "hello"가 입력이 되면, 이를 "olleh"로 뒤집어 출력한다.

문자열 배열 char str[6] = {'h','e','l','l','o'}; 가 입력되었을 때 뒤집어진다.

또한 포인터를 이용한 문자열이 들어올때도 마찬가지이다.

char* str = "hello"; 가 입력이 들어와도 Type이 char* 동일하기 때문에 가능하다.

아래는 코드

반응형
#include <stdio.h>

int main()
{
	//char str[6] = {'h','e','l','l','o'};
	char* str = "hello";
	int len = 0;

	// str에 저장된 문자열의 길이갯수를 저장(NULL 제외)
	len = strlen(str);   

	printf("출력 : \n");
	for (int i = len - 1; i >= 0; --i) {   // for문의 초기값을 len으로 주어 뒤에서 부터 문자열을 출력한다.
			printf("%c", str[i]);
	}
	printf("\n");

	return 0;
}

 

 

반응형
반응형

아래 코드는 두 수의 최대공약수를 구해주는 함수에 관한 코드이다.

/*
	최대공약수 구하기 알고리즘
	2개 값 입력, 최대 공약수 출력 함수
	알고리즘:
		1. v가 u보다 크면 v와 u값을 바꾼다.
		2. u = u - v
		3. u가 0이면 v가 최대공약수. 아니면 다시 처음으로 돌아간다.
*/

#include<stdio.h>

int GCD(void) {
	int u = 0;
	int v = 0;
	int temp = 0;
	int result = 0;

	printf("2개의 값을 입력하시오.\n");
	printf("a:");
	scanf_s("%d", &u);
	printf("b:");
	scanf_s("%d", &v);

	while(1)
	{
		if (v > u) {
			temp = u;
			u = v;			// 1. v가 u보다 크다면, v와 u값을 바꾼다.
			v = temp;

			u = u - v;		// 2. 
		}
		else {
			u = u - v;
		}

		if (u == 0)
		{
			result = v;		// 3. u가 0이면 v가 최대공약수
			break;
		}
	}
	return result;
}

int main(void)
{
	int result;
	result = GCD();
	printf("최대공약수는: %d", result);

	return 0;
}

 

반응형

 

똑같은 기능을 하는 최대 공약수를 구하는 방법을 아래는 재귀함수를 이용한 방식이다.

/*
	최대공약수 구하기 알고리즘(Recursive Function 모드 (재귀함수))
	2개 값 입력, 최대 공약수 출력 함수
	알고리즘:
		1. v가 0이 아니면,
			1.1. u = u % v
			1.2. u와 v를 교환
			1.3. 1으로 돌아감.
		2. v가 0이면 u가 최대공약수
*/

#include<stdio.h>

int GCD_recursion(int u, int v) {
	
	if (v == 0)
		return u;
	else
		return GCD_recursion(v, u % v);
}

int main(void)
{
	int u, v, result;
	
	printf("2개의 값을 입력하시오.\n");
	printf("a:");
	scanf_s("%d", &u);
	printf("b:");
	scanf_s("%d", &v);

	result = GCD_recursion(u, v);
	printf("최대공약수는: %d", result);

	return 0;
}

 

아래 함수는 똑같이 최대 공약수를 구하는 방법이지만, 알고리즘 성능이 좀 더 향상 된 방법이다.

/*
	최대공약수 구하기 알고리즘(성능 개선 모드)
	2개 값 입력, 최대 공약수 출력 함수
	알고리즘:
		1. v가 0이 아니면,
			1.1. u = u % v
			1.2. u와 v를 교환
			1.3. 1으로 돌아감.
		2. v가 0이면 u가 최대공약수
*/

#include<stdio.h>

int GCD(void) {
	int u = 0;
	int v = 0;
	int temp = 0;
	int result = 0;

	printf("2개의 값을 입력하시오.\n");
	printf("a:");
	scanf_s("%d", &u);
	printf("b:");
	scanf_s("%d", &v);

	while(v != 0)	// v가 0이 아니면 무한 반복
	{
		u = u % v;	// 1.1.
		temp = v;	// 1.2.
		v = u;
		u = temp;
	}
	result = u;		// 2.

	return result;
}

int main(void)
{
	int result;
	result = GCD();
	printf("최대공약수는: %d", result);

	return 0;
}

 

 

반응형
반응형

구조체 및 구조체 배열에 관해서는 아래 참고.

https://ansan-survivor.tistory.com/1333

 

[C언어] 구조체(struct)에 배열을 선언하여 사용 방법, 선언과 동시에 초기화

앞서 구조체에 대한 설명이 있다. https://ansan-survivor.tistory.com/1331 [C언어] 구조체(struct) 에 대해서, C언어 구조체란? 구조체 사용방법, 구조체 선언과 동시에 초기화 구조체(struct)란?  - 여러 자료..

ansan-survivor.tistory.com

 

위 구조체를 포인터 형태로 접근하는 방법이다.

 

pos의 자료형은 struct point 이므로 포인터 변수 pptr의 타입도 struct point * 으로 선언했다. 그리고 포인터이므로 pos 구조체의 주소를 넣어주었다.

// 구조체 선언 및 초기화
struct point pos = {11, 12};

// 구조체 인스턴스 pos의 주소를 가리키는 포인터 선언
struct point * pptr = &pos;

 

포인터 변수 선언한 pptr은 아래와 같이 이용한다. 해당 구조체에 값을 넣기 위해

*pptr 으로 구조체에 접근, 연산자 . 마침표를 이용해 구조체 내부의 값 xpos, ypos에 접근하는 방식이다.

(*pptr).xpos = 10;
(*pptr).ypos = 20;

하지만 위 연산자를 아래와 같이 대체할 수 있다. (빨간색 부분을 보면 된다)

(*pptr).xpos  ==  pptr->xpos

pptr->xpos = 10;
pptr->ypos = 20;

 

반응형

 

사용 예제

#include <stdio.h>

struct point
{
	int xpos;
	int ypos;
};

int main()
{
	// 구조체 선언과 동시에 초기화 (2개의 인스턴스 pos1, pos2)
	struct point pos1 = { 1, 2 };
	struct point pos2 = { 100, 200 };

	// pos1인스턴스를 가리키는 포인터 변수 선언
	struct point * pptr = &pos1;

	// pptr이 pos1을 가리키니, pos1으로 접근함
	(*pptr).xpos += 4;
	(*pptr).ypos += 5;
	printf("[%d %d] \n", pptr->xpos, pptr->ypos);


	return 0;
}

해당 주소에 접근해서 더해짐

반응형
반응형

앞서 구조체에 대한 설명이 있다.

https://ansan-survivor.tistory.com/1331

 

[C언어] 구조체(struct) 에 대해서, C언어 구조체란? 구조체 사용방법, 구조체 선언과 동시에 초기화

구조체(struct)란?  - 여러 자료형(int, double 등)을 하나로 묶어서 표현할 수 있도록 함.  - struct [자료형] 형태. 즉, 사용자 정의 자료형을 만듦.  - 구조체를 만들면 여러 자료형을 담고 있는 구조

ansan-survivor.tistory.com

 

이 구조체에 대한 인스턴스를 변수 하나가 아닌 배열로 선언이 가능하다.

아래는 arr[3] 으로 배열 3개를 만들어 각각 구조체 인스턴스가 하나씩 들어간 형태이다.

#define _CRT_SECURE_NO_WARNINGS // visual studio 보안 경고로 인한 컴파일 에러 방지
#include <stdio.h>

struct point
{
	int xpos;
	int ypos;
};

int main()
{
	// point구조체의 인스턴스로 배열선언
	struct point arr[3];
	int i = 0;

	for (i=0;i<3;i++)
	{
		printf("점 좌표 입력:");
		scanf("%d %d", &arr[i].xpos, &arr[i].ypos);
	}

	for (i = 0; i < 3; i++)
	{
		printf("[%d, %d]", arr[i].xpos, arr[i].ypos);
	}

	return 0;
}
반응형

결과를 보면 arr[0]에 xpos, ypos 그리고 나머지 arr[1], arr[2]에도 다 들어가있다.

그것을 결과로 출력한 것.

 

 

여러 타입(Type) 자료형이 들어가있는 구조체(Struct)의 선언 및 바로 초기화

#include <stdio.h>

struct person
{
	char name[20];
	char phoneNum[20];
	int age;
};

int main()
{
	// 구조체 배열 인스턴스를 선언과 동시에 초기화 시키기 (초기값 부여)
	struct person arr[3] = {
		{"jack", "010-1234-4323", 31},
		{"tom", "010-4321-4323", 21},
		{"tom", "010-1646-4323", 45}
	};

	int i;

	for (i=0;i<3;i++)
	{
		printf("%s %s %d \n", arr[i].name, arr[i].phoneNum, arr[i].age);
	}

	return 0;
}

 

 

 

반응형
반응형

구조체(struct)란? 

 - 여러 자료형(int, double 등)을 하나로 묶어서 표현할 수 있도록 함.
 - struct [자료형] 형태. 즉, 사용자 정의 자료형을 만듦.

 - 구조체를 만들면 여러 자료형을 담고 있는 구조 하나만을 선언해서 가져올 수 있다.

 

#define _CRT_SECURE_NO_WARNINGS
# include <stdio.h>

// x, y점은 서로 독립된 것이 아니라, 하나의 정보를 표현한다.
// 좌표점 세트(구조체)를 아래와 같이 정의
struct point	
{
	int xpos;
	int ypos;
};

// 구조체를 이용해서 좌표간 거리 구하기
int main()
{
	// 각각 x,y좌표를 지닌 2개의 구조체 생성.
	struct point pos1, pos2;
	
	double distance;


	fputs("1번째 좌표: ", stdout);
	scanf("%d %d", &pos1.xpos, &pos1.ypos);


	fputs("2번째 좌표: ", stdout);
	scanf("%d %d", &pos2.xpos, &pos2.ypos);


	// 두 좌표 입력된 값 출력
	printf("첫번째 좌표점 : %d, %d\n", pos1.xpos, pos1.ypos);
	printf("두번째 좌표점 : %d, %d\n", pos2.xpos, pos2.ypos);

	return 0;
}

위와 같은 방식으로 구조체 인스턴스(pos1, pos2)를 생성하고, 그 내부에 인자를 하나씩(pos1.xpos, pos1.ypos) 빼서 쓸 수 있다. 인스턴스에서 내부 인자에 접근하는 방법은 마침표(.)을 사이에 넣으면 된다.

반응형

<여러 타입(Type)자료형을 넣은 구조체>

    인적정보가 담긴 구조체를 생성.

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>

// char와 int 자료형이 섞여있는 구조체 생성 (인적 데이터)
struct person
{
	char name[20];
	char phoneNum[20];
	int age;
};

int main()
{
	//	man1 과 man2 두 구조체인스턴스 생성.
	struct person man1, man2;	

	// man1에 대한 데이터 생성. (strcpy함수를 이용해 문자열 복사)
	strcpy(man1.name, "홍길동");
	strcpy(man1.phoneNum, "010-1234-5678");
	man1.age = 23;


	// man2에 대한 데이터는 사용자 입력 받음
	printf("이름 입력: ");
	scanf("%s", man2.name);
	printf("번호 입력: ");
	scanf("%s", man2.phoneNum);
	printf("나이 입력: ");
	scanf("%d", &(man2.age));


	printf("첫번째 사람 이름: %s \n", man1.name);
	printf("첫번째 사람 번호: %s \n", man1.phoneNum);
	printf("첫번째 사람 나이: %d \n", man1.age);

	printf("두번째 사람 이름: %s \n", man2.name);
	printf("두번째 사람 번호: %s \n", man2.phoneNum);
	printf("두번째 사람 나이: %d \n", man2.age);

	return 0;
}

구조체 인스턴스 man1은 자동입력된 데이터, man2는 유저의 입력은 받는 데이터.

구조체의 Type은 char과 int가 함께 들어가있다.

 

 

<구조체 선언과 동시에 변수까지 선언하기>

    아래과 같이 main에서 구조체 인스턴스를 선언할 필요없이, 구조체 생성과 동시에 선언이 가능하다.

    } 뒤에 띄어쓰기가 반드시 있어야 한다.

서로 같은 의미 main( )밖에서도 구조체 바로 아래 선언은 가능하다.

 

 

 

<구조체 선언과 동시에 초기화 하기>

    아래과 같이 선언과 동시에 값을 넣으면, 구조체에 있는 변수 순서대로 값이 들어간다.

#include <stdio.h>

struct point
{
	int xpos;
	int ypos;
};

struct person
{
	char name[20];
	char phoneNum[20];
	int age;
};

// 초기화 방식이 배열과 유사함.
// 초기화 할 데이터들을 중괄호 안에 순서대로 나열하면 된다.

int main()
{
	struct point pos = { 10, 20 };
	struct person man = { "이승기", "010-1234-5678", 21 };

	printf("%d %d \n", pos.xpos, pos.ypos);
	printf("%s %s %d \n", man.name, man.phoneNum, man.age);

	return 0;
}

{&amp;nbsp; } 중괄호를 열고 값을 넣으면 해당값이 자동으로 들어가 초기화 한다.

 

 

반응형
반응형

두개의 문자열을 하나의 문자열로 합쳐주는 함수.

 

영단어 뜻으로는 아래와 같다.

String concatenation : 문자열을 연결, 연속 한다. (문자열을 덧붙인다.)

이를 합쳐서 strcat 라고 한다.


함수 원형:
char * strcat(char * dest, const char * scr);
char * strcat(char * dest, const char * scr, size_t n);


-> 덧붙여질 문자열의 주소 값 반환

 

#include <stdio.h>
#include <string.h>

int main()
{
	char str1[30] = "First~";
	char str2[30] = "Second";

	char str3[30] = "simple num: ";
	char str4[30] = "1234567890";

	// case 1
	puts(str1);         //	붙이기 전.
	strcat(str1,str2);  //	str1 뒤에 str2를 이어 붙임. [First~'\0']여기 NULL 자리를 str2로 채우고 NULL을 맨 뒤로 보냄.								

	//**주의사항: str1 이 str2가 들어갈 충분한 배열공간을 갖고 있어야 뒤에 채워짐
	puts(str1);         //	붙이기 후.

	// case 2
	strncat(str3, str4, 7);		//	n은 덧붙일 문자열의 최대 길이를 제한한다. 특히 NULL문자를 포함해 복사함으로,
					//	여기서 [1234567]까지 복사되고 그 뒤에 '\0'까지 복사가 된다. 즉, 총8개의 문자가 복사되는 것임.
	puts(str3);

	return 0;
}
반응형

 

(결과) 두 문자열을 합쳐버렸다

 

 

반응형
반응형

서로 두개의 문자열을 비교해서 같으면 0을 반환하고, 왼쪽이 크면 +1 작으면 -1을 반환하는 함수이다.

아래 예를 보면 알 수 있다. (알파벳도 결국 아스키 코드이며, 그 아스키 코드값으로 비교한다)

#define _CRT_SECURE_NO_WARNINGS //  보안 경고로 인한 컴파일 에러 방지
#include <stdio.h>
#include <string.h>

int main()
{
	printf("%d \n", strcmp("ABCD", "ABCD"));		//	같으므로 0을 반환
	printf("%d \n", strcmp("ABCD", "ABCC"));		//	C < D 이므로 s1이 값이큼. 0보다 큰값 반환.				(왼쪽이 큼)
	printf("%d \n", strcmp("ABCD", "ABCDE"));		//	ABCD까지 같으나, E값이 나와서 s2가 더 큼. 0보다 작은값 반환.(오른쪽이 큼)
	return 0;
}

결과

반응형

위 원리를 이용해서 아래와 같이 만들 수 있다.

2번의 문자열을 입력해서 그 두 문자열을 비교해서 일치여부 파악

#define _CRT_SECURE_NO_WARNINGS // fopen 보안 경고로 인한 컴파일 에러 방지
#include <stdio.h>
#include <string.h>

int main()
{

	char str1[20];
	char str2[20];

	printf("문자열 입력 1: ");
	scanf("%s", str1);

	printf("문자열 입력 2: ");
	scanf("%s", str2);

	// str1, str2가 같으면 0이 출력 그럼 False가 되는데, !(not)을 붙임으로 써 True를 만들어서 if 내부를 실행 시킴.
	if (!strcmp(str1, str2))		
	{
		puts("두 문자열은 완벽히 동일합니다.");
	}
	else
	{
		puts("두 문자는 동일하지 않습니다.");

		//	str1, str2 의 3번째 까지 문자를 비교해 일치하면 0을 반환하는데 if(False),그러나 !을 만나서 if(TRUE) 이므로 내부를 실행함.
		if (!strncmp(str1, str2, 3))				
			puts("그러나 앞 세글자는 동일합니다.");
	}

	return 0;

}

두 문자열이 같을 때

두 문자열이 다를 때

다르만 일부 조건이 맞을 때

 

 

 

 

반응형
반응형

문자열 내장 라이브러리는 #include <string.h> 을 추가해야 있다.

문자열을 복사하는 내장 함수로는 아래 두가지가 있다.

 

함수의 원형.

 

char * strcpy(char * dest, const char * src);

char * strncpy(char * dest, const char * src, size_t n);

 

 

간단한 복사 예

#define _CRT_SECURE_NO_WARNINGS // visual studio 보안 경고로 인한 컴파일 에러 방지
#include <stdio.h>
#include <string.h>


int main()
{
	// str1에만 값이 있고, str2는 초기화 값을 넣지 않음.
	char str1[20] = "1234567890";
	char str2[20];

	// str1을 str2에 복사
	strcpy(str2, str1);

	// 출력확인
	puts(str1);
	puts(str2);

	return 0;
}

(결과) str1의 값이 str2에 복사되어 출력이 가능한 것을 볼 수 있다.

** 그러나 메모리 침범의 결과를 만들 수 있는 strcpy보다, strncpy를 아래와 같이 사용하는게 안정적 코드를 만드는데 좋다.

#define _CRT_SECURE_NO_WARNINGS // fopen 보안 경고로 인한 컴파일 에러 방지
#include <stdio.h>
#include <string.h>


int main()
{
	// str1에만 값이 있고, str2는 초기화 값을 넣지 않음.
	char str1[20] = "1234567890";
	char str2[20];

	// str1을 str2에 복사 * 안전한 사용법 strncpy
	strncpy(str2, str1, sizeof(str2));

	// 출력확인
	puts(str1);
	puts(str2);

	return 0;
}

결과는 같다.

 

반응형

 

 

아래 코드는 유도리 있게 딱 할당된 메모리 만큼만 복사하고 마지막에 NULL을 넣어 문자열을 끝낸다.

#define _CRT_SECURE_NO_WARNINGS // fopen 보안 경고로 인한 컴파일 에러 방지
#include <stdio.h>
#include <string.h>


int main()
{
	// str1에만 값이 있고, str2는 초기화 값을 넣지 않음.
	char str1[20] = "1234567890";
	char str3[5];

	// str1을 str3에 복사 * 안전한 사용법 strncpy
	strncpy(str3, str1, sizeof(str3) - 1);	//	맨 마지막자리만 빼고 복사를 하라! (Null이 들어갈 공간 마련하기 위해)
	str3[sizeof(str3) - 1] = 0;				//	str[5-1] = str[4], 즉, 문자열의 마지막 자리에 0을 대입. 문자열을 끝냄.


	// 출력확인
	puts(str1);
	puts(str3);

	return 0;
}

(결과)

 

 

반응형
1234···9

+ Recent posts