在c語言中 "string"保存的就是首個字符所在的地址 所以可以把 字符串常量"string" 賦值給指針 char *p; p="string" 但不能把字符串常量直接賦給數組,需要用到 strcpy。 但可以對數組初始化爲字符串,也就是字符數組。如 char str[] = "string";
兩種初始化的區別:char * p="the fine day" 和 char str[]="the fine day" 不同, 這兩個都是給字符串的初始化,前者只是把字符串的首地址給str,沒有分配足夠的內存地址來保存整個字符串 , 後者初始化的同時,把他們保存在數組中,也就是分配好了所有字符需要的內存。 所以:
(1) char *p = "string"; // 地址變量p 保存的是 's' 的地址,,(2) char str[] = "the fine day"; //字符數組str保存的是整個字符串,某些情況下退化爲指針
(3) char *str1 = "the day"; // OK.
此時,如果要複製另一個字符串str1 到p或str:
strcpy(p, str1); //錯誤! 需改爲 p=(char*)malloc( strlen(str1)+1 ); 才正確
strcpy(str, str1); //沒錯誤,已有足夠內存,但不能總是保證。
strncpy(str, str1, strlen(str) ); //正確!不作討論
實際上,(1)中是不對的,好像新標準已經會報錯;
通常應該這樣初始化:strcpy(p, "string");
或者改爲:const *p = ""string"; 但這樣就不能修改p了。
2. 整形指針的初始化
試看下面語句哪一行 能夠 打印輸出?
int a = 10;
int * p1 = 0;
int * p2 = &a; //常見,初始化爲某變量的地址
int * p3 = 20;
printf("p1=%p, *p1=%d\n", p1, *p1);
printf("p2=%p, *p2=%d\n", p2, *p2);
printf("p3=%p, *p3=%d\n", p3, *p3);
這幾行語句編譯時會有警告:p3那一行將整數賦值給指針,沒做類型轉換。
運行時會導致崩潰。
爲什麼呢?
仔細看一下,int * p1 = 0; //真的初始化了嗎?
int * p3 = 20; // *p3 初始化成20了嗎?
其實int *p1 = 0 相當於 int *p1 = NULL,不能讀取空指針 p1 以及 *p1 的值!
而 int *p3 = 20 相當於 int *p3; p3 = (int *)0x00000014; 不能讀取*p3的值。
3. 指針數組的初始化
問題一:
const char *p[] ={"aaa", "bbb"}; // 這樣在定義p的時候完成了初始化,那麼
int *p1[] ={1,2}; //Wrong! 爲什麼不可以? 如何在定義p1的時候進行初始化?
int *p2[] = {NULL, NULL}; //OK. 這樣又可以了?
問題二:
我想定義一個指針數組(雖然很少人用這個東西),那麼,對這個指針的初始化怎麼做?
int * pstr[5];
------------------------
const char *p[] = {"aaa", "bbb"}; 指向字符的指針數組,數組中的元素是字符串,指針數組保存的是字符串首地址,沒有問題。
對於int *p1[] ={1, 2}而言,存在二義性,它既可以表示int p1[2][0],即p1[0][0]=1,p1[1][0]=2
也可表示爲int p1[n][2],即:p1[0][0]=1,p1[0][1]=2;
我們可以這樣:
int *p[3];
for(i=0; i<3; ++i)
{
p[i] = (int *)malloc( sizeof(int));
}
/* Do something with p[i] */
for(i=0; i<3; ++i)
{
free(p[i]);
}
不然怎麼樣呢? 這樣比較好:
int arr[3][2] = { {1, 2}, {3, 4}, {5, 6} };
int *pa[3];
for(int i=0; i < 3; ++i) {
pa[i] = arr[i];
}
而 int *p[3] = { {1, 2}, {3, 4}, {5, 6} }; 是不行的!Warning一堆。
4. struct 指針的初始化
struct_type *p;
p = (struct_type *)malloc( sizeof(struct_type) );
總之,儘量用其他變量來初始化指針。