c/c++柔性數組成員
阿新 • • 發佈:2018-06-15
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++柔性數組成員