最基礎的指針如下: int a; int* p = &a; 答:p指向a的地址,&是取a的地址。*指的是指針中取內容的符號。 2.str[]和str*的區別: char str1[] = "abc"; char str2[] = "abc"; const char str3[] = "abc"; c ...
- 最基礎的指針如下:
int a;
int* p = &a;
答:p指向a的地址,&是取a的地址。*指的是指針中取內容的符號。
2.str[]和str*的區別:
char str1[] = "abc";
char str2[] = "abc";
const char str3[] = "abc";
const char str4[] = "abc";
const char *str5 = "abc";
const char *str6 = "abc";
char *str7 = "abc";
char *str8 = "abc";
cout<<(str1==str2)<<endl;
cout<<(str3==str4)<<endl;
cout<<(str5==str6)<<endl;
cout<<(str7==str8)<<endl;
//輸出 0 0 1 1
這題不是比較字元串內容,而是比較字元串的地址。str1,str2,str3,str4都是新數組,分配新空間。所以它們的地址不同。後面四行是淺拷貝。就是把新指針指過去。
答:結果是:0 0 1 1str1,str2,str3,str4是數組變數,它們有各自的記憶體空間;而str5,str6,str7,str8是指針,它們指向相同的常量區域
3.str[]用sizeof會出錯嗎?
int MyStylen(char str[])
{
return (int)(sizeof(str)-1);//無論何時都是返回3
}
當函數傳遞的是數組指針的時候就自動退化為指針了, 而指針的長度為4,減去1就是3。
但是按照下麵的代碼就會得到正常的值:
char str[] = "hello world";
int len = sizeof(str)-1;
cout<<len;//輸出 11
4.註意數組指針和指針
int a[5] ={1,2,3,4,5};
int *ptr = (int *)(&a+1);
cout<<*(a+1)<<" "<<*(ptr-1);//輸出2 5
&a代表的不是取a這個變數的地址,而是取數組元素的地址。a指向數組的頭部,就是第一個元素的地址。數組名a和&a的記憶體地址相同。
因此,&a+1,表示跨過了整個數組。指向的是第六位。
所以ptr-1就是a[5]的第五位。
sizeof(a) = 20 //54,長度類型位元組數。
sizeof(&a) = 20 //54,長度類型位元組數。
int main()
{
int a[5];
printf("%d\n", a);// 1245036, 指向第一個元素的首地址
printf("%d\n", &a);//1245036, 指向整個數組的地址
printf("%d\n",a+1);//1245040, a[1]元素的地址
printf("%d\n",&a+1);//1245056, 整個數組的位元組長度
printf("%d\n",&a[0]+1);//1245040, 下一個元素的地址
printf("%d\n",sizeof(a));//數組不自動轉換為指針,得到的結果是數組的長度*數組中元素類型所占的位元組數
printf("%d\n",sizeof(&a));//同上
printf("%d\n",(int)a+1);//1245037 (1245036+1)
return 0;
}
5.註意指針要分配給足夠的空間
char a;
char *str = &a;
strcpy(str, "hello");
cout<<str;
請問上面的程式是否可以正常運行?
答: 不能。因為 char類型的a變數只擁有了一位元組的空間,但是"hello"擁有6位元組的空間(包含最後的'\0'),所以程式崩潰。
6.小心編譯器的指針字元串初始化
char *s="AAA";
cout<<s<<endl;
s[0]='B';
cout<<s<<endl;
這段程式能否正常運行?
答: 不能。因為char *s預設為只讀值,將char *a改為char a[]即可。如果定義const char *a也是沒有必要的,因為本身已經是只讀了,不需要加const設為常數值。
7.函數指針
int(*s[10])(int);
不懂。
8.函數傳遞指針的時候是副本
void GetMemory(char *p)
{
p=new char[100];
strcpy(p,"hello world");
}
void main(void)
{
char *str=NULL;
GetMemory(str);
cout<<str;
delete []str;
str=NULL;
}
上述代碼能運行嗎?
解答: 不能。因為函數參數不能傳遞分配空間的,不能返回的。可以這樣修改:
void GetMemory(char **p) // 改成晦澀難懂的指針的指針
{
*p=new char[100]; //給*p的分配地址
strcpy(*p,"hello world"); // 拷貝內容到*p
}
void main(void)
{
char *str=NULL;
GetMemory(&str); //這地方取地址
cout<<str;
delete []str;
str=NULL;
}
9.要時刻記住初始化字元串:
char a[10];
cout<<strlen(a)<<endl;
sizeof()和初不初始化沒有關係,但是庫函數strlen()和初始化有關。所以strlen(a)不會返回10。