指針及遞歸函數概述
1.認識指針
【地址】內存每個字節都有一個數字的編號,稱為地址。
【指針】指針是一個變量,用來裝地址。
【注】指針是地址變量,地址是指針常量
2.指針的作用
①同一個棧內的數據處理,使用指針沒有意義;
②指針就是用來訪問棧外面的空間;
③指針就是用來跨棧的
3.空指針和野指針
【空指針】值為0的指針(NULL)
【野指針】指針的值未知,或者說指向了未知的地方
【泛型指針】void *p
4.函數的遞歸調用
調用自身的函數,稱為遞歸函數,調用自身的行為稱為遞歸調用?【注】函數的遞歸調用只能用於靜態的數據運算,如果是動態數據,風險過高,容易崩潰。
方法
①首先確定臨界值,即無需計算,獲得的值;
②找這一次和上一次的關系;
③假設當前函數已經可以使用,調用自身計算上一次的運行結果,再寫出這次的運行結果
指針及遞歸函數講解
1.遞歸函數
//棧空間溢出
int func(int n) {
if (n == 1) {
return 1;
}
return func(n - 1) + n;
}
//任何函數都可以調用任何函數
int main(int argc, const char * argv[]) {
printf("%d",func(4));
return 0;
}
2.認識指針
當一個指針p,裝了變量a的地址,稱為p指向了a。
//取變量的地址,取的是變量的首地址。 int a = 5; int *p = &a; *p = a;
【注】p:根據p裡面存的地址,找到這個地址,取這個類型的大小,它是一個運算,相當於&a,找到地址為&a的那個字節,取*p個字節,得到一個變量,就是a。舉個例子:p就相當於天貓,a是我們,p=&a是填寫物流地址的過程,*p就是送貨,整個過程為注冊—郵寄地址—送貨的過程
int main(int argc, const char * argv[]) {
//聲明整型變量a,存儲數字5,用相應指針指向a,通過指針,將a修改成6.
int a = 5;
int * p;
//用相應指針指向a
p = &a;
// 通過指針,將a修改成6.
*p = 6;
printf("a=%d\n",a);
return 0;
}
2.指針的加法運算:?指針+1,加一個*p的字節數,加一個p指向變量的字節數
int main(int argc, const char * argv[]) {
char c;
int a;
int *p = &a;
//p+1與p相比增加了4字節
printf("%p\n",p);
printf("%p\n",p+1);
//q+1比q增加了一個字節
char *q = &c;
printf("%p\n",q);
printf("%p\n",q+1);
return 0;
}
3.指針與數組:數組是指針的常量,指針是數組的變量
int main(int argc, const char * argv[]) {
int a[5] = {1,3,5,7,10};
//數組名是數組首元素地址
int * p = &a[0];
printf("p = %p\n",p);
printf("p+1 = %p\n",p+1);
//取到首元素
*p = a[0];
printf("*p = %d\n",*p);
printf("*(p+1)=%d\n",*(p+1));
printf("*p+1=%d",*p+1);
//指針+1,加的是一個*p所指向類型的字節大小
*(p+1) = a[1];
//數組名是數組首元素地址
p = a;
return 0;
}
小練習
編寫函數,將兩個整型變量的和,賦給第一個變量,差賦給第二個變量。
參考答案(一萬個讀者有一萬個哈姆雷特,一萬個程序員有一萬種編碼風格,答案僅供參考)
編寫函數,將兩個整型變量的和,賦給第一個變量,差賦給第二個變量。
void entrust(int * a,int * b) {
int c = *a;
*a = *a + *b;
*b = c - *b;
}
int main(int argc, const char * argv[]) {
int p = 5;
int q = 2;
entrust(&p, &q);
return 0;
}