반응형
반응형

 

📝구조체 (struct), typedef(별칭)

#include <stdio.h>
#include <stdlib.h>

typedef struct Point
{
    int x;
    int y;
} PointAlias;
// typedef struct Point PointAlias; 와 동일한 표현
// struct Point라는 글자를 PointAlias라는 글자로표현하겠다는 의미


int main()
{
    struct Point p1;
    struct Point p2; // C++은 struct 안 붙혀도 인식한다.

    PointAlias p3;   // typedef로 별칭을 부여한 이름을 사용한 예제

    Point pt = {1, 2}; // pt.x = 1 , pt.y = 2

    p1.x = 20;
    p1.y = 30;

    p2.x = 30;
    p2.y = 40;

    printf("(%d, %d)\n", p1.x, p1.y); // 20, 30
    printf("(%d, %d)\n", p2.x, p2.y); // 30, 40
}

 

struct 구조체명 {

    구조체 내용...

}

위와 같은 구조를 통해 변수를 관련 있는 변수를 하나로 관리할 수 있습니다. 위에서 Point란 x좌표 ,y좌표를 가진 2차원 점의 위치를 의미합니다.

 

 

📝 구조체 변수에 접근하기, 구조체 포인터

#include <stdio.h>
#include <stdlib.h>

typedef struct Point
{
    int x;
    int y;
} Point;


int main() 
{
    Point pt = {1, 2}; // pt.x = 1 , pt.y = 2
    Point* pp = &pt;

    // pt의 주소의 x에 접근, pt의 주소의 y에 접근
    printf("(%d, %d)\n", pt.x, pt.y);         // 1, 2
    printf("(%d, %d)\n", (*pp).x, (*pp).y);   // 1, 2
    // 주소로 참조변수에 접근시 (pp의 주소 즉, pt의 주소) ->로 표현
    printf("(%d, %d)\n", pp->x, pp->y);       // 1, 2
    // 위와 같은 형식으로 pt의 주소에 x 또는 y에 접근할 수 있다.
    printf("(%d, %d)\n", (&pt)->x, (&pt)->y); // 1, 2
}

 

구조체 포인터의 경우 일반 포인터와 동일하게 사용하면 됩니다.

  • 구조체명* 포인터변수명 = &구조체 변수명
    • (*포인터변수명)을 통해 값을 출력할 수 있으며 → *은 주소값을 실제 값으로 변환
    • 포인터변수명->을 통해서도 값을 출력할 수 있습니다. → ->은 주소값을 실제값으로 변환
    • (&pt)의 경우->의 역할이 주소값을 실제값으로 변환시키기 때문에 주소값 자체를 저장하고 있는 pp의 경우 그냥 사용하면 값이 출력되지만 pt의 경우 값 그 자체를 저장하고 있지 주소값이 아니기 때문에 &을 이용해 주소로 변환시키고 ->을 통해 실제 값으로 바꿔서 접근이 가능합니다. → 물론 이러한 행위는 의미없긴 합니다. pt.x, pt.y로 바로 접근하면 되기 때문이다

 

#include <stdio.h>
#include <stdlib.h>

typedef struct Point
{
	int x;
	int y;
} Point;


int main() 
{
	Point p1 = { 2, 3 }; // Stack 영역에 저장
	
	Point* p = (Point*)malloc(sizeof(Point)); // Stack영역에 포인터 생성 후 실질적 값은 Heap 영역에 저장
	p->x = 2;
	p->y = 3;

	printf("(%d, %d)\n", p1.x, p1.y); // 2 , 3 출력
	printf("(%d, %d)\n", p->x, p->y); // 2 , 3 출력
	 
	Point arr[5] = { {1,1}, {2,2} };
	Point* arr_p = (Point*)malloc(sizeof(Point) * 2);
	
	// 배열 포인터 접근
	arr_p[0].x = 1; 
	arr_p[0].y = 1; 
	arr_p[1].x = 2; 
	arr_p[1].y = 2;

	// 포인터로 다음 배열 접근시 + 1 (int만 그런건지 테스트가 필요한 부분이긴 하다.)
	printf("arr_p[0].x %d == (arr_p)->x) %d\n",arr_p[0].x, (arr_p)->x);
	printf("arr_p[0].y %d == (arr_p)->y) %d\n",arr_p[0].y,(arr_p)->y);
	printf("arr_p[1].x %d == (arr_p + 1)->x) %d\n", arr_p[1].x,(arr_p + 1)->x);
	printf("arr_p[1].y %d == (arr_p + 1)->y) %d\n", arr_p[1].y,(arr_p + 1)->y);

	

}
반응형
반응형

📝배열

// 배열
#include <stdio.h>
#include <stdlib.h>

int main() 
{
    int a=10, b=20, c=30, d=40;   // 비연속적으로 메모리에 저장
    int arr[4] = {10, 20, 30, 40}; // 연속적으로 메모리에 저장

    printf("%d %d %d %d\n", a, b, c, d); // 10, 20, 30, 40
    printf("%d %d %d %d\n", arr[0], arr[1], arr[2], arr[3]); // 10, 20, 30, 40

}

 

 

📝포인터

// 포인터
#include <stdio.h>
#include <stdlib.h>

int main() 
{
    int a=10, b=20, c=30, d=40;// 비연속적으로 메모리에 저장
    int arr[4] = { 10,20,30,40 };// 연속적으로 메모리에 저장

    int* p = &a;   // a의 주소값을 보관 (물론 주소값을 보관하기 때문에 p라는 변수로서 할당된다.)
    int* pa = arr; // arr[0]의 주소값을 보관

    printf("p : %d, pa : %d\n", p, pa);                          // 1823472356, 1823472488
    printf("&a : %d, arr : %d\n", &a, &arr[0]);                  // 1823472356, 1823472488
    printf("p의 값 = a의 값 = %d\n", *p);                        // 10
    printf("pa의 값 = arr[0]의 값 = %d\n", *pa);                 // 10
    printf("&p(p의 주소) : %d, &pa(pa의 주소) : %d\n", &p, &pa); // 1823472536, 1823472568

    // 배열 Pointer의 경우 배열처럼 사용가능
    printf("%d %d %d %d\n", pa[0], pa[1], pa[2], pa[3]); // 10, 20, 30, 40

}

 

포인터메모리에 할당된 주소를 가르키게 된다

 

  • 자료형* 변수명 = &할당된 변수명
    • 할당된 변수명의 주소(&)를 기억하는 변수가 만들어지게 된다.
    • *변수명을 통해 해당 주소의 실제 값을 읽어올 수 있다

배열의 경우 연속된 공간에 저장한다 그래서 포인터를 이용해 해당 주소를 가르키게 되면 포인터 변수명[0], 포인터 변수명[1] 과 같이 실제 값을 가져올 수 있습니다

 

📝메모리 저장 영역 (stack, Heap)

// 데이터 영역
#include <stdio.h>
#include <stdlib.h>

int g = 30; // G-D 영역 (전역변수, 정적변수, 상수)

int main() 
{
    int m = 20; // stack 영역 (함수내의 변수)
    int n = 20; // stack 영역

    int* p; // stack 영역
    p = (int*)malloc(4); // Heap 영역 (4byte 할당)

    *p = 10; // Heap 영역에 10 할당
    printf("%d", *p);

    // 4byte의 크기를 Heap 영역에 생성 후 p라는 포인터 변수가 그 주소값을 가르키게 된다.

    free(p); // 영역 할당을 free로 제거 시켜야 사라지게 된다.
}

메모리는 크게 2가지로 나뉘는데 stack영역과 Heap 영역으로 나뉘게 됩니다.

 

📝stack영역의 경우

호출된 함수가 마치고 복귀할 주소 및 데이터(지역변수, 매개변수, 리턴 값 등)를 임시로 저장하는 공간입니다 만약 재귀함수가 많이 발생해 stack영역을 초과하게 되면stack overflow 에러가 발생하게 됩니다. Stack은 컴파일 타임에 크기가 결정되기 때문에 무제한으로 할당 할 수 없습니다

 

📝Heap영역의 경우

런타임(프로그램 동작) 시 크기가 결정됩니다. malloc등으로 Heap영역의 메모리를 사용해 원하는 공간만큼 할당해 사용합니다. 이렇게 공간을 할당하고 해제하지 않으면 Memory Leak이 발생하게 됩니다. JAVA의경우 JVM이 이 행위를 대신 해주죠 Stack의 비해 메모리 공간이 많지만 포인터로 접근해야 하기 때문에 속도가 느립니다

 

 

📝 정적배열, 동적배열

// 정적배열, 동적배열
#include <stdio.h>
#include <stdlib.h>

int main() 
{
    int arr[20]; // 정적배열

    arr[0] = 0;
    arr[1] = 10;
    arr[2] = 20;
    arr[3] = 30;
    arr[4] = 40;

    for (int i = 0;i < 5; i++) {
        printf("%d\n", arr[i]); // 0, 10, 20, 30 , 40
    }

    int* p;
    p = (int*)malloc(40); // 동적 배열

    p[0] = 0;
    p[1] = 10;
    p[2] = 20;
    p[3] = 30;
    p[4] = 40;

    for (int i = 0;i < 5; i++) {
        printf("%d\n", p[i]); // 0, 10, 20, 30 , 40
    }

    free(p);
    
    // sizeof를 이용한 할당방식
    int* ps;
    ps = (int*)malloc(sizeof(int) * 5); // sizeof(int) * 5 → int형 5개를 생성

    ps[0] = 0;
    ps[1] = 10;
    ps[2] = 20;
    ps[3] = 30;
    ps[4] = 40;

    for (int i = 0;i < 5; i++) {
        printf("%d\n", ps[i]); // 0, 10, 20, 30 , 40
    }

    free(ps);

}

정적배열의 경우 stack영역을 사용하는 걸 의미하고 동적배열의 경우 Heap영역을 사용하는 걸 의미합니다.

 

📝 사용자에게 값을 입력 받기

// 사용자에게 배열크기 입력받기
#include <stdio.h>
#include <stdlib.h>

int main() 
{
    int size = 0;
    printf("배열의 크기를 입력해주세요 : ");
    scanf_s("%d", &size); // size을 사용자에게 입력 받는다.

    // int arr[size]; // 정적배열인 경우 배열크기에 변수 할당 불가
    int* pa = (int*)malloc(sizeof(int) * size); // 동적배열은 가능하다.


    for (int i = 0; i < size; i++) {
    printf("[%d] 배열의 값을 입력해주세요 ", i);
    scanf_s("%d", &pa[i]); // 배열을 입력해주세요
    }

    for (int i = 0; i < size; i++) {
        printf("pa[%d] : %d\n", i, pa[i]);
    }
}

 

반응형
반응형
#include <stdio.h>
#include <stdlib.h>

int main() 
{
    for (int i = 0; i <= 10; i++) { // 10번 반복
        if (i % 2 == 0) { // 짝수만 선별
            printf("even : %d\n", i); // i의 값을 출력
    	}
    }
}

 

반응형
반응형
주석처리 및 주석해제 Ctrl + Shift + /
라인 복사 해당 라인에 올려둔 상태로 Ctrl + C
라인 붙여넣기 Ctrl + V
라인 삭제(잘라내기) Ctrl + X
맨 처음 라인으로 이동 Ctrl + home
맨 마지막 라인으로 이동 Ctrl + End
반응형
반응형

설치 URL : https://visualstudio.microsoft.com/ko/vs/community/

 

Visual Studio 2022 커뮤니티 버전 – 최신 무료 버전 다운로드

Windows, Android 및 iOS용 최신 개발자 앱을 만들기 위한 모든 기능을 갖춘 확장 가능한 무료 IDE를 사용해 보세요. 지금 무료로 커뮤니티를 다운로드하세요.

visualstudio.microsoft.com

 

위에 링크를 통해서 다운을 받아주세요

 

C++를 사용한 데스크톱 개발을 클릭해서 추가 설치해줍니다.

 

 

새 프로젝트 만들기로 프로젝트를 만들어줍니다

 

 

빈 프로젝트를 선택해주세요

 

 

프로젝트 이름과 위치를 설정해줍니다 그러면 프로젝트가 만들어집니다. 그 후에 소스 파일을 만들어보도록 하겠습니다.

 

 

소스파일 - 우클릭 - 새항목으로 만들어줍니다.

 

cpp 확장자인 경우 C++컴파일러를 사용하고 c 확장자인 경우에는 C컴파일러를 사용합니다.

 

 

Ctrl + F5 → 컴파일 단축키

반응형
반응형
<!DOCTYPE html>
<html lang="ko">

<head>
    <meta charset="UTF-8">
    <title>test</title>
    <style>
        *{
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body, html{
            width: 100%;
            height: 100%;
        }


        #container{
            width: 100%;
            min-width: 700px;
            height: 100%;
        }

        #testDiv{
            width: calc(100% - 400px);
            height: 100%;
            float: left;
            background-color: blueviolet;
        }
    </style>
</head>

<body>
    <div id="container">
        <div id="testDiv">

        </div>
    </div>
</body>

</html>
<!-- 출처 : https://usang0810.tistory.com/m/31 -->

css에 calc() 연산이 있는데 width나 height 값을 동적으로 더해지거나 빼거나 하는 값을 넣을 수 있습니다.
예) width: calc(100% - 400px) 일 경우 전체 영역에 - 400px을 차지합니다.

→ 나머지 공간을 100%로 같이 잡으면 꽉찬 영역이 동적으로 변하는 걸 확인 할 수 있습니다.

반응형
반응형
package com.lsj.chatting;

import java.net.InetAddress;
import java.net.UnknownHostException;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

/**
 * Handles requests for the application home page.
 */
@Controller
public class HomeController {
	
	@RequestMapping(value = "/getServerInfo", method = RequestMethod.GET)
	public void getServerInfo() throws UnknownHostException {
		
		System.out.println("HostName : " + InetAddress.getLocalHost().getHostName());
		System.out.println("Address : " + InetAddress.getLocalHost().getHostAddress());


        String osName = System.getProperty("os.name").toLowerCase();

        System.out.println("os.name property: " + osName);

        if (osName.contains("win")) {
            System.out.println("This is Windows");
        } else if (osName.contains("mac")) {
            System.out.println("This is Mac");
        } else if (osName.contains("nix") || osName.contains("nux") || osName.contains("aix")) {
            System.out.println("This is Unix or Linux");
        } else if (osName.contains("sunos")) {
            System.out.println("This is Solaris");
        } else {
            System.out.println("Your OS is not support!!");
        }
		
	}
	
}
반응형
반응형

📝HttpServletRequest

클라이언트가 보낸 요청의 정보를 가지고있다.
→ 즉, 요청이 들어오면 그 요청에대한 정보를 가지고 있다.

request.getHeader("host"); → 요청한 host에 대한 정보를 가지고있다.

 

📝HttpServletResponse

HTTP 요청에 대한 응답 메시지를 생성하고, 기타 편의 기능을 제공한다.
→ 즉, 사용자에게 보낼 응답에 대한 정보를 가지고 있다.

response.setContentType("text/plain");
response.setCharacterEncoding("utf-8"); → text/plain utf-8 형태로 응답을 보내겠다.

반응형
반응형

 

plugins {
	id 'org.springframework.boot' version '2.7.4'
	id 'io.spring.dependency-management' version '1.0.14.RELEASE'
	id 'java'
}

group = 'com.lsj'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'

configurations {
	compileOnly {
		extendsFrom annotationProcessor
	}
}

repositories {
	mavenCentral()
}

dependencies {
	/** 추가 라이브러리 **/
	// https://mvnrepository.com/artifact/org.apache.tomcat.embed/tomcat-embed-jasper
	implementation 'org.apache.tomcat.embed:tomcat-embed-jasper:9.0.58'

	// https://mvnrepository.com/artifact/javax.persistence/javax.persistence-api
	implementation group: 'javax.persistence', name: 'javax.persistence-api', version: '2.2'

	implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
	implementation 'org.springframework.boot:spring-boot-starter-security'
	implementation 'org.springframework.boot:spring-boot-starter-web'
	compileOnly 'org.projectlombok:lombok'
	developmentOnly 'org.springframework.boot:spring-boot-devtools'
	runtimeOnly 'com.oracle.database.jdbc:ojdbc8'
	annotationProcessor 'org.projectlombok:lombok'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
	testImplementation 'org.springframework.security:spring-security-test'
}

tasks.named('test') {
	useJUnitPlatform()
}

gradle 설정입니다.

package com.lsj.chatting;

import java.sql.Timestamp;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

import org.hibernate.annotations.ColumnDefault;
import org.hibernate.annotations.CreationTimestamp;

/** 하기 어노테이션 사용하려면 Javax Persistence API Gradle 추가 필요 **/
@Entity // 하기 필드 기준으로 DB에  User 테이블을 생성하라는 의미
public class BlogUser {

	@Id // Primary key
	@GeneratedValue(strategy = GenerationType.IDENTITY) // 프로젝트에서 연결된 DB의 넘버링 전략을 따라간다.
	// → 즉, DB에 따라 AutoIncrement 또는 Sequence가 결정 되어서 알아서 만들어준다. (자동 증가 PK 필요함으로 이와 같은 행동 함) 
	// (MySql에서는 AutoIncrement, Oracle에서는 Sequence 사용)
	private int id;
	
	@Column(nullable = false, length = 30) // null 방지 및 길이 30
	private String username;
	
	@Column(nullable = false, length = 100) 
	private String password;
	
	@Column(nullable = false, length = 50) 
	private String email;
	
	@ColumnDefault("'user'") // → Column Default 값 String이기 때문에 ' ' 안에 넣어야한다.
	private String role; // Enum을 
	// → admin : 0
	// → user : 0
	// → manager : 0
	
	@CreationTimestamp // 현재 시각 바로 자동 입력
	private Timestamp createDate;
	
}

어노테이션을 이용해 테이블 생성하기 위한 Java 파일 입니다.

server:
  port: 8000 # 톰캣 포트 (스프링부트는 톰캣이 내장되어 있다.)
  servlet:
    context-path: /chatting # 기본 url Path 
    encoding:
      charset: UTF-8
      enabled: true
      force: true
    
spring:
  mvc:
    view:
      prefix: /WEB-INF/views/
      suffix: .jsp 
      # @GetMapping 에서 함수의 return 값이 String인 경우 return 에 대한 내용은 jsp의 파일 이름입니다.
      # @GetMapping 
      # public String callJsp(){
      #   return "home" → /WEB-INF/views/home.jsp 화면을 뿌려라 
      #   일반적으로 스프링부트는 JSP를 지원하지 않기 때문에 JSP를 사용하기 위해서는 JSP 해석 템플릿 엔진인 jasper을 Gradle에서 다운로드를 해야한다.
      #}
  
  datasource:
    driver-class-name: oracle.jdbc.OracleDriver
    url: jdbc:oracle:thin:@localhost:1521:orcl
    username: c##root
    password: 1234
    
  jpa:
    open-in-view: true
    hibernate:
      ddl-auto: create # 최초 전략 Applicaiton 재시작시 테이블 있으면 지우고 다시 만들게 된다.
      naming:
        physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
        # field 명 그대로 필드를 만들게 된다.
        # physical-strategy: org.hibernate.boot.model.naming.CamelCaseToUnderscoresNamingStrategy
        # CamelCase 전략을 따라가는데 field 명이 myEmail인 경우 my_email로 변환시켜서 만들어준다. 
      use-new-id-generator-mappings: false 
      # false : JPA 기본 전략을 쓴다. 
      # false : JPA 기본 전략을 쓰지 않는다. → User에 선언한 GenerationType.IDENTITY을 쓰겠다
    show-sql: true
    properties:
      hibernate.format_sql: true

  jackson:
    serialization:
      fail-on-empty-beans: false

yml 파일로 JPA 사용할 설정이 들어있습니다.

 

Hibernate: 
    
    drop table BlogUser cascade constraints
Hibernate: 
    
    create table BlogUser (
       id number(10,0) generated as identity,
        createDate timestamp,
        email varchar2(50 char) not null,
        password varchar2(100 char) not null,
        role varchar2(255 char) default 'user',
        username varchar2(30 char) not null,
        primary key (id)
    )

시작시 Hibernate라는 애가 Java 파일 설정을 읽어서 Query를 생성시켜줍니다.

반응형