標題: 函數指針 [打印本頁]
作者: bibi 時間: 2015-4-18 20:37
標題: 函數指針
函數指針
定義 void (*FunP)(int) ; //也可以寫成 void (*FunP)(int x);
就象某一數據變量的內存地址可以存儲在相應的指針變量中一樣,函數的首地址也以存儲在某個函數指針變量里的。這樣,我就可以通過這個函數指針變量來調用所指向的函數了。
1、C語言面向對象的實現
libvirt是Linux下的一個虛擬化管理API庫,里面用到很多這樣的東東。。。。
2、qsort函數
qsort包含在<stdlib.h>頭文件中,此函數根據你給的比較條件進行快速排序,通過指針移動實現排序。排序之后的結果仍然放在原數組中。使用qsort函數必須自己寫一個比較函數compar。
int compar (const void* p1, const void* p2);
函數原型:
void qsort (void* base, size_t num, size_t size, int (*compar)(const void*,const void*));
該函數第三個參數就是一個函數指針。。
#include <stdio.h>
#include <stdlib.h>
int values[] = { 40, 10, 100, 90, 20, 25 };
int compare (const void * a, const void * b) // 升序排列
{
return ( *(int*)a - *(int*)b );
}
int main(int argc, char *argv[])
{
int n;
qsort (values, 6, sizeof(int), compare);
for (n=0; n<6; n++)
printf ("%d ",values[n]);
getchar();
return 0;
}
3、打印函數值,使用函數指針
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
/* tabulates values of trigonometric functions */
void tabulate(double (*f)(double), double first, double last, double inc)
{
double x;
int i, num_intervals;
num_intervals = ceil((last - first)/inc);
for (i = 0; i<=num_intervals; i++)
{
x = first + i*inc;
printf("%10.5f %10.5f\n", x, (*f)(x));
}
}
int main(int argc, char *argv[])
{
double initial = 0.0f,
final = 1.0f,
inc = 0.05f;
printf("\n x cos(x)\n");
tabulate(cos, initial, final, inc);
getchar();
return 0;
}

數組指針
定義 int (*p)[n];
()優先級高,首先說明p是一個指針,指向一個整型的一維數組,這個一維數組的長度是n,也可以說是p的步長。也就是說執行p+1時,p要跨過n個整型數據的長度。
如要將二維數組賦給一指針,應這樣賦值:
int a[4][6];
int (*p)[6]; //該語句是定義一個數組指針,指向的類型是包含4個元素的一維數組。
p=a; //將該二維數組的首地址賦給p,也就是a[0]或&a[0][0]
p++; //該語句執行過后,也就是p=p+1;p跨過行a[0][]指向了行a[1][]
所以數組指針也稱指向一維數組的指針,亦稱行指針。
===============例子==============================
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int a[4][6];
int (*p)[6];
p = a; // 數組指針指向二維數組
// a數組元素可用以下五種表達式來引用:
// (1)a[j](2)*(a+j) (3)*(*(a+i)+j)(4)(*(a+i))[j](5)*(&a[0][0]+4*i+j)
*(*(p+1)+2) = 4;
// 此處加斷點
return 0;
}
指針數組
定義 int *p[n];
[]優先級高,先與p結合成為一個數組,再由int*說明這是一個整型指針數組,它有n個指針類型的數組元素。這里執行p+1是錯誤的,這樣賦值也是錯誤的:p=a;因為p是個不可知的表示,只存在p[0]、p[1]、p[2]...p[n-1],而且它們分別是指針變量可以用來存放變量地址。但可以這樣 *p=a; 這里*p表示指針數組第一個元素的值,a的首地址的值。
如要將二維數組賦給一指針數組:
int *p[3];
int a[3][4];
for(i=0;i<3;i++)
p=a;
這里int *p[3] 表示一個一維數組內存放著三個指針變量,分別是p[0]、p[1]、p[2]
所以要分別賦值。
這樣兩者的區別就豁然開朗了,數組指針只是一個指針變量,似乎是C語言里專門用來指向二維數組的,它占有內存中一個指針的存儲空間。指針數組是多個指針變量,以數組形式存在內存當中,占有多個指針的存儲空間。
還需要說明的一點就是,同時用來指向二維數組時,其引用和用數組名引用都是一樣的。
比如要表示數組中i行j列一個元素:
*(p+j)、*(*(p+i)+j)、(*(p+i))[j]、p[j]
優先級:()>[]>*
指針函數
指針函數是指帶指針的函數,即本質是一個函數。函數返回類型是某一類型的指針
類型標識符 *函數名(參數表)
int *f(x,y);
首先它是一個函數,只不過這個函數的返回值是一個地址值。函數返回值必須用同類型的指針變量來接受,也就是說,指針函數一定有函數返回值,而且,在主調函數中,函數返回值必須賦給同類型的指針變量。
使用二維指針 ,計算圖像數據的平均值(刪減)
// Raw video process class header file
//
#pragma once
#include "KMemDataStream.h"
// 處理數據流
class Rprocess : KMemDataStream
{
public:
Rprocess(void* pMem, size_t size/* 數據緩存大小 */, bool freeOnClose = false);
Rprocess(size_t size/* 數據緩存大小 */, bool freeOnClose = false);// Create a memory stream
~Rprocess(void);
void CommInit();
// other code
// 處理過程
void process();
protected:
// Multi-frame average
void MFA_ImageAdd8(BYTE *pData/* in */, BYTE* pResult/* out */, int w, int h, int stride);
private:
int m_nWidth;
int m_nHeight;
int m_bitcount;
BYTE **val; // 圖像緩存,用于幀平均法設計
int m, // m個緩存指針
n; // 每個指針指向的長度1024*576
BYTE *m_ptmp; // 指向初始的val[0]地址,只是用于釋放內存,因為程序的運行過程,val地址被反復交換,釋放內存的時候造成bug
void allocateMemory (const int m_,const int n_);
void releaseMemory ();
};
//=========================實現文件==================================
#include "StdAfx.h"
#include "Rprocess.h"
#define _N_num 4
#define _Buf_length 589824
Rprocess::Rprocess(void* pMem, size_t size, bool freeOnClose/* = false*/) : KMemDataStream(pMem, size, freeOnClose)
{
m_pImage = (BYTE *)m_lpData;
CommInit();
}
Rprocess::Rprocess(size_t size, bool freeOnClose /*= false*/) : KMemDataStream(size, freeOnClose)
{
m_pImage = (BYTE *)m_lpData;
CommInit();
}
Rprocess::~Rprocess(void)
{
releaseMemory();
}
void Rprocess::CommInit()
{
m_nWidth = 1024;
m_nHeight = 576;
m_bitcount = 8;
m = 0;
n = 0;
val = 0;
allocateMemory(_N_num, _Buf_length);
}
//////////////////////////////////////////////////////////////////////////
// 處理8位灰度圖像, 該程序需要很大的優化。。。。。
void Rprocess::process()
{
//other code
BYTE *image = (BYTE *)GetBits();
//各級長寬
int* pnMatrixInfo = new int[(nLevel+2)*3];
pnMatrixInfo[0] = nLevel;
pnMatrixInfo[1] = GetWidth() ; //w
pnMatrixInfo[2] = GetHeight() ; //h
pnMatrixInfo[3] = GetPitch(); //stride
//灰度內存塊
BYTE *pPixelsGrey = new BYTE[pnMatrixInfo[2] * pnMatrixInfo[3]];
// 取圖像的平均值
MFA_ImageAdd8(image, pPixelsGrey, pnMatrixInfo[1], pnMatrixInfo[2], pnMatrixInfo[3]);
delete pPixelsGrey;
}
// 功能:幀平均算法
// 參數:
//pData 要添加的新的數據幀
//pResult 返回的平均值
void Rprocess::MFA_ImageAdd8(BYTE *pData/* in */, BYTE* pResult/* out */, int w, int h, int stride)
{
int pixelByte8 = 1 ;
BYTE* _pixels_R = pResult;
int _strideoff = stride - pixelByte8 * w;
unsigned short _letf=0;
unsigned short _top=0;
unsigned short _right = w;
unsigned short _bottom = h;
// 將pData添加到val緩沖區,m=4
BYTE *tmp = val[0];// 紀錄val[0]的地址, 并且向里面復制數據
memcpy(tmp, pData, n*sizeof(BYTE));
for (int i = 1; i < m; i++) // i=1,2,3 指針前移
{
val[i-1] = val;
}
val[m-1] = tmp;//
// 計算平均值
int x, y;
int k = 0;
for(y = _top; y < _bottom; y++)
{
for(x = _letf; x < _right; x++)
{
int nResult = 0;
// 取出平均值過來
for (int j = 0; j < m; ++j) // 0 1 2 3
{
//int i = y*stride + x;
//ASSERT(i <= n);
nResult += val[j][k]; // 這句話有語病
}
nResult = nResult / m;
*_pixels_R = (BYTE)nResult;
k++;
_pixels_R++;
}
_pixels_R += _strideoff;
k += _strideoff;
}
return;
}
void Rprocess::allocateMemory (const int m_,const int n_)
{
TRACE2("allocate memory, m=%d, n=%d\n\n", m_, n_);
m = abs(m_); n = abs(n_);
if (m == 0 || n == 0) {
val = 0;
return;
}
val = (BYTE **)malloc(m*sizeof(BYTE*));
val[0] = (BYTE*)calloc(m*n,sizeof(BYTE));
memcpy(val[0], m_pImage, n*sizeof(BYTE)); // copy data to buffer
m_ptmp = val[0];// 釋放標志
for(int i=1; i<m; i++)
{
val = val[i-1] + n;
ASSERT(val);
memcpy(val, m_pImage, n*sizeof(BYTE));// 用初始的圖像填充開辟的緩沖區
}
}
void Rprocess::releaseMemory ()
{
if (val != 0 ) {
//free(val[0]); // 出現偶然bug
free(m_ptmp);
free(val);
val = 0;
}
}
歡迎光臨 (http://www.zg4o1577.cn/bbs/) |
Powered by Discuz! X3.1 |
主站蜘蛛池模板:
亚洲视频www
|
久久亚洲国产
|
日韩在线视频一区
|
国产精品伦一区二区三级视频
|
99久久精品免费看国产小宝寻花
|
免费在线视频一区二区
|
日韩视频一区在线观看
|
日日操夜夜操天天操
|
国产成人精品一区二区三区四区
|
天天成人综合网
|
国产麻豆乱码精品一区二区三区
|
国产一二三区精品视频
|
好好的日在线视频
|
欧美寡妇偷汉性猛交
|
一区二区av
|
国产剧情一区
|
九一在线|
天天操综合网
|
久久久国产精品视频
|
久久精品国产免费
|
精品国产一区二区久久
|
毛片在线视频
|
中文字幕精
|
国产日韩精品一区
|
欧美精品在线免费
|
成人深夜小视频
|
91中文字幕
|
秋霞电影院午夜伦
|
午夜精品久久久久久久久久久久
|
欧美亚洲高清
|
av网站免费看
|
成人欧美日韩一区二区三区
|
欧美黄色片
|
亚洲精品日日夜夜
|
中文字幕亚洲精品
|
国产精品久久久久无码av
|
久久尤物免费一区二区三区
|
亚洲精品视频在线
|
久久国产精品-久久精品
|
六月色婷
|
日韩中文字幕在线播放
|