1.指針函數和函數指針
1.1 指針函數
指針函數是函數,函數的返回值是指針
- 不能返回局部變量的地址
- 指針函數返回的地址可以作為下一個函數調用的參數
?1.2 函數指針
函數指針是指針,指針指向一個函數
#include <stdio.h>int Add(int x, int y) {return x + y; }int Sub(int x, int y) {return x - y; }int Mul(int x, int y) {return x * y; }int Div(int x, int y) {return x / y; }int jisuanqi(int x, int y, int (*p)(int x, int y)) {return p(x,y); }int main(void) {int (*p)(int x, int y) = NULL;int num1 = 0;int num2 = 0;char op = 0;scanf("%d %c%d",&num1,&op,&num2);switch(op){case '+':p = Add;break;case '-':p = Sub;break;case '*':p = Mul;break;case '/':p = Div;break;}printf("Ret = %d\n",jisuanqi(num1, num2, p)); //p指向某函數return 0; }
2.二級指針
2.1 定義
二級指針是指向一級指針變量的指針
int **q;定義一個指針變量q,占8個字節空間,指向ige指針變量空間,即指向一級指針變量的指針
2.2 使用場景
1.函數體內部想修改函數體外部指針變量的值時,需要傳遞指針變量的地址即二級指針
2.指針數組傳參,數組的數組名是指向數組第一個元素的指針,第一個元素是指針,所以數組名為指向指針的指針即二級指針
3.指針數組和數組指針
3.1 定義
1.指針數組:是數組,數組的每個元素是指針
2.數組指針:是指針,指針指向整個數組
int *a[5]; 定義一個數組,占40個字節空間,數組名為a,每個元素都是int *型的指針int (*a)[5]; 定義一個指針,占8個字節,指針變量名為a,是指向數組為20個字節空間的指針
3.2 指針數組
int *a[5]; char *pstr[5];
- 存放字符串使用字符型數組,操作字符串使用指針
- 存放字符串數組使用字符型二維數組,操作字符串數組使用指針數組
3.3 利用指針數組操作二維數組中的字符串實現排序
- 二維數組存放字符串數組
- 指針數組元素變化代替二維數組字符串變化,提高程序效率
?
3.4 數組指針
- 對一維數組數組名&:值不變 ,類型升級為指向整個數組的指針
- 對指針數組*:值不變,類型降級為指向數組第一個元素的指針
int a[5] = {1,2,3,4,5};a == &a[0];a == int *
注意:兩種情況a不能理解為int *
- sizeof:獲得數據類型、變量所占字節
- &:&int * -> int **? ?&a -> int (*p)[5]
?第十一行:&a+1指向下一個數組的首地址,再強制轉換為int *型,再減一即減去四個字節,回到數組a的第五個元素,故打印出來為5
?3.5 數組指針的使用場景
?1.一維數組和指針的關系
- 數組的數組名是指向數組第一個元素的指針常量
int a[5] = {1,2,3,4,5}; int *p = NULL;p = &a[0]; p = a;a == &a[0];a[n] == *(a+n) == *(p+n) == p[n]
2.二維數組和指針的關系
- 數組的數組名是指向數組第一行的數組指針
int a[2][3] = {1,2,3,4,5,6}; int *p = NULL; int (*q)[3] = NULL;p = &a[0][0]; p = a[0]; p = *a; q = a;a:指向數組第一行元素的數組指針 int (*)[3] a[0]:指向a[0][0]的指針 int * a[1]:指向a[1][0]的指針 int *訪問數組第m行第n列元素的方式: a[m][n] *(a[m]+n) *(*(a+m)+n) *(p+m*N+n) *(*(q+m)+n) *(q[m]+n) q[m][n]
作業
1.封裝一個函數,將字符串“12345”轉換成整形12345
2.封裝函數實現mystrlen,mystrcpy,mystrcat,mystrcmp功能
3.從終端接收五個字符串,對他們排序后輸出
#include <stdio.h>int ToNum(char *a)
{int i = 0;int num[32] = {0};int sum = 0;while(*a != '\0'){num[i] = *a - '0';sum = sum * 10 + num[i];i++;a++;}return sum;
}int main(void)
{char a[32] = "12345";printf("outnum = %d\n",ToNum(a));return 0;
}
#include <stdio.h>int mystrlen(const char *str)
{int i = 0;while(*str != '\0'){str++;i++;}return i;
}char *mystrcpy(const char *pstr, char *pret)
{char *ret = pret;while(*pstr != '\0'){*pret = *pstr;pret++;pstr++;}return ret;
}int mystrcmp(const char *pstr, const char *pdst)
{while(*pstr == *pdst){if(*pstr == '\0'){return 0;}pstr++;pdst++;}return *pstr - *pdst;
}char *mystrcat(char *pstr, const char *pdst)
{int len = mystrlen(pstr);char *str = pstr;pstr += len;while(*pdst != '\0'){*pstr = *pdst;pstr++;pdst++;}return str;
}int main(void)
{char str[100] = {0};char dst[100] = {0};char ret[100] = {0};gets(str);gets(dst);printf("strlen:len_str = %d\n",mystrlen(str));printf("strcpy:ret_cpy_str = %s\n",mystrcpy(str,ret));if(mystrcmp(str,dst) > 0){printf("str > cmp\n");}else if(mystrcmp(str,dst) == 0){printf("str = dst\n");}else{printf("str < dst\n");}printf("strcat:new_str = %s\n",mystrcat(str,dst));return 0;
}
#include <stdio.h>
#include <string.h>int main(void)
{char a[5][100] = {0};char *pstr[5] = {a[0], a[1], a[2], a[3], a[4]};char tmp[100] = {0};int i = 0;int j = 0;for(i = 0; i < 5; i++){gets(a[i]);}for(j = 0; j < 4; j++){for(i = 0; i < 4-j; i++){if(strcmp(pstr[i], pstr[i+1]) > 0){strcpy(tmp,pstr[i]);strcpy(pstr[i], pstr[i+1]);strcpy(pstr[i+1], tmp);}}}for(i = 0; i < 5; i++){printf("a[%d] = %s\n",i,a[i]);}return 0;
}