VCer代码 VCer开源 VCer文章 VCer工具 VCer知道 VCer词典 VCer读书 VCer论坛   站点首页 我要张贴 控制面板
VCer代码 VCer开源 VCer文章 VCer工具 VCer知道 VCer词典 VCer读书 VCer论坛   站点首页 我要张贴 控制面板

目前位置: VCer资源中心 >>> VCer文章
子级分类: 软件工程 C++/MFC基础 Windows界面 网络与通信 图形图象处理 系统通信 数据库 文件系统 硬件/系统调用 开发工具 组件技术 其它技术
我来转发一篇文章!>>>


围绕p()与(*p)()的争论
 
对于一个函数:void func(void);我们通常可以定义一个这样的函数指针指向它:void (*p)(void) = func;通过p调用func时,通常有两种写法:p();或者(*p)(); 围绕这两种写法,当初C89制定的时候曾经有过争论。(*p)();是一种旧式的规定,旧式规定圆括号左边必须具有“函数”类型,如果是指向函数的指针,那么必须加上*声明符。但C89不再把圆括号的左边限定为“函数”类型,而是一个后缀表达式。那么问题就来了,如果p的值是函数地址,那么*号就是声明符,但如果p指向的内容是函数地址,*号就得被看作运算符了。同一种形式会有两种解释,这是一个矛盾。不仅函数调用如此,指向数组的指针也存在这种矛盾。编译器为了处理这种情况得增加代码,效率自然就降低了。争论的最后结果是谁也不能把对方完全说服,于是就干脆两种都支持了。笔者认为应该抛弃旧式的规定,p();这种形式简洁明了,又符合函数的一般形式,何乐而不为? 第八章练习的答案,同时给出用typedef的分解方法:int (*(*func)[5][6])[7][8];func是一个指向数组的指针,这类数组的元素是一个具有5X6个int元素的二维数组,而这个二维数组的元素又是一个二维数组。typedef int (*PARA)[7][8];typedef PARA (*func)[5][6];int (*( ...
作者:不祥 oases2008张贴于2005-01-01 00:00:00.0,共阅读1313次,回复0
C++和C的不同点
 
C++和C的不同点1.C++比C多了一种注释方式:双斜杠注释一次可注释一行. 例: int i; i=0; // 这一行是注释,下一行将i加一. i++;2.在C++中,变量可以随时处定义,而在C中必须在程序和函数的开始处定义. 例: /*这里是C的例子*/ int i; for(i=0;i<10;i++); //如果是C++可以将i在用时再定义. for(int i=0;i<10;i++);3.在C中声明一个struct结构,那么在用的时候要加上struct关键字,在C++中不需要.*同样的,enum结构和union结构中也是如此. 例: /*在C语言里*/ struct st {int x,y;}; /*用时:*/ struct st myst; //在C++中可以这样 struct st {int x,y;}; //用时: st myst;4.在C++中使用了新的IO库:iostream.h在C中只有stdio.h. 例: #include <i ...
作者:不祥 oases2008张贴于2005-01-01 00:00:00.0,共阅读1469次,回复0
i++,i--的前置,后置++i,--i的详细解释
 
对i++,i--,++i,--i的易解,在此举一例子详解: main( ) { int x,y,z; x=y=2;z=3; y=x++-1;printf("%d\t%d\t",x,y); /*x=3,y=1,后置++,先把x赋值给y,再做运算,而x的值无论是前还是后置都加1*/ y=++x-1;printf("%d\t%d\t",x,y);/*x=4,y=3,前置++,先把x加1后赋值给y,然后做运算(此行x初值是上行的终值=3)*/ y=z--+1;printf("%d\t%d\t",z,y); /*z=2,y=4,同上理可知*/ y=--z+1;printf("%d\t%d\t",z,y); /*z=1,y=2,同理可证*/ getch(); } 希望能给初学者带来易处,你要多多发表和支持菜鸟的文章哟~~本文转载自IT网it求职笔试真题库网。
作者:不祥 oases2008张贴于2005-01-01 00:00:00.0,共阅读1306次,回复0
指针的算术运算
 
指针可以加上或减去一个整数。指针的这种运算的意义和通常的数值的加减运算的意义是不一样的。例如: 例二: 1。 char a[20]; 2。 int *ptr=a; ... ... 3。 ptr++; 在上例中,指针ptr的类型是int*,它指向的类型是int,它被初始化为指向整 形变量a。接下来的第3句中,指针ptr被加了1,编译器是这样处理的:它把指针ptr的值加上了sizeof(int),在32位程序中,是被加上了4。由于地址是用字节做单位的,故ptr所指向的地址由原来的变量a的地址向高地址方向增加了4个字节。 由于char类型的长度是一个字节,所以,原来ptr是指向数组a的第0号单元开始的四个字节,此时指向了数组a中从第4号单元开始的四个字节。 我们可以用一个指针和一个循环来遍历一个数组,看例子: 例三: int array[20]; int *ptr=array; ... //此处略去为整型数组赋值的代码。 ... for(i=0;i<20;i++) { (*ptr)++; ptr++; } 这个例子将整型数组中各个单元的值加1。由于每次循环都将指针ptr加1,所 以每次循环都能访问数组的下一个单元。 再看例子: 例四: 1。 char a[20]; 2。 int *ptr=a; ... ... 3。 ptr+=5; 在这个例子中,ptr被加上了5,编译器是这样处理的:将指 ...
作者:不祥 oases2008张贴于2005-01-01 00:00:00.0,共阅读1371次,回复0
this指针小结
 
this不可以被写, 通常用作对象自身的读取,可以省略.有一种情况需要显式使用this指针.当需要对this进行比较操作时, 例子如下void X::copy(const X & obj){ if( this!= obj ) //如果属同一对象,就无需拷贝操作 { ... }}本文转载自IT网it求职笔试真题库网。
作者:不祥 oases2008张贴于2005-01-01 00:00:00.0,共阅读1267次,回复0
什么是数组名?----一个让你吃惊的事实!
 
数组是指针的基础,多数人就是从数组的学习开始指针的旅程的。下面我节选一些在各种论坛和文章里经常见到的关于数组的文字:“一维数组是一级指针”“二维数组是二级指针”“数组名可以作为指针使用”“数组名就是..........的常量指针”“数组名就是..........的指针常量”..................................这些文字看起来非常熟悉吧?类似的文字还有许多,或许你就是经常说这些话的人呢。不过非常遗憾,这些文字都是错误的,实际上数组名永远都不会是指针!这个结论也许会让你震惊,但它的确是事实。数组名、指针、地址这几个概念虽然是基础中的基础,但它们恰恰是被混淆和滥用得最多的概念,把数组名说成指针,是一个概念性的错误,实质是混淆了指针与地址两个概念的本质。俗话说得好:浅水淹死人。因此,在讨论数组之前,有必要先回过头来澄清一下什么是指针,什么是地址,什么是数组名。 指针是C语言具有低级语言特征的最直接的证据。在汇编语言里面,指针的概念随处可见。比如SP,SP寄存器又叫堆栈指针,它的值是地址,由于SP保存的是地址,并且SP的值是不断变化的,因此可以看作一个变量,而且是一个地址变量。地址也是C语言指针的值,C语言的指针跟SP这样的寄存器虽然不完全一样,但原理却是相通的。C语言的指针也是一种地址变量,C89明确规定,指针是一个保存对象地址的变量。这里要注 ...
作者:不祥 oases2008张贴于2005-01-01 00:00:00.0,共阅读1348次,回复0
经典C语言面试题
 
1.从文件中读取数值(大约有10000个数据)计算他们的平均值。要求程序执行速度最快;2.计算打印一个二叉树所用的时间复杂度。3.从文件中随即提取一个字符串,只能扫描文件一次,且不能用表格存储所有字符串在文件中的偏移。4.如何检测链表是否带有循环。5.编写代码确定一个变量是有符号数还是无符号数。6.文件描述符和文件指针有何区别。7.库函数和系统调用有何区别。8.数组和指针这两种类型有何区别。9.静态库和动态库有何区别。10.总线错误(bus error)和断错误(segment fault)有何区别。11.typedef int x[10]和#define x int[10]的区别。12.linux中的信号是什么。13.linux中的线程和进程有何区别。本文转载自IT网it求职笔试真题库网。
作者:不祥 oases2008张贴于2005-01-01 00:00:00.0,共阅读1870次,回复0
const的思考
 
1、什么是const?常类型是指使用类型修饰符const说明的类型,常类型的变量或对象的值是不能被更新的。(当然,我们可以偷梁换柱进行更新:)2、为什么引入const?  const 推出的初始目的,正是为了取代预编译指令,消除它的缺点,同时继承它的优点。3、cons有什么主要的作用?(1)可以定义const常量,具有不可变性。例如:const int Max=100;int Array[Max]; (2)便于进行类型检查,使编译器对处理内容有更多了解,消除了一些隐患。例如:void f(const int i) { .........}编译器就会知道i是一个常量,不允许修改;(3)可以避免意义模糊的数字出现,同样可以很方便地进行参数的调整和修改。同宏定义一样,可以做到不变则已,一变都变!如(1)中,如果想修改Max的内容,只需要:const int Max=you want;即可!(4)可以保护被修饰的东西,防止意外的修改,增强程序的健壮性。还是上面的例子,如果在函数体内修改了i,编译器就会报错;例如: void f(const int i) { i=10;//error! }(5) 为函数重载提供了一个参考。class A{......void f(int i) {......} //一个函数void f(int i) const {......} //上一个函数的重载.... ...
作者:不祥 oases2008张贴于2005-01-01 00:00:00.0,共阅读1159次,回复0
C语言的优势
 
C比其他语言变化少(越老越经典),容易学,工作又好找。以上是个人看法,因为我现在觉得:C才是王道!本文转载自IT网it求职笔试真题库网。
作者:不祥 oases2008张贴于2005-01-01 00:00:00.0,共阅读1344次,回复0
using namespace std
 
所谓namespace,是指标识符的各种可见范围。C++标准程序库中的所有标识符都被定义于一个名为std的namespace中。由于namespace的概念,使用C++标准程序库的任何标识符时,可以有三种选择:1、直接指定标识符。例如std::ostream而不是ostream。完整语句如下:std::cout << std::hex << 3.4 << std::endl;2、使用using关键字。using std::cout;using std::endl;以上程序可以写成cout << std::hex << 3.4 << endl;3、最方便的就是使用using namespace std,这样命名空间std内定义的所有标识符都有效(曝光)。就好像它们被声明为全局变量一样。那么以上语句可以如下写:cout << hex << 3.4 << endl;本文转载自IT网it求职笔试真题库网。
作者:不祥 oases2008张贴于2005-01-01 00:00:00.0,共阅读1435次,回复0
一道c++面试题 -----常量的分配位置
 
char str1[] = "abc"; // char str2[] = "abc"; const char str3[] = "abc"; const char str4[] = "abc"; const char* str5 = "abc"; const char* str6 = "abc"; cout << boolalpha << ( str1==str2 ) << endl; //false cout << boolalpha << ( str3==str4 ) << endl; //false cout << boolalpha << ( str5==str6 ) << endl; //falseOut: false false true本文转载自IT网it求职笔试真题库网。
作者:不祥 oases2008张贴于2005-01-01 00:00:00.0,共阅读1447次,回复0
Thinking in C -- C指针
 
忘记悲伤最好的办法可能就是让自己有事做吧。 因为工作需要,很多好朋友都在重新补最基础也是最重要的C语言。人常说没有学好指针就等于没有学过C,在学校时可能老师只是为了应付考试,而一直在讲那些死板的语法。但对这个C语言(也是任何编程思想)的精髓没有重视。 确实,在几年的编程过程中,感觉对指针的精通可以让我们对任何语言都触类旁通了。语言只是方便我们表达自己思想的助记符,真正的程序在内存中是如何运行的?理解指针可以让你更清楚的知道。 最近在网上看了一些讲解指针的文章,从这些文章中将自己对指针的了解加以整理,我认为基本上如果可以真正理解下面这些,那么你可以对别人说你对C的思想已经精通了。完全精通一门语言当然还要知道它常用的库函数,当然那些就要你自己多编,多记了。/*--------------------------------概念------------------------------------------*/ 指针是一个特殊的变量,它里面存储的数值被解释成为内存里的一个地址。 要搞清一个指针需要搞清指针的四方面的内容:[1]指针的类型,[2]指针所指向的类型,[3]指针的值或者叫指针所指向的内存区,[4]还有指针本身所占据的内存区。 --sizeof(指针变量名) 一般32位机都为4; 指针的类型(即指针本身的类型)和指针所指向的类型是两个概念。当你对C越来越熟悉时 ...
作者:不祥 oases2008张贴于2005-01-01 00:00:00.0,共阅读1261次,回复0
c语言的宏
 
关于c语言的宏,我肯定许多人一定有过惨痛的经验。几年前一个典型的错误让我找了一天:#define MACRO_1 5#define MACRO_2 MACRO_1 + 1int a = MACRO_2 * 3;我希望的结果当然是a = 18,可是实际上大家应该都知道a是 5 + 1 * 3 = 8.我以为这样的错误我不会再犯,可是前一阵我还是被一个几乎相同的错误给消耗了一个下午:#define PHY_ADDER 0x400000#define PHY_ADDER_2 PHY_ADDER + 0x100000int *p = (int *)PHY_ADDER_2;指针p的值是多少?0x500000?那只是我想要的结果。p = 0x400000 + 0x100000 * sizeof(int);在我的机器上等于0x800000。你知道为什么吗?指针的加法有这么点特性,如果你知道p++并不意味着p值只加了1你就知道为什么了。 一定要给你的宏加上括号!!本文转载自IT网it求职笔试真题库网。
作者:不祥 oases2008张贴于2005-01-01 00:00:00.0,共阅读1278次,回复0
static 用法小结
 
static关键字是C, C++中都存在的关键字, 它主要有三种使用方式, 其中前两种只指在C语言中使用, 第三种在C++中使用(C,C++中具体细微操作不尽相同, 本文以C++为准).(1)局部静态变量(2)外部静态变量/函数(3)静态数据成员/成员函数下面就这三种使用方式及注意事项分别说明一、局部静态变量在C/C++中, 局部变量按照存储形式可分为三种auto, static, register(<C语言程序设计(第二版)>谭浩强, 第174-175页)与auto类型(普通)局部变量相比, static局部变量有三点不同1. 存储空间分配不同auto类型分配在栈上, 属于动态存储类别, 占动态存储区空间, 函数调用结束后自动释放, 而static分配在静态存储区, 在程序整个运行期间都不释放. 两者之间的作用域相同, 但生存期不同.2. static局部变量在所处模块在初次运行时进行初始化工作, 且只操作一次3. 对于局部静态变量, 如果不赋初值, 编译期会自动赋初值0或空字符, 而auto类型的初值是不确定的. (对于C++中的class对象例外, class的对象实例如果不初始化, 则会自动调用默认构造函数, 不管是否是static类型)特点: static局部变量的”记忆性”与生存期的”全局性”所谓”记忆性”是指在两次函数调用时, 在第二次调用进入时, 能保持第一次调用退 ...
作者:不祥 oases2008张贴于2005-01-01 00:00:00.0,共阅读1481次,回复0
STL之list容器(笔记)
 
容器list,所控制的长度为N的序列是以一个有着N个节点的双向链表来存储的,支持双向迭代器。优势:可以在链表中随意的插入和删除元素或是子链表,所需的仅是改变前后指针。劣势:在定位操作中比如查找和随即存取,时间是线性增加的,而且在存储上每个节点还有前向和后向两个指针。异常:模版类list的另外一个有点是在异常处理方面,对任何容器来说,器成员函数在执行中抛出的异常,使容器本身处于一种一致的状态,可以被销毁,并且容器没有对其所分配的存储空间失去控制。但对大部分操作尤其是那些能够影响多个元素的操作,当抛出异常时,并美欧制定容器的精确状态,但list保证对于大部分成员函数抛出异常时,容器能够恢复到操作前的状态。typedef list<T,allocator<T>> mycont; //使用默认模版参数,可以省略第二个参数构造函数:list() 声明一个空列表;list(al) 声明一个空列表,但她还存储一个分配器对象al;list(n) 声明一个有n个元素的列表,每个元素都是由其默认构造函数T()构造出来的list(n,val) 声明一个由n个元素的列表,每个元素都是由其复制构造函数T(val)得来的list(n,val,al) 声明一个和上面一样的列表,但还存储分配器对象al;list(first,last) 声明一个列表,其元素的初始值来源于由区间所指定的序列中的元素list(firs ...
作者:不祥 oases2008张贴于2005-01-01 00:00:00.0,共阅读2871次,回复0
STL之vector容器
 
标准模版类也定义了一个模版类basic_string,basic_string得一个模版参数是元素类型。他们之间得不同之处:basic_string得构造函数和析构函数只能在C程序中声明得类型,可以通过逐位复制得方式来位这样得对象赋值。vector则可以在其中包含任意类型。basic_string参数中需要一个traits类来为它得另一个模版参数,traits指定了如何移动或是比较序列中得元素,并且指定了如何读写由元素构成得文件。vector元素则不能使用这样得traits。basic_string对象可以移交以null结尾得序列,vector对象只理解我们存储在它里面的序列。basic_string对象可以使用写时复制,模版类vector则不行。basic_string对象还提供了一些与字符串处理相关得函数。标准C++库还定义了string是basic_string<char,char_traits<char>>得同义词。 vectro<bool> 模版类vector得特化版本,处理元素类型为bool得序列,可以更加经济得使用内存,将8个元素存储在一个相同得字节空间内,并定义了特殊得flip和swap处理函数; typedef vector<T,allocalor<T>> mycont; 通过使用默认得模版参数,可以省略第二个参数构造函数: vector() 声明一个空得ve ...
作者:不祥 oases2008张贴于2005-01-01 00:00:00.0,共阅读1979次,回复0
C++精华(STL)学习笔记之算法
 
<algorithm>是STL中最大得一个文件,它是由一大堆模版函数组成得。这些函数包括:max 检测两个元素得较大值min 检测两个元素得较小值swap 交换两个已储存得值iter_swap 交换两个由迭代器描述得值max_element 检测一个序列中较大得值min_element 检测一个序列中较小得值equal 比较两个序列是否相等lexicographical_compare 比较两个序列中一个序列是否排在另一个序列得前面mismatch 检测两个序列中第一个不相等得地方find 检测一个序列中第一个值等于给定值得位置 find_if 检测序列中第一个是pr(x)返回true得元素(pr是一个函数对象)adjacent_find 要检测第一对相等得相邻元素count 要计算一个序列中等于一个给定值得元素得个数count_if 计算一个序列中使ptr(x)返回true得个数得序列search 要在另外一个序列中检测一个序列第一次出现得地方search_n 要在一个序列中检测第一个连续出现n次指定值得地方find_end 要在另外一个序列中检测一个序列最后一次出现得地方find_first_of 要在一个序列中检测另一个序列中任意一个元素第一次出现得地方for_each 使用函数对象OP对序列中得每个元素都调用一次op(x)generate 要使用函数对象fun,将每个元素都 ...
作者:不祥 oases2008张贴于2005-01-01 00:00:00.0,共阅读1561次,回复0
char* a = "zhf"; 和 char a[] = "zhf"; 之间的区别
 
char* a = "zhf"; 定义一个 指针 a,指向一个 常量字符串 "zhf" 的首地址,由于 "zhf" 是一个常量字符串, 在常量区,无法修改,所以 a[1] = 'k' 出错,它意图修改常量;但是 a 这个指针本身是可以修改的。char a[] = "zhf"; 定义一个 char 数组,该数组的内容是 "zhf", 这里有一个赋值,"zhf" 被赋值给了这个数组, 数组中的值是可以修改的,也就是 a[1] = 'k' 是允许的;但是 数组名 是const 属性的, 不能修改。--------------------char *a[]="aaaaaaa";char *b="bbbbbbb"; aaaaaaaaaaa是在运行时刻赋值的; 而bbbbbbbbbbb是在编译时就确定的; 但是,在以后的存取中,在栈上的数组比指针所指向的字符串(例如堆)快。 对应的汇编代码 10:a=c[1]; 004010678A4DF1movcl,byteptr[ebp-0Fh] 0040106A884DFCmovbyteptr[ebp-4],cl 11:a=p[1]; 0040106D8B55ECmovedx,dwordptr[ebp-14h] 004010708A4201moval,byteptr[edx+1] 004010738845FCmovbyteptr[ebp-4],al ...
作者:不祥 oases2008张贴于2005-01-01 00:00:00.0,共阅读1213次,回复0
多态性——vptr和vtable
 
多态性 (polymorphism) 是面向对象编程的基本特征之一。而在C++ 中,多态性通过虚函数 (virtual function) 来实现。我们来看一段简单的代码:  #include <iostream>  using namespace std;  class Base  {  int a;  public:  virtual void fun1() {cout<<"Base::fun1()"<<endl;}  virtual void fun2() {cout<<"Base::fun2()"<<endl;}  virtual void fun3() {cout<<"Base::fun3()"<<endl;}  };  class A:public Base  {  int a;  public:  void fun1() {cout<<"A::fun1()"<<endl;}  void fun2() {cout<<"A::fun2()"<<endl;}  };  void foo (Base& obj)  {  obj.fun1();  obj.fun2();  obj.fun3();  }  int main()  {  Base b;  A a;  foo(b);  foo(a);  }  运行结果为:  Base::fun1()  Base::fun2()  B ...
作者:不祥 oases2008张贴于2005-01-01 00:00:00.0,共阅读1182次,回复0
inline函数的小结
 
C89不支持内联函数,C99才支持。 由于inline函数具有内部链接,因此数个文件定义相同名字的内联函数不会发生冲突,而类函数宏就不行,会产生重复定义。 inline函数是真正的函数,可以由语句组成;但函数宏所做的只是替换,不是真正的函数,当然也不能有语句。函数中的语句大于8句以上的话,一般编译器就自动将你的inline函数转化为uninline函数。宏是把那个代码在当前位置展开,根本不用测试,肯定是最快的。 内联函数编译之后应该是把代码直接插到调用位置(应该是指编译器不优化情况下)所以执行的时候不会去压栈,调用函数代码,退栈,所以如果执行的次数多,就会比较快。 执行到非内联函数时,函数不在当前位置,是个指针,然后经历压栈,调用函数代码,退栈三个过程。会比较慢。inline的引入大部分是为了参数类型安全检查和防止边界效应。如果是函数宏,可能有边界效应。本文转载自IT网it求职笔试真题库网。
作者:不祥 oases2008张贴于2005-01-01 00:00:00.0,共阅读1459次,回复0

页次: 7/10页 记录总数191 9 7 [ 1 2 3 4 5 6 7 8 9 10 ] 8 :