zoukankan      html  css  js  c++  java
  • 014_stdc_C语言

    回顾:
       enum 枚举  
          
       union 联合(共用)
        请谈一谈  结构体和联合的区别
    
       指针高级
           二级指针
             修改函数外面 指针变量
             字符串数组 操作

    ------------------------------

     void *  空指针 没有类型的指针 

       任何类型的指针可以赋值给空指针,无需类型转换

      在使用空指针时,需要将空指针转换为具体的类型

    #include <stdio.h>
    int main(){
        void *pv = NULL; //空指针
        char c = 'A';
        int i= 0x31323334;  //1234
        char *pc=NULL;
        pc= &c;
        pc= (char *)&i;
        pv = &c;//
        printf("*pv = %c
    ",*(char *)pv);//A   在使用空指针时,需要将空指针转换为具体的类型
        printf("*pc = %c
    ",*pc);//4  高位到低位输出字符串
        printf("*pc = %c
    ",*(pc+1));//3
        printf("*pc = %c
    ",*(pc+2));//2
        printf("*pc = %c
    ",*(pc+3));//1
        getchar();
        return 0;
    }

       空指针的使用

           1. 函数形式参数的类型

    /*
     * 空指针的使用
     */
    
    #include <stdio.h>
    //可以对任意类型的变量进行输出
    void myprint( void *pv,int type)
    {
        if(type == 1)
        {
            printf("*pv = %d
    ",*(int *)pv);
        }
        if(type == 2)
        {
            printf("*pv = %c
    ",*(char *)pv);
        }
        if(type == 3)
        {
            printf("*pv = %lf
    ",*(double *)pv);
        }
    
    }
    int main(){
    
        int i = 20;
        char c = 'C';
        double d = 3.14;
    #if 0
        printf("i = %d
    ",i);
        printf("c = %c
    ",c);
        printf("d = %lf
    ",d);
    #endif
        myprint(&i,1);
        myprint(&c,2);
        myprint(&d,3);
        getchar();
        return 0;
    }

          2. 动态内存申请到的内存,返回指向该内存区域的void * 指针

       函数指针

    /*
     * 函数指针
    /
    #include <stdio.h>
    int add(int a,int b){
        return a+b;
    }
    int main(){
        printf("add 函数的地址:%p
    ",&add); //??
        printf("main 函数的地址:%p
    ",&main); //??
        getchar();
    }

      add 函数的地址:00007FF7535B1000
    main 函数的地址:00007FF7535B1010

         1. 函数都是有地址,函数名即代表内存地址

    #include <stdio.h>
    int add(int a,int b){
        return a+b;
    }
    int main(){
        printf("add 函数的地址:%p
    ",add); //??
        printf("main 函数的地址:%p
    ",main); //??
        getchar();
    }

      add 函数的地址:00007FF615181000
    main 函数的地址:00007FF615181010

        int (*fptr)(int,int); //声明了一个函数指针变量
                                   //指针变量名 fptr,该函数指针 返回一个int  传入 两个int的类型
    #include <stdio.h>
    int add(int a,int b){
        return a+b;
    }
    int (*fptr)(int,int);
    int main(){
        fptr = add; //将函数add 的地址 赋值给函数指针变量
        printf("*fptr = %p
    ",*fptr);
        printf("add 函数的地址:%p
    ",add); //??
        printf("main 函数的地址:%p
    ",main); //??
        getchar();
    }
    *fptr = 00007FF67D581000
    add 函数的地址:00007FF67D581000
    main 函数的地址:00007FF67D581010

    2. 能否声明一个变量保存函数的地址,保存函数的地址的变量就是函数指针变量,即函数指针

    //通过 函数指针变量 调用函数

    #include <stdio.h>
    int add(int a,int b){
        return a+b;
    }
    int (*fptr)(int,int);
    int main(){
        fptr = add; //将函数add 的地址 赋值给函数指针变量
        //通过 函数指针变量 调用函数
        printf("函数add调用返回 = %d
    ",add(4,6));
        printf("*fptr间接调用返回 = %d
    ",(*fptr)(4,6)); //间接调用add
        getchar();
    }

         3. 声明函数指针类型

     //声明函数指针 类型
        //int * pa;  //声明了一个int * 变量pa
        //typedef int * pa; //声明了一个 int * 类型的别名 pa
        //pa p1,p2,p3; //声明了3个整形指针变量
    类型名可以创建多个变量

    typedef int (*pfunc)(int,int); //声明一个函数指针的类型pfunc
    pfunc fp1,fp2,fp3,fp4; //用fptr 类型声明多个函数指针变量

    #include <stdio.h>
    int add(int a,int b){
        return a+b;
    }
    int (*fptr)(int,int);
    int main(){
        fptr = add; //将函数add 的地址 赋值给函数指针变量
        typedef   int (*pfunc)(int,int);  //声明一个函数指针的类型pfunc
        pfunc fp1,fp2,fp3,fp4; //用fptr 类型声明多个函数指针变量
        fp1 = add;
        printf("函数fp1调用返回 = %d
    ",fp1(4,6)); //间接调用add
        getchar();
        return 0;
    }
    函数fp1调用返回 = 10
    /*
     * 函数指针
     *   编写  剩下的三个函数
     *        int sub(int a,int b);
     *        int mul(int a,int b);
     *        int div(int a,int b);
     *
     *        将函数地址赋值给下面的函数指针变量,
     *        通过函数指针变量退函数进行调用
     *
        pfunc fp1,fp2,fp3,fp4; //用fptr 类型声明多个函数指针变量
     */
    #include <stdio.h>
    int add(int a,int b);
    int sub(int a,int b);
    int mul(int a,int b);
    int div(int a,int b);
    int add(int a,int b){
        return a+b;
    }
    int sub(int a,int b){
        return a-b;
    }                    
    
    int mul(int a,int b){
        return a*b;
    }
    
    int div(int a,int b){
        return a/b;
    }
    int (*fptr)(int,int);
    int main(){
        typedef   int (*pfunc)(int,int);  //声明一个函数指针的类型pfunc
        pfunc fp1,fp2,fp3,fp4; //用fptr 类型声明多个函数指针变量
        fp1 = add;
        fp2 = sub;
        fp3 = mul;
        fp4 = div;
        printf("函数fp1调用返回 = %d
    ",fp1(4,6)); //间接调用add
        printf("函数fp2调用返回 = %d
    ",fp2(4,6)); //间接调用add
        printf("函数fp3调用返回 = %d
    ",fp3(4,6)); //间接调用add
        printf("函数fp4调用返回 = %d
    ",fp4(4,6)); //间接调用add
        getchar();
        return 0;
    }
    函数fp1调用返回 = 10
    函数fp2调用返回 = -2
    函数fp3调用返回 = 24
    函数fp4调用返回 = 0
         4. 函数指针变量的使用
            1. 函数指针变量作为 其他函数的参数
               回调函数
            2. 作为函数的返回值
    /*
     * 函数指针的使用
     *     函数指针作为函数的参数
     */
    #include <stdio.h>
    int  add(int a,int b){
        return a+b;
    }
    typedef int (*pfunc)(int,int); //声明了一个pfunc 的函数指针类型
    //传入的第三参数是函数指针类型
    int compute(int a,int b,pfunc opr);
    int compute(int a,int b,pfunc opr)
    {
        return opr(a,b);
    }
    int main(){
        int a = 20;
        int b = 30;
        int c = 0; 
        c = compute(a,b,add);//第三个参数是个回调函数
        printf("add c = %d
    ",c);
        getchar();
        return 0;
    }
    add c = 50
    /*
     * 函数指针作为 函数的返回值
     */
    pfunc select(char opr)
    {
        if(opr == '+')
            return add;
    }
    typedef int (*pfunc)(int,int); //声明了一个pfunc 的函数指针类型
    pfunc c;         //定义变量名称为c的指针类型
    c = select('+');//保存函数add的地址,而不是select的地址

     函数指针作为 函数的返回值

    #include <stdio.h>
    int  add(int a,int b){
        return a+b;
    }
    typedef int (*pfunc)(int,int); //声明了一个pfunc 的函数指针类型
    pfunc select(char opr);
    pfunc select(char opr)
    {
        if(opr == '+')
            return add;
    }
    int main(){
        int a = 20;
        int b = 30;
        pfunc c; //定义变量名称为c的指针类型
        c = select('+');//保存函数add的地址
        printf("c的地址:%p
    ",c); //??
        printf("add 函数的地址:%p
    ",add); //??
        printf("运算的结果 = %d
    ",c(a,b));//add(a,b)
        getchar();
        return 0;
    }
          c的地址:00007FF6BE0E1000
    add 函数的地址:00007FF6BE0E1000
    运算的结果 = 50
    /*
     * 函数指针作为 函数的返回值
     */
    #include <stdio.h>
    int add(int a,int b){
        return a+b;
    }
    
    int sub(int a,int b){
        return a-b;
    }
    
    int mul(int a,int b){
        return a*b;
    }
    
    int div(int a,int b){
        return a/b;
    }
    typedef int (*pfunc)(int a,int b);
    
    pfunc select(char opr);
    pfunc select(char opr)
    {
        if(opr == '+')
            return add;
        if(opr == '-')
            return sub;
        if(opr == '*')
            return mul;
        if(opr == '/')
            return div;
    }
    
    int compute(int a,int b,char opr);
    int compute(int a,int b,char opr)
    {
        pfunc pf1;
        pf1 = select(opr);
    
        return pf1(a,b);
    }
    
    int main(){
        printf("运算的结果 = %d
    ",compute(30,20,'*'));
        printf("运算的结果 = %d
    ",compute(30,20,'-'));
        printf("运算的结果 = %d
    ",compute(30,20,'+'));
        printf("运算的结果 = %d
    ",compute(30,20,'/'));
        getchar();
        return 0;
    }
    /*
     * 函数指针数组
     */
    #include <stdio.h>
    int add(int a,int b){
        return a+b;
    }
    
    int sub(int a,int b){
        return a-b;
    }
    
    int mul(int a,int b){
        return a*b;
    }
    
    int div(int a,int b){
        return a/b;
    }
    
    typedef int (*pfunc)(int a,int b);
    pfunc  pf_arry[127];
    void initArry()
    {
        pf_arry['+'] = add;
        pf_arry['-'] = sub;
        pf_arry['*'] = mul;
        pf_arry['/'] = div;
    }
    int compute(int a,int b,char opr)
    {
        pfunc pf1 = pf_arry[opr];
        return pf1(a,b);
    }
    int main(){
        //要初始化数组
        initArry();
        printf("运算的结果=%d
    ",compute(12,23,'+'));
        getchar();
        return 0;
    }

    运算的结果=35

    //在main函数中 添加代码 可以实现 输入一个表达式
    //输出该表达式的结果

    #include <stdio.h>
    int add(int a,int b){
        return a+b;
    }
    
    int sub(int a,int b){
        return a-b;
    }
    
    int mul(int a,int b){
        return a*b;
    }
    
    int div(int a,int b){
        return a/b;
    }
    
    typedef int (*pfunc)(int a,int b);
    pfunc  pf_arry[127];
    void initArry()
    {
        pf_arry['+'] = add;
        pf_arry['-'] = sub;
        pf_arry['*'] = mul;
        pf_arry['/'] = div;
    }
    int compute(int a,int b,char opr)
    {
        pfunc pf1 = pf_arry[opr];
        return pf1(a,b);
    }
    int main(){
        //要初始化数组
        int as=12,bs=21;
        char cs='+';
        printf("请输入一个表达式:"); 
        scanf("%d%c%d",&as,&cs,&bs);
    
        initArry();
        //在main函数中 添加代码 可以实现 输入一个表达式
        //输出该表达式的结果
        printf("运算的结果=%d
    ",compute(as,bs,cs));
        getchar();
        getchar();
        return 0;
    }

    请输入一个表达式:5+8
    运算的结果=13

    标准函数库
          函数库 有很多函数组成

    printf();
    scanf();

    time();
    rand();
    srand();

    strlen();
    strcmp();
    strcpy();
    atoi();
    abs();

    内存管理库函数

     动态内存分配函数

    在程序运行中,根据需要临时分配一块内存,就是动态内存分配.
    要申请的内存空间需要程序员手动(显式调用函数)申请,手动释放

       void *malloc(size_t size);
        可以向系统动态申请连续内存,#include <stdlib.h>
        唯一参数 申请内存的字节数
        如果申请成功返回 申请内存的首地址,申请不成功返i回NULL.
        返回值的类型: void * 空指针  没有类型的指针
        如果要使用该内存地址 需要将空指针 转换为有类型的指针
        int *p =(int *) malloc(4); //申请了4个字节,
        *p = 200;//将200 写到 malloc 分配的内存中
        void free(void *ptr);
        释放动态申请到的内存,参数为要释放内存的首地址
        释放的内存是一个整体 
    /*
     * 申请动态内存并使用 释放
     *
     */
    #include <stdio.h>
    #include <stdlib.h>
    
    int main(){
        int *pi = NULL;
        pi = (int *)malloc(4);
        *pi = 200;
        printf("*pi = %d
    ",*pi);
        free(pi);
        pi = NULL; //pi原来指向的内存已经被free,pi赋值为NULL
        getchar();
        return 0;
    }
    /*
     * 申请动态内存并使用 释放
     * [练习]
     *     1. 申请其他基本类型 动态内存,并使用, 使用后注意释放
     *     2. 申请一个Student类型的动态内存,并使用.注意释放
     */
    #include <stdio.h>
    #include <stdlib.h>
    
    int main(){
        float *pi = NULL;
        pi = (float *)malloc(4);
        *pi = 200.2;
        printf("*pi = %.2f
    ",*pi);
        free(pi);
        pi = NULL; //pi原来指向的内存已经被free,pi赋值为NULL
        getchar();
        return 0;
    }
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    typedef struct {
        char name[20];
        int score;
        int age;
    }Student;
    int main(){
        Student *pi = NULL;
        pi = (Student *)malloc(sizeof(Student));
        strcpy(pi->name,"如花");
        pi->score =  30;
        pi->age   = 18;
        printf("name = %s
    ",pi->name);
        printf("score= %d
    ",pi->score);
        printf("age  = %d
    ",pi->age);
        free(pi);
        pi = NULL; //pi原来指向的内存已经被free,pi赋值为NULL
        getchar();
        return 0;
    }

    把功能放在函数

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    typedef struct {
        char name[20];
        int score;
        int age;
    }Student;
    Student *input(){//返回一个结构体类型指针的函数
        Student *pi = NULL;
        pi = (Student *)malloc(sizeof(Student));
        strcpy(pi->name,"如花");
        pi->score =  30;
        pi->age   = 18;
        return pi;//返回一个结构体类型指针
    }
    void output(Student* pi){
        printf("name = %s
    ",pi->name);
        printf("score= %d
    ",pi->score);
        printf("age  = %d
    ",pi->age);
    }
    int main(){
        Student *ps = NULL;
        ps=input();
        output(ps);
        free(ps);
        ps = NULL; //pi原来指向的内存已经被free,pi赋值为NULL
        getchar();
        return 0;
    }

    calloc

         void *calloc(size_t nmemb, size_t size);
          calloc  对动态分配的内存 清0
          第一个参数  要分配多少个存储单元
          第二个参数  每一单元的字节数是多少

    malloc(10*sizeof(Student)); //分配10个学员结构体的空间
    calloc(10,sizeof(Student)); //分配10个学员结构体的空间

         void *realloc(void *ptr, size_t size);
         如果malloc 分配的空间 不够,可以通过realloc 在原来的内存基础上 往后继续分配
         
         第一个参数,是前面malloc 分配的首地址,需要重新分配的大小
         int *p = (int *)malloc(10);
         p = (int *)realloc(p,20); //在原来地址的基础上 分配20字节
    
         calloc  realloc  调用 也需要free 

    时间函数 

    time(0); //返回 从1970.1.1 0:0:0 到现在的秒数
    time_t time(time_t *tloc);

    也可以通过传入一个time_t(unsigned int *)指针,带回秒数

    #include <stdio.h>
    #include <time.h>
    int main(){
        unsigned int sec =0;
        sec = time(0);
        printf("%u
    ",sec);
        getchar();
        return 0;
    }

    char *ctime(const time_t *timep);
    对输入的秒数 转换为日历字符串进行输出

    #include <time.h> 
    #include <stdio.h> 
    int main() {
        time_t timer;
        timer=time(NULL);
        printf("%s
    ",ctime(&timer));
        getchar();
        return 0; 
    }
    Wed May 20 15:58:39 2020

    pt = localtime(&timer); //可以定制显示日历信息

    #include <time.h> 
    #include <stdio.h> 
    int main() {
        time_t timer;
        timer=time(NULL);
        struct tm * pt = NULL; 
        printf("%s
    ",ctime(&timer));
        pt = localtime(&timer); //可以定制显示日历信息
        printf("今天%d号,%d月,%d年
    ",pt->tm_mday,pt->tm_mon+1,pt->tm_year+1900);
        getchar();
        return 0; 
    }
    Wed May 20 16:04:07 2020
    
    今天20号,5月,2020年

    char *asctime(const struct tm *tm);
    对传入的结构体指针 转换输出日历字符串 跟ctime相同

    #include <time.h> 
    #include <stdio.h> 
    int main() {
        time_t timer;
        timer=time(NULL);
        struct tm * pt = NULL; 
        printf("%s
    ",ctime(&timer));
        pt = localtime(&timer); //可以定制显示日历信息
        printf("今天%d号,%d月,%d年
    ",pt->tm_mday,pt->tm_mon+1,pt->tm_year+1900);
        printf("asctime = %s
    ",asctime(pt)); //跟ctime 效果一样
        getchar();
        return 0; 
    }
    Wed May 20 16:07:07 2020
    
    今天20号,5月,2020年
    asctime = Wed May 20 16:07:07 2020

    打印时分秒

    printf("秒%d,分%d,时%d,今天%d号,%d月,%d年
    ",pt->tm_sec,pt->tm_min,pt->tm_hour, pt->tm_mday,pt->tm_mon+1,pt->tm_year+1900);
    秒23,分14,时16,今天20号,5月,2020年

    struct tm *gmtime(const time_t *timep);
    格林威治 时间

    Linux系统下

    /*
     * 时间函数
     */
    
    #include <stdio.h>
    #include <time.h>
    // typedef   long int  time_t
    int main(){
        long int sec = 0;
        struct tm * pt = NULL; 
    
        //sec = time(0);
        time(&sec);
    
        printf("sec = %ld
    ",sec);
        printf("ctime = %s
    ",ctime(&sec)); //输出固定格式日历字符串
    
        pt = localtime(&sec); //可以定制显示日历信息
        printf("今天%d号,%d月,%d年
    ",pt->tm_mday,pt->tm_mon+1,pt->tm_year+1900);
        //打印时分秒
    
        printf("asctime = %s
    ",asctime(pt)); //跟ctime 效果一样
    
        return 0;
    }
    何所为,不仅仅是一种态度,更是一种艺术!
  • 相关阅读:
    self 和 super 关键字
    NSString类
    函数和对象方法的区别
    求两个数是否互质及最大公约数
    TJU Problem 1644 Reverse Text
    TJU Problem 2520 Quicksum
    TJU Problem 2101 Bullseye
    TJU Problem 2548 Celebrity jeopardy
    poj 2586 Y2K Accounting Bug
    poj 2109 Power of Cryptography
  • 原文地址:https://www.cnblogs.com/tanzizheng/p/12924330.html
Copyright © 2011-2022 走看看