C语言自学笔记(小甲鱼)

C语言

1. 基础

1. 变量

#include <stdio.h>

int main() {
    int a = 1;
    char b = 'b';
    float c = 3.1;
    double d = 3.1111111111;
    printf("a:%d\n",a);
    printf("b:%c\n",b);
    printf("c:%.2f\n",c);
    printf("d:%.6f\n",d);
    return 0;
}

2. 常量

#include <stdio.h>

# define NAME "hdk"
# define YEAR 1996

int main() {
    printf("name: %s\n",NAME);
    printf("year: %d\n",YEAR);
    return 0;
}

3. 数据类型

查看数据类型大小

sizeof(object)
sizeof(type_name)
sizeof object
#include <stdio.h>

int main() {
    int i;
    char c;
    float f;
    i = 123;
    c = 'c';
    f = 8.01;

    printf("int: %d\n",sizeof i);
    printf("char: %d\n",sizeof(c));
    printf("float: %d\n",sizeof(float));
    return 0;
}

signed and unsigned

  • int 默认 signed int:可以表示负数
  • unsigned int:不能表示负数

4. 取值范围

1 Byte(字节) = 8 bits

补码:

  • 正数的补码是该数的二进制形式
  • 负数的补码需要以下几个步骤获得:
    1. 先取得该数的绝对值的二进制形式
    2. 再将第一步的值按位取反
    3. 最后将第2步的值加1

5. 字符和字符串

#include <stdio.h>

int main() {
    char s1[] = "good";
    char s2[] = {'b','a','d','\0'};
    printf("%s\n",s1);
    printf("%s\n",s2);
    return 0;
}

6 . 运算符

5/3 = 1 丢弃小数

短路求值

#include <stdio.h>

int main() {
    int a = 3;
    int b = 3;
    (a=0) && (b=5);
    printf("%d:%d\n",a,b);
    (a=1)||(b=5);
    printf("%d:%d",a,b);
    return 0;
}

7. 条件语句

switch加break

#include <stdio.h>

int main() {
    printf("who r u?");
    char p;
    scanf("%c",&p);
    switch (p) {
        case 'a':
            printf("a");
            break;
        case 'b':
            printf("b");
            break;
        default:
            printf("bad");
    }
    return 0;
}

8. 注意

int i = 1
j = i++
j = 1
j = ++i
j = 2

goto

#include <stdio.h>

int main() {
    int count = 0;
    while(1){
        count++;
        if (count==5){
            goto hhh;
        }
    }
    hhh: printf("hhh");
    printf("%d",count);
    return 0;
}

2. 数组和指针

1. 数组初始化

int a[10];
//不初始化,就有十个随机数

int a[10] = {1};
//第一个是1,剩下都是0

int a[] = {0,1,2,3}
//有值是可以不写长度

2. 字符串

#include <string.h>

char str[] = "......";
strlen(str);


strcpy(newString, oldString);
// 新字符串要比就的大

strncpy(newString, oldString, 5);
newString[5] = '\0';

strcat(str2, str1);
// str2 = str2+str1
// strncat后面不自动加\0

strcmp(str1, str2);
// 比较str1,str2是否一致
// strncmp比较前n个字符

3. 指针

#include <stdio.h>

int main() {
    char a = 'a';
    int b =123;
    char *pa = &a;
    int *pb = &b;
    printf("a: %c\n", *pa);
    printf("b: %d\n", *pb);

    *pa = 'b';
    *pb = 321;
    printf("a: %c\n", a);
    printf("b: %d\n", b);

    printf("pa: %p\n", pa);
    printf("pb: %p\n", pb);
    return 0;
}

a: a
b: 123
a: b
b: 321
pa: 000000000064FE0F
pb: 000000000064FE08

当指针指向数组时是我们可以对他进行加减运算,意义就相当于指向距离指针所在位置向前或向后第n个元素

#include <stdio.h>

int main() {
    char a[] = "hdk";
    char *p = a;
    printf("%c",*(p+1));
    printf("%c",*(a+1));
    return 0;
}

4. 指针数组区别

  • 指针数组
#include <stdio.h>

int main() {
    char *p[] = {"aaa","bbb","ccc"};
    printf("%s",p[1]);
    return 0;
}
  • 数组指针
#include <stdio.h>

int main() {
    int temp[5] = {1,2,3,4,5};
    int (*a)[5] = &temp;
    for (int i = 0; i < 5; i++) {
        printf("%d\n",*(*a+i));
    }
    return 0;
}

5. 二维数组指针

#include <stdio.h>

int main() {
    int array[2][4] = {{1,2,0,0},{3,4,0,0}};
    int (*p)[4] = array;  //必须是4
    printf("**(p+1): %d\n", **(p+1));  //第二行
    printf("**(array+1): %d\n", **(array+1));
    printf("array[1][0]: %d\n", (array[1][0]));
    printf("*(*(p+1)+2): %d\n", *(*(p+1)+1));  //第二行,第二列
    printf("*(*(array+1)+2): %d\n", *(*(array+1)+1));
    printf("array[1][2]: %d\n", (array[1][1]));
    return 0;
}

6. void指针

通用指针,可以指向任意类型

#include <stdio.h>

int main() {
    int num = 1024;
    int *pi = &num;
    char *ps = "hdk";
    void *a;
    a = pi;
    printf("%p;%p\n",pi,a);
    printf("%d\n", *(int *)a);
    a = ps;
    printf("%p;%p\n",ps,a);
    printf("%s\n", (char *)a);
    return 0;
}

7. NULL指针

define NULL ((void *)0)

指针不知道指向哪,用null指针

8. 指向指针的指针

#include <stdio.h>

int main() {
    int num = 1;
    int *p = &num;
    int **pp = &p;
    printf("num: %d\n", num);
    printf("*p: %d\n", *p);
    printf("**pp: %d\n", **pp);
    printf("&p: %p\n", &p);
    printf("pp: %p\n", pp);
    printf("&num: %p\n", &num);
    printf("p: %p\n", p);
    printf("*pp: %p\n", *pp);
    return 0;
}
num: 1
*p: 1
**pp: 1
&p: 000000000064FE08
pp: 000000000064FE08
&num: 000000000064FE14
p: 000000000064FE14
*pp: 000000000064FE14
#include <stdio.h>

int main() {
    char *c[] = {"aaa","bbb","ccc"};
    char **pc;
    char **pp[3];
    pc = &c[2];
    pp[0] = &c[0];
    pp[1] = &c[1];
    pp[2] = &c[2];
    printf("cc: %s\n", *pc);
    for(int i=0; i<3; i++){
        printf("c: %s\n", *pp[i]);
    }
    return 0;
}

9. 常量和指针

const = final

const int = 1;

常量指针

#include <stdio.h>

int main() {
    int num = 1;
    int * const p = &num;
    printf("%p\n",p);
    num = 2;
    printf("%p\n",p);
    return 0;
}

指针自身不可以被修改

指针指向的值可以被修改

3. 函数

1. 函数定义

#include <stdio.h>

//函数声明: 当函数定义在main之后
void print_C();

void print_C(){
    printf("CCCCCCCCCCCCCCCCCCCCCCCCCC\n");
}

int main() {
    print_C();
    print_C();
    return 0;
}
#include <stdio.h>

int sum(int n);

int sum(int n){
    int sum = 0;
    for(int i=1; i<=n; i++){
        sum = sum+i;
    }
    return sum;
}

int main() {
    int n;
    scanf("%d",&n);
    printf("%d",sum(n));
    return 0;
}

2. 参数指针

#include <stdio.h>

int swap(int *x, int *y){
    int temp;
    temp = *x;
    *x = *y;
    *y = temp;
}

int main() {
    int x=1;
    int y=2;
    printf("x=%d,y=%d\n",x,y);
    swap(&x, &y);
    printf("x=%d,y=%d",x,y);
    return 0;
}

x=1,y=2
x=2,y=1
#include <stdio.h>

int getArray(int array[3]){
    array[1] = 100;
    for(int i=0; i<3;i++){
        printf("%d\n",array[i]);
    }
}

int main() {
    int array[3] = {1,2,3};
    getArray(array);
    for(int i=0; i<3;i++){
        printf("%d\n",array[i]);
    }
    return 0;
}

1
100
3
1
100
3

可变参数

#include <stdio.h>
#include <stdarg.h>

int sum(int n, ...){
    int sum=0;
    //字符指针
    va_list vap;
    va_start(vap, n);
    for(int i=0; i<n; i++){
        sum = sum + va_arg(vap, int);
    }
    va_end(vap);
    return sum;
}

int main() {
    int result = sum(3,1,2,3);
    printf("%d",result);
    return 0;
}

output:
6

3. 指针函数

#include <stdio.h>

char *getWord(char c){
    switch(c){
        case 'A':
            return "Apple";
            break;
        case 'B':
            return "Banana";
            break;
        default:
            return "None";
    }
}

int main() {
    char input;
    printf("please input a number: ");
    scanf("%c",&input);
    printf("%s", getWord(input));
    return 0;
}

错误代码:

#include <stdio.h>

char *getWord(char c){
    char c1[] = "Apple";
    char c2[] = "banana";
    char c3[] = "None";
    switch(c){
        case 'A':
            return c1;
            break;
        case 'B':
            return c2;
            break;
        default:
            return c3;
    }
}

int main() {
    char input;
    printf("please input a number: ");
    scanf("%c",&input);
    printf("%s", getWord(input));
    return 0;
}

不要返回局部变量的指针

4. 函数指针

#include <stdio.h>

int square(int num){
    return num*num;
}

int main() {
    int num = 0;
    int (*p)(int);
    scanf("%d",&num);
    //函数名相当于函数的地址
    p = square;
    printf("%d",(*p)(num));
//    printf("%d",p(num));
    return 0;
}
#include <stdio.h>

int add(int num1, int num2){
    return num1+num2;
}
int mul(int num1, int num2){
    return num1*num2;
}
int cal(int (*p)(int, int), int num1, int num2){
    return (*p)(num1, num2);
}

int main() {
    printf("%d\n",cal(add, 3,5));
    return 0;
}
#include <stdio.h>

int add(int num1, int num2){
    return num1+num2;
}
int mul(int num1, int num2){
    return num1*num2;
}
int cal(int (*p)(int, int), int num1, int num2){
    return (*p)(num1, num2);
}
//函数指针写函数
int (*select(char op))(int, int){
    switch(op){
        case '+': return add;
        case '*': return mul;
    }
}

int main() {
    char op;
    int (*p)(int, int);
    scanf("%c", &op);
    p = select(op);
    printf("%d\n",cal(p, 3,5));
    return 0;
}

5.全局变量

#include <stdio.h>

int count = 0;
int a(){
    count++;
}
int b(){
    count++;
}

int main() {
    a();
    b();
    printf("%d",count);
}
  • 如果不对全局变量初始化,他自动初始化为0

  • 全局变量不能定义在函数之后,extern可以解决

#include <stdio.h>
int a();

int a(){
    extern int count;
    count++;
}
int b(){
    extern int count;
    count++;
}
int count = 0;

int main() {
    a();
    b();
    printf("%d",count);
}

6. 作用域

static设定变量只在一个文件内有效。不能用extern

7. 存储类型

  • auto::默认类型
  • register:寄存器类型,无法取出地址
register int i = 0;
  • extern:默认
  • static:和java类似;类似于全局
  • typedef

8. 递归

汉诺塔

#include <stdio.h>

void hano(int n, char x, char y, char z){
    if (n == 1){
        printf("%c--->%c\n", x,z);
    }else{
        //x上前n-1个借助z从x移动到y
        hano(n-1, x, z, y);
        printf("%c----%c\n", x, z);
        //y上前n-1个从x移动到z
        hano(n-1, y, x, z);
    }
}

int main() {
    int n;
    scanf("%d", &n);
    hano(n, 'x', 'y', 'z');
}

快速排序

#include <stdio.h>

void quick_sort(int arr[], int l, int r){
    //i左指针,j右指针
    int i = l, j = r;
    int temp;
    int mid = arr[(l + r)/2];
    while ( i<=j ){
        while (arr[i] < mid){
            i++;
        }
        while (arr[j] > mid){
            j--;
        }
        if (i<=j){
            temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
            i++;
            j--;
        }
    }
    if (l < j){
        quick_sort(arr, l, j);
    }
    if (i < r){
        quick_sort(arr, i, r);
    }
}

int main() {
    int arr[] = {6,3,4,6,3,5,6,3,53,5,2,54,35,2,5,25};
    int length = sizeof(arr) / sizeof(arr[0]);
    quick_sort(arr, 0, length-1);
    for(int i=0; i<length; i++){
        printf("%d ",arr[i]);
    }
    return 0;
}

9. 内存管理

  • malloc:申请动态内存
  • free:释放动态内存
  • calloc:申请初始化一系列内存空间
  • realloc:重新分配内存空间

free只能释放申请的内存空间

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

int main() {
    int *pi;
    int num = 123;

    pi = (int *)malloc(sizeof(int));
    if (pi == NULL){
        printf("null");
        exit(1);
    }else{
        scanf("%d", pi);
        printf("%d\n", *pi);

        // 错误代码
        // pi = &num;

        free(pi);
        printf("%d", *pi);
    }
    return 0;
}

桉数组方式调用malloc

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

int main() {
    int *pi = NULL;
    int num;
    scanf("%d",&num);
    pi = malloc(num * sizeof(int));
    for(int i=0; i<num; i++){
        scanf("%d", &pi[i]);
    }
    for(int i=0; i<num; i++){
        printf("%d " , pi[i]);
    }
    return 0;
}

初始化内存空间memset or calloc

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

int main() {
    int *pi = NULL;
    int num = 10;
    pi = malloc(num * sizeof(int));
    //pi = calloc(num, sizeof(int));
    //全部初始化为0
    memset(pi, 0, num * sizeof(int));
    for(int i=0; i<num; i++){
        printf("%d ", pi[i]);
    }
    return 0;
}

发现一开始的内存空间不够用memcpy

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

int main() {
    int *pi = NULL;
    int *pj = NULL;
    int num = 10;
    pi = malloc(num * sizeof(int));
    pj = malloc(20 * sizeof(int));
    memcpy(pj, pi, 10);
    free(pi);
    for(int i=0; i<20; i++){
        printf("%d ", pj[i]);
    }
    return 0;
}            

realloc动态扩充内存

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

int main() {
    int *pi = NULL;
    int num;
    int count = 0;
    do{
        scanf("%d", &num);
        count++;
        pi = realloc(pi, count * sizeof(int));
        pi[count-1] = num;
    }while(num != -1);
    for(int i=0; i<count; i++){
        printf("%d ", pi[i]);
    }
    return 0;
}
  • 堆是由程序员手动申请,手动释放
  • 栈是由系统自动分配,自动释放

10. 宏定义

#include <stdio.h>

#define PI 3.14
#define MAX(x,y) ((x)>(y) ? (x):(y))

int main() {
    int r = 2;
    float s = PI * 2* r;
#undef PI
    printf("%d", MAX(99,3));
    return 0;
}
#include <stdio.h>

#define STR(s) # s
#define TOGETHER(x, y) x ## y
#define SHOWLIST(...) printf(# __VA_ARGS__)
#define PRINT(format, ...) printf(# format, ## __VA_ARGS__)

int main() {
    printf("%s\n",STR(xxxx));
    printf("%d\n",TOGETHER(2,3));
    SHOWLIST(GOOD, 111, 234);
    PRINT(%d, 123);
    PRINT(hhh);
    return 0;
}

4. 结构体

#include <stdio.h>

struct Book{
    char title[128];
    float price;
    unsigned int date;
};

int main() {
    struct Book book;
    scanf("%s",book.title);
    scanf("%f",&book.price);
    scanf("%d",&book.date);
    printf("%s, %f, %d\n", book.title, book.price,book.date);
    return 0;
}

1. 结构体嵌套

#include <stdio.h>

struct Date{
    int year;
    int month;
};
struct Book{
    char title[128];
    float price;
    struct Date dat;
} book = {
        "good",
        1.1,
        {2011,12}
};

int main() {
    printf("%s, %f, %d%d\n", book.title, book.price,book.dat.year,book.dat.month);
    return 0;
}

2. 结构体指针

#include <stdio.h>

struct Date{
    int year;
    int month;
};
struct Book{
    char title[128];
    float price;
    struct Date dat;
} book = {
        "good",
        1.1,
        {2011,12}
};

int main() {
    struct Book *book1;
    book1 = &book;
    printf("%s, %f, %d%d\n", (*book1).title, (*book1).price,(*book1).dat.year,(*book1).dat.month);
    printf("%s, %f, %d%d\n", book1->title, book1->price,book1->dat.year,book1->dat.month);
    return 0;
}

3. 传递结构体变量

#include <stdio.h>

int main() {
    struct Test{
        int x;
        int y;
    } t1, t2;
    t1.x = 3;
    t1.y = 4;
    t2 = t1;
    printf("%d\n",t2.x);
    return 0;
}
#include <stdio.h>

struct Date{
    int year;
    int month;
};
struct Book{
    char title[128];
    float price;
    struct Date dat;
};
struct Book getInput(struct Book book){
    scanf("%s", book.title);
    scanf("%f", &book.price);
    scanf("%d-%d", &book.dat.year, &book.dat.month);
    return book;
};
void printBook(struct Book book){
    printf("%s,%f,%d-%d\n",book.title,book.price,book.dat.year,
            book.dat.month);
}

int main() {
    struct Book b1, b2;
    b1 = getInput(b1);
    putchar('\n');
    b2 = getInput(b2);
    printBook(b1);
    printBook(b2);
    return 0;
}
#include <stdio.h>

struct Date{
    int year;
    int month;
};
struct Book{
    char title[128];
    float price;
    struct Date dat;
};
void getInput(struct Book *book){
    scanf("%s", book->title);
    scanf("%f", &book->price);
    scanf("%d-%d", &book->dat.year, &book->dat.month);
};
void printBook(struct Book *book){
    printf("%s,%f,%d-%d\n",book->title,book->price,book->dat.year,
            book->dat.month);
}

int main() {
    struct Book b1, b2;
    getInput(&b1);
    putchar('\n');
    getInput(&b2);
    printBook(&b1);
    printBook(&b2);
    return 0;
}

4.动态申请结构体

使用malloc

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

struct Date{
    int year;
    int month;
};
struct Book{
    char title[128];
    float price;
    struct Date dat;
};
void getInput(struct Book *book){
    scanf("%s", book->title);
    scanf("%f", &book->price);
    scanf("%d-%d", &book->dat.year, &book->dat.month);
};
void printBook(struct Book *book){
    printf("%s,%f,%d-%d\n",book->title,book->price,book->dat.year,
            book->dat.month);
}

int main() {
    struct Book *b1, *b2;
    b1 = (struct Book *)malloc(sizeof(struct Book));
    b2 = (struct Book *)malloc(sizeof(struct Book));
    getInput(b1);
    putchar('\n');
    getInput(b2);
    printBook(b1);
    printBook(b2);
    free(b1);
    free(b2);
    return 0;
}

5. 单链表

头插法

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

struct Node{
    int value;
    struct Node *next;
};
void getInput(struct Node *node){
    scanf("%d",&node->value);
}
void addNode(struct Node **head){
    struct Node *node, *temp;
    node = (struct Node *)malloc(sizeof(struct Node));
    if (node==NULL){
        exit(1);
    }
    getInput(node);
    if(*head != NULL){
        temp = *head;
        *head = node;
        node->next = temp;
    }else{
        *head = node;
        node->next = NULL;
    }
}
void printNode(struct Node *head){
    struct Node *node;
    int count = 1;
    node = head;
    while(node != NULL){
        printf("%d ", node->value);
        node = node->next;
        count ++;
    }
}

int main() {
    struct Node *head = NULL;
    int num;
    for(int i=0; i<5; i++){
        addNode(&head);
    }
    printNode(head);
    return 0;
}

尾插法

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

struct Node{
    int value;
    struct Node *next;
};
void getInput(struct Node *node){
    scanf("%d",&node->value);
}
void addNode(struct Node **head){
    struct Node *node, *temp;
    node = (struct Node *)malloc(sizeof(struct Node));
    if (node==NULL){
        exit(1);
    }
    getInput(node);
    if(*head != NULL){
        temp = *head;
        while(temp->next != NULL){
            temp = temp->next;
        }
        temp->next = node;
        node->next = NULL;
    }else{
        *head = node;
        node->next = NULL;
    }
}
void printNode(struct Node *head){
    struct Node *node;
    int count = 1;
    node = head;
    while(node != NULL){
        printf("%d ", node->value);
        node = node->next;
        count++;
    }
}

int main() {
    struct Node *head = NULL;
    int num;
    for(int i=0; i<5; i++){
        addNode(&head);
    }
    printNode(head);
    return 0;
}
#include <stdio.h>
#include <stdlib.h>

struct Node{
    int value;
    struct Node *next;
};
void getInput(struct Node *node){
    scanf("%d",&node->value);
}
void addNode(struct Node **head){
    struct Node *node;
    static struct Node *tail;
    node = (struct Node *)malloc(sizeof(struct Node));
    if (node==NULL){
        exit(1);
    }
    getInput(node);
    if(*head != NULL){
        tail->next = node;
        node->next = NULL;
    }else{
        *head = node;
        node->next = NULL;
    }
    tail = node;
}
void printNode(struct Node *head){
    struct Node *node;
    int count = 1;
    node = head;
    while(node != NULL){
        printf("%d ", node->value);
        node = node->next;
        count++;
    }
}

int main() {
    struct Node *head = NULL;
    int num;
    for(int i=0; i<5; i++){
        addNode(&head);
    }
    printNode(head);
    return 0;
}

搜索

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

struct Node{
    int value;
    struct Node *next;
};
void getInput(struct Node *node){
    scanf("%d",&node->value);
}
void addNode(struct Node **head){
    struct Node *node;
    static struct Node *tail;
    node = (struct Node *)malloc(sizeof(struct Node));
    if (node==NULL){
        exit(1);
    }
    getInput(node);
    if(*head != NULL){
        tail->next = node;
        node->next = NULL;
    }else{
        *head = node;
        node->next = NULL;
    }
    tail = node;
}
struct Node *searchNode(struct Node *head, int tar){
    int count = 1;
    struct Node *node;
    node = head;
    while(node!=NULL){
        if (node->value == tar){
            break;
        }
        node = node->next;
        count ++;
    }
    printf("%dth", count);
    return node;
}
void printNode(struct Node *head){
    struct Node *node;
    int count = 1;
    node = head;
    while(node != NULL){
        printf("%d ", node->value);
        node = node->next;
        count++;
    }
}

int main() {
    struct Node *head = NULL;
    int num;
    for(int i=0; i<5; i++){
        addNode(&head);
    }
    printNode(head);
    searchNode(head, 5);
    return 0;
}

6. 内存池

当用户申请内存块时,先查看内存池里是否有合适的。

7. typedef

基础

#include <stdio.h>

//typedef int integer;
#define integer int

int main() {
    integer a = 1111;
    printf("%d", a);
    return 0;
}
#include <stdio.h>

#define integer int

int main() {
    unsigned integer a = 1111;
    printf("%d", a);
    return 0;
}
#include <stdio.h>

typedef int integer;
typedef int *p;

int main() {
    integer a = 1111;
    p b = &a;
    p c = b;
    printf("%p\n", &a);
    printf("%p\n", b);
    printf("%p\n", c);
    return 0;
}
#include <stdio.h>

typedef int integer;
#define p int*

int main() {
    integer a = 1111;
    p b = &a;
    p c = b;
    printf("%p\n", &a);
    printf("%p\n", b);
    printf("%p\n", c);
    return 0;
}
#include <stdio.h>
#include <stdlib.h>

typedef struct Date{
    int year;
    int month;
} DATE, *PDATE;

int main() {
    struct Date *date;
    date = (PDATE)malloc(sizeof(DATE));
    date->year=2020;
    date->month=6;
    printf("%d-%d", date->year, date->month);
    return 0;
}

进阶

#include <stdio.h>

typedef int (*P_to_ARR)[3];

int main() {
    int arr[3] = {1,2,3};
    P_to_ARR p = &arr;
    for(int i=0; i<3; i++){
        printf("%d\n",(*p)[i]);
    }
    return 0;
}
#include <stdio.h>

typedef int (*P_to_fun)();

int fun(){
    return 1;
}

int main() {
    P_to_fun p = &fun;
    printf("%d\n",(*p)());
    return 0;
}
#include <stdio.h>

typedef int *(*P_to_fun)(int);

int *fun1(int num){
    printf("%d ",num);
    return &num;
}
int *fun2(int num){
    printf("%d ",num);
    return &num;
}
int *fun3(int num){
    printf("%d ",num);
    return &num;
}

int main() {
    P_to_fun array[3] = {&fun1,&fun2,fun3};
    for (int i=0; i<3; i++){
        printf("%p\n",(*array[i])(i));
    }
    return 0;
}

8. 共用体

共用体的所有成员,拥有同一个内存地址

#include <stdio.h>
#include <string.h>

union Test{
    int i;
    double d;
    char str[5];
};

int main() {
    union Test test;
    test.i = 123;
    test.d = 3.14;
    strcpy(test.str, "abcde");
    printf("%p\n",&test.i);
    printf("%p\n",&test.d);
    printf("%p\n",test.str);

    printf("%d\n",test.i);
    printf("%f\n",test.d);
    printf("%s\n",test.str);

    printf("%d\n",sizeof(test));
    return 0;
}
000000000064FE18
000000000064FE18
000000000064FE18
1684234849
3.125193
abcde
8

5. 进阶

1. 枚举

#include <stdio.h>
#include <time.h>

union Test{
    int i;
    double d;
    char str[5];
};

int main() {
    enum Week{
        sun,mon,tues
    };
    enum Week day;
    struct tm *p;
    time_t t;

    time(&t);
    p = localtime(&t);
    day = p->tm_wday;
    switch (day) {
        case sun:
            printf("relax");
            break;
        case mon:
            printf("go");
            break;
    }
    return 0;
}
enum Week{
    //从10开始,默认0
        sun=10,mon,tues
    };

2. 位域

#include <stdio.h>

int main() {
    struct Test{
        //冒号后面设置字节数,int小于32
        unsigned int a:1;
        unsigned int b:1;
        unsigned int c:2;
    };
    struct Test test;
    test.a = 0;
    test.b = 1;
    test.c = 2;
    printf("%d-%d-%d", test.a,test.b,test.c);
    return 0;
}

3. 位运算

  • ~ 取反
  • & 与
  • ^ 异或,相同为0
  • | 或
#include <stdio.h>

int main() {
    int mask = 0xFF;
    int v1 = 0xABCDEF;
    int v2 = 0xABCDEF;
    int v3 = 0xABCDEF;
    v1 &= mask;
    v2 |= mask;
    v3 ^= mask;
    printf("%X\n", v1);
    printf("%X\n", v2);
    printf("%X\n", v2);
    return 0;
}
EF
ABCDFF
ABCDFF
  • << 左移位运算符

    11001010<<2 = 00101000

  • <<右移位运算符

    11001010>>2 = 00110010

#include <stdio.h>

int main() {
    int value = 1;
    while(value < 1024) {
        value <<= 1;  // value = value << 1
        printf("%d ", value);
    }
    printf("\n");
    value = 1024;
    while(value > 0) {
        value >>= 1;
        printf("%d ", value);
    }
    return 0;
}
2 4 8 16 32 64 128 256 512 1024
512 256 128 64 32 16 8 4 2 1 0

6. 文件操作

1. 读 打印

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

int main() {
   FILE *fp;
   int ch;
   if ((fp = fopen("hello.txt","r"))==NULL){
       printf("error");
       exit(1);
   }
   while((ch=getc(fp))!= EOF){
       putchar(ch);
   }
   fclose(fp);
   return 0;
}

2. 复制文件内容到另一个文件

#include <stdio.h>

int main() {
    FILE *fp1, *fp2;
    int ch;
    fp1 = fopen("hello.txt","r");
    fp2 = fopen("hhh.txt","w");
    while((ch=fgetc(fp1))!= EOF){
        fputc(ch,fp2);
    }
    fclose(fp1);
    fclose(fp2);
    return 0;
}

3. 写读文件

#include <stdio.h>

int main() {
    FILE *fp1;
    char buffer[1024];
    int ch;
    fp1 = fopen("hello.txt","w");
    fputs("hello\n", fp1);
    fputs("hdk\n", fp1);
    fclose(fp1);

    fp1 = fopen("hello.txt","r");
    while(!feof(fp1)){
        fgets(buffer, 1024, fp1);
        printf("%s",buffer);
    }
    return 0;
}
#include <stdio.h>
#include <time.h>

int main() {
    FILE *fp1;
    struct tm *p;
    time_t t;
    time(&t);
    p = localtime(&t);
    fp1 = fopen("hello.txt","w");
    fprintf("%d-%d-%d", 1900+p->tm_year, 1+p->tm_mon, p->tm_mday);
    fclose(fp1);

    int y, m, d;
    fp1 = fopen("hello.txt","r");
    fscanf("%d-%d-%d", &y,&m,&d);
    printf("%d-%d-%d",y,m,d);
    fclose(fp1);
    return 0;
}

4. 二进制

#include <stdio.h>

int main() {
    FILE *fp1;
    fp1 = fopen("hello.txt","wb");
    fputc('5',fp1);
    fputc('2',fp1);
    fputc('1',fp1);
    fclose(fp1);
    return 0;
}
#include <stdio.h>

int main() {
    FILE *fp1;
    char a[10] = "acv";
    fp1 = fopen("hello.txt","wb");
//    第一个放指针
    fwrite(a, sizeof(a), 1, fp1);
    fclose(fp1);
    return 0;
}

5. 随机读写

#include <stdio.h>

int main() {
    FILE *fp1;
    char a[10] = "acv";
    fp1 = fopen("hello.txt","wb");
    printf("%ld\n",ftell(fp1));
    fputc('h',fp1);
    printf("%ld\n",ftell(fp1));
    fputc('d',fp1);
    printf("%ld\n",ftell(fp1));
    fputs("kkkkk",fp1);
    printf("%ld\n",ftell(fp1));
    fclose(fp1);
    return 0;
}
0
1
2
7

6. 标准流

#include <stdio.h>

int main() {
    FILE *fp1;
    fp1 = fopen("oooooooooo","r");
    fputs("fail", stderr);
    fclose(fp1);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/longzhistudy/p/13200310.html