2317 words
12 minutes
[C]C언어 기본

Basic reference for C programming

Type#

  • 소수형을 int에 담으면 소수점 이하가 버려진다.
#include <stdio.h>
int main() {
char c = 'A';
char str[] = "Hello C Programming";
printf("%c\n",c);
printf("%s\n",str);
short st = -40;
int i = 65536;
long l = 1234567890L;
printf("Short : %hd\n",st); // hd means short
printf("Int : %d\n",i);
printf("Long : %ld\n",l);
float f = 3.14f;
double d = 3.141592;
printf("Float : %f\n",f);
printf("Double : %lf\n",d);
}

Standard I/O#

입력

  • scanf
  • gets

출력

  • puts :
  • printf

case 1

#include <stdio.h>
int main() {
char str[100];
int num1 , num2;
printf("scan 2 numbers : ");
scanf("%d %d", &num1, &num2);
printf("num1 : %d, num2 : %d\n", num1, num2);
printf("%d+%d=%d\n", num1, num2, num1+num2);
printf("%d-%d=%d\n", num1, num2, num1-num2);
printf("%d*%d=%d\n", num1, num2, num1*num2);
return 0;
}

case 2

#include <stdio.h>
int main() {
char str[100];
pyts("input string : ");
gets(str);
puts(str);
return 0;
}

case 3

int main() {
int num =42;
char ch = 'A';
float f = 3.14;
double d = 3.141592;
printf("int : %d\n", num);
printf("char : %c", ch);
printf("float : %.2f\nDouble : %.5lf", f, d);
}

Flow Control#

switch#

  • break이 없다면 다음 case로 순차적으로 계속 실행한다.
#include <stdio.h>
int main() {
int n[3] = {73,95,82};
int sum = 0;
for int(i=0;i<3;i++) {
sum += n[i];
}
switch(sum/30) {
case 10:
case 9:
printf("A");
case 8:
printf("B");
case 7:
case 6:
printf("C");
default:
printf("D");
}
}

Loop#

for loop#

(initialization,test condition,increment or decrement)

test condition 이후 실행. 이후 increment or decrement

#include<stdio.h>
int main() {
for (int i=2; i < 9; i++) {
for (int j=1; j <=9;j++) {
printf("%d*%d = %d ",i,j,i*j);
}
printf("\n");
}
return 0;
}

while loop#

  • while은 증감식이 블럭 안쪽에 있는 loop이다.

case 1

int main() {
int i=0;
while(1) {
printf("value: %d\n ",i);
if (i >=4) {
break; // print 0~4
}
i++;
}
return 0;
}

case 2

#include<stdio.h>
int main() {
int a =1,b=1;
int sum = 0;
while (a <= 5) {
if (b % 2 ==0) {
sum += b;
} else {
sum -= b;
}
a ++ ;
b += 2;
}
printf("%d\n",sum);
return 0;
}
``
case 3
```c
#include<stdio.h>
int main() {
int i =0;
while(i< 10) {
i++; // start from 1
if(i%2!=0) {
continue;
}
printf("i=%d\n");
}
return 0;
}

do while loop#

Strings#

String#

문자열 선언 방법들

#include<stdio.h>
int main() {
char str1[] = "Hello World";
printf("%s\n",str1);
char str[20] = "Hello World";
printf("%s\n",str2);
char *str = "Hello World";
printf("%s\n",str)
char str3 = {'H','e' ,'l','l' ,'o','\n'}
printf("%s\n",str3)
}
  • 문자열 출력
  • ‘\0’ 은 null 문자를 의미
#include<stdio.h>
int main() {
char str1[] = "Hello World";
printf("idx \n")
for (int i=0;str1[i] != '\0'; i++) {
printf("%c",str1[i]);
}
printf("ptr \n");
char *ptr = str1;
while (*ptr !='\0') {
printf("%c", *ptr);
ptr++;
}
printf("strlen \n");
int len = strlen(str1);
for (int i =0; i < len; i++) {
printf("%c",str[i]);
}
}

Format Specifier#

printf에서 문자열 출력형태

  • %d : 정수
  • %c : 문자. 문자 1개
  • %s : 문자열
  • %f : 실수
  • %p : 포인터
  • %x : 16진수

String functions#

  • strcat(s1,s2) : 문자열 붙이기
  • strlen(s) : 문자열의 길이
  • sizeof(s) : 입력 파라미터가 순수하게 메모리를 잡아먹는 크기 \0 포함이라 strlen 보다 1만큼 더 크다.
  • strcpy(target,origin) : 문자열 복사. origin에 있는 문자열 전체를 target으로 복사함
  • snprint(buffer,format,string) : 문자열 담을 버퍼, 서식문자열, 서식문자열에 맞게 출력할 값을 받아 출력함

Array#

  • 배열 자체는 그냥 OS가 특정 단위로 메모리를 연결해 놓은 것이다.
  • 기본적으로 같은 데이터 타입을 가지는 변수들의 집합

basic

#include<stdio.h>
int main() {
int intArr[] = {1,2,3,4,5};
int size =5;
printf("intArr:\n");
for (int i=0;i<size; i++) {
printf("%d",intArr[i]);
}
return 0;
}

다차원 배열#

n차원 배열

case 1

#include<stdio.h>
int main() {
int arr[2][3] = {{1,2,3},{4,5,6}};
printf("arr:\n");
printf("00: %d\n",arr[0][0]);
printf("01: %d\n",arr[0][1]);
printf("02: %d\n",arr[0][2]);
printf("10: %d\n",arr[1][0]);
printf("11: %d\n",arr[1][1]);
printf("12: %d\n",arr[1][2]);
return 0;
}

문자열 배열#

#include<stdio.h>
int main() {
const char *strArr[2][2] = {{"Hello","World"},{"C","Programming"}};
printf("strArr:\n");
printf("00: %s\n",strArr[0][0]);
printf("01: %s\n",strArr[0][1]);
printf("10: %s\n",strArr[1][0]);
printf("11: %s\n",strArr[1][1]);
return 0;
}

Pointer#

메모리 접근하기#

  • & : ampersand operator. 변수의 메모리상의 주소를 반환
  • * : asterisk operator. 포인터 변수를 선언할 때 사용. 포인터 변수는 주소를 저장할 수 있는 변수를 의미. 기본적으로 주소만 저장함 포인터 변수가 가리키는 메모리상의 값을 반환

선언시 포인터변수와 사용시 포인터변수가 다르다.

#include<stdio.h>
int main() {
int n = 41;
int *p = &n;
printf("%d\n",p); // 주소가 출력됨
printf("%d\n",*p); // 값이 출력됨
}

문자열 및 배열 포인터#

  • 배열과 문자열에 포인터 변수를 선언할 경우 & 가 생략된다.
  • 배열의 첫번째 인덱스와 포인터가 가리키는 값은 같다.
  • 문자 n개와 문자열은 다르다 문자열은 마지막에 null 문자가 들어가 있다.(length +1)

포인터 배열

case 1

#include<stdio.h>
int main() {
int arr[] = {10,20,30,40,50};
int *ptr = arr;
printf("first element : %d\n", arr[0]);
printf("pointer value : %d\n", *ptr);
}

case 2

배열을 가리키는 포인터 포인터가 4개요소를 가진 배열을 가리키고 있음 ptr이 가리키고 있는 것의 주소값을 출력하면 배열의 첫번째 요소의 주소값이 출력된다. 포인터를 증가시키면 행을 넘어간다.

#include<stdio.h>
int main() {
int arr[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
int (*ptr)[4] ; // pointer to an array of 4 integers
ptr = arr;
printf("%d\n",ptr[0][0]); // 1
ptr++;
printf("%d\n",ptr[0][0]); // 5
ptr++;
printf("%d\n",ptr[0][0]); // 9
}

case 3

#include<stdio.h>
int main() {
int arr[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
int (*ptr)[4];
ptr = arr;
for (int i=0; i<3; i++) {
if((*ptr)[0] <6) {
for(int j=0; j<4; j++) {
printf("%d",(*ptr)[j] +2);
}
} else {
for (int j =0; j< 4; j++) {
printf("%d",(*ptr)[j] -3);
}
}
}
ptr++;
printf("\n")
}

포인터 String

case 1

#include<stdio.h>
int main() {
char *str = "Hello World";
char str2[] = "Hello World";
}

case 2

#include<stdio.h>
int main() {
char str[] = "Hello World";
char *ptr = str;
while (*ptr != '\0') {
printf("%c",*ptr);
ptr++; // go to next address
}
printf("\n");
return 0;
}

case 3

#include<stdio.h>
int pts() {
char *s = "Hello C Programming";
printf("%c" *s); // H
printf("%c",*(s+1)); // next address of s and get value
printf("%c",*(s+2));
printf("%c",*(s+3));
return 0;
}
int pts2() {
char *s = "Hello C Programming";
printf("%c",s[0]); // H
printf("%c",s[1]); // e
printf("%c",s[2]); // l
printf("%c",s[3]); // l
return 0;
}

Function#

case 1

#include<stdio.h>
int subtract(int a, int b) {
return a-b;
}
int main() {
int res = subtract(10,5);
printf("%d\n",res);
return 0;
}

Pointer as function argument

case 1

포인터로 문자열을 받아서 출력

#include<stdio.h>
void printStr(char *str) { // get memory address!! (initialization)
printf("given string : %s\n",str);
}
int main() {
char myStr[] = "C Programming";
printStr(myStr);
return 0;
}

case 2

case 1 과 동일하게 동작. 주소값이 배열의 첫번째 요소

#include<stdio.h>
void printStr(char str[]) {
printf("given string : %s\n",str);
}
int main() {
char myStr[] = "C Programming";
printStr(myStr);
return 0;
}

case 3

process의 int num, charch는 포인터 초기화여서 메모리 주소를 받는다.

#include<stdio.h>
void process(int *num, char *ch) {
printf("given num : %d\n", *num);
printf("given str : %d\n", *ch);
}
int main() {
int number = 42;
char character = 'A';
process(&number, &character);
return 0;
}

case 4

#include<stdio.h>
void swap(int *a, int *b) { // get memory address.
int temp = *a; // set value of a to temp
*a = *b; // set value of b to address of a
*b = temp; // set temp to address of b
}
int main() {
int x = 400;
int y = 600;
printf("before : x=%d, y=%d\n",x,y);;
swap(&x,&y)
printf("after : x=%d, y=%d\n",x,y);;
}

Recursive Function#

case 1

#include<stdio.h>
int nSum(int n) {
if( n ==0){
return 0;
} else {
int res = n + nSum(n-1);
return res;
}
}
int main() {
int a = 5;
int sum = nSum(a);
printf("given: %d, res : %d",a,sum);
return 0;
}

case 2

#include<stdio.h>
int fibo(int n) {
if (n <=1) {
return n;
} else {
return fibo(n-1) + fibo(n-2);
}
}
int main() {
int n = 11;
for (int i = 0; i < n; i++) {
printf("%d ",fibo(i));
}
return 0;
}

case 3

주소의 끝까지 1씩 누적되기 때문에 결국 문자열의 길이가 반환된다.

#include<stdio.h>
int strLen(char *str) {
if (*str == '\0') {
return 0;
} else {
return 1 + strLen(str+1); // next address as a parameter
}
}
int main() {
char *str = "Hello C Programming";
int len = strLen(str);
printf("length : %d\n",len);
return 0;
}

case 4

(*str ==c) 는 조건식이라 0 혹은 1을 반환.

#include<stdio.h>
int freq(char *str, char c) {
if (*str == '\0') {
return 0;
} else {
return (*str == c) + freq(str+1,c); // next address as a parameter
}
}
int main() {
char test[] = "Hello C Programming";
char c = 'l';
int res = freq(test,c);
printf("frequency of %c : %d\n",c,res);
}

case 5

#include<stdio.h>
int maxVal(int *arr, int size) {
if (size ==1) {
return arr[0];
} else {
int max = maxVal(arr,size-1);
return (arr[size-1] > max) ? arr[size-1] : max;
}
}
int main() {
int arr[] = {1,2,3,4,5,6,7,8,9,10};
int size = sizeof(arr)/sizeof(arr[0]); // 40/4 = 10 // 4 byte is size of int
int res = maxVal(arr,size);
printf("max value : %d\n",res);
return 0;
}

struct#

  • 포인터 접근
  • 구조체 자체가 배열에 들어갈 경우
struct Car {
char name[50];
int year;
float price;
};
int main() {
struct Car tcar;
int i;
char md[] = "SomeModel";
for(i=0; md[i] != '\0'; i++) {
tcar.name[i] = md[i];
}
tcar.name[i] = '\0';
tcar.year = 2021;
tcar.price = 60000.25;
printf("Car name : %s\n",tcar.name);
printf("Car year : %d\n",tcar.year);
printf("Car price : %.2f\n",tcar.price);
}

포인터 변수와 구조체

구조체 포인터를 통해 구조체 요소에 접근할 경우 -> 사용.

#include<stdio.h>
#include<string.h>
struct Car {
char name[50];
int year;
float price;
};
void printCar(struct Car *car) {
printf("Car name : %s\n",car->name);
printf("Car year : %d\n",car->year);
printf("Car price : %.2f\n",car->price);
}
int main() {
struct Car tcar;
strcpy(tcar.name,"SomeModel");
struct Car *ptr = &tcar;
ptr->year = 2021; // set value by pointer variable
ptr->price = 60000.25;
printCar(ptr);
}

typedef#

  • 기존 데이터 타입에 alias부여. 구조체를 typedef를 써서 custom 자료형을 만들경우 해당 자료형으로 객체 선언 가능
  • 보통 구조체와 조합해서 사용. 구조체를 하나의 타입으로 만들어줌.

case 1

#include<stdio.h>
typedef struct {
char name[50];
int year;
float price;
} Car;
int main() {
Car tcar;
strcpy(tcar.name,"SomeModel");
tcar.year = 2021;
printf("Car name : %s\n",tcar.name);
printf("Car year : %d\n",tcar.year);
return 0;
}

ASCII#

ASCII : 문자 인코딩의 일종. 문자 인코딩은 어떤 문자를 특정한 숫자나 코드에 매핑하는 것.

매핑 ex)

  • 대문자 A : 65
  • 소문자 a : 97
  • 문자 “0” : 48

case 1

#include<stdio.h>
int main() {
char c ='A';
int ascii = int c; // convert to int
printf("ASCII : %d\n",ascii);
}

case 2

문자 0 에서 아스키 숫자가 8 증가한 문자 “8” 을 출력함

#include<stdio.h>
int main() {
int num = 8;
char digit = (char) (num + '0');
printf("Integer Value : %d\n", num);
printf("Digit char : %c\n",digit) ; // 8
}

goto, continue#

  • goto : 즉시 타겟 라벨로 이동시키는 키워드
  • continue : 즉시 다음 반복으로 이동시키는 키워드.

case 1

#include<stdio.h>
int main() {
for(i=0;i<10;i++) {
if(i==7) {
goto target;
} else {
printf("%d ",i)
}
printf("i = %d\n",i);
}
target:
printf("goto target label\n");
return 0;
}

case 2

#include<stdio.h>
int main() {
int i ;
for(i=10; i>=0; i--) {
if (i * i ==25){
continue;
}
printf("i = %d\n"i);
}
}

CBR vs CBV#

[C]C언어 기본
https://yjinheon.netlify.app/posts/01programming/clang/clang-basics/
Author
Datamind
Published at
2021-07-13
License
CC BY-NC-SA 4.0