《c和指標》上有一段:
指標和陣列並不是相等的,
當宣告乙個陣列時,它同時也分配了一寫記憶體空間,用於儲存陣列元素,
但當宣告乙個指標時,它只分配了用於容納指標的空間(32位中4個位元組的大小)。
如:int a[5];
int *p;
a和p都具有指標值,都可以進行間接訪問和下標引用操作。但是他們還是存在很大區別:
宣告乙個陣列時,編譯器將根據宣告所指定的元素數量維陣列儲存記憶體空間,然後再建立陣列名。他的值是乙個常量,指向這段空間的起始位置。
宣告乙個指標變數時,編譯器只為指標本身保留記憶體空間。而且指標變數並未初始化為任何現有的記憶體空間。
因此上述宣告之後,*a是完全合法的,*p將會訪問記憶體中某個不確定的位置。另外表示式p++可以通過編譯,但a++卻不可以,原因是a的值是一常量 p是乙個變數;
一維陣列訪問
以下標方式 array[i]
以指標方式 *(array+i);
陣列名是隱含意義的常指標(直接位址) 其關聯型別是陣列元素的型別
站在c++編譯器的角度,*p 相當於我們程式設計師手工(顯示)利用間接賦值,去操作記憶體
""是c++編譯器幫我們程式設計師做了乙個*p的操作
當乙個陣列名作為函式引數時,陣列名的值就是指向陣列第乙個元素的指標,所以此時傳遞給函式的是指標的拷貝。
#include int sum ( int ap[ ] , intint sum(int ap, int n) 和int sum(int *ap, int n)效果一樣的n )
returnm;}
void
main()
; cout
<< "
sum =
"<< sum ( a , 10 ) <
}
二維陣列名同樣代表陣列首元素的位址
//int b[2][5]===>b的型別為int(*)[5]不是char**
多維陣列名的本質:陣列指標即
指向乙個陣列的指標
inta[3][5]
(a+i) 代表是整個第i行的位址
*(a+i)就表示
第i行首元素的位址
*(a+i) + j ===> & a[i][j]
*( *(a+i) + j) ===>a[i][j]元素的值
一級指標做函式引數:
int array(char buf[60]);會退化為指標
int array(char buf)
int array(char * buf)
二級指標做函式引數
int array2(char array[10][30])//10無作用 30確定其步長
int array(char array[30])
int array(char (*array)[30])//陣列指標的
二維陣列可以看做是一維陣列
二維陣列中的每個元素是一維陣列
二維陣列引數中第一維的引數可以省略
void f(int a[5]) ====》void f(int a); ===》 void f(int* a);
void g(int a[3][3])====》 void g(int a[3]); ====》 void g(int (*a)[3]);
實參 ( 陣列引數 )
所匹配的形參(等效指標引數)
一維陣列 char a[30]
指標 char* (可直接char* p=a;下面的類似)
指標陣列 char *a[30]
指標的指標 char **a 指標的指標([30]陣列做函式引數退化為指標 , 況且又是個指標陣列所以**)
二維陣列 char a[10][30]
陣列的指標 char(*a)[30](陣列指標
陣列指標(行指標)char(*c)[10]
char(*c)[10] 不改變
指標的指標 char**c(二重指標)
char**c 不改變
int printfarr23_1(char myarray[10][30], int多維陣列名本質就是乙個陣列指標inum)
return0;
}int printf2array_2(char myarray[30], int
inum)
return0;
}int printf2array_3(char (*myarray)[30],int
inum)
return0;
}void
main()
; //
printf2array_2(myarray, 4
); printf2array_3(myarray, 4);
system(
"pause");
}
二重指標的用法
(1)二重指標指向一重指標的位址
(2)二重指標指向指標陣列的
(3)實踐程式設計中二重指標用的比較少,大部分時候就是和指標陣列糾結起來用的。
(4)實踐程式設計中有時在函式傳參時為了通過函式內部改變外部的乙個指標變數,會傳這個指標變數的位址(也就是二重指標)進去。
intchar*str與char**str1相等只適用於形參 或者char**str1指向char*strmain()
;
char **str1 = str;//
;不可以直接定義 **str1 = ;指標陣列指標
cout << "
sizeof(str)
"<< sizeof(str) <
cout
<< "
sizeof(str[1])
"<< sizeof(str[1]) <
cout
<< "
sizeof(str[0])
"<< sizeof(str[0]) <
for (int i = 0; i < sizeof(str) / sizeof(str[0]);i++)
system(
"pause");
return0;
}
華為的面試題:
若有函式宣告voidf(char** p),則使得函式呼叫f(var)不正確的var定義是———?
a char var[10][10]; b char *var[10]
c void* var=null; d char* v=null,**var=&v;
解析:1.char var[10][10];var的型別是 char (*)[10] 型別(不理解的話需要好好看看課本)
2.char *var[10]; var陣列是存放char *型別的陣列,陣列名var是陣列var元素的首位址,所以var的
型別是char**型別
3.void * 是定義沒有指標型別的指標,void *可以指向任何型別的資料。在c99中舉個例子int *p = malloc(sizeof(int)); 可以不寫強制型別轉換,因為malloc返回乙個void *型別的指標,
char**p = malloc(100); 這樣定義一樣可以通過
4.v是char*型別的,那麼取v的位址肯定是char**型別的,所以var是char**型別的。
結構體變數作為函式形參的時候,實際上和普通變數(類似於int之類的)傳參時表現一樣的。所以說結構體變數其實也是普通變數。
用結構體變數作實參時,採取的是「值傳遞」的方式
陣列作為函式引數
一 一維陣列名作函式引數 用陣列名作函式引數,應該在主調函式和被調函式分別定義陣列,例如 void main 在被呼叫函式中宣告了形引數組的大小為10,但在實際中,指定其大小是不起任何作用的,因為c語言編譯對形引數組大小不做檢查,只將實參陣列的首元素位址傳給形引數組。形引數組可以不指定大小,在定義陣...
陣列作為函式引數
陣列元素的作用與變數相當,一般來說,凡是變數可以出現的地方,都可以用陣列元素代替。陣列名也可以做實參和形參,傳遞的是陣列第乙個元素的位址。陣列元素可以用作函式實參,但是不能用作形參,因為形參是在函式被呼叫時臨時分配儲存單元的,不可能為乙個陣列元素單獨分配儲存單元 陣列是乙個整體,在記憶體中佔連續的一...
陣列作為函式引數
做題遇到乙個陣列傳參,發現了一些小問題。1.對於陣列長度來說,用sizeof 陣列名 求出來的並不是陣列的大小,確切的說,不是我要的大小,他是求出了陣列所佔空間的大小。int a 5 int n sizeof a 這樣算出來的n不是想象中的陣列長度5,我得出的結果是20,因為乙個元素佔4個位元組,5...