博文

[置顶] (转帖)二进制、八进制、十六进制(2006-07-28 03:25:00)

摘要:二进制、八进制、十六进制 6.1 为什么需要八进制和十六进制? 6.2 二、八、十六进制数转换到十进制数   6.2.1 二进制数转换为十进制数   6.2.2 八进制数转换为十进制数   6.2.3 八进制数的表达方法   6.2.4 八进制数在转义符中的使用   6.2.5 十六进制数转换成十进制数   6.2.6 十六进制数的表达方法   6.2.7 十六进制数在转义符中的使用 6.3 十进制数转换到二、八、十六进制数   6.3.1 10进制数转换为2进制数   6.3.2 10进制数转换为8、16进制数 6.4 二、十六进制数互相转换 6.5 原码、反码、补码 6.6 通过调试查看变量的值 6.7 本章小结 这是一节“前不着村后不着店”的课。不同进制之间的转换纯粹是数学上的计算。不过,你不必担心会有么复杂,无非是乘或除的计算。 生活中其实很多地方的计数方法都多少有点不同进制的影子。 比如我们最常用的10进制,其实起源于人有10个指头。如果我们的祖先始终没有摆脱手脚不分的境况,我想我们现在一定是在使用20进制。 至于二进制……没有袜子称为0只袜子,有一只袜子称为1只袜子,但若有两袜子,则我们常说的是:1双袜子。 生活中还有:七进制,比如星期。十六进制,比如小时或“一打”,六十进制,比如分钟或角度……   6.1 为什么需要八进制和十六进制?   编程中,我们常用的还是10进制……必竟C/C++是高级语言。 比如: int a = 100,b = 99; 不过,由于数据在计算机中的表示,最终以二进制的形式存在,所以有时候使用二进制,可以更直观地解决问题。 但,二进制数太长了。比如int 类型占用4个字节,32位。比如100,用int类型的二进制数表达将是: 0000 0000 0000 0000 0110 0100 面对这么长的数进行思考或操作,没有人会喜欢。因此,C,C++ 没有提供在代码直接写二进制数的方法。   用16进制或8进制可以解决这个问题。因为,进制越大,数的表达长度也就越短。不过,为什么偏偏是16或8进制,而不其它的,诸如9或20进制呢? 2、8、16,分别是2的1次方,3次方......

阅读全文(4291) | 评论:1

(转)关于指针及数组的基本概念问题(2006-07-28 03:44:00)

摘要:原贴: http://www.programfan.com/club/showbbs.asp?id=95120xiangyu138的答复 回答网友的问题:主题:关于指针及数组的基本概念问题1.请问如下的函数参数定义是不是相等的,用指针做参数有什么意义Node(double *xyz) { x = xyz[0]; y = xyz[1]; z = xyz[2]; }Node(double xyz[3]) { x = xyz[0]; y = xyz[1]; z = xyz[2]; }答:两者是相等的,而且第一种其实更标准,因为第二种也是转化为第一种。在函数形式参数里是没有数组的,都被转化为指针了。所以这时在函数里面没有办法通过像:sizeof(xyz)/sizeof(xyz[0])来取得数组元素的个数(因为根本就不是数组),所以一般还要传递一个数组元素个数的值,否则编这个函数的人不知道你原来的数组个数是多少。如:Node(double xyz[],int n) { x = xyz[0]; y = xyz[1]; z = xyz[2]; } 2.单看double *xyz 的定义,是不是数或数组都可以传递。但是看了{ x = xyz[0]; y = xyz[1]; z = xyz[2]; }这个具体实现所以才知道要传递一个数组过来?答:这个完全错,是看形式参数double *xyz 就知道要传递一个一次指针(一次地址)过来,你要是传数值就会出错的,而且不能传二次指针如:char **argv;的argv。 3.请问 main(int argc,char **argv)这里面的char **argv 具体是表示的是什么意思,传递参数进来时,是应该传递一个指针还是其他,谢谢!答:char **argv 是二次指针,也就是二次地址的意思,就是地址的地址(本身地址也是一个二进制数,它也需要一个地址来保存的哦)。可以传char *aa[];这个是指针数组(也就是数组的元素是指针),或者是二次指针char **a。 **************************1.那为什么我看大部分都喜欢用指针而不直接用数组呢?我觉得用数组定义的很清楚啊答:随便你了,没有所谓的大部分的,其实两者的速度差不多的。3.传 char* p[3] = { "abc", "1234567......

阅读全文(1738) | 评论:0

[转]const型指针变量(2006-07-28 03:43:00)

摘要:有三种不同的方法来说明const变量,其作用和含义都是不同的。 第一式:将const放在指针变量的类型之前。表示指针变量所指向的数据是一个常量,即不能改变指针变量所指向的数据值,但可以改变指针变量的值。   int x, y;    const int *p = &x;  *p = 24;     // ERROR  p = &y;     // OK 第二式:将const放在指针变量的*后。表示指针变量的值是一个常量,即不能改变指针的值,但可以改变指针变量所指向的数据值。     int n, i;    int *const p = &n;    *p = 25;   // ok    *p = &i;   // error 第三式:把一个const放在指针变量的类型之前,将另一个const放在指针变量的*后。表示指针变量的值是一个常量,指针变量所指向的数据也是一个常量。二者都不能改变。     int j, k;    const int *const pp = &j;    *pp = 25;  // error    pp = &k;   // error const类型的指针主要用做函数的参数,以限制在函数体内不能修改指针变量的值,或不能修改指针所指向的数据值。......

阅读全文(1902) | 评论:0

[转]关于指针的教程(2006-07-28 03:42:00)

摘要:什么是指针?   其实指针就像是其它变量一样,所不同的是一般的变量包含的是实际的真实的数据,而指针是一个指示器,它告诉程序在内存的哪块区域可以找到数据。这是一个非常重要的概念,有很多程序和算法都是围绕指针而设计的,如链表。 开始学习   如何定义一个指针呢?就像你定义一个其它变量一样,只不过你要在指针名字前加上一个星号。我们来看一个例子:   下面这个程序定义了两个指针,它们都是指向整型数据。 int* pNumberOne; int* pNumberTwo;   你注意到在两个变量名前的“p”前缀了吗?这是程序员通常在定义指针时的一个习惯,以提高便程序的阅读性,表示这是个指针。现在让我们来初始化这两个指针: pNumberOne = &some_number; pNumberTwo = &some_other_number;   &号读作“什么的地址”,它表示返回的是变量在内存中的地址而不是变量本身的值。在这个例子中,pNumberOne 等于some_number的地址,所以现在pNumberOne指向some_number。 如果现在我们在程序中要用到some_number,我们就可以使用pNumberOne。 我们来学习一个例子:   在这个例子中你将学到很多,如果你对指针的概念一点都不了解,我建议你多看几遍这个例子,指针是个很复杂的东西,但你会很快掌握它的。   这个例子用以增强你对上面所介绍内容的了解。它是用C编写的(注:原英文版是用C写的代码,译者重新用C++改写写了所有代码,并在DEV C++ 和VC++中编译通过!) #include <iostream.h> void main() { // 声明变量: int nNumber; int *pPointer; // 现在给它们赋值: nNumber = 15; pPointer = &nNumber; //打印出变量nNumber的值: cout<<"nNumber is equal to :"<< nNumber<<endl; // 现在通过指针改变nNumber的值: *pPointer = 25; //证明nNumber已经被上面的程序改变 //重新打印出nNumber的值: cou......

阅读全文(1151) | 评论:0

[转]关于指针(2006-07-28 03:41:00)

摘要:  不可否认,指针是C的精华,也是C的难点。每一个学C的人,当年应该都是在“漆黑”中摸过来的。我现在编程序时用指针用得很多,可以说绝大多数值与是通过指针来传递的,而struct、class的实例等则是完全用指针或引用来传递的。  我不敢说我是什么高手,也不敢说我对指针有多了解,对于网上的一大堆提问,我不敢说我能很好地回答。但是,我想:我把自己的一点点感悟写出来,多多少少会给读者一点启示。写得不到之处,请读者朋友们斧正。 一、指针就是变量:  虽然申明指针的时候也提类型,如:  char *p1;  int *p2;  float *p3;  double *p4;  .....  但是,这只表示该指针指向某类型的数据,而不表示该指针的类型。说白了,指针都是一个类型:四字节无符号整数。 二、指针的加减运算很特殊:  p++、p--之类的运算并不是让p这个“四字节无符号整数”加一或减一,而是让它指向下一个或上一个存储单元,它实际加减的值就是它所指类型的值的size。  比如:  char *型指针,每次加减的改变量都是1;  float *型的指针,每次加减的改变量都是4;  void *型指针无法加减。  还要注意的是:指针不能相加,指针相减的差为int型。  正是因为指针有着不同于其它变量的运算方式,所以,在任何时候用到指针都必须明确“指针的类型”(即指针所指的变量的类型)。这就不难理解为什么函数声明时必须用“int abc(char *p)”而调用的时候却成了“a = abc(p);”这样的形式了。 三、用指针做参数传递的是指针值,不是指针本身:  要理解参数传递,首先必须把“形参”与“实参”弄明白。  函数A在调用函数B时,如果要传递一个参数C,实际是在函数B中重新建立一个变量C,并将函数A中的C值传入其中,于是函数B就可以使用这个值了,在函数B中,无论有没有修改这个C值,对于函数A中的C都没有影响。函数B结束时,会将所有内存收回,局部变量C被销毁,函数B对变量C所做的一切修改都将被抛弃。  以上示例中,函数A中的变量C称为“实参”,函数B中的变量C被称为“形参”,调用函数时,会在B函数体内建立一个形参,该形参的值与实参的值是相同的,但是形参的改变不影响实参,函数结束时,形参被销毁,实参依然没有发生变化。  指针也是一个变量,所以它也符合以上的......

阅读全文(1771) | 评论:0

[转]指针本质论(2006-07-28 03:40:00)

摘要: 指针本质论   指针是一个变量,是用来存储地址的变量。这就是指针的本质。  有人可能很纳闷,指针为什么一定要定义成某类型(int, char)呢,不能就是“指针类型”吗?接触过汇编的就容易理解为什么。存储单元的单位是字节,对一个地址进行操作(读取或赋值)就要指明是对单个字节、两个字节、还是双字(四字节)。同样,指针是存储地址的,说白了,指针就是一个地址,自然也要说明了;而且,这个类型还关乎指针自加自减时真正加减的字节数。    顺便说一下,数组名也是指针,数组在申请空间时数组名存储该存储空间的首地址,注意数组名存储的是地址,因此也是指针,只是该指针一旦赋值后就不能修改,即所谓常指针。***************************  如下函数希望为指针p申请空间,但不能达到目的,为什么呢?void GetMemory(char *p){    char *s=NULL;    s= (char*)malloc(100*sizeof(char));     p=s;}  归根结底,C函数形参实参之间只是“值传递”:当形参是普通变量时,传递的是实参的值;当形参是指针时,传递的是指针变量的值,即某变量的地址,这样,可以通过指针成功的改变其所指单元的值,但自身的改变不会传回给实参。上例可改为:void GetMemory(char **p){    char *s=NULL;    s= (char*)malloc(100*sizeof(char));     *p=s;}注意这样修改后,调用时实参应该是指针的“地址”(或指向指针的指针)。  见下例,Test函数可以成功修改a[0]的值,尽管形参a的值发生了变化,但不会改变实参a的值,这就说明指针形参的改变不影响指针实参的改变,但通过形参指针修改了其所对应的存储单元的值是,这改变将影响到实参。#include <iostream>using namespace std;void Test(int *a){ *(a++) = 5; //该函数真正所做的修改:将a所指存储空间的值赋为5,并将a值加1 cou......

阅读全文(1547) | 评论:0

[转帖]C语言中数组和指针的互操作(2006-07-28 03:40:00)

摘要:C语言中数组和指针的互操作    曾听好多朋友说,C是一种怀旧的语言,因为它的历史很久远,然而自从各种面向对象的编程语言的相续出现让它的影响力日减。当然了,这是无可非议的,但是C的高效性其他语言无妨比拟的,所以我们有必要把握其中的精华与奥妙,也就有必要知道其中的基本的数据结构的比如数组,稍微有点深度的堆栈、列表、结构体等的操作和实现。指针也是C语言中的一个很优秀灵活的结构,对它的了解也是必不可少的。    我们一般都认为数组是一维的数据存储结构,因为二位数组或者说矩阵都可以看作是多个一维数组的组合结构,定义在其上的数据存储访问方式是一样的。所以一维数组是其中最基础的最重要的部分,只有理解了此类数据结构的本质才能触类旁通了。    数组(array)是若干同类变量的聚合,允许通过统一的名字饮用其中的变量。所以数组也就是一个同一类型的数据的有限集合。可以通过下表来访问数组中的某一/些数组元素。在C语言中数组都由连续的内存区域构成(有时候,不一定是这样),最低地址对应首元素,数组的下标是从0开始的,所以首元素也就是数组下标为0的元素,最高的地址对应最末的元素,即第N-1个元素(如果我们定义的数组为N元)。数组的定义方式:    在C语言中允许在声明数组的时候同时对其进行初始化,也可以把声明和定义放在不同的位置,初始化的一般的类似于如下的表达式:type_specifier array_name[size1]...[sizeN] = {value_list};其中vlaue_list是由逗号(,)分隔的常量表,常量表必须和type_specifier兼容。最后由分号与下一个语句分隔。由此可见一维数组的定义方式为:type_specifier array_name[size] = {value_list};如下:char hello[12] = {'H','e','l','l','o',',',' ','w','o','r','l','d','\0'};     注意:字符数组是一"'\0'"收尾的,这是C标准的一部分。因为在操作字符数组的时候是以'\0'作为结束判断的标志。当然......

阅读全文(1390) | 评论:0

[转]动态申请的问题(2006-07-28 03:39:00)

摘要:前几天写一个函数,需要一个不定长的数组,又由于是在函数中需要修改的,就做了下边的定义: PointStruct *pPoint=new PointStruct[]; pPoint[0].x=0; pPoint[1].x=1; ………… 想通过这样实现动态添加元素,后来发现只能申请到3个,pPoint[3]就不能被赋值了,编译没有出错提示,但一运行就报错。 之后又改为pPointStruct *pPoint=new PointStruct{1,2,3,4,……,n};之后再赋值pPoint[n+1]=n+1;pPoint[n+2]=n+2;……后来发现只能赋值到pPoint[2n+1],当再给pPoint[2n+2]赋值时,就又会出现编译没有错误,一运行就报错的情况。 总结:用pPointStruct *pPoint=new PointStruct{1,2,3,4,……,n};的形式申请了n个存储空间,但实际上还有另外n+1个空间,作为备用的,所以在申请n个之后还能继续添加,直到n+1个,再往后就不行了.至于PointStruct *pPoint=new PointStruct[];的形式为什么会有那样的结果,我也想不出来^_^,也许那本身就是一个错误的语句吧! 这些都是个人想的,不知道是否真的像我想的那样,希望各位有不同见解能说出来. 关于指针动态申请2 还是有关指针的动态申请空间的问题. 定义了PointStruct* pPointxy;      pPointxy=new PointStruct [4]; fun(x1,y1,x2,y2,pPointxy); 在程序中fun函数共执行了10次,每次执行之后都将pPointxy的每个元素赋给另外一个数组接收,调试发现最后一次执行fun函数的时候,pPointxy的最后一个元素的值就出现了异常. 仔细查找后发现很奇怪的现象,在fun前设置一个断点,在fun之后设置一个断点,当执行到第一个断点的时候,pPointxy的各个元素的值都正常,但当到下一个断点的时候,pPointxy的最后一个元素的值竟然发生了改变!我是在紧接着fun之后设的断点,两个断点之间根本就没有对pPontxy修改的语句.也就是说只在fun函数中被修改的pPointxy在函......

阅读全文(1730) | 评论:0

《彻底搞定C指针》第7篇 函数名与函数指针(2006-07-28 03:36:00)

摘要:第7篇 函数名与函数指针 白云小飞 一 通常的函数调用    一个通常的函数调用的例子://自行包含头文件void MyFun(int x);    //此处的申明也可写成:void MyFun( int );int main(int argc, char* argv[]){   MyFun(10);     //这里是调用MyFun(10);函数      return 0;}void MyFun(int x)  //这里定义一个MyFun函数{   printf(“%d\n”,x);}    这个MyFun函数是一个无返回值的函数,它并不完成什么事情。这种调用函数的格式你应该是很熟悉的吧!看主函数中调用MyFun函数的书写格式:MyFun(10);    我们一开始只是从功能上或者说从数学意义上理解MyFun这个函数,知道MyFun函数名代表的是一个功能(或是说一段代码)。    直到——    学习到函数指针概念时。我才不得不在思考:函数名到底又是什么东西呢?    (不要以为这是没有什么意义的事噢!呵呵,继续往下看你就知道了。)二 函数指针变量的申明    就象某一数据变量的内存地址可以存储在相应的指针变量中一样,函数的首地址也以存储在某个函数指针变量里的。这样,我就可以通过这个函数指针变量来调用所指向的函数了。    在C系列语言中,任何一个变量,总是要先申明,之后才能使用的。那么,函数指针变量也应该要先申明吧?那又是如何来申明呢?以上面的例子为例,我来申明一个可以指向MyFun函数的函数指针变量FunP。下面就是申明FunP变量的方法:void (*FunP)(int) ;   /......

阅读全文(1145) | 评论:0

《彻底搞定C指针》第6篇 指向另一指针的指针(2006-07-28 03:35:00)

摘要: 第六篇 指向另一指针的指针 白云小飞 一. 回顾指针概念:早在本系列第二篇中我就对指针的实质进行了阐述。今天我们又要学习一个叫做指向另一指针地址的指针。让我们先回顾一下指针的概念吧!当我们程序如下申明变量:short int i;char a;short int * pi;程序会在内存某地址空间上为各变量开辟空间,如下图所示。内存地址→6     7      8     9     10     11    12    13     14    15-------------------------------------------------------------------------------------…  |     |      |      |      |      |       |      |      |      |   -------------------------------------------------------------------------------------   ......

阅读全文(1116) | 评论:0