1. 程式人生 > >c/c++柔性數組成員

c/c++柔性數組成員

typedef In har 在哪裏 %d 實體 \n UC 告訴

柔性數組成員

定義和聲明分離

#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\n",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
\n", 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是‘\0‘。這樣一來,就相當於只用指針tp,就既可以控制結構體裏面的成員,也可以控制結構體外面的字符串。
Test* tp = (Test*) malloc(sizeof(Test) + strlen(str) + 1); tp->a = 10; tp->b = 11; strcpy((char*)(tp+1), str); printf("%s\n", (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
  Test t;
  long dd;
  char str[] = "Hello c Hello c++!";
  long ee;
  //非常的神奇,雖然沒有對t.pc賦值,但是打印出了正確的數據。
  printf("%s\n",t.pc);//Hello c Hello c++!
}

為什麽,雖然沒有對t.pc賦值,但是打印出了正確的數據呢?

方法裏聲明的局部成員,存放在棧區,編譯器把數組str放到了,Test t的下面,而且Test的成員pc還是0空間的數組,也就是不占用內存空間,所以pc內存地址正好和str的內存地址相同了,所以即使不對t.pc賦值,也能正確打印出Hello c Hello c++!。

疑問,為什麽不管Test t和char str[] = "Hello c Hello c++!";定義在哪裏,編譯器都能把str放到Test t的下面。

c/c++柔性數組成員