C/C++語言中引入了指針,使得程序能夠直接訪問內(nèi)存地址,使得很多復雜的操作變得簡單,同時也提高了程序的運行效率。指針即是地址,但是地址卻是通過指針變量來存儲的。這就好比我們的教室,每個教室都有一個房間號,一個房間號也對應著一間教室,此處的教室就是固定的地址(指針),其地址是通過房間號(指針變量)來表示的。地址就是指針,而房間號就是指針變量。
筆者在《C/C++指針入門詳解(一)》一文中給出了指針的基礎(chǔ)知識和基本用法。詳見鏈接:
https://blog.csdn.net/sunnyoldman001/article/details/128061186?spm=1001.2014.3001.5502
本文給出了有關(guān)指針的更多應用場景及示例,例如函數(shù)指針、文件指針、更換數(shù)據(jù)類型、雙指針等等。
1.根據(jù)需要改變內(nèi)存中數(shù)據(jù)的數(shù)據(jù)類型
例1:在位域中,經(jīng)常會根據(jù)需要把某單一變量存儲到內(nèi)存中,然后根據(jù)需要將其轉(zhuǎn)換為結(jié)構(gòu)體類型,進而可以進行一些復雜的操作,例如提取某個或某幾個比特位上的數(shù)據(jù)等。
示例代碼:
#include"stdio.h"
struct weiyu
{unsigned char a:5;
unsigned char b:2;
unsigned char c:4;
};
int main()
{weiyu *p;
unsigned short val = 1521;//10111110001
//將存儲變量a的地址賦值給指針變量p,并將內(nèi)存中的數(shù)據(jù)類型改換為結(jié)構(gòu)體
p = (struct weiyu*)&val;
printf("weiyu a = %d\n", p->a);
printf("weiyu b = %d\n", p->b);
printf("weiyu c = %d\n", p->c);
return 0;
}
運行結(jié)果:
說明:
本例中將低比特位0 ~ 4上的“10001”賦值為結(jié)構(gòu)體成員a,因此a的值是17,將比特位5 ~ 6上的“11”賦值為結(jié)構(gòu)體成員b,因此b的值是3,將比特位8 ~ 11上的“101”賦值為結(jié)構(gòu)體成員c,因此c的值是5。比特位7上的“1”被舍棄。
2.文件指針
例2:打開某一文本文本,向屏幕輸出該文件內(nèi)容,并統(tǒng)計字符‘e’出現(xiàn)的次數(shù)。
參考代碼:
#include "stdio.h"
#include "stdlib.h"
int main()
{FILE *fp;//文件指針
char ch;
int count = 0;
//打開文件,并用文件指針fp指向文件的首地址
if( ( fp = fopen("file.cpp", "rt" ) ) == NULL )
{printf("Cannot open file!");
exit(1);
}
ch = fgetc(fp);//從文件中讀取一個字符
while( ch != EOF )
{putchar(ch);//向屏幕輸出讀到的字符
if( ch == 'e' )
{ count++;
}
ch = fgetc(fp);
}
fclose(fp);//關(guān)閉文件
printf( "\n字母e出現(xiàn)的次數(shù):%d\n", count );
return 0;
}
運行結(jié)果:
3.雙指針
指針可以用來實現(xiàn)函數(shù)的雙向傳值功能,其原理類似于在把指針作為地址(可以看成是一個教室),地址里的內(nèi)容可以根據(jù)需要進行修改(教室里的學生可以更換),以實現(xiàn)雙向傳值的功能。但是地址本身是不可以更改的(你不能把教室搬家)。但是有些時候還真就是希望可以把地址搬家,那么怎么辦呢?其實可以利用雙指針來實現(xiàn),也就是把地址放入新的地址中,類似于在一個教學樓里,在房間號已經(jīng)固定的情況下,為了滿足某一種需要,而重新給教室分配房間號一樣,如果把教室看成地址的話,那么教學樓就是一個二級地址,用來存儲教室。當把教學樓作為地址單函數(shù)參數(shù)的話,那么該地址中的內(nèi)容就可以根據(jù)需要隨意修改了,這其實就是雙指針。
例3:利用函數(shù)參數(shù)的形式交換兩個指針的地址
參考代碼:
#include"stdio.h"
#include"malloc.h"
void swap( int **p,int **q );
int main()
{int a, b, **p, **q;
//首先給p和q分配空間,存儲的是地址的地址
p = (int **)malloc( sizeof(int) );
q = (int **)malloc( sizeof(int) );
a = 1;
b = 2;
*p = &a;
*q = &b;
printf( "交換前地址:p: %x, q: %x\n", *p, *q );
printf( "交換前的數(shù)據(jù):p: %d, q: %d\n", **p, **q );
swap( p, q );
printf( "交換后地址:p: %x, q: %x\n", *p, *q );
printf( "交換后的數(shù)據(jù):p: %d, q: %d\n", **p, **q );
return 0;
}
//將p和q所指向地址中存儲的地址進行交換
void swap( int **p,int **q )
{int *temp;
temp = *p;
*p = *q;
*q = temp;
}
運行結(jié)果:
說明:此用法比較復雜,在雙指針被使用前必須要初始化。用時要慎重?。?!
4.函數(shù)指針
C語言中的函數(shù)指針是指向函數(shù)的指針變量。用法類似于C++的模板。
定義函數(shù)指針的一般形式為:
類型說明符 (*函數(shù)名)(形參表) ;
此函數(shù)僅僅是一個聲明,無函數(shù)體。此處的“函數(shù)名”嚴格來說只是一個指針,它指向了某個函數(shù)的入口地址。
例4:利用函數(shù)指針實現(xiàn)求兩個整數(shù)的大值、最小值、和。
參考的代碼:
#include"stdio.h"
int max( int a, int b );
int min( int a, int b );
int sum( int a, int b );
int (*f)(int a, int b);
int main()
{int a = 1, b = 2;
f = max;
int c = (*f)( a, b );
printf( "%2d 和 %2d 的大值: %2d\n", a, b, c );
f = min;
c = (*f)( a, b );
printf( "%2d 和 %2d 的最小值: %2d\n", a, b, c );
f = sum;
c = (*f)( a, b );
printf( "%2d 和 %2d 的和: %2d\n", a, b, c );
return 0;
}
int max( int a, int b )
{return a >b ? a : b;
}
int min( int a, int b )
{return a >b ? b : a;
}
int sum( int a, int b )
{return a + b;
}
運行結(jié)果:
5.指針數(shù)組
指針數(shù)組是指數(shù)組中的元素都是指針變量,即數(shù)組的元素都是地址。常用于字符串數(shù)組的操作。
指針數(shù)組的定義如下:
類型說明符 *指針變量名[長度];
例5:給定5個字符串,然后統(tǒng)計字符串的大長度。
參考代碼:
#include"stdio.h"
#include"string.h"
#define N 5
int main()
{int i, length, len;
char *str[N] = {"C/C++", "computer", "programming", "pragma", "once" };
char *maxLenStr;
length = 0;
for( i=0; iif( ( len = strlen( str[i] ) ) >length )
{ length = len;
maxLenStr = str[i];
}
}
printf( "最長字符串是:%s, 其長度為:%d\n", maxLenStr, length );
return 0;
}
運行結(jié)果:
說明:在第7行代碼,字符串數(shù)組中的每個元素均是字符串常量,將其賦值給左端的指針數(shù)組,在不同C語言編譯器中對其處理的結(jié)果是相同的,但是會出現(xiàn)告警信息:將字符串常量賦值為字符指針變量。這是由指針數(shù)組中的元素沒有進行初始化導致的。
——————————————————————
未完待續(xù)!
你是否還在尋找穩(wěn)定的海外服務器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準確流量調(diào)度確保服務器高可用性,企業(yè)級服務器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧