c語言全局變數數組
『壹』 c語言,如何定義數組為全局變數
在C語言中,全局變數和函數聲明及定義並列,也就是說,聲明在最外層作用域的變數即為全局變數
如在如下程序中
int i;
int main()
{
int i_ = i;
i = 9;
return 0;
}
int
i就是一個全局變數,故在main函數中可以調用或修改i的值
所以,定義數組也和普通全局變數的方法相同,如
char str[10];
int main()
{
str[0] = 'a';
str[1] = '\0';
return 0;
}
但是有幾點需要注意:
C中自上向下語法分析和編譯語法樹,如果要讓所有函數都能調用該全局變數,就要把其放在所有函數定義之前,確保聲明的作用域覆蓋整個程序;
在全局變數聲明時,其初始值必須為編譯時常量,不能為變數;
若要使用程序外的全局變數,需要在修飾符中加入extern關鍵字,並不要忘了和原本定義處鏈接
『貳』 關於C語言變數和數組的聲明問題
首先聲明變數了是有內存分配的。
如果定義數組後可以得到連續的內存分配(有時候特別佔用空間)。所以C語言出了鏈表(可以不連續的村一組數據)。
下面是C語言內存分配特性,可以參考。
1、C中內存分為四個區
棧:用來存放函數的形參和函數內的局部變數。由編譯器分配空間,在函數執行完後由編譯器自動釋放。
堆:用來存放由動態分配函數(如malloc)分配的空間。是由程序員自己手動分配的,並且必須由程序員使用free釋放。如果忘記用free釋放,會導致所分配的空間一直占著不放,導致內存泄露。
全局局:用來存放全局變數和靜態變數。存在於程序的整個運行期間,是由編譯器分配和釋放的。
文字常量區:例如char *c = 「123456」;則」123456」為文字常量,存放於文字常量區。也由編譯器控制分配和釋放。
程序代碼區:用來存放程序的二進制代碼。
例子(一)
int a = 0; //全局區
void main()
{
int b; //棧
char s[] = abc; //s在棧,abc在文字常量區
char *p1,*p2; //棧
char *p3 = 123456; //123456在常量區,p3在棧上
static int c =0; //全局區
p1 = (char *)malloc(10); //p1在棧,分配的10位元組在堆
p2 = (char *)malloc(20); //p2在棧,分配的20位元組在堆
strcpy(p1, 123456); //123456放在常量區
}
例子(二)
//返回char型指針
char *f()
{
//s數組存放於棧上
char s[4] = {'1','2','3','0'};
return s; //返回s數組的地址,但程序運行完s數組就被釋放了
}
void main()
{
char *s;
s = f();
printf (%s, s); //列印出來亂碼。因為s所指向地址已經沒有數據
}
2、動態分配釋放內存
用malloc動態分配內存後一定要判斷一下分配是否成功,判斷指針的值是否為NULL。
內存分配成功後要對內存單元進行初始化。
內存分配成功且初始化後使用時別越界了。
內存使用完後要用free(p)釋放,注意,釋放後,p的值是不會變的,仍然是一個地址值,仍然指向那塊內存區,只是這塊內存區的值變成垃圾了。為了防止後面繼續使用這塊內存,應在free(p)後,立即p=NULL,這樣後面如果要使用,判斷p是否為NULL時就會判斷出來。
NO.1
void GetMemory(char *p)
{
p = (char *)malloc(100);
}
void Test(void)
{
char *str = NULL;
GetMemory(str);
strcpy(str,hello world);
printf(str);
}
請問運行Test函數後會是什麼樣的結果?
NO.2
char *GetMemory(void)
{
char p[] = hello world;
retrun p;
}
void Test(void)
{
char *str = NULL;
str = GetMemory();
printf(str);
}
問題同NO.1
NO.3
void GetMemory2(char **p, int num)
{
*p = (char *)malloc(num);
}
void Test(void)
{
char *str = NULL;
GetMemory(&str,100);
strcpy(str,hello);
printf(str);
}
問題同NO.1
NO.4
void Test(void)
{
char *str = (char *)malloc(100);
strcpy(str,hello);
free(str);
if(str != NULL)
{
strcpy(str,world);
printf(str);
}
}
問題同NO.1
我對以上問題的分析:
NO.1:程序首先申請一個char類型的指針str,並把str指向NULL(即str里存的是NULL的地址,*str為NULL中的值為0),調用函數的過程中做了如下動作:1申請一個char類型的指針p,2把str的內容到了p里(這是參數傳遞過程中系統所做的),3為p指針申請了100個空間,4返回Test函數.最後程序把字元串helloworld拷貝到str指向的內存空間里.到這里錯誤出現了!str的空間始終為NULL而並沒有實際的空間.深刻理解函數調用的第2步,將不難發現問題所在!(建議:畫圖理解)
NO.2:程序首先申請一個char類型的指針str,並把str指向NULL.調用函數的過程中做了如下動作:1申請一數組p[]並將其賦值為hello world(數組的空間大小為12),2返回數組名p付給str指針(即返回了數組的首地址).那麼這樣就可以列印出字元串"helloworld"了么?當然是不能的!因為在函數調用的時候漏掉了最後一步.也就是在第2步return數組名後,函數調用還要進行一步操作,也就是釋放內存空間.當一個函數被調用結束後它會釋放掉它裡面所有的變數所佔用的空間.所以數組空間被釋放掉了,也就是說str所指向的內容將不確定是什麼東西.
NO.3:正確答案為可以列印出hello.但內存泄漏了!
NO.4:申請空間,拷貝字元串,釋放空間.前三步操作都沒有任何問題.到if語句里的判斷條件開始出錯了,因為一個指針被釋放之後其內容並不是NULL,而是一個不確定的值.所以if語句永遠都不能被執行.這也是著名的"野"指針問題.所以我們在編寫程序釋放一個指針之後一定要人為的將指針付成NULL.這樣就會避免出現"野"指針的出現.有人說"野"指針很可怕,會帶來意想不到的錯誤.
『叄』 C語言中怎樣在頭文件中定義一個能夠在所有文件中都可以使用的全局數組變數
C語言可以通過在.c文件中定義,頭文件中extern的方式實現一個能夠在所有文件中都可以使用的全局數組變數。
具體做法如下:
設有一個多項目文件有 1.c、2.c和3.c三個源程序文件;
如果有一個全局數組需要所有文件使用,那麼可以添加一個data.c文件,在其中添加全局數組的定義;
向項目中添加data.h文件,在data.h文件中用 extern聲明該數組;
只需要在相應的.c文件中添加#include "data.h",那麼久可以使用data.c中的全局數組了。
『肆』 c語言函數怎麼調用數組部分
一、數組可定義為全局變數,函數直接調用。
二、數組可定義為局部變數,再通過參數傳遞到函數中調用(實參傳數組名,表示數組首地址,也可通過指針或數組名+數字來傳遞數組局部地址)。
三、main函數想要調用函數返回的數組,可用static定義靜態變數或malloc定義動態數組(字元串常量也可返回使用,但局部變數,在函數調用結束會被釋放,不能作為返回地址使用)。
下面是演示代碼:
#include <stdio.h>
#include <string.h>
#include <malloc.h>
char str1[]="我是全局變數數組";
char *fun0(char str2[]);
char *fun1();
char *fun2();
int main()
{
char *str3=NULL,*str4=NULL,*str5=NULL;
char str2[]="我是main函數的局部數組變數";
str3=fun0(str2);
printf("str3:%s,fun函數調用結束,我的地址依然可以使用 ",str3);
str4=fun1();
printf("str4:%s,fun函數調用結束,我的地址依然可以使用 ",str4);
str5=fun2();
printf("str5:%s,fun函數調用結束,函數結束不會自動釋放 ",str5);
free(str5);
return 0;
}
char *fun0(char s[])
{
static char str3[]="我是fun函數申明的靜態數組變數";
printf("str1:%s,fun函數可以直接調用 ",str1);
printf("str2:%s,fun函數通過參數將我的地址傳進來 ",s);
return str3;
}
char *fun1()
{
char *str4="我是fun1函數的字元串常量";
return str4;
}
char *fun2()
{
int len;
char sTemp[]="這是一個臨時數組,之後用於給mallc申請的地址傳值,傳遞內容為:(我是fun函數通過mallic申請的數組)";
char *str5=NULL;
len=strlen(sTemp+63);
str5=(char *)malloc(sizeof(char)*len+1);
if(!str5)return NULL;
strcpy(str5,sTemp+63);
str5[len-2]=0;
return str5;
}