指针
指针是一个变量,其值为另一个变量的地址
在变量声明的时候,如果没有确切的地址可以赋值,一般为指针变量赋一个 NULL 值。赋为 NULL 值的指针被称为空指针。NULL 指针是一个定义在标准库中的值为零的常量。
int *ip; /* 一个整型的指针 */
double *dp; /* 一个 double 型的指针 */
float *fp; /* 一个浮点型的指针 */
char *ch; /* 一个字符型的指针 */
#include
int main()
{
int var = 20;
int *ip;
ip = &var;
printf("&var:\t%p\n", &var);
printf("ip:\t%p\n", ip);
printf("var:\t%d\n", var);
printf("*ip:\t%d\n", *ip);
return 0;
}
output:
&var: 0060FF08
ip: 0060FF08
var: 20
*ip: 20
数组指针
数组不能递增,而数组的指针可以递增
通过递增变量指针,可以顺序访问数组中每一个元素
#include
const int MAX = 3;
int main ()
{
int var[] = {10, 100, 200};
int i, *ptr;
/* 指针中的数组地址 */
ptr = var;
for ( i = 0; i < MAX; i++)
{
printf("存储地址:var[%d] = %x\n", i, ptr );
printf("存储值:var[%d] = %d\n", i, *ptr );
/* 移动到下一个位置 */
ptr++;
}
return 0;
}
output:
存储地址:var[0] = bf882b30
存储值:var[0] = 10
存储地址:of var[1] = bf882b34
存储值: var[1] = 100
存储地址:of var[2] = bf882b38
存储值:var[2] = 200
不知道数组长度,也可以打印数组:
#include
const int MAX = 3;
int main ()
{
int var[] = {10, 100, 200};
int i, *ptr;
/* 指针中第一个元素的地址 */
ptr = var;
i = 0;
while ( ptr <= &var[MAX - 1] )
{
printf("Address of var[%d] = %x\n", i, ptr );
printf("Value of var[%d] = %d\n", i, *ptr );
/* 指向上一个位置 */
ptr++;
i++;
}
return 0;
}
output:
Address of var[0] = bfdbcb20
Value of var[0] = 10
Address of var[1] = bfdbcb24
Value of var[1] = 100
Address of var[2] = bfdbcb28
Value of var[2] = 200
指针数组
存储指针的数组
把 ptr 声明为一个数组,由 MAX 个整数指针组成。ptr 中的每个元素,都是一个指向 int 值的指针。
#include
const int MAX = 3;
int main()
{
int var[] = {10, 100, 200};
int i, *ptr[MAX];
for(i=0; i
output
*ptr[0]:10
*ptr[1]:100
*ptr[2]:200
也可以用一个指向字符的指针数组来存储一个字符串列表
#include
const int MAX = 4;
int main ()
{
const char *names[] = {
"Zara Ali",
"Hina Ali",
"Nuha Ali",
"Sara Ali",
};
int i = 0;
for ( i = 0; i < MAX; i++)
{
printf("Value of names[%d] = %s\n", i, names[i] );
}
return 0;
}
Value of names[0] = Zara Ali
Value of names[1] = Hina Ali
Value of names[2] = Nuha Ali
Value of names[3] = Sara Ali
指针的指针
#include
int main ()
{
int var;
int *ptr;
int **pptr;
var = 3000;
/* 获取 var 的地址 */
ptr = &var;
/* 使用运算符 & 获取 ptr 的地址 */
pptr = &ptr;
/* 使用 pptr 获取值 */
printf("Value of var = %d\n", var );
printf("Value available at *ptr = %d\n", *ptr );
printf("Value available at **pptr = %d\n", **pptr);
return 0;
}
Value of var = 3000
Value available at *ptr = 3000
Value available at **pptr = 3000
传递指针给函数
获取当前时间的函数:
#include
#include
void getSeconds(unsigned long *par); //获取当前时间
int main ()
{
unsigned long sec; //存储时间
getSeconds( &sec ); //传入变量的指针
/* 输出实际值 */
printf("Number of seconds: %ld\n", sec );
return 0;
}
void getSeconds(unsigned long *par)
{
/* 获取当前的秒数 */
*par = time( NULL );
return;
}
output:
Number of seconds: 1539228344
传递数组指针给函数:
传入数组指针和数组大小,返回数组平均值
#include
float getAverage(int *arr, int size); //传入数组指针和数组大小,返回数组平均值
int main ()
{
int arr[] = {1, 2, 3, 2, 1};
float avg;
avg = getAverage(arr, 5);
printf("average is %f\n", avg);
return 0;
}
float getAverage(int *arr, int size)
{
float avg;
int i, sum = 0; //注意!sum一定要赋初值
for(i=0; i
average is 1.800000
从函数返回指针
下面的函数会生成 10 个随机数,并使用表示指针的数组名(即第一个数组元素的地址)来返回它们:
#include
#include
#include
/* 要生成和返回随机数的函数,函数变量类型为指针 */
int * getRandom( )
{
static int r[10];
int i;
/* 设置种子,srand为stdlib库函数,time为time库函数 */
srand( (unsigned)time( NULL ) );
for ( i = 0; i < 10; ++i)
{
r[i] = rand();
printf("%d\n", r[i] );
}
return r;
}
/* 要调用上面定义函数的主函数 */
int main ()
{
/* 一个指向整数的指针 */
int *p;
int i;
p = getRandom();
for ( i = 0; i < 10; i++ )
{
printf("*(p + [%d]) : %d\n", i, *(p + i) );
}
return 0;
}
1523198053
1187214107
1108300978
430494959
1421301276
930971084
123250484
106932140
1604461820
149169022
*(p + [0]) : 1523198053
*(p + [1]) : 1187214107
*(p + [2]) : 1108300978
*(p + [3]) : 430494959
*(p + [4]) : 1421301276
*(p + [5]) : 930971084
*(p + [6]) : 123250484
*(p + [7]) : 106932140
*(p + [8]) : 1604461820
*(p + [9]) : 149169022
函数指针
函数指针是指向函数的指针变量。
函数指针的使用与函数一样,相当于起了个别名:
#include
int max(int x, int y)
{
return x > y ? x : y; // 三元运算符
}
int main ()
{
int a, b, c, m;
//将函数地址赋给函数指针变量,注意函数指针的定义形式
int (*p)(int, int) = &max; //max亦可
scanf("%d %d %d", &a, &b, &c);
m = p(p(a, b), c);
printf("the max number is %d\n", m);
return 0;
}
回调函数
回调函数是指使用者自己定义一个函数,实现这个函数的程序内容,然后把这个函数(入口地址)作为参数传入别人(或系统)的函数中,由别人(或系统)的函数在运行时来调用的函数。
#include
#include
// 函数指针作为参数
void populate_array(int *array, size_t arraySize, int (*getNextValue)(void))
{
for (size_t i=0; i