存档

2012年3月 的存档

从《The C Programming Language》中学到的那些编程风格和设计思想

2012年3月20日 2 条评论

---

读书不是目的,关键在于思考。

很早就在水木上看到有人推荐《The C Programming Language》这本书,一直都没看,开学一个月就专心拜读了一下,并认真做了课后习题。读来收获不少,主要有两点:一是加深了自己对一些基础知识的理解和感悟;二是从中学到了一些不错的编程风格和设计思想,这些东西虽看起来不起眼但细细嚼来还是很值得学习的。下面就从四个方面做一个小总结,水平有限,加之刚读第一遍,难免有疏漏和错误,非常欢迎批评补充。

===读书感悟===

===设计思想===

===编程风格===

===经典例程===

读书感悟

首先,不得不说这不愧为大师之作(网上将其誉为C圣经),一本薄的不能再薄的书,200多页,却涵盖了C语言的大部分精粹;值得一提的是,该书仅仅定价30元,这在计算机类书籍中可以说是很便宜了,与市面上充斥的各种C语言教程在性价比上形成了很大的对比。不过不得不承认,个人感觉这不是一本入门书,读起来是需要一定基础的。

其次,说一下该书的撰写风格和读书建议。书中不是成篇幅地罗列一个个语法和知识点,而是以例程驱动,大部分知识点都是以一个小程序来说明,所以建议读的过程中也将例程当做习题来做,然后与作者给出的程序进行对比,会发现自己的思维是多么的不缜密,考虑问题是多么的欠缺,等你慢慢“上道”了,写出一个和作者类似甚至觉得比他给出的答案要好的时候,兴趣和成就感便会促使你良性循环。

也许有人会说,书中的例子很简单,但我想说尽管很简单,但每个例子都是经典之作,而且能有效地治理眼高手低,在编写代码的过程中,太多的细节让人醍醐灌顶,可谓处处珠玑,书中一些精巧的程序段不禁会让人感觉:啊哈,原来是这样,原来还可以这样写。这样读来能明白之前好多不知所以然的地方。

最后,说一下这一本不到300页的书都包含了什么内容。书中从经典的hello world开始,可以说是手把手编写并讲述了C语言的大部分语法,不仅如此,更实现了二分查找快排希尔排序(这个的实现比我们数据结构中学习的要巧妙不少)、链表二叉树哈希这些重要的数据结构和算法。书中的大部分例程不仅能让你了解C,不仅能教你如何编写有效率且易读的代码,更能让你了解一些底层的设计思想,例如getchar,strcpy,fopen,printf等众多库函数的实现思想都有体现,帮助你探索源码,追根溯源。另外书中还包含了一些系统调用接口,编译原理(一个递归下降的语法分析,这部分没看懂,还要再读啊)的实现等。

阅读全文...

过来人对于在校生找工作的一点看法 (转)

2012年3月19日 3 条评论

---

发信人: clarkkevin (过河卒), 信区: job
标  题: 过来人对于在校生找工作的一点看法
发信站: 兵马俑BBS (Sun Mar 18 00:21:10 2012), 本站(bbs.xjtu.edu.cn)

今天看了大家在网上就西邮的学生蔑视交大学生的事情大发感慨,所以想写点东西供大家参考。

本人07年硕士毕业,毕业后去了上海在一个外资公司干了三年时间,10年从公司辞职回到西安自主创业,目前有自己的一个小公司。当然也是刚刚起步。

谈谈我对与工作的一个体会还有我对于人生的一个观点。记得前两天看《钱学森》的时候钱老在病榻之时说过,想作为一个合格的科技工作者不能埋头于技术本身,还要懂得文学与音乐,记不得具体的说法了,大概就是这个样子。

以下是我真实的经历,与诸公分享。

我是07年5月30号到上海报道,这一天股市大跌,所以我记忆深刻,我刚到上海就发现身边的人不是在讨论股票,就是在讨论房子,我一直问自己的一个问题是我怎么能在上海买得起房子,我当时的观点是:社会是不公平的,又是公平的,我不用去关心这些问题,我要做的就是努力学好技术,上海由10000套房子,我就必须排名在10000名以内,我就能有房子,因而我在刚到公司的一年时间里,每天晚上都工作到11点,每天我老婆都睡着了,我还要看很长时间的书,经常一个月30天都在公司里,这样的工作确实起到了一定的效果,我的技术实力很快在公司得到了认可,在第一年我的调薪最后我了解到是我同期去的人的三倍。我说这些不是为了炫耀,是为了给我真正想说的做一个铺垫。

阅读全文...

数组、指针和地址运算:一个经典的小问题

2012年3月18日 没有评论

---

在《The C Programming Language》中提到,数组、指针和地址的算术运算是C语言的一大优点,使用指针运算不仅能使得代码简洁精炼,更能编写高效率的程序,但是灵活运用却不是那么容易的事情,在使用过程中可能会遇到很多小问题,本节罗列一个比较经典的小例子。

代码见下:

#include<stdio.h>

void test(char *arg[]);

void main()
{
	char *arg[] =
	{
		"find",
		"-x",
		"-n"
	};
  //printf("%c\n",(*++arg)[0]); // --1
	test(arg);
	printf("%c\n",*++arg[0]); // --2
}

void test(char *arg[])// --3
{
	printf("%c\n",(*++arg)[0]);
}

对于上述代码分析如下:

阅读全文...

动态二维数组的申请与释放:使用指针数组和数组指针在物理空间上的区别

2012年3月18日 没有评论

---

上一篇文章中,我们提到使用数组指针申请动态二维数组时的释放问题,在C/C++中,动态申请二维数组有两种方式,一种是先申请一个指向所需类型的指针数组,然后对数组中的每个元素再依次申请空间,在物理形态上该方法申请了两次空间;另一种是使用数组指针直接申请所需的空间,物理形态上该方法只申请了一次空间。

二者在内存的物理空间上是具有不同的表现形式的,如图所示,本节我们就简单讨论下。

两种方法皆见代码,为了对比,我们也定义了一个一维数组;为了验证上面所说的二者在物理空间上的形态差别,我们分别输出了一系列变量。

阅读全文...

C/C++内存泄漏检测 & 数组指针的空间释放

2012年3月18日 1 条评论

---

周一助教上机课,有学生问到动态申请的二维数组空间如何释放,对于使用二维指针申请的只要一步步释放掉就可以了,让人可能产生疑惑的就是使用数组指针申请的情况,即

int (*p)[3] = new int [4][3];
// ...
delete []p;    //---1
delete[](*p);  //---2

在释放这个二维数组时,应该使用1和2哪种方式呢?哪种对呢?

其实静心分析下,并不难,哪种写法都是对的。

为什么?

首先我对于每种释放情况都测试内存是否有泄漏,以此验证释放的正确性;然后我们使用最直接的方法输出相关数据来验证释放的正确性。

对于C/C++如何检测内存泄露,就是简单的库调用,这里不赘述,详见下面代码和参考文献,不过注意,检测结果的信息输出是在调试的情况下查看输出窗口(output)的

#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>

#include <stdio.h>

void main()
{
	int (*p)[3] = new int [4][3];

	//delete []p;
	delete[](*p);

	_CrtDumpMemoryLeaks();//调试运行到该步,输出检测信息
}

阅读全文...

volatile关键字

2012年3月18日 2 条评论

---

The C Programming Language》中提到volatile关键字,没怎么看明白,就查了一点资料,另外,实验室的“万古萌物”童鞋给我提供了一个小例子,如下两张图片很好地说明了volatile关键字的用途。

volatile关键字在嵌入式中用的比较多,同const一样都是类型限定符。

volatile关键字在当一个变量有可能意外地发生变化(如多线程应用中被几个任务共享的变量)的情况下使用。volatile意在阻止编译器对该变量进行优化,防止因其意外改变而发生错误。即,在用到这个变量时,都会从新从该变量的原始地址读取变量值,而不是直接读取保存在寄存器中的值

    

阅读全文...

分类: C/C++ 标签: ,

二进制思考系列文章(目录)

2012年3月2日 2 条评论

二进制思考(四):位运算经典题目练习

2012年3月2日 没有评论

---

本文主要是基于《The C Programming Language》的位运算题目进行了一个整理,第一道题和第四道题都是该书中的题目,本节在这里给出一些可能的实现。

========目录=======

--二进制1的个数

--前导0的个数

--二进制逆序

--二进制循环移位

--高低位交换

==================

二进制1的个数

计算二进制1的个数,位运算可以有多种方法,本文实现了三种方法,前两种思想基本一样,细节不同,可对比看一下,欢迎讨论,代码如下

阅读全文...

二进制思考(三):位排序、位索引(bit-map)简单举例

2012年3月1日 3 条评论

---

本节目的是利用上一节的知识加深理解《编程珠玑》中的一道位排序题目,位排序的思想比较简单,具体代码见参考文献吧,这里就不罗列了。

本文主要是写一下《The C Programming Language》第二章中一道非常简单的小题目,文中使用了三种方法,可以对比一下。

题目:编写函数squeeze(s1,s2),将字符串s1中任何与字符串s2中字符匹配的字符都删除。

分析:这道题目的注意点主要有两个,一是搜索匹配的字符,二是删除字符时后续字符的前移。这两方面都是有技巧在里面的,见代码

方法一:暴力搜索

#include<stdio.h>

void squeeze(char *s1, char *s2);
int ishave(char *s2, char c); // 判重

void main()
{
	char s1[] = "abcdefghigklmn";
	char s2[] = "helloworld";
	squeeze(s1,s2);
	printf("%s\n",s1);
}

void squeeze(char *s1, char *s2)
{
	int i = 0, j = 0;
	for(; s1[i] != '\0'; ++i)
	{
		if(!ishave(s2,s1[i]))
		{
			s1[j++] = s1[i];
		}
	}
	s1[j] = '\0';
}

int ishave(char *s2, char c)
{
	int i = 0;
	while(s2[i] != '\0')
	{
		if(s2[i] == c)
			return 1;
		++i;
	}
	return 0;
}

阅读全文...