程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C >> C語言入門知識 >> C語言06指針進階

C語言06指針進階

編輯:C語言入門知識

1 指針的使用

1.1 問題

 

寫一個程序,回顧指針的基本應用,然後測試空指針和野指針,再加上條件判斷進行避免。

1.2 步驟

實現此案例需要按照如下步驟進行。

步驟一:指針的使用代碼如下所示:

#include

void swap(int *a, int *b)
{
int tmp = *a;
*a = *b;
*b = tmp;
}

int main()
{
int a = 10;
int *p = &a;
printf("a = %d\n", *p);

printf("p = %p\n", p);
p = p + 1;
printf("p + 1 = %p\n", p);

p = p - 1;
printf("p - 1 = %p\n", p);

int b = 20;
printf("a = %d, b = %d\n", a, b);
swap(&a, &b);
printf("a = %d, b = %d\n", a, b);

const int *p1 = &a;
//*p1 = 30;
p1 = &b;

int *const p2 = &a;
*p2 = 40;
//p2 = &b;

p = NULL;
if (p)
printf("p = %p\n", p);

return 0;
}
  1.  

上述代碼中,以下代碼:



void swap(int *a, int *b)
{
int tmp = *a;
*a = *b;
*b = tmp;
}
  1.  

定義了一個函數swap1,該函數有兩個參數,為整型指針變量a和b。在該函數中,以下語句:

  1. int tmp = *a;
  2. *a = *b;
  3. *b = tmp;

通過第三個變量tmp,將整型指針變量a和b指向的地址的值進行交換。

上述代碼中,以下代碼:

  1. int a = 10;
  2. int *p = &a;
  3. printf("a = %d\n", *p);

首先,定義一個整型變量a,並初始化為10。

然後,定義一個整型指針變量p,並初始化為變量a的地址。

最後,輸出指針變量p指向的地址的內容。

上述代碼中,以下代碼:

  1. printf("p = %p\n", p);
  2. p = p + 1;
  3. printf("p + 1 = %p\n", p);

首先,輸出指針變量加1前的地址值。

然後,將指針變量p加1。

最後,輸出指針變量加1後的地址值。

上述代碼中,以下代碼:

  1. p = p - 1;
  2. printf("p - 1 = %p\n", p);

首先,將指針變量p減1。

然後,輸出指針變量減1後的地址值。

上述代碼中,以下代碼:

  1. int b = 20;
  2. printf("a = %d, b = %d\n", a, b);
  3. swap(&a, &b);
  4. printf("a = %d, b = %d\n", a, b);

首先,定義一個整型變量b,並初始化為20。

然後,輸出變量a和b在調用swap函數前的值。

下一步,調用函數swap。

最後,輸出變量a和b在調用swap函數後的值。

上述代碼中,以下代碼:

  1. const int *p1 = &a;
  2. //*p1 = 30;
  3. p1 = &b;

在*號左邊加const關鍵字,鎖定的是指針p1指向的地址的內容,所以第2行是錯誤的而第3行是正確的。

上述代碼中,以下代碼:

  1. int *const p2 = &a;
  2. *p2 = 40;
  3. //p2 = &b;

在*號右邊加const關鍵字,鎖定的是指針p1本身,所以第2行是正確的而第3行是錯誤的。

上述代碼中,以下代碼:

  1. p = NULL;
  2. if (p)
  3. printf("p = %p\n", p);

為防止野指針的出現,在不再使用指針p後,應將其置空,這樣可以通過條件p是否為空來判斷指針是否有效。

1.3 完整代碼

本案例的完整代碼如下所示:

#include

void swap(int *a, int *b)
{
int tmp = *a;
*a = *b;
*b = tmp;
}

int main()
{
int a = 10;
int *p = &a;
printf("a = %d\n", *p);

printf("p = %p\n", p);
p = p + 1;
printf("p + 1 = %p\n", p);

p = p - 1;
printf("p - 1 = %p\n", p);

int b = 20;
printf("a = %d, b = %d\n", a, b);
swap(&a, &b);
printf("a = %d, b = %d\n", a, b);

const int *p1 = &a;
//*p1 = 30;
p1 = &b;

int *const p2 = &a;
*p2 = 40;
//p2 = &b;

p = NULL;
if (p)
printf("p = %p\n", p);

return 0;
}
  1.  

2 二級指針的應用

2.1 問題

使用二級指針操作字符串數組。

2.2 步驟

實現此案例需要按照如下步驟進行。

步驟一:二級指針的應用(指針數組:本質為數組,存放的是指針)

代碼如下所示:

  1. #include
  2.  
  3. int main()
  4. {
  5. char *name[] = {"zhangsan", "lisi", "wangwu", "zhaoliu"};
  6. char **p = name;
  7.  
  8. for (int i = 0; i < 4; i++)
  9. printf("%s\n", p[i]);
  10.  
  11. return 0;
  12. }

上述代碼中,以下代碼:

  1. char *name[] = {"zhangsan", "lisi", "wangwu", "zhaoliu"};

定義一個指針數組name,並初始化為四個字符串。

上述代碼中,以下代碼:

  1. char **p = name;

定義一個二級指針p,並初始化為指針數組名name。

上述代碼中,以下代碼:

  1. for (int i = 0; i < 4; i++)
  2. printf("%s\n", p[i]);

設置循環,將二級指針p指向的字符指針數組內的內容輸出。其中,p等效於name,p[i]等效於name[i]。

2.3 完整代碼

本案例的完整代碼如下所示:

  1. #include
  2.  
  3. int main()
  4. {
  5. char *name[] = {"zhangsan", "lisi", "wangwu", "zhaoliu"};
  6. char **p = name;
  7.  
  8. for (int i = 0; i < 4; i++)
  9. printf("%s\n", p[i]);
  10.  
  11. return 0;
  12. }

3 二級指針的應用(續1)

3.1 問題

定義一個函數,要求實現字符串轉換成int,要求一個字符一個字符的轉換,如果遇到不是數字字符的就返回前面的整數和後面的字符串。

3.2 步驟

實現此案例需要按照如下步驟進行。

步驟一:二級指針的應用(續1)代碼如下所示:

#include

int convert(char **str)
{
int num = 0;
while (**str)
{
if (**str >= '0' && **str <= '9')
num = num * 10 + **str - '0';
else
break;
(*str)++;
}

return num;
}

int main()
{
char str[] = "1234abc";
char *p = str;
printf("%d\n", convert(&p));
printf("%s\n", p);

return 0;
}
  1.  

上述代碼中,以下代碼:

int convert(char **str)
{
int num = 0;
while (**str)
{
if (**str >= '0' && **str <= '9')
num = num * 10 + **str - '0';
else
break;
(*str)++;
}

return num;
}
  1.  

定義一個函數convert,用於將字符串中的前面數字字符轉換成數字並輸出後面的字符串。在該函數中,以下代碼:

  1. int num = 0;

定義一個整型變量num,用於存儲轉換後的數字。在該函數中,以下代碼:

  1. if (**str >= '0' && **str <= '9')
  2. num = num * 10 + **str - '0';

判斷字符**str是否是數字字符,若是,則將其進行轉換。在該函數中,以下代碼:

  1. while (**str)
  2. {
  3. if (**str >= '0' && **str <= '9')
  4. num = num * 10 + **str - '0';
  5. else
  6. break;
  7. (*str)++;
  8. }

設置循環,逐個檢查字符串*str中的每個字符,如果是數字字符,則將其進行轉換。否則,退出循環。在該函數中,以下代碼:

  1. return num;

返回,轉換後的數字。

上述代碼中,以下代碼:

  1. int main()
  2. {
  3. char str[] = "1234abc";
  4. char *p = str;
  5. printf("%d\n", convert(&p));
  6. printf("%s\n", p);
  7.  
  8. return 0;
  9. }

首先定義一個字符數組str,並初始化一個字符串。

然後,定義一個字符指針p,並初始化為字符數組str。

下一步,打印轉換後的數字。

最後,打印剩余的字符。

3.3 完整代碼

本案例的完整代碼如下所示:

#include

int convert(char **str)
{
int num = 0;
while (**str)
{
if (**str >= '0' && **str <= '9')
num = num * 10 + **str - '0';
else
break;
(*str)++;
}

return num;
}

int main()
{
char str[] = "1234abc";
char *p = str;
printf("%d\n", convert(&p));
printf("%s\n", p);

return 0;
}
  1.  

4 void*的基本用法

4.1 問題

定義一個int*,然後賦值給void*,並對void*的基本用法進行測試。

4.2 步驟

實現此案例需要按照如下步驟進行。

步驟一:void*的基本用法

代碼如下所示:

  1. #include
  2.  
  3. int main()
  4. {
  5. int a = 10;
  6. int *p = &a;
  7.  
  8. void *p1 = p;
  9. //*p1 = 20;
  10. *(int*)p1 = 20;
  11. printf("a = %d\n", *(int*)p1);
  12.  
  13. return 0;
  14. }

上述代碼中,以下代碼:

  1. int a = 10;

定義一個整型變量a,並初始化為10。

上述代碼中,以下代碼:

  1. int *p = &a;

定義一個整型指針變量p,並初始化為整型變量a的地址。

上述代碼中,以下代碼:

  1. void *p1 = p;

定義一個萬能指針p1,並初始化為整型指針p的值。萬能指針是可以指向任意數據類型的變量的指針。

上述代碼中,以下代碼:

  1. //*p1 = 20;

萬能指針不能直接用*訪問指針所指向的地址的內容。

上述代碼中,以下代碼:

  1. *(int*)p1 = 20;
  2. printf("a = %d\n", *(int*)p1);

萬能指針必須先轉換成其指向的數據類型後,才能用*訪問指針所指向的地址的內容。

4.3 完整代碼

本案例的完整代碼如下所示:

  1. #include
  2.  
  3. int main()
  4. {
  5. int a = 10;
  6. int *p = &a;
  7.  
  8. void *p1 = p;
  9. //*p1 = 20;
  10. *(int*)p1 = 20;
  11. printf("a = %d\n", *(int*)p1);
  12.  
  13. return 0;
  14. }

5 函數指針的使用

5.1 問題

使用函數指針實現對一組數據實現不同的處理方式。

5.2 步驟

實現此案例需要按照如下步驟進行。

步驟一:函數指針的使用代碼如下所示:



#include

int min(int *buf, int size)
{
int min = buf[0];
for (int i = 0; i < size; i++)
if (buf[i] < min)
min = buf[i];

return min;
}

int max(int *buf, int size)
{
int max = buf[0];
for (int i = 0; i < size; i++)
if (buf[i] > max)
max = buf[i];

return max;
}

int main()
{
int data[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0};
int (*p)(int*, int);

p = min;
printf("data中的最小值是%d\n", p(data, 10));

p = max;
printf("data中的最大值是%d\n", p(data, 10));

return 0;
}
  1.  

上述代碼中,以下代碼:

  1. int min(int *buf, int size)
  2. {
  3. int min = buf[0];
  4. for (int i = 0; i < size; i++)
  5. if (buf[i] < min)
  6. min = buf[i];
  7.  
  8. return min;
  9. }

定義一個函數min,用於求一組數中的最小值。該函數有兩個參數,說明如下:

第一個參數為包含一組數的數組。

第二個參數為數組的個數。

該函數中,以下語句:

  1. int min = buf[0];

定義一個整型變量min,用於保存一組數中的最小值。該函數中,以下語句:

  1. for (int i = 0; i < size; i++)
  2. if (buf[i] < min)
  3. min = buf[i];

遍歷數組,找出最小值。該函數中,以下語句:

  1. return min;

返回最小值。

上述代碼中,以下代碼:

  1. int max(int *buf, int size)
  2. {
  3. int max = buf[0];
  4. for (int i = 0; i < size; i++)
  5. if (buf[i] > max)
  6. max = buf[i];
  7.  
  8. return max;
  9. }

定義一個函數max,用於求一組數中的最大值。該函數有兩個參數,說明如下:

第一個參數為包含一組數的數組。

第二個參數為數組的個數。

該函數中,以下語句:

  1. int max = buf[0];

定義一個整型變量max,用於保存一組數中的最大值。該函數中,以下語句:

  1. for (int i = 0; i < size; i++)
  2. if (buf[i] > max)
  3. max = buf[i];

遍歷數組,找出最大值。該函數中,以下語句:

  1. return max;

返回最大值。

上述代碼中,以下代碼:

  1. int main()
  2. {
  3. int data[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0};

在主函數中,定義一個整型數組data,並初始化為10個整數。

上述代碼中,以下代碼:

  1. int (*p)(int*, int);

定義一個函數指針,該指針指向的函數必須返回整型數,並且包含兩個參數,一個是整型指針變量,另一個是整型變量。

上述代碼中,以下代碼:

  1. p = min;

將函數名min賦值給函數指針p。

注意:賦值時,函數名所對應的函數的返回值和參數類型必須與函數指針要求的一致。

上述代碼中,以下代碼:

  1. printf("data中的最小值是%d\n", p(data, 10));

使用函數指針p調用函數min。

上述代碼中,以下代碼:

  1. p = max;

將函數名max賦值給函數指針p。

上述代碼中,以下代碼:

  1. printf("data中的最大值是%d\n", p(data, 10));

使用函數指針p調用函數max。

5.3 完整代碼

本案例的完整代碼如下所示:

#include

int min(int *buf, int size)
{
int min = buf[0];
for (int i = 0; i < size; i++)
if (buf[i] < min)
min = buf[i];

return min;
}

int max(int *buf, int size)
{
int max = buf[0];
for (int i = 0; i < size; i++)
if (buf[i] > max)
max = buf[i];

return max;
}

int main()
{
int data[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0};
int (*p)(int*, int);

p = min;
printf("data中的最小值是%d\n", p(data, 10));

p = max;
printf("data中的最大值是%d\n", p(data, 10));

return 0;
}
  1.  

6 函數指針的使用(續1)

6.1 問題

利用不同的排序規則排序。

6.2 步驟

實現此案例需要按照如下步驟進行。

步驟一:在主程序中,定義一個數組

代碼如下:

  1. #include
  2.  
  3. int main()
  4. {
  5. int a[10] = {1,2,3,4,5,6,7,8,9,0};
  6.  
  7. return 0;
  8. }

步驟二:定義數組打印函數

代碼如下:

  1. #include
  2.  
  3. void print(int* a, int n)
  4. {
  5. for (int i=0; i printf("%d ", a[i]);
  6. }
  7. printf("\n");
  8. }
  9.  
  10. int main()
  11. {
  12. int a[10] = {1,2,3,4,5,6,7,8,9,0};
  13. print(a, 10);
  14.  
  15. return 0;
  16. }

步驟三:定義帶排序規則的排序函數

排序方法采用冒泡方法。代碼如下:



#include

void print(int* a, int n)
{
for (int i=0; i printf("%d ", a[i]);
}
printf("\n");
}
int rule1(int x, int y)
{
return x - y;
}
void sort(int* a, int n, int (*f)(int, int))
{
for (int i=0; i for (int j=0; j if (f(a[j], a[j+1])>0) {
int t = a[j];
a[j] = a[j+1];
a[j+1] = t;
}
}
}
}
int main()
{
int a[10] = {1,2,3,4,5,6,7,8,9,0};
print(a, 10);

sort(a, 10, rule1);
print(a, 10);

return 0;
}
  1.  

上述代碼中,以下代碼:

  1. int rule1(int x, int y)
  2. {
  3. return x - y;
  4. }

是排序規則,該函數返回形參x與y的差,如果返回值大於0,代表x大於y;如果返回值等於0,代表x等於y;如果返回值小於0,代表x小於y。

上述代碼中,以下代碼:

  1. void sort(int* a, int n, int (*f)(int, int))

是排序函數的函數頭,該函數是一個無返回值的函數,函數名為sort,函數帶有三個形參,第一個形參是一個整型指針變量,它用於接收需要排序的數據;第二個形參是一個整型變量,它用於接收需要排序的數據的個數;第三個形參是一個函數的指針變量,int表示該函數指針變量指向的函數的返回值為整型,f為函數指針變量的變量名,(int,int)代表該函數指針變量指向的函數有兩個形參。

在主函數中,使用以下代碼調用sort函數:

  1. sort(a, 10, rule1);

其中,第一個實參a為數組a的數組名,第二個實參10為數組a的數組長度,第三個實參rule1為函數名,該函數為排序規則。

上述代碼中,以下代碼:

  1. if (f(a[j], a[j+1])>0) {
  2. int t = a[j];
  3. a[j] = a[j+1];
  4. a[j+1] = t;
  5. }

是使用函數指針調用函數,指針變量f作為形參,接收實參傳遞過來的函數的入口地址,即rule1函數,使用f(a[j],a[j+1])調用rule1函數,其中,a[j]和a[j+1]是函數指針變量f指向的函數的兩個實參,即函數rule1的兩個實參。

步驟四:定義其它排序規則函數代碼如下:



#include

void print(int* a, int n)
{
for (int i=0; i printf("%d ", a[i]);
}
printf("\n");
}
int rule1(int x, int y)
{
return x - y;
}
int rule2(int x, int y)
{
return y - x;
}
int rule3(int x, int y)
{
return x%3 - y%3;
}
void sort(int* a, int n, int (*f)(int, int))
{
for (int i=0; i for (int j=0; j if (f(a[j], a[j+1])>0) {
int t = a[j];
a[j] = a[j+1];
a[j+1] = t;
}
}
}
}
int main()
{
int a[10] = {1,2,3,4,5,6,7,8,9,0};
print(a, 10);

sort(a, 10, rule1);
print(a, 10);

sort(a, 10, rule2);
print(a, 10);

sort(a, 10, rule3);
print(a, 10);

return 0;
}
  1.  

6.3 完整代碼


#include

void print(int* a, int n)
{
for (int i=0; i printf("%d ", a[i]);
}
printf("\n");
}
int rule1(int x, int y)
{
return x - y;
}
int rule2(int x, int y)
{
return y - x;
}
int rule3(int x, int y)
{
return x%3 - y%3;
}
void sort(int* a, int n, int (*f)(int, int))
{
for (int i=0; i for (int j=0; j if (f(a[j], a[j+1])>0) {
int t = a[j];
a[j] = a[j+1];
a[j+1] = t;
}
}
}
}
int main()
{
int a[10] = {1,2,3,4,5,6,7,8,9,0};
print(a, 10);

sort(a, 10, rule1);
print(a, 10);

sort(a, 10, rule2);
print(a, 10);

sort(a, 10, rule3);
print(a, 10);

return 0;
}
  1.  
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved