函數指針
(一)、1、函數的地址 = &函數名(或者直接可以等於函數名,但較多用的還是&函數名)
2、函數名是指針常量,保存的是函數入口的地址
(二)、例子
int func(int num)
{
printf("num == %d\n",num);
}
int main()
{
func(5);
int (*p_func)(int); ☆
printf("%d\n",sizeof(p_func)); △
}
1、函數名只有一個字節:如果將☆處修改爲:int *p_func(int),則還是一個字節,如果將 △ 處修改爲sizeof(func)
還是一個字節
2、函數指針爲四個字節:如果將☆ 處修改爲int (*p_func)(int);結果爲4,將△ 修改爲sizeof(&func)結果爲4
3、函數名是什麼?是函數的入口地址
函數的入口地址是什麼?&函數名
(以上兩者並不矛盾,只是兩種不同的表述)
函數指針數組
(一)、定義:int (*p_func_array[3])(int);
(二)、初始化:
假設前面已經定義了三個調用函數func1,func2,func3
p_func_array[0] = &func1;
p_func_array[1] = &func2;
p_func_array[2] = &func3;
(三)、調用:
假設要每個函數要調用30次:
for(i = 0;i < 30;i++)
for(j = 0;j < 30;j++)
{
p_func_array[j](5);
}
回調函數
void func4(int (*p_func)(int)){
p_func(5);
}
int main()
{
func4(&func1)
func4(&func2)
func4(&func3)
}
回調函數的好處是統一接口,增強擴展性
函數
(一)、函數可以不加形參名,比如:void swap_int(int,int);但是最好加上(二)、函數接口(就是一個函數)的三大要素
1、函數原型
2、函數的說明文檔,其中包括函數的功能,函數形參的作用,函數的返回值
六、傳值和傳參:
例子:
#include <stdio.h>
void exchange(int *p1,int *p2)
{
int temp;
temp = *p1;
*p1 = *p2;
*p2 = temp;
}
int main()
{
int num1;
int num2;
printf("Please enter num1:");
scanf("%d",&num1);
printf("Please enter num2:");
scanf("%d",&num2);
exchange(&num1,&num2);
printf("The result is:num1 == %d,num2 == %d\n",num1,num2);
return 0;
}
假設用的是傳值,則可假設棧空間內存分配如下:
函數的調用過程:
1、通過函數名找到函數的入口地址
2、給函數的形參分配空間
3、傳參,將實參傳給形參
4、執行函數體結構語句,交換temp,a,b
5、函數返回值返回
6、釋放棧空間
7、再打印num1,num2
傳值不能進行交換的原因是返回值執行過後,棧空間已經被釋放,根本沒有進行交換
假設用的傳地址
對x,y指向的內存空間進行操作,即對a,b直接進行操作
例子:
void add_ptr(char &ptr)
{
ptr++;
}
int main()
{
char *ptr = "hello world";
add_ptr(ptr);
printf("%s",ptr);
}
ptr並不是指針本身的地址,而是h的地址,是ptr的內容,要傳&ptr,對其地址進行操作,形參需要用指針的指針來接:**ptr
傳參總結:
1、只讀(想對操作數只使用不修改)實參變量對應空間的值傳實參變量名。
2、寫(想對操作數使用並且修改)實參變量對應空間的值傳實參變量的地址。
另外:
1、char a[] ="hello world";可以修改因爲數組分配在棧空間
2、char *a = "hello world";不可修改因爲分配在全局變量區的or段
傳出參數和傳入參數
(一)、傳出參數:output
傳入參數:input
(二)、例子:
int continue_max(char *src,char *dest)
{
return max;
…………
}
int main()
{
char *src = "dqihwdcb1234365fsdnr";
char dest[100];
continue_max(dest,src);
return 0;
}
先定義一個空的字符數組dest,在經過函數填充,可帶出值,dest爲傳出參數,src爲傳入參數
返回值
(一)、爲什麼要在主函數最後加return 0?通知系統程序正常結束,不用再做判斷
char *func()
{
char ptr[100] = "hello world";
return ptr;
}
int main()
{
char *ptr = func();
printf("%s\n",ptr);
return 0;
}
不行,打印之前棧空間已經被釋放
可以定義:static char ptr[] = "hello world";
或者:char *ptr = "hello world";
exit函數
1、exit(1):結束整個程序並退出(括號內可以加任意值,都可以退出)2、要看在哪一步退出?用echo$?(命令行模式下),打印當前程序結束的返回值
如果在exit(1)處結束的,則輸出1,如果在exit(2)處結束的,則輸出2,以此類推。
3、但是隻打印一二完全沒有代表性,可以這樣:
if(num == 5)
{
printf("PASSWD ERROR!");
exit(1);
}
4、爲了增加程序的可讀性,可以用宏定義:
#define PASSWD_ERROR 2
{
exit(PASSWD_ERROR);
}