사용자의 홈 디렉토리가 생성되는 곳, useradd 명령어로 새로운 사용자를 생성하면 대부분 사용자의 ID와 동일한 이름의 디렉토리가 자동으로 생성됨.
/lib
커널과 프로그램에 필요한 각종 라이브러리가 저장되는 곳.커널모듈파일과 라이브러리파일 즉, 커널이 필요로하는 커널모듈파일들과 프로그램(C, C++ 등)에 필요한 각종 라이브러리 파일들이 존재하는 디렉토리.
/media
DVD, CD-ROM, USB 등과 같은 탈부착이 가능한 장치들의 마운트포인트로 사용되는 디렉토리.
/mnt
/media 디렉토리와 비슷한 용도로 탈부착이 가능한 장치들에 대하여 일시적인 마운트포인트로 사용하는 디렉토리.
/proc
일명 "가상파일시스템" 이라고 하는 곳으로 현재 메모리에 존재하는 모든 작업들이 파일형태로 존재하는 곳이다. 디스크상에 실제 존재하는 것이 아니라 메모리상에 존재하기 때문에 가상파일시스템이라고 부른다. 실제 운용상태를 정확하게 파악할 수 있는 중요한 정보를 제공하며 여기에 존재하는 파일들 가운데 현재 실행중인 커널(kernel)의 옵션 값을 즉시 변경할 수 있는 파라미터파일들이 있기 때문에 시스템 운용에 있어 매우 중요한 의미를 가진다.
/root
시스템 최고관리자인 root 사용자의 개인 홈디렉토리.
/sbin
ifconfig, e2fsck, ethtool, halt 등과 같이 주로 시스템 관리자들이 사용하는 시스템관리자용 명령어를 저장하고 있는 디렉토리.
/tmp
일명 "공용디렉토리" . 시스템을 사용하는 모든 사용자들이 공동으로 사용하는 디렉토리. mysql 에서 사용하는 mysql.sock 등과 같은 소켓파일, 또는 아파치에서 사용하는 세션파일등이 생성되기도 한다. 웹해킹에 사용되기도 해서 주의를 요망.
/usr
시스템이 아닌 일반사용자들이 주로 사용하는 디렉토리. 즉, c++, chsh, cpp, crontab, du, find등과 같이 일반사용자들용 명령어들은 /usr/bin 에 위치한다.
/usr/bin/
일반 사용자들이 사용가능한 명령어 파일들이 존재하는 디렉토리.
/usr/X11R6/
X 윈도우 시스템의 루트 디렉토리.
/usr/include/
C 프로그램에 필요한 헤드파일(*.h) 디렉토리.
/usr/lib/
/lib 에 들어가지 않은 라이브러리 디렉토리.
/usr/sbin/
/bin 에 제외된 명령어와 네트워크관련 명령어가 들어있는 디렉토리.
/usr/src/
프로그램 소스(주로 커널소스)가 저장되는 디렉토리.
/usr/local/
MySQL, Apache, PHP 등과 같은 어플리케이션들을 소스로 컨파일설치할 때 사용되는 장소.
/usr/share/man/
명령어들의 도움말을 주는 메뉴얼(manual)페이지 디렉토리. 즉, 이 디렉토리에는 시스템에서 사용하는 모든 맨페이지파일(man page)이 존재함.
/var
시스템운용중에 생성되었다가 삭제되는 데이터를 일시적으로 저장하기 위한 디렉토리. 거의 모든 시스템로그파일은 /var/log 에 저장되고, DNS 의 zone 설정파일은 /var/named 에 저장되고, 메일파일은 /var/spool/mail 에 저장되며, 크론설정파일은 /var/spool/cron 디렉토리에 각각 저장됨.
/var/tmp/
/tmp 디렉토리와 같은 공용디렉토리. 즉, /tmp 디렉토리와 /var/tmp 디렉토리의 퍼미션은 1777 로서 sticky bit 가 설정되어 있는 공용디렉토리이다. 리눅스 시스템에서 공용디렉토리는 /tmp 와 /var/tmp 둘뿐이다.
최상위 디렉토리인 / 디렉토리에만 존재하는 것이 아니라 파일시스템마다 존재할 수 있는 디렉토리임. 이 디렉토리는 fsck 또는 e2fsck 등과 같은 파일시스템 체크 및 복구유틸리티 실행후에 주로 생성이 되는 것으로서 복구되지 않은 채로 블록(block)만 존재하는 파일 즉, 연결이 끊어진 inode 들이 숫자파일형태로 존재하는 곳임. 숫자형태로 존재하는 파일들은 mv 명령어로 파일이름만 바꾸면 바로 복구될 수 있다.
c++ STL에 vector / java에는 array list/ c#에는 list / golang에는 slice
동적배열은? <--------------------------> 정적배열(fixed size array 길이 정해진 배열 [10]int)
[]int
길이 변하는 배열
실제 고정 길이의 배열이 따로 있고 그 고정 길이 배열을 가르키고, 포인트하고 있다!!
배열의 길이가 늘어나면 새로운 더 긴 배열을 만든 다음에 거기로 모든 값을 복사시키고 그 배열로 포인트 바꿈
"동적 배열은 실제 배열을 포인트하고 있다."
동적배열선언 만드는 여러 방법들
var a [] int
a:=[]int{초기값}
a:=make([]int,3)
a:=make([ ]int, length, capacity)
length 길이
내가 쓰고 있는 길이
capacity 확보해놓은 공간
(동적배열, 값을 추가할 때 배열 늘리는데 2배씩 확보해놓음 그래서 길이와 cap다를 수 있음)
항목 추가 명령어 append
a:= []int {}
a= append(a,1)
a에 다시 대입
슬라이스 = append(슬라이스,항목)
a[start Index : End Index]
(start ~ end] 마지막은 포함안됨
a[10]int{1,2,3,4,5,6,7,8,9,10}
a[4:6]
a[시작인덱스 5번째 : 6번째]
즉 5번째~6번째까지 슬라이스 의미
a[4: ]
5번째부터~ 끝까지
a[ :4]
처음부터 ~4번째까지
슬라이스는 원래 배열이 있고 그 배열을 가르키는 포인터
슬라이스는 잘라내는 게 아니라 그 일부분을 가르키는 배열!
//추가된 값이 원래길이,확보된 공간 벗어나게 되면
새 메모리 만들어서 거기에 복사됨. 그럼 메모리 주소 바뀜!
코드로 보기
package main
import"fmt"funcmain() {
//////////////////////////////////len cap 메모리를 새로 확보해야돼서 주소도 달라짐 새로운 메모리에 담아서// a:= []int{1,2}// b:= append(a,3)// fmt.Printf("%p %p\n",a,b)// for i := 0; i<len(a); i++{// fmt.Printf("%d,",a[i])// }// fmt.Println()// for i := 0; i<len(b); i++{// fmt.Printf("%d,",b[i])// }// fmt.Println()// fmt.Println(cap(a)," ", cap(b))///////make로 넣기//메모리 같아서 b값 바꾸니까 a도 바뀜// a:= make([]int, 2,4)// a[0]=1// a[1]=2// b:= append(a,3)// fmt.Printf("%p %p\n",a,b)// fmt.Println(a)// fmt.Println(b)// b[0]=4// b[1]=5// fmt.Println(a)// fmt.Println(b)//////처음부터 아예 공간을 다르게 확보하게 싶다면// a:= []int{1,2}//// a := make([]int, 2, 4)// a[0] = 1// a[1] = 2// //슬라이스 새로 만듦// b := make([]int, len(a))// for i := 0; i < len(a); i++ {// b[i] = a[i]// }// b = append(b, 3)// fmt.Printf("%p %p\n",a,b)
}
3가지 경우임
1. 값넘쳐서 새 메모리에 담아짐
2. 값안넘쳐서 메모리 a랑 b같음 b변경될때 그대로인 메모리안에서 바뀌어서 a도 바뀜
3. 아예 슬라이스 새로 만들어서 공간 따로 확보함
//배열 뒤에서 하나씩 지우기
package main
import"fmt"//뒤에 하나씩 지워나가는 함수//배열 반환,int 맨뒤에 값도 반환funcRemoveBack(a []int)([]int, int){
//처음부터 a배열길이에서 1뺀것, 즉 맨뒤에를 하나 없앤다return a[ :len(a)-1], a[len(a)-1]
}
funcmain() {
a:=[]int{1,2,3,4,5,6,7,8,9,10}
for i :=0; i<5; i++{
var lastlostone int
a, lastlostone= RemoveBack(a)
fmt.Printf("%d,",lastlostone)
}
fmt.Println()
fmt.Println(a)
}
1. %d : 10진수로 출력 정수형 2. %f : 실수형 3. %e : 지수형 4. %o : 8진수로 출력 5. %x : 16진수로 출력 6. %u : 부호없는 10진수로 출력 7. %g : 실수형으로 자동 출력 8. %p : 포인터의 주소를 출력 9. %c : 하나의 문자로 출력 문자형 10. %s : 문자열을 출력
package main
import"fmt"funcmain() {
//a는 int 형 이라 선언var a int//p는 int형 포인트var p *int//p에 a 주소 대입, p의 값은 a의 주소를 가르키고 있다
p = &a
//a는 3으로 대입
a=3//3
fmt.Println(a)
//0xc000100028 메모리의 주소 나옴
fmt.Println(p)
//포인터가 가르키는 값 3(주소가 가르키는 값)
fmt.Println(*p)
}
포인터 왜 쓰냐
원래 a출력했을 때
x++로 해도
값만 복사됐지 a와 b는 다른거라서 1추가 안되고 여전히 1이었음
x는 괄호 밖에서 역할 못하고
포인터 쓰면
package main
import"fmt"funcmain() {
//포인터가 왜 사용되는지 보자`~~~~`var a int
a=1//포인터형 *x으로 해서 a의 주소값으로 해야함
Increase(&a)
fmt.Println(a)
}
funcIncrease(x *int) {
//x가 가지고 있는 값은 메모리 주소인데//그 메모리가 가르키는 주소의 값은 = 메모리가 가르키는 주소의 (원래)값 + 1
*x=*x+1//얘는 아까 x++와 같은 거라 볼 수 있쥐, 그때 포인터로 안하면 a에서 값만 복사돼서 x++여도 x는 함수 안이라서 a가 늘어나진 않았어
}
이거 사용해서
structure로 만든 거 보기
함수는 값이 복사돼서 쓰이기만 하지
안에 있는 s는 다 다른거임 그래서 결과도 넣은 거 안나오고
수학,a라고 나옴
package main
import"fmt"type Student struct {
name string
age int
grade string
class string
}
func(s Student)PrintSungjuk(){
fmt.Println(s.class,s.grade)
}
func(s Student)InputSungjuk(class string, grade string){
s.class = class
s.grade =grade
}
funcmain(){
var s Student= Student{name: "t",age:23, class: "수학",grade: "A"}
s.InputSungjuk("과학","c")
s.PrintSungjuk();
}
s를 포인터형으로 받으면 해결됨!!!
*Student로 바꿔주면 됨
package main
import"fmt"type Student struct {
name string
age int
grade string
class string
}
func(s *Student)PrintSungjuk(){
fmt.Println(s.class,s.grade)
}
func(s *Student)InputSungjuk(class string, grade string){
s.class = class
s.grade =grade
}
funcmain(){
var s Student= Student{name: "t",age:23, class: "수학",grade: "A"}
s.InputSungjuk("과학","c")
s.PrintSungjuk();
}
[질문] C++로 할 수 있는 프로그래밍 스타일은 절차적 프로그래밍, 객체 지향 프로그래밍만 있을까요?
[답] 아니오. Generic Programming 도 가능합니다.
Generic Programming은 한국에서는 보통 '일반적 프로그래밍'이라고 이야기 합니다. 저도 처음에는 그렇게 들었습니다.
그러나 이것은 잘못된 표현이지 않을까 생각합니다. 영어 사전을 보면 Generic 이라는 것은 '총칭(總稱)적인' 이라는 뜻도 있는데 이것이 '일반적'이라는 단어보다 더 확실하며 제가 2004년에 일본에서 구입한 "C++ 설계와 진화(Bjarne Stroustrup 저)"라는 일본 번역서에도 Generic은 총칭으로 표기하고 있습니다.
클래스는 아시는 바와 같이 멤버 변수와 멤버 함수로 이루어져 있습니다. 그리고 멤버 함수도 그 내용은 저의 생각에 의해 변수들이 조작으로 되어 있습니다.
'암소는 동물이다'라는 식으로 C++ 언어에서 총칭을 하는 것은 변수의 타입(type)을 총칭화 하는 것입니다
STL의 구성 요소
1. 반복자 :STL 컨테이너에 저장된 원소들을 가리키는 포인터
2. 컨테이너 : 데이터를 저장하고 관리하기 위한 클래스 (vector, list, map, deque 등..)
템플릿(template)은C++프로그래밍 언어의 한 기능으로, 함수와 클래스가제네릭 형과 동작할 수 있게 도와 준다. 함수나 클래스를 개별적으로 다시 작성하지 않고도 각기 다른 수많은자료형에서 동작할 수 있게 한다. 여러 자료 형으로 사용할 수 있도록 하게 만들어 놓은 틀.
여러 다른 자료형(int, long, float, double, class... )을 템플릿 인자 ('<...>' 안에 들어가는)로 받아, 함수 내부에서 활용할 수 있도록 한 것이다. 다시 말하면, 여러 다른 자료형에 대하여 같은 역할을 하는 하나의 함수 계열을 하나의 템플릿으로 표현할 수 있다는 점이다.
클래스 템플릿
클래스 템플릿은 클래스를 템플릿 변수에따라 생성할 수 있게 하는 기능이다. 클래스 템플릿은컨테이너의 용도로 많이 쓰인다.
템플릿 특수화
특정 타입, 다른 기능수행 즉 특수화하게 하려고 따로 템플릿 정의해 만드는거
템플릿 만들 때는 템플릿 선언
template <typename T>
T라는 타입에 템플릿 선언한다는 뜻 ,
myFunc(1,3)
여기 맞게 값넣으면 알아서 함수구체화됨
"이렇게 템플릿의 구체화는 컴파일 타임에 필요한 타입에 대해서만 구체화를 하게된다. 위코드에서 구체화된 두 개의 함수 이름은 같고 시그니처만 다르므로 서로 오버로딩 관계다. 색이 다른 붕어빵~"
둘의 차이점
클래스 템플릿 사용할 때 반드시 타입 명시해줘야 함.
auto obj = MyClass<int>(3):
3써서 타입추론이 자동이뤄지는거 아닐까? 왜 타입을 강제지정할까?
[클래스 템플릿 구체화에 대한 이해]
(객체생성) 인스턴스화가 되기 전(=생성자가 호출되기 전)에 먼저 객체를 위한 메모리가 할당되어야 하는데
메모리 할당을 위해서는
생성자에 전달되는 인수의 타입을 미리 알아야함! (여기서 객체에서 사용되는 타입은 클래스 멤버 변수의 타입을 말함.)