main()
{
char s[30];
strcpy(s, "Good News!"); /*給數組賦字符串*/
.
.
.
}
上面程序在編譯時, 遇到char s[30]這條語句時, 編譯程序會在內存的某處留
出連續30個字節的區域, 並將第一個字節的地址賦給s。當遇到strcpy( strcpy 爲
Turbo C2.0的函數)時, 首先在目標文件的某處建立一個"Good News!/0" 的字符串。
其中/0表示字符串終止, 終止符是編譯時自動加上的, 然後一個字符一個字符地復
制到s所指的內存區域。因此定義字符串數組時, 其元素個數至少應該比字符串的
長度多1。
注意:
1. 字符串數組不能用"="直接賦值, 即s="Good News!"是不合法的。所以應分
清字符串數組和字符串指針的不同賦值方法。
2. 對於長字符串, Turbo C2.0允許使用下述方法:
例如:
main()
{
char s[100];
strcpy(s, "The writer would like to thank you for"
"your interest in his book. He hopes you"
"can get some helps from the book.");
.
.
.
}
指針數組賦值
例如:
main()
{
char *f[2];
int *a[2];
f[0]="thank you"; /*給字符型數組指針變量賦值*/
f[1]="Good Morning";
*a[0]=1, *a[1]=-11; /*給整型數數組指針變量賦值*/
.
.
.
}
------------------------------------------------------------------------------------------------------------------
補充:
無論是靜態,局部還是全局數組只有在定義時才能初始話,否則必須通過其它方法,比如循環操作實現。
任何
int a[3];
static int b[3];
a[3] = {1, 2, 3};
b[3] = {1, 2, 3};
沒有在定義時初始化都是錯誤的!
-------------------------------------------------------------------------------------------------------------------
以下是轉載:
學了這麼多年的C語言,突然發現連字符串賦值都出錯,真的很傷心。
char a[10];
怎麼給這個數組賦值呢?
1、定義的時候直接用字符串賦值
char a[10]="hello";
注意:不能先定義再給它賦值,如char a[10]; a[10]="hello";這樣是錯誤的!
2、對數組中字符逐個賦值
char a[10]={'h','e','l','l','o'};
3、利用strcpy
char a[10]; strcpy(a, "hello");
易錯情況:
1、char a[10]; a[10]="hello";//一個字符怎麼能容納一個字符串?況且a[10]也是不存在的!
2、char a[10]; a="hello";//這種情況容易出現,a雖然是指針,但是它已經指向在堆棧中分配的10個字符空間,現在這個情況a又指向數據區中的hello常量,這裏的指針a出現混亂,不允許!
還有:不能使用關係運算符“==”來比較兩個字符串,只能用strcmp() 函數來處理。
C語言的運算符根本無法操作字符串。在C語言中把字符串當作數組來處理,因此,對字符串的限制方式和對數組的一樣,特別是,它們都不能用C語言的運算符進行復制和比較操作。
直接嘗試對字符串進行復制或比較操作會失敗。例如,假定str1和str2有如下聲明:
char str1[10], str2[10];
利用=運算符來把字符串複製到字符數組中是不可能的:
str1 = "abc"; /*** WRONG ***/
str2 = str1; /*** WRONG ***/
C語言把這些語句解釋爲一個指針與另一個指針之間的(非法的)賦值運算。但是,使用=初始化字符數組是合法的:
char str1[10] = "abc";
這是因爲在聲明中,=不是賦值運算符。
試圖使用關係運算符或判等運算符來比較字符串是合法的,但不會產生預期的結果:
if (str1==str2) ... /*** WRONG ***/
這條語句把str1和str2作爲指針來進行比較,而不是比較兩個數組的內容。因爲str1和str2有不同的地址,所以表達式str1 == str2的值一定爲0。
-------------------------------------------------------------------------------------------------------------------------------------
有空再查下動態數組的定義使用:
數組到底應該有多大才合適,有時可能不得而知。所以希望能夠在運行時具有改變數組大小的能力。
動態數組就可以在任何時候改變大小。
通俗的說靜態數組就是在定義數組的時候,由操作系統分配的空間,比如
int a[10];
這就是在定義時由系統給你分配了10個int類型的空間,這個空間是可以初始化的,比如
int a[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
那麼在這個定義之後,系統會首先分配10個int類型的存儲空間,然後把大括號裏面的數字分別的,按順序放到這10個空間裏。你所做的只是寫這麼一句,而數組賦值的操作就由系統完成了。當然,初始化與否看你的需求,初始化不是強制性操作,想初始化就初始化,不想也沒問題,還是上面的例子繼續:
int a[10];
這裏定義了,但是沒初始化,這沒有任何問題,以後你可以自己往裏面賦值,比如
a[1] = 8;
a[5] = 3;
或者
for(int i = 0; i < 10; i++)
a[i] = i;
等等
對於動態數組,不能被初始化,因爲動態數組在定義時只是個指針,比如
int *a;
這裏變量a只是個指向int類型的指針,而不是數組。動態分配有10個int類型元素的數組,如下:
a = (int) malloc(10*sizeof(int));
很明顯,指針a在定義的時候不能被初始化,比如這樣寫就是錯誤的:
int *a = {1,2,3,4,5,6,7,8,9,10}; /* 錯誤! */
因爲a是隻有4個字節的指針,沒有可用的存儲空間給需要初始化的變量。
----------------------------------------------------------------------------------------------------------------------------------------------------
第三節 初始化數組
1.數組的初始化
數組可以初始化,即在定義時,使它包含程序馬上能使用的值。
例如,下面的代碼定義了一個全局數組,並用一組Fibonacci數初始化:
int iArray[10]={1,1,2,3,5,8,13,21,34,55); //初始化
void main()
{
//...
}
初始化數組的值的個數不能多於數組元素個數,初始化數組的值也不能通過跳過逗號的方式來省略,這在C中是允許的,但在C++中不允許。
例如,下面的代碼對數組進行初始化是錯誤的:
int arrayl[5]={1,2,3,4,5,6}; //error: 初始化值個數多於數組元素個數
int array2[5]={1,,2,3,4}; //error:初始化值不能省略
int array3[5]={1,2,3,}; //error:初始化值不能省略
int array4[5]={}; //error:語法格式錯誤
void main()
{
//...
}
初始化值的個數可少於數組元素個數。當初始化值的個數少於數組元素個數時,前面的按序初始化相應值, 後面的初始化爲0(全局或靜態數組)或爲不確定值(局部數組)。
例如,下面的程序對數組進行初始化:
//*********************
//** ch7_2.cpp **
//*********************
#include <iostream.h>
int array1[5]={1,2,3};
static int array2[5]={1};
void main()
{
int arr1[5]={2};
static int arr2[5]={1,2};
int n;
cout <<"global:/n";
for(n=0; n<5; n++)
cout <<" " <<array1[n];
cout <<"/nglobal static:/n";
for(n=0; n<5; n++)
cout <<" " <<array2[n];
cout <<"/nlocal:/n";
for(n=0; n<5; n++)
cout <<" " <<arr1[n];
cout <<"/nlocal static:/n";
for(n=0; n<5; n++)
cout <<" " <<arr2[n];
cout <<endl;
}
運行結果爲:
global:
l 2 3 0 0
global static:
1 0 0 0 0
local:
2 23567 23567 23567 23567
local static:
1 2 0 0 0
例中,全局數組和全局靜態數組的初始化是在主函數運行之前完成的,而局部數組和局部靜態數組的初始化是在進入主函數後完成的。
全局數組arrayl[5]對於初始化表的值按序初始化爲1,2,3,還有兩個元素的值則按默認初始化爲0。
全局靜態數組array2[5]與全局數組的初始化情況一樣,初始化表值(1)表示第1個元素的值,而不是指全部數組元素都爲1。
局部數組arrl[5]根據初始化表值的內容按序初始化, 由於初始化表值只有1個,所以還有4個元素的值爲不確定。在這裏均爲數值23567。
局部靜態數組arr2[5]先根據初始化表按序初始化,其餘3個數組元素的值默認初始化爲0。
2.初始化字符數組
初始化字符數組有兩種方法,一種是:
char array[10]={"hello"};
另一種是:
char array[10]={'h','e','l','l','/0'};
第一種方法用途較廣,初始化時,系統自動在數組沒有填值的位置用,'/0'補上。另外, 這種方法中的花括號可以省略,即能表示成:
char array[10]="hello";
第二種方法一次一個元素地初始化數組,如同初始化整型數組。這種方法通常用於輸入不容易在鍵盤上生成的那些不可見字符。
例如,下面的代碼中初始化值爲若干製表符:
char chArray[5]={'/t','/t','/t','/t','/0');
這裏不要忘記爲最後的,'/0'分配空間。如果要初始化一個字符串"hello",那爲它定義的數組至少有6個數組元素。
例如,下面的代碼給數組初始化,但會引起不可預料的錯誤:
char array[5]="hello";
該代碼不會引起編譯錯誤,但由於改寫了數組空間以外的內存單元,所以是危險的。
3.省略數組大小
有初始化的數組定義可以省略方括號中的數組大小。
例如,下面的代碼中數組定義爲5個元素:
int a[]={2,4,6,8,10};
編譯時必須知道數組的大小。通常,聲明數組時方括號內的數字決定了數組的大小。有初始化的數組定義又省略方括號中的數組大小時,編譯器統計花括號之間的元素個數,以求出數組的大小。
例如,下面的代碼產生相同的結果:
static int a1[5]={1,2,3,4,5};
static int a2[]={1,2,3,4,5};
讓編譯器得出初始化數組的大小有幾個好處。它常常用於初始化一個元素個數在初始化中確定的數組,提供程序員修改元素個數的機會。
在沒有規定數組大小的情況下,怎麼知道數組的大小呢? sizeof操作解決了該問題。 例如,下面的代碼用sizeof確定數組的大小:
//*********************
//** ch7_3.cpp **
//*********************
#include <iostream.h>
void main()
{
static int a[]={1,2,4,8,16};
for(int i=0; i<(sizeof(a)/sizeof(int)); i++)
cout <<a[i] <<" ";
cout <<endl;
}
運行結果爲:
1 2 4 8 16
sizeof操作使for循環自動調整次數。如果要從初始化a數組的集合中增刪元素,只需重新編譯即可,其他內容無須更動。
每個數組所佔的存儲量都可以用sizeof操作來確定! sizeof返回指定項的字節數。sizeof常用於數組,使代碼可在16位機器和32位機器之間移植:
對於字符串的初始化,要注意數組實際分配的空間大小是字符串中字符個數加上末尾的,'/0',結束符。
例如,下面的代碼定義一個字符數組:
//*********************
//** ch7_4.cpp **
//*********************
#include <iostream.h>
void main()
{
char ch[]="how are you";
cout <<"size of array: " <<sizeof(ch) <<endl;
cout <<"size of string: " <<strlen("how are you") <<endl;
}
運行結果爲:
size of array:12
size of string:ll
例中,數組大小爲12,而字符串長度爲11。
省略數組大小只能在有初始化的數組定義中。
例如,下面的代碼將產生一個編譯錯誤:
int a[];//error:沒有確定數組大小
在定義數組的場合,無論如何,編譯器必須知道數組的大小。