摘要:
1.指针没有指向一块合法的内存 定义了指针变量,但是没有为指针分配内存,即指针没有指向一块合法的内浅显的例子就不举了,这里举几个比较隐蔽的例子。1.1结构体成员指针未初始化struct student{ char *name; int score;}stu,*pstu;int main(){ strcpy(stu.name,"Jimy"); stu.score = 99; return 0;} 很多初学者犯了这个错误还不知道是怎么回事。这里定义了结构体变量stu,但是他没想到这个结构体内部char *name这成员在定义结构体变量stu时,只是给name这个指针变量本身分配 阅读全文
摘要:
对于程序员,一般来说,我们可以简单的理解为内存分为三个部分:静态区,栈,堆。很多书没有把把堆和栈解释清楚,导致初学者总是分不清楚。其实堆栈就是栈,而不是堆。堆的英文是heap;栈的英文是stack,也翻译为堆栈。堆和栈都有自己的特性,这里先不做讨论。陈正冲老师在此处打了一个比方:一层教学楼,可能有外语教室,允许外语系学生和老师进入;还可能有数学教师,允许数学系学生和老师进入;还可能有校长办公室,允许校长进入。同样,内存也是这样,内存的三个部分,不是所有的东西都能存进去的。静态区:保存自动全局变量和static变量(包括static全局和局部变量)。静态区的内容在总个程序的生命周期内都存在,由编 阅读全文
摘要:
那到底什么是野指针呢?怎么去理解这个“野”呢?我们先看别的两个关于“野”的词:野孩子:没人要,没人管的孩子;行为动作不守规矩,调皮捣蛋的孩子。野狗:没有主人的狗,没有链子锁着的狗,喜欢四处咬人。对付野孩子的最好办法是给他定一套规矩,好好管教。一旦发现没有按规矩办事就好好收拾他。对付野狗最好的办法就是拿条狗链锁着它,不让它四处乱跑。对付也指针肯怕比对付野孩子或野狗更困难。我们需要把对付野孩子和野狗的办法都用上。既需要规矩,也需要链子。前面我们把内存比作尺子,很轻松的理解了内存。尺子上的0毫米处就是内存的0地址处,也就是NULL地址处。这条栓“野指针”的链子就是这个“NULL”。定义指针变量的同时 阅读全文
摘要:
1.函数指针的定义 顾名思义,函数指针就是函数的指针。它是一个指针,指向一个函数。看例子:A) char * (*fun1)(char * p1,char * p2);B) char * *fun2(char * p1,char * p2);C) char * fun3(char * p1,char * p2); 看看上面三个表达式分别是什么意思?C)这很容易,fun3是函数名,p1,p2是参数,其类型为char *型,函数的返回值为char *类型。B) 也很简单,与C)表达式相比,唯一不同的就是函数的返回值类型为char**,是个二级指针。A) fun1是函数名吗?回忆一下前面讲解数组.. 阅读全文
摘要:
1.一个实例+理论分析在了解数组和指针的访问方式前提下,下面再看这个例子:main(){int a[5]={1,2,3,4,5};int *ptr=(int *)(&a+1);printf("%d,%d",*(a+1),*(ptr-1));}打印出来的值为多少呢? 这里主要是考查关于指针加减操作的理解。 对指针进行加1操作,得到的是下一个元素的地址,而不是原有地址值直接加1。所 以,一个类型为T的指针的移动,以sizeof(T) 为移动单位。 因此,对上题来说,a是一个一维数组,数组中有5个元素,所以a的类型是数组指针;ptr是一个int 型的指针,ptr的类型是整 阅读全文
摘要:
先看下面的例子:int a[5];1.内存布局的示意图 所有人都明白这里定义了一个数组,其包含了5个int型的数据。我们可以用a[0],a[1]等来访问数组里面的每一个元素,那么这些元素的名字就是a[0],a[1]…吗?看下面的示意图:如上图所示,当我们定义一个数组a时,编译器根据指定的元素个数和元素的类型分配确定大小(元素类型大小*元素个数)的一块内存,并把这块内存的名字命名为a。名字a一旦与这块内存匹配就不能被改变。a[0],a[1]等为a的元素,但并非元素的名字。数组的每一个元素都是没有名字的。2.利用sizeof来研究数组的内存结构关系 那现在再来解决sizeof关键字时的几个问题.. 阅读全文
摘要:
1.一种直观的方法假设现在需要往内存0x12ff7c地址上存入一个整型数0x100。我们怎么才能做到呢?我们知道可以通过一个指针向其指向的内存地址写入数据,那么这里的内存地址0x12ff7c其本质不就是一个指针嘛。所以我们可以用下面的方法:int *p = (int *)0x12ff7c;*p = 0x100;需要注意的是将地址0x12ff7c赋值给指针变量p的时候必须强制转换。1.1 为什么在此处,我们敢往0x12ff7c这个地址赋值呢? 至于这里为什么选择内存地址0x12ff7c,而不选择别的地址,比如0xff00等。这仅仅是为了方便在VisualC++ 6.0上测试而已。如果你选择0x. 阅读全文
摘要:
1. int *p = NULL; 代表定义一个指向整型变量的指针p,然后p的值设为NULL,也就是设为0;用另一种方式说,就是对一个刚定义的指向整型变量的指针,赋初始值,让其指向0地址。 2. *p = NULL; 代表对一个由指针p指向的变量(什么类型,不知道),赋值为0,是将那个变量赋值为0。 我们可以先看下面的代码:int *p = NULL;这时候我们可以通过编译器查看p的值为0x00000000。这句代码的意思是:定义一个指针变量p,其指向的内存里面保存的是int类型的数据;在定义变量p的同时把p的值设置为0x00000000,而不是把*p的值设置为0x00000000。这个过程叫 阅读全文
摘要:
优先级运算符名称或含义使用形式结合方向说明1[]数组下标数组名[常量表达式]左到右()圆括号(表达式)/函数名(形参表).成员选择(对象)对象.成员名->成员选择(指针)对象指针->成员名2-负号运算符-表达式右到左单目运算符(类型)强制类型转换(数据类型)表达式++自增运算符++变量名/变量名++单目运算符--自减运算符--变量名/变量名--单目运算符*取值运算符*指针变量单目运算符&取地址运算符&变量名单目运算符!逻辑非运算符!表达式单目运算符~按位取反运算符~表达式单目运算符sizeof长度运算符sizeof(表达式)3/除表达式/表达式左到右双目运算符*乘表 阅读全文
摘要:
1.C语言程序四步开发步骤(1)编辑。可以用任何一种编辑软件将在纸上编写好的C语言程序输入计算机,并将C语言源程序文件*.c以纯文本文件形式保存在计算机的磁盘上(不能设置字体、字号等)。(2)编译。编译过程使用C语言编译程序将编辑好的源程序文件“*.c”,翻译成二进制目标代码文件“*.obj”。编译程序对源程序逐句检查语法错误发现错误后,不仅会显示错误的位置(行号),还会告知错误类型信息。我们需要再次回到编辑软件修改源程序的错误,然后,再进行编译,直至排除所有语法和语义错误。(3)连接。程序编译后产生的目标文件是可重定位的程序模块,不能直接运行。连接将编译生成的各个目标程序模块和系统或第三方提 阅读全文