完整的学习C++的读书路线图(1)(2)
}
else ia=stri[i];
strp[i++]=ia;
}
strp[i]=’\0’;
return(strp);
}
main()
{ char s[50];
gets(s);
printf("%s\n", jiami(s));
}
2.统计文本单词的个数
输入一行字符,统计其中有多少个单词,单词之间用格分隔开。
算法思路:
(1)从文本(字符串)的左边开始,取出一个字符;设逻辑量word表示所取字符是否是单词内的字符,初值设为0
(2)若所取字符不是“空格”,“逗号”,“分号”或“感叹号”等单词的分隔符,再判断word是否为1,若word不为1则表是新单词的开始,让单词数num = num +1,让word =1;
(3)若所取字符是“空格”,“逗号”,“分号”或“感叹号”等单词的分隔符, 则表示字符不是单词内字符,让word=0;
(4) 再依次取下一个字符,重得(2)(3)直到文本结束。
下面程序段是字符串string中包含的单词数
#include "stdio.h"
main()
{char c,string[80];
int i,num=0,word=0;
gets(string);
for(i=0;(c=string[i])!='\0';i++)
if(c==' ') word=0;
else if(word==0)
{ word=1;
num++;}
printf("There are %d word in the line.\n",num);
}
十二、穷举法
穷举法(又称“枚举法”)的基本思想是:一一列举各种可能的情况,并判断哪一种可能是符合要求的解,这是一种“在没有其它办法的情况的方法”,是一种最“笨”的方法,然而对一些无法用解析法求解的问题往往能奏效,通常采用循环来处理穷举问题。
例: 将一张面值为100元的人民币等值换成100张5元、1元和0.5元的零钞,要求每种零钞不少于1张,问有哪几种组合?
main()
{ int i, j, k;
printf(" 5元 1元 5角\n");
for(i=1; i<=20; i++)
for(j=1; j<=100-i; j++)
{ k=100-i-j;
if(5*i+1*j+0.5*k==100)
printf(" %3d %3d %3d\n", i, j, k);
}
}
十三、递归算法
用自身的结构来描述自身,称递归
VB允许在一个Sub子过程和Function过程的定义内部调用自己,即递归Sub子过程和递归Function函数。递归处理一般用栈来实现,每调用一次自身,把当前参数压栈,直到递归结束条件;然后从栈中弹出当前参数,直到栈空。
递归条件:(1)递归结束条件及结束时的值;(2)能用递归形式表示,且递归向终止条件发展。
例:编fac(n)=n! 的递归函数
int fac(int n)
{ if(n==1)
return(1);
else
return(n*fac(n-1));
}
main()
{ int n;
scanf("%d", &n);
printf("n!=%d\n", fac(n));
}
签到工作后,用人单位承诺是嵌入式方向,让我好生欢喜,而且用人单位也很负责任的为我们应届毕业生着想,委托了一家在东北地区小有名气的培训机构为我们提供价格不菲的培训, 其中当然少不了C语言,于是特意买了本《C语言的科学与艺术》好好复习C.一个博士生讲解的C语言中级教程,虽然没有多少新意,但是总有一些久而荒废的知识,贴出来不断提醒自己“温故知新”。
1.关于printf输出函数自从学过C++后,就再也没有用过C的printf函数,与std::cout相比printf不能判断输出量的类型,而且对内存的操作,会有危险。
printf的原型中参数是常量字符串+……;返回值是整形。
其中的常量字符串中的输出格式需要注意:常用的%d、%f、%s不用多说,但是%g和%%需要说明一下:%g表示普通型,数值用%f和%e格式中较短的一个显示,在不能事先确定输出值的情况下,他是最好的输出格式。如定义了float型的变量,如果它是一个整数值,那么以%g格式输出不会显示一堆0,好像是以%d格式输出一般,若是小数值,也不会补充一堆0,让人看得很亲切。
%%是百分号的输出表示,而不是我们常规思路那样用转义字符\.
精度控制:
负号:表示数值左对齐,没有负号右对齐;
宽度:表示输出字段的最小字符数。若要显示的数值所占空间少,则以空格 填充;若数值太大,不能在指定大小的字段中显示,那么扩大字段宽度直到能够容纳这个数值。
小数点精度:对%g而言,精度参数说明了最大有效位;%f和%e来说精度参数指定了小数点后的位数;%s而言,则表示字符串中显示的位数。
注意:小数点占一位!
返回值为int,在windows下平台下表示了printf函数输出的字符个数,或者发生输出错误的相关字节。特别注意一点:\t\n等制表换行的字符,虽然在输出是没有确切的字符显示,但是也算一个字符!
2.关于scanf()函数
这个函数一样没法识别输入量的类型,所以也要在参数表里显示指定类型,如%d,%f等等,但是有一点不同于printf的就是%f,在输出时%f可以输出double和float两种类型,但是输入时,double的位数明显大于float于是如果象这样:
double d;
scanf(“%f”,&d);
printf(“%f”,d);
就会输出%!$%#^@#%一堆不知所云的东西,原因就在于类型的宽度问题,正确的是以%lf输出。
在windows的32位系统环境下,sizeof 后short 2;int 4;float 4;double 8;但是让我不理解的是long double也是8(怎么也应该比double大呀);
在linux的32位系统环境下,sizeof后只有long double于win32不同是12.这让我少感欣慰。
但是还有一点需要注意:输入时可加上宽度限制,但是不可加精度限制;
如:char c,d;scanf(“%3c,%3c”,&c,&d);printf(“%c,%d”,c,d);若输入abcdef[Enter]则会认定abc中赋给c的是a,def中赋给d的是d.
3.getchar和putchar
这两个函数都是一次处理一个字符,以前曾写过:
while(c = getchar())
{putchar(c);
putchar('\n');……}
这次和班里的一位同学讨论说,按照常理思考应该是输入一个字符,马上输出一个字符,但当我们输入一个字符串时,会把这个字符串挨个输出一遍。
由于这两个函数都可由以上两个函数实现,所以我想是不是putchar中用到了scanf,然后向2那样把输入的字符串放到一个buffer里,然后依次截取下来,轮流处理。
而若想输入一个字符,马上输出一个字符,可能是需要系统检测keydown的中断,来处理。
这个问题还不明白,希望如果有哪位高手路过,指点一下!谢谢。
有个哲人曾说过“一知半解是危险的。”最近对这句话的体会越来越深刻。
林语堂先生说过“只用一样东西,不明白它的道理,是在不高明。”谨记慎行!
全局变量&局部变量
当全局变量和局部变量同名时,会遮蔽全局变量,在函数内引用此变量时会用到同名的局部变量,而不会用到全局变量(如果想引用全局变量需要加上::)。而且局部变量可以相互遮蔽,如if嵌套,for嵌套等。
这都与局部变量的作用域有关,而作用域又根据各编译器的实现有关,这就联系到编译原理的内容(顺便复习一下)。
一般而言,标示符的符号表要包含几种属性:名字、类型、存储类别、作用域、可视性、存储分配信息。
1)名字:
符号表中符号名一般不允许重名,若程序出现重名标示符,则根据语言的定义, 按照该标示符的作用域和可视性规则进行相应的处理。
若程序允许重载,函数名通过它们的参数个数、类型、返回值来区分。
2)类型:
决定变量的数据在存储空间的存储格式,还决定了在变量上可施加的运算。
3)存储类别:
其定义方法有两种形式:关键字指定,变量定义+位置。
这个属性是编译过程语义处理,检查和存储分配的重要依据,还决定了它的作用 域可视性生命周期等问题。
4)作用域和可视性:
通常一个变量的作用域就是该变量可以出现的地方;函数形参作为函数内部变量处理;分程序结构本身含有局部变量声明的语句。
5)存储分配:
编译程序一般根据标示符的存储类别以及他们出现的位置和次序来确定每个变量应分配的存储区及该区域的具体位置。
静态存储区 公共静态区 公共+外部 整个域作用
局部静态区 局部静态 局部
动态存储区
标示符在源程序中出现的位置和先后顺序决定了标示符在存储区中的具体位置,即一个偏移量。
关于符号表的建立:
如程序:
main()
{int a = 1; float c =0.1;
{
float a =1.0;
{float x=5.5,b =7.1;}
{int b =9; c =a+b+c;}
}
}
1.建立符号表第一层到内存中main的指向;
2.建立符号表第二层到内存中a,c的指向,指向a;
3.建立符号表第三层到内存中a的指向,指向a;(第二层的a与第三层的a不同)
4.建立符号表第四层到内存中x,b的指向,遇到后一个括号}表明本层结束,建立内存中结束项,然后从结束项建立 指针,指向上层最后一个元素,即第三层的a,然后删除本层的符号表到内存中的指针;
……
n.最后形成的结果是符号表到内存中共有三个指向,分别指向main、a和c的a、a,然后又很多结束项指回前三层。
(由于不会在blog里用图形,所以不能更形象地标示出来。等以后整明白的。)
特别一点:如果是不同的C文件中,以static方式来声明同名的全局变量,如果要正常运行,要求只能有一个C文件对此变量赋值,此时连接不会出错
补充:
Static全局变量和普通全局变量的区别
全局变量本身就是静态存储方式,静态全局变量当然也是,两者在存储方式上并无区别。
这两者的区别在于非静态全局变量的作用域是整个源程序,当一个源程序由多个源文件构成时,非静态的全局变量在各个文件中都是有效的,而静态全局变量则限制了其作用域,即只在定义该变量的源文件内有效,在同一源程序的其他源文件中不可使用。
由于静态全局变量的作用域限制于一个源文件中,只能为该文件内的函数使用,也可避免一些在其他文件中引起的错误。
Static局部变量和普通局部变量的区别
静态局部变量的存储方式与普通局部变量不同,因此生命周期也不同,后者是动态的,存放于堆栈中。
全局的在静态区,动态的分配在堆中。
Static函数与普通函数的区别
Static函数在内存中只有一份拷贝,而普通函数每次调用,都会有一份拷贝。
*/ /*
"C之诡谲"C语言之精华总结!
C之诡谲(上)
从研究生二年纪开始学习计算机也差不多两年了,一路走来,有很多的收获,也有不少的遗憾,现在正好有一段闲暇,就想对走过的路留下一些足迹,回忆。每个人都有自己不同的人生,说到这里,就是程序人生了,歌德在《浮士德》中说过:“如果不曾在悲哀中咀嚼过面包,不曾在哭泣中等待过明天,这样的人就不知道你——天的力量。”所以我想记下一些带给我悲哀,带给我哭泣的程序人生。其实学习计算机的基础课程是非常重要的,离散数学,编译原理,操作系统,形式语言……,如果你认真走过了这些路,在以后的日子你会发现你的路会越走越宽,以前的努力和汗水会不断的给你灵感,给你支持,给你前进的武器和勇气。你会发现以后取得的很多成就,不过是朝花夕拾而已!
对于程序语言我喜欢的是C++,它能带给你别的语言无法给予你的无上的智力快感,当然也会给你一门语言所能给你的魔鬼般的折磨。其实Java,C#,Python语言也非常的不错,我也极为喜欢。它们都是非常成功的语言,我从来就不愿意做某一种语言的盲目信仰者,每种语言都有它成功的地方,失败的地方,都有它适合的地方,不如意的地方。所以每一次看到评价语言的文章,我看看,但从来不会发言。
C++的前世是C,而且C所留下的神秘以及精简在C++中是青出于蓝而胜于蓝!C所带给人的困惑以及灵活太多,即使一个有几年经验的高段C程序员仍然有可能在C语言的小水沟里翻船。不过其实C语言真的不难,下面我想指出C语言中最神秘而又诡谲多变的四个地方,它们也继续在C++语言中变幻莫测。
- 最新评论
