C语言中有各种比较纠结的结构,容易混淆,也经常说是面试的重点,现在就来总结下各种小纠结;
指针常量和常量指针
要想搞清楚这一对,必须先知道const关键字;const关键字用来修饰一个变量,表示该变量是只读变量,不可以修改的;(在C语言中const修饰的变量是可以用指针来强制改变的,但在C++中是不行的;)
顺便说下const的几个作用:
1、修饰变量为只读,能对不想修改的变量进行保护作用,
能提高程序的健壮性;
2、const定义的常量编译器可以对其进行数据静态类型安全检查;
3、const修饰函数形式参数:当输入参数为用户自定义类型和抽象数据类型时,将“值传递”改为“const&传递”可以提高效率;
4、
关键字const的作用是为给读你代码的人传达非常有用的信息。
指针常量:(int* const p)指针是常量,指针指向不可以改变,内容可以改变;
常量指针:(int const *p)指向常量的指针,指向可以改变,但内容不可以改变;
总结:看const修饰的是指针还是变量;
数组指针和指针数组
数组指针:表示指向数组的指针,一般就是说二维数组指针;表示为:int (*ap)[11];
指针数组:表示数组中存放的都是指针;表示为:int × array[11];
演示代码:
#include<stdio.h>
int main()
{
int i, j;
/*********指针数组*********/
char* array[3];
array[0] = "yu";
array[1] = "zhi";
array[2] = "hui";
printf("char* array:%s %s %s\n", array[0], array[1], array[2]);
/*********数组指针*************/
int intArray[3][3] = {
{1,2,3},
{11,12,13},
{21,22,23}
};
int (*ap)[3] = intArray;
for (i = 0; i < 3; i++)
for (j = 0; j < 3; j++)
printf("(ap+%d)[%d]:%d\n", i, j, (*(ap+i))[j]);
return 0;
}
函数指针和指针函数
函数指针:指向函数的指针;表示:int (*func)(int);
指针函数:返回指针的函数;表示: int* func(int);
演示代码:
#include<stdio.h>
// 指针函数
int* test(int *tmp)
{
*tmp += 10;
return tmp;
}
void test1(int i)
{
printf("int test1 i is:%d\n", i);
}
void test2(int i)
{
printf("int test2 i is:%d\n", i);
}
int main(void)
{
int tmp = 10;
printf("tmp:%d\n", (*test(&tmp)));
// 函数指针,指向函数的指针
void (*p)(int) = test1;
(*p)(110);
p = test2;
p(119);
return 0;
}
额外的总结下函数指针的一些问题:
在《C陷阱和缺陷》一书中有提到一个问题:在某微处理器上,当计算机启动时,硬件调用首地址为0位置上的子例程;
最终设计的语句是:(* ( void (*)() ) 0 ) ();看着挺复杂的,其实还是很简单的,书上也对此进行了详细的说明;这里就大概说下吧:
首先是构造一个函数指针:void (*)();其中省略了函数名(不习惯的话,可以随意添加一个),不传入参数,无返回值;
然后把0强制转换为该函数指针,一定要记住:其实函数指针以及函数都是个地址而已,表示从哪个地址入口开始执行;这里强制转换和变量的强制转换一样的:( void (*)() )0;此时的函数指针就是执行 0地址处;
最后是调用该函数指针,调用一个函数指针,一般是这样:(*func)(),这是标准的调用语句;也可以简写为:func();所以最后调用下该函数指针:(* (void (*)())0)();
返回函数指针的函数
返回函数指针的函数,最典型的就是 signal()函数;可以参考下:http://blog.csdn.net/yuzhihui_no1/article/details/44748585
其实这个函数:void (*signal(int signo, void (*func)(int) ) ) (int);如果不借用typedef 我还真不知道怎么实现它,主要是函数头不知道该怎么写;下面看下我利用typedef来实现的返回函数指针的函数:
#include<stdio.h>
int test(int i)
{
printf("in test! i = %d\n", i);
return i;
}
typedef int (*func)(int);
func test1(int i)
{
int (*p)(int) = test;
printf("ret test! i = %d\n",(*p)(i));
return p;
}
int main(void)
{
test1(1)(100);
return 0;
}
运行结果:
返回数组指针的函数
返回数组的函数是什么样子?我开始绕进去了,后来仔细想了下,那不就是返回指针的函数嘛。哈哈,现在来看下返回数组指针的函数,其实就是返回个二维数组指针;
返回数组指针的函数:返回一个指向二维数组的指针;表示为:int (*func(int i)) [4]{};
演示代码
#include<stdio.h>
#include<stdlib.h>
// int (*array)[4];
int (*func(int count))[4]
{
int (*array)[4] = malloc(4*sizeof(int));
(*array)[0] = count*1;
(*array)[1] = count*10;
(*(array+1))[0] = count*100;
(*(array+1))[1] = count*1000;
return array;
}
int main()
{
int (*tmp)[4] = func(1);
printf("array[00]:%d\n", (*tmp)[0]);
printf("array[01]:%d\n", (*tmp)[1]);
printf("array[10]:%d\n", (*(1+tmp))[0]);
printf("array[11]:%d\n", (*(1+tmp))[1]);
free (tmp);
//free (array);
return 0;
}
运行结果:
函数指针数组
函数指针数组:数组里面存放的都是函数指针;表示为:int (*array[3])(int);
函数指针数组在系统设计中还是比较容易用到的,其实就是把几个函数指针存放到数组中,方便后面调用;
演示代码:
#include<stdio.h>
void test(int i)
{
i *= 1;
printf("int test i is:%d\n", i);
}
void test1(int i)
{
i *= 10;
printf("int test1 i is:%d\n", i);
}
void test2(int i)
{
i *= 100;
printf("int test2 i is:%d\n", i);
}
void test3(int i)
{
i *= 1000;
printf("int test3 i is:%d\n", i);
}
int main(void)
{
void (*func[4])(int) =
{
test,
test1,
test2,
test3
};
(*func[0])(1);
(*func[1])(1);
(*func[2])(1);
(*func[3])(1);
return 0;
}
运行结果:
转载请注明作者和原文出处,原文地址:
http://blog.csdn.net/yuzhihui_no1/article/details/44748585
若有不正确之处,望大家指正,共同学习!谢谢!!!