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;
    }
    何所为,不仅仅是一种态度,更是一种艺术!
  • 相关阅读:
    nginx -s reload 时报错 [error] open() "/run/nginx.pid" failed (2: No such file or directory)
    系统调用(四):SSDT
    系统调用(三): 分析KiFastCallEntry(二)
    系统调用(二): 分析KiFastCallEntry(一)
    系统调用(一): 重写WriteProcessMemory
    CVE-2009-0927分析
    CVE-2008-0015分析
    CVE-2006-4868分析
    在linux上使用impdp命令时提示ORA-12154: TNS:could not resolve the connect identifier specified的问题
    破解myeclipse10失败的一个奇葩原因
  • 原文地址:https://www.cnblogs.com/tanzizheng/p/12924330.html
Copyright © 2011-2022 走看看