指針及遞歸函數概述
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; }