Posts Tagged ‘C’

2011/10/01

时间倒回到2011年5月的一天,大学的最后一门课《计算机信息安全技术》,讲到《缓冲区溢出》这一章,并且给出了一段示例代码来演示缓冲区溢出,回到宿舍后出于好奇我运行了一下这段代码,发现结果并不是书上所说的那样,当时在人人网也发过一篇吐槽的日志,但是一直拖到现在都没有仔细的去研究过,正好现在十一放假没事,就花点时间搞搞啦。 书第136页-137页。代码如下,出于简单考虑(其实书上的C++代码格式也是错的),我除去了头文件和cout函数,这样就跟纯C语言代码是一样了。 01 void function(int a) 02 { 03     char buffer[5]; 04     char *ret; 05     ret=buffer+12; 06     *ret+=8; 07 } 08 int main() 09 { 10     int x; 11     x=10; 12     function(7); 13     x=1; 14     return 0; 15 } 书上说最后x的值是10,不是1,而我的结果恰恰相反。 接着用gcc产生汇编代码,在这里用 gcc -O0 -S 命令告诉编译器不采用任何优化措施,产生最原始的汇编代码,这样有利于我们分析,即使是采用-O1级优化的时候,汇编代码已经很难读了,大家可以试一试。 01 function: 02     pushl %ebp 03    […]

Tags: ,. 9,880 views
2011/02/14

函数指针,顾名思义就是指向函数的指针,它与一般的指针有什么不同呢?我觉得,函数指针只是在定义的时候有一点不同,使用的时候,它就是一个指针该怎么用就怎么用。 int (*f)(int,double); 类似于上面的定义式就是函数指针的定义了。 从前往后分析,最前面的int 说明了这个所指向的函数的返回值,显然,这个被指向的函数会返回一个整型的值;(*f)()结构说明了这是一个函数指针,(int,double)说明了这个指针指向的函数的参数形式,即第一个参数是int型,第二个参数是double型,这时,我们脑海里可以想象有一个这样的函数 int function(int a,double b),并且有一个叫 f 的指针指向了这个函数(其实是指向了这个函数段的起始地址)。 有了前面的分析,就不难理解这个定义了 char * (*f)(double,double); 下面再来一个难一点的,int (*g[])(int ,int);首先这肯定是一个指针,但是[]怎么理解呢?按照数组的理解方法,例如int array[9]定义了一个9个元素的数组,每个元素都是int型,以此类推,这是一个函数指针数组,每一个数组元素的类型都是一个函数指针,他们都各自指向一个类似于 int func(int,int)的函数。 如何使用函数指针呢?我们知道,函数名其实就是指向函数代码段的一个指针,因此,f和function都可以看成是一个指针,都指向了内存中同一块代码段,所以,调用f(3,4.5)与function(3,4.5)是一样的,相当于是给原来的函数一个别名吧。当然,f是一个指针,理所当然可以对他进行“间接访问”,即 (*f)(3,4.5)。 一般情况下对于函数指针的常见情况也就是以上这些了,那么函数指针到底有什么用呢? >说实话,我自己写代码到目前为止还没用过函数指针,一方面是我对这个不熟悉,在coding的过程中不能灵活运用;另一方面函数指针可能确实不如其他语法常用,因此,我举一个《C和指针》中类似的例子。 例子一:不用函数指针的实现。 swith(op){ case ‘+’:add(x,y);break; case ‘-‘:sub(x,y);break; case ‘*’:mul(x,y);break; case ‘/’:div(x,y);break; } 上面的代码实现了模拟一个计算器对于x,y做加减乘除,那么用函数指针如何实现呢? 例子二:用函数指针实现。 首先我们需要声明函数,并对函数指针数组初始化。 double add(double,double); double sub(double,double); double mul(double,double); double div(double,double); /*声明函数指针数组*/   double (*op_fun[4])(double,double)={add,sub,mul,div}; 现在我们可以这样使用: result=op_fun[op](x,y); OK,以上就是鄙人学习函数指针的一点点心得。

Tags: ,,. 6,377 views
2010/04/18

更新是需要的。否则对不起来踩博客的童鞋们~~ 只是我最近比较忙阿,觉得没什么好更新的,也许要等到明年我闲下来了,才会有精力来好好打理博客,想念各位~ 先就把这个《C语言简单词法分析器》放上来吧,很早之前我就在CFAN论坛发过,如有雷同,纯属有意。 代码就不贴,直接上文件。猛击此处 顺便透露一下,下一篇博客估计是《简单四则运算器》,嘿嘿,还是一堆代码,不解释,你懂的~~(最近很流行这句话)

Tags: ,. 7,753 views
2009/08/22

D大同学   曰:数组作为参数会退化为指针,这个规则应该牢记。。。

KC  曰:当数组首地址被作为指针传…

Tags: ,,. 6,314 views
2009/08/14

一段时间没用数组指针,居然忘记了这个语法了,调试了半天都不行,真郁闷… 我贴出一段代码来描述我的意思。 QUOTE: 有问题的代码 #include<iostream> using namespace std; void print(int *p) {     int i,j;     for(i=0;i<20;i++)//一种打印方式     {         for(j=0;j<3;j++)         cout<<p[i][j]<<",";     }     cout<<endl;     for(i=0;i<20;i++)//另一种打印方式     {         for(j=0;j<3;j++)         cout<<*(*(p+i)+j)<<",";     } } int main() {     int array[20][3];     for(int i=0;i<20;i++)//赋值     {         for(int j=0;j<3;j++)         array[i][j]=i+j+2;     }     print(array);//打印     return 0; } //如果把array改成char型呢?相应的函数定义怎么改? 如果把array改成char型呢?相应的函数定义怎么改? [ 本帖最后由 52computer 于 2009-3-10 14:13 编辑 ] ———————————————————————                         热心人的解答 ——————————————————————— #include using namespace std; void print(int p[][3]) {         int i,j;         for(i=0;i<20;i++)//一种打印方式         {                 for(j=0;j<3;j++)                     cout<<<",";         }         cout<         for(i=0;i<20;i++)//另一种打印方式         {                 for(j=0;j<3;j++)                         cout<<*(*(p+i)+j)<<",";         } } […]

Tags: ,. 2,604 views
2009/08/13

转自原博客 初学 C++ 的程序员可能会认为 vector 的下标操作可以添加元素,其实不然:      vector<int> ivec;   // empty vector      for (vector<int>::size_type ix = 0; ix != 10; ++ix)          ivec[ix] = ix; // disaster: ivec has no elements 上述程序试图在 ivec 中插入 10 个新元素,元素值依次为 0 到 9 的整数。但是,这里 ivec 是空的 vector 对象,而且下标只能用于获取已存在的元素。 这个循环的正确写法应该是:      for (vector<int>::size_type ix = 0; ix != 10; […]

Tags: ,,. 6,528 views
Tags: ,,. 1,709 views