zoukankan      html  css  js  c++  java
  • 柔性数组成员

    柔性数组成员

    定义和声明分离

    #include <stdio.h>
    
    //只是告诉编译器,当编译到使用到这个函数的的代码时,虽然还没有找到函数定义的实体,但是也让它编译不出错误。
    extern int fun(int a);
    extern int x;
    
    int x;
    int main(){
      //在这行调用fun函数,但是编译器只找到了声明,没有找到fun的定义,所以编译不出错误,编译器在后面找到了fun函数的定义实体,所以运行没有问题。
      fun(10);
      //在这行使用全局变量x,但是编译器只找到了声明,没有找到x的定义,所以编译不出错误,编译器在后面找到了全局变量x的定义实体,所以运行没有问题。
      x = 22;
    }
    
    int fun(int b){
      printf("b = %d
    ",b);
      return b;
    }
    
    运行结果:
    b = 22
    

    结构体里有指向字符串指针

    结构体里如果有指向字符串指针,就会发生字符串在结构体的外面,不能由结构体来统一管理。

    #include <stdio.h>
    
    struct Test{
      int a;
      long b;
      char* c;
    };
    
    int main(){
      //结构体里如果有指向字符串指针,就会发生字符串在结构体的外面,不能有结构体来统一管理。
      char *str = "asd";
      struct Test t;
      t.c = str;
      printf("%s
    ", t.c);
    }
    

    解决办法:

    #include <stdio.h>
    #include <malloc.h>
    #include <string.h>
    
    typedef struct Test{
      int a;
      long b;
    } Test;
    
    int main(){
      char* str = "i am out of struct Test";
      //sizeof(Test)结构体需要字节数,strlen(str)是str需要的字节数,最后的加1是''。这样一来,就相当于只用指针tp,就既可以控制结构体里面的成员,也可以控制结构体外面的字符串。
      Test* tp =  (Test*) malloc(sizeof(Test) + strlen(str) + 1);
      tp->a = 10;
      tp->b = 11;
      strcpy((char*)(tp+1), str);
      printf("%s
    ", (char*)(tp+1));
      free(tp);
      
    }
    

    上面的代码有个弊端,就是访问那个str时,需要使用不容易理解的tp+1,改进如下。

    #include <stdio.h>
    
    typedef struct Test{
      
      int a;
      long b;
      char pc[0];
    }Test;
    
    int main(){
      int a;
      long b;
      long c;
      //不管Test t放在哪行,t.pc都指向下面的str
      Test t;
      long dd;
      char str[] = "Hello c Hello c++!";
      long ee;
      //非常的神奇,虽然没有对t.pc赋值,但是打印出了正确的数据。
      printf("%s
    ",t.pc);//Hello c Hello c++!
    }
    

    为什么,虽然没有对t.pc赋值,但是打印出了正确的数据呢?

    方法里声明的局部成员,存放在栈区,编译器把数组str放到了,Test t的下面,而且Test的成员pc还是0空间的数组,也就是不占用内存空间,所以pc内存地址正好和str的内存地址相同了,所以即使不对t.pc赋值,也能正确打印出Hello c Hello c++!。但是如果用char *str = "Hello c Hello c++!";的方式定义str,str就是一个常量了,就不会存放在栈区了,所以是无法被pc成员访问的。

    疑问,为什么不管Test t和char str[] = "Hello c Hello c++!";定义在哪里,编译器都能把str放到Test t的下面。

    因为str的占用的空间在main函数里是最大的,所以放到了栈的最底下,Test t占用的空间第二大所以放到了str的上面,所以t.pc指向了str,如果str占用的空间小,就不能保证t.pc指向str了。

    C语言局部变量在内存栈中的顺序:https://blog.csdn.net/qq_19406483/article/details/77511447

    柔性数组

    #include <stdio.h>
    #include <malloc.h>
    
    typedef struct Test{
      int i;
      int ary[0];
    }Test;
    
    int main(){
      int len;
      scanf("%d", &len);
      Test* t = (Test*)malloc(sizeof(Test) + (sizeof(int) * len));
      for(int i = 0; i < len; ++i){
        t->ary[i] = i + 1;
      }
      for(int j = 0; j < len; ++j){
        printf("%d ",t->ary[j]);
      }
      printf("
    ");
      free(t);
    }
    
  • 相关阅读:
    POJ 1066 Treasure Hunt (线段相交)
    玲珑杯 第4次 String cut(暴力字符串)
    POJ 2653 Pick-up sticks (线段相交)
    HDU 3535 AreYouBusy (混合背包)
    HDU 1712 ACboy needs your help(分组背包)
    HDU 1074 Doing Homework (状压dp)
    POJ 1635 Subway tree systems (树的最小表示法)
    HDU 汉诺塔系列
    HYSBZ 1500 维修数列(伸展树模板)
    photoshop 快速切图
  • 原文地址:https://www.cnblogs.com/xiaoshiwang/p/9199571.html
Copyright © 2011-2022 走看看