C언어

정리 - 2 -

twoweeks-within 2024. 11. 11. 20:23

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 = &num;

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