swap 함수
swap ( *a, *b); a,b 를 바꿈
: 구현은 내가 해야함
putchar 함수
단일 문자를 출력
기본형 : int putchar(int char);
반환 int , 출력: 아스키값> 문자
putchar(65); == putchar('A');
포인터 후위연산
char str[100]="hello world\n";
char *pstr = str;
//pstr = str 의 시작 주소 ( ex) 0x12)
//pstr++ = pstr의 다음 주소(0x13 // char형 이므로 1 byte)
putchar(*pstr++) : 문자 출력후 ++
putchar (*(pstr++)) ++ 한걸 출력
while문에 () 조건이 문자로 오면 아스키값으로 0인지 1인지 확인
2진수,16진수
&a=0x7ffee12a3a0c일때
2진수 :00000000 00000000 01111111 11101110 00010010 10100011 10100000 00001100
16진수 :0x00 0x00 0x7f 0xee...
함수형 포인터
void test(){ printf("func test\n",);}
int main(){
void (*fp)(); // fp 라는 함수형 포인터 선언 // 8byte임..
fp=test;
fp(); // test 주소로 가서 그 함수가 실행됨
함수명과 변수명이 같을 때 우선선위: 변수명
// include 라이브러리 안에 수많은 함수와의 중복 가능 성이 높기 떄문에..
// 함수가 죽어버림( 호출도 하지 않게됨)
배열의 갯수 구하기
size_t total_elements = sizeof(data) / sizeof(data[0]);
ex) int data[10] = 10 * sizeof(int) = 40
sizeof(data[0]) = 1 * sizeof(int ) =4 >> 시작주소 크기로 나누면 size_t 제거 가능
strcmp 함수
두 문자열을 비교 > 동일한지, 앞서거나 뒤지는지 확인하는
(결과)
0 : 동일
양수 : str1 이 사전순 뒤
음수: str1 이 " 앞
사전순 앞에 : 알파벳순으로 정렬했을때, 앞쪽에 위치하는 문자열 // 첫번째 차이가 나는문자만으로 문자열의 순서 파악!
ex) str1: aba str2: abad
a+b+a-a-b-a-d = -d (d의 아스키코드값 100=0x64)= -100
함수구현
int strcmp(char *s1, char *s2){
while (*s1 && (*s1 == *s2)){ // 결국 문자열 끝엔 서로 0 이라 무한 루프 돎... > 둘중 하나가 0이면 종료되는 && 추가
s1++;
s2++;
}
return *s1-*s2;
}
구조체
struct 구조체이름 {
데이터형 변수이름1;
데이터형 변수이름2; ...
}; // int char float ,,, 등 여러 형태를 모아둘 수 있음
// 포인터, 구조체(구조체 안에 구초제),
>> ex) struct student{ // 안에 있는 만큼의 크기 할당
int s_id;
char name[20];
char a; // 이때는 4byte 먹음
// 저장할때 쭉 읽어오는데 하나만 하면 좀 공백이 생기니깐,, 4byte를 다 줘버림 깔끔하게
};
pading : 메모리 공간을 더 잡아먹지만 ,cpu 효율성 good
구조체 내부 형태 중 제일 큰 크기를 맞춤 ( ex) double 이면 8byte로)
컴파일러는 메모리를 그때그때 효율적으로 할당
32bit Cpu에서 한 번에 8byte를 한다면..
한 메모리 주소를 읽어오기위해서 2번을 움직여야 하기에
매우매우 비효율적이여짐, but 꼭 필요할때는 쓸 수야 있음 (double: 정밀 소수점 처리/ longlong: 큰숫자)
int main(){
struct student st1; // 구조체의 이 함수 내에서 쓸 이름 만들기
( 타입인자 ) (타입변수: st1)
st1.s_id= 10; // 그 구조체 안에 변수의 값 입력
strcpy(st1.name,"kimkim");
}
typedef struct student std;
타입 형태의 이름을 새로 만들어줌!
복잡한 타입일때 코드 가독성을 올려줌
struct student 라는 구조체의 타입형태 이름을 std로 바꿔주는거임
대신, 여러가지 이름을 하고싶을 때는 비효율적
더 줄이면 >
typedef struct student{
} 이름; << 타입 이름을 여기에
#define size32_t int
int > char ,float 과 같은 형태로서 한번에 타입을 바꾸기 용이함!
>> int main()
size32_t a; // a는 int 형이 됨.
(*함수) 에 구조체 넘기기
void std_func(std st){ //함수는 값을 복사! 저장X
st.s_id=10; //st1 을 복사해와서 s_id를 10으로 셋팅. (이 함수 내에서만)
strcpy(st.name,"leelee");
printf("s_id: %d\n", st.s_id);
printf("name:%s\n",st.name);
}
int main(){
std st1;
std_func(st1); //이거는 값을 보냄,, 주소를 보내고 싶다면 &st1, 을 하고 함수 매개변수로는 포인터 설정
printf("s_id: %d\n", st1.s_id);
printf("name:%s\n",st1.name);
}
값들을 넘기고 싶다면
1. std std_func(std st) {
return st;
}
int main(){
st1= std_func(st1); //함수의 반환값을 st1에 저장하겠다
}
2. void std_func(std *st) { // 포인터로 전달 st의 주소를 받아옴 (주소를 받아오는게 포인터)
st->s_id = 10; // st 주소에 가서 s_id 의 값을 10으로 설정하라;
strcpy(st->name, "leelee"); // 구조체 포인터 연산자 : ' -> ' //"직접가서" 원본 구조체 멤버에게 접근
}
int main() {
std st1;
std_func(&st1); // 주소를 전달
}
2-1) 만약.. 이러면 X
void std_func(std*st){
st.s_id=10;
strcpy(st.name,"leelee");
// 주소를 받아왔기에 주소를 10으로 하라는 > 에러
구조체 시작주소를 받아오려면
printf("st1: %p\n", (void*)&st1); // 구조체는 & 을 붙여줘야함
// 그냥 st1을 하면? 이상한나라의 주소가 나옴
st1 의 시작주소는 구조체의 첫번째 멤버의 주소와 같음
&st1 = st1.s_id;
2. 배열의 전체 주소와 시작 주소를 보낼때의 디테일차이!
* char a[20];
printf("a: %p",(void*)a); //배열의 시작주소만 보냄 = &a
printf("&a:%p",(void*)&a); //배열 전체를 가르킴, 시작주소가 출력 > char *a[20]
ex)for문, while문 같은 상황일경우...
for에서 &a[i] : 딱 몇번째를 지정할 수 있다면 ( why? 전체를 가져왔으니깐)
(a+i): 하면 시작주소에서 몇번째로 지정해야함
while에서 &a[9]= 10번째 주소, (a+9)= 10번째 주소
*물론 결과값은 같으나,, 표현 방식에서 디테일한 차이가 발생
//&a[i] 를 사용하면 주소를 명시적으로 직접 지정.
//(a+i)를 사용하면 시작주소에서 i번째 요소를 간접적으로 지정
구조체 안에 구조체 넣기
std st1;
std *st2= &st1;
printf("s_id2: %d\n",st2->s_id);를 해도 같음
위의 구조체를 넣으려면...
typedef struct student{
int age;
char name[20];
}student;
typedef struct human{
int s_id;
student man;
}human;
int main(){
human st1; //구조체안의 구조체를 포함하는 ,즉, 최대 구조체를 선언
st1.s_id=10; // st1 즉 human 안에 s_id를 10으로함
strcpy(st1.man.name, "ohju");
st1.man.age=25; } //st1 안에있는 구조체 man 안에 age를 25로함
함수에서 구조체 안의 구조체를 포인터로 하려면..
st->man.name // 구조체 안의 구조체를 할땐 젤 앞에만,, ' -> ' 안은 ' . '
출력 : %s, st->man.name // 공간 까지는 주소로 접근, 그 공간안에 왔으니 ' . ' 으로
안까지 ->로 하고싶으면..
human{
student * man; 으로 변경
}
int main(){
human st1;
student st;
st1.man = &st //man 에다가 st&의 주소를 넘겨버림
}
주의
void func(char *st) 안에서는 st->man->age 가 됨
int main()에서는!
human st1; // 이므로 ( 포인터가 아님!)
st1.man->age //가됨 , main->age는 구조체 자체적으로 포인터
주소를 이동할때는 ' -> ' , 값을 이동할때는 ' . '
상수 형태의 문자열
char str1[] = "My string" ; // 변수 형태의 문자열 : 값 변경 가능
char *str1 = "Your string" ; // 상수형태
= Y 의 주소값이 저장됨
//
1000 Y
1001 o
1002 u
1003 r
...
//
printf("show your string");
printf(0x1234); // s의 주소값
Whoareyou("Hong");
void Whoareyou(char * me){
// me 에는 Hong 시작 주소 즉, H 의 주소가 들어감
}
int *ptr = #
int **dptr =&ptr;
ptr= num 의 주소
dptr = ptr 의 주소가 들어가야함
'C언어' 카테고리의 다른 글
각종 정리 -1 (2) | 2024.11.08 |
---|---|
[c] 채팅프로그램 (0) | 2024.11.07 |
makefile (script language) (1) | 2024.11.07 |
[c] 헤더파일, 문자열입력 (0) | 2024.11.07 |