您的位置:首页 > 编程语言 > C语言/C++

C和指针读书笔记(第十三章)

2016-10-13 19:59 246 查看
1. 指向指针的指针

赋值

int i;
int *pi;
int **ppi;
//把ppi初始化指向变量pi
ppi = π
//把pi(通过ppi间接访问)初始化为指向变量i
*ppi = &i;


2.

int f; //一个整形变量
int *f;  //一个指向整型的指针
int* f, g;  //声明了一个指针f和一个普通的整形变量g
int f();  //声明了一个函数f,它的返回值是整数
int *f();
//函数调用操作()优先级高于间接访问,故首先执行
//f是一个函数,它的返回值类型是一个指向整型的指针
int (*f)();
//第二对括号是函数调用操作符
//第一对括号是间接访问在函数调用之前进行,使f成为了函数指针,它所指向的函数返回一个整型值
//函数指针指向存在于内存中的某个函数
int *(*f)();
//f是一个函数指针,知识所指向的函数的返回值是一个整型指针
//必须对f进行间接访问操作才能得到一个整型值
int f[];  //f是一个整型数组
int *f[];  //f是一个数组,元素类型十指向整型的指针
int f()[];
//f是一个函数,返回值是整型数组
//非法,因为含糊的返回值只能是标量值,不能返回数组
int f[]();
//f是数组,元素类型是函数
//非法,数组元素必须具有相同的长度
int (*f[])();
//括号内的表达式*f[]首先进行求值,所以f是一个元素为某种类型的指针的数组
//表达式末尾的()是函数调用操作符,所以f是一个数组
//数组元素的类型是函数指针,它所指向的函数的返回值是一个整型值
int *(*f[])();
//创建一个指针数组,指针所指向的类型是返回值为整型指针的函数
int (*f)(int, float);
//把f声明为函数指针,它所指的函数接受两个参数
//参数分别是一个整型值和浮点类型值,并返回一个整型值
int *(*g[])(int, float);
//把g声明为一个数组,数组的元素类型是一个函数指针
//g所指向的函数接受两个参数,分别是一个整型值和浮点型值,并返回一个整形指针


3. 函数指针

int f(int);
int (*pf)(int) = &f;
//创建函数指针pf,并初始化指向函数f
//函数的初始化之前必须要有函数的原型,编译器需要检查f的类型和pf的类型一致
//初始化表达式种的&操作符是可选的,因为函数名被使用时总是由编译器把它转换为函数指针
int ans;
int f(25);
//使用名字调用函数f,函数名首先被转换为一个函数指针,该指针指定函数在内存中的位置
//然后函数调用操作符调用该函数,执行开始于这个地址的代码
int (*pf)(25);
//把函数指针转化为一个函数名,再照第一个的方法执行
ans = pf(25);
//效果和之前一样,间接访问操作非必需,因为编译器需要的是一个函数指针


4. 回调函数

用户把一个函数指针作为参数传递给其他函数,后者将“回调”用户的函数。如果函数可以再不同的时间执行不同类型的工作或者执行只能由函数调用者定义的工作,都可以使用回调函数。

回调函数无法知道比较的值的类型,所以参数的类型被声明为* void。表示一个指向未知类型的指针。

可以通过函数指针来实现回调函数。一个指向回调函数的指针作为参数传递给另一个函数,后者使用这个指针调用回调函数。

函数示例:

#include <stdio.h>

Node *search_list(Node *node, void const *value,
int (*compare)(void const *, void const *))  //函数指针
{
while(node != NULL){
if(compare(&node->value, value) == 0)  //相等
break;
node = node->link;
}
return node;
}


5. 转移表

转移表就是一个函数指针数组。

创建一个转移表需要两个步骤,首先,声明并初始化一个函数指针数组。并确保这些函数原型出现在这个数组的声明之前。第二个步骤是声明函数指针。

double add(double, double);
double sub(double, double);
double mul(double, double);
double div(double, double);  //函数原型

double (*oper_func[])(double, double) = {
add, sub, mul, div
};


转移表也使用函数指针。转移表像switch语句一样执行选择,转移表由一个函数指针数组组成(这些函数必须具有相同的原型)。函数通过下标选择某个指针,再通过指针调用对应的函数。必须保证下标值处于适当的范围之内,因为再转移表中调试错误非常困难。

6. 命令行参数P267

如果某个执行环境实现了命令行参数,这些参数是通过两个形参传递给main函数的,这两个形参称为argc,argv。argv是一个整数,用于表示参数的数量,argv是一个指着我你,指向一个序列的字符型指针。该序列以一个NULL指针作为结束标志。其中第1个参数就是成的名字,程序可以通过对argv执行间接操作来访问命令行参数。

7. 字符串常量

当一个字符串常量出现在表达式中时,它的值是一个指针常量。编译器把这些指定字符的一份拷贝存储在内存的某个位置,并存储一个指向第一个字符的指针。

"xyz"+1;  //字符串常量实际是个指针,指向x,所以+1后指向y,故输出y
*"xyz"  //对指针进行间接访问操作时,其结果就是指针所指向的内容,所以指向x,输出x
"xyz"[2]  //输出z


//参数是一个0~100的值
//根据参数值打印一定比例的星号,四舍五入并除以十的结果决定打印出多少个星号
#include <stdio.h>

int main(void)
{
int a;
printf("input a number between 0 and 100: ");
scanf("%d\n", &a);
star(a);
return 0;
}

void star(int n)
{
n += 5;
n /= 10;
printf("%s\n", "**********" + 10 -n);
}


//把二进制转换为字符并打印
#include <stdio.h>

void binary_to_ascii(unsigned int value)
{
unsigned int quotient;
quotient = value/10;
if(quotient != 0){
binary_to_ascii(quotient);
}
putchar(value % 10 + '0');
}


2016.10.14
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c语言 读书笔记