- 博客(34)
- 资源 (4)
- 收藏
- 关注
原创 冒泡法
冒泡排序法规律总结1、如果有N个数,则需要进行N-1趟排序,决定最外层的循环for (int i = 1; i 2、每一趟重复执行的动作是相邻的两个数进行比较,if (a[j-1] > a[j])则交换a[j-1]与a[j]的值。 3、每一趟到底比较多少次呢?每一趟比较j都是从1循环到N-i,因此比较的次数如下:for (j = 1; j <= N - i; ++j
2012-03-31 17:20:49 683
原创 函数设计中存在的一些问题
对函数传入,是指用实参将外部数据传给函数,以便于在函数体内对其处理。对函数传出,是指用返回值将函数处理的结果交给主调函数。 设计函数时要考虑到:1、函数是否担负修改实参的任务?2、传入实参是否会影响效率?3、形参是否还要承担向调用者传递部分结果的任务? 关注函数的返回值:当它是变量或对象时,一切OK。因为返回值是局部变量的复制品。但若返回值是地址或引用,则要引起
2012-03-31 14:56:46 1029
原创 void指针的操作
1、可以与另一个任何类型的指针相比较;2、可以向函数的void类型的形参传入指针,但不可向非void类型的形参传入void指针;3、函数可以返回void类型的指针;4、可以向另一个该类型的指针赋值;5、可以得到任何类型的指针的值;6、不得对其所指向的对象进行任何操作;7、指向void*的二级指针类型还是void*。
2012-03-30 22:41:37 866
原创 为什么使用二级指针
设计一个函数:void find1(char array[], char search, char *pa) 要求: 这个函数参数中的数组array是以\0值为结束的字符串,要求在字符串array中查找与参数search给出的字符相同的字符。如果找到,通过第三个参数(pa)返回array字符串中首先碰到的字符的地址。如果没有找到,则为pa为NULL。依题意,实现代码如下
2012-03-30 21:48:47 5311 2
原创 指针使用时需要注意的问题
1、未分配内存就使用它;2、内存分配未成功,却使用了它;3、内存分配虽然成功,但是尚未初始化就使用它;4、内存分配成功并且已经初始化,但操作越过了边界;5、忘记了释放内存或只释放一部分,造成内存泄漏;6、释放了内存却继续使用它;7、程序中的对象调用关系过于复杂,实在难以搞清楚某个对象究竟是否已经释放;8、函数return语句写错了,返回了栈内存的地址;9、使用fre
2012-03-30 20:41:02 946
原创 字符串常量
字符串常量是数组首地址,因此可以数组引用的形式使用它,例如printf("%s", &"abcdefghi"[4]);输出结果为efghi。还何以这样:printf("%s", "abcdefghi" + 4);输出结果同样为efghi。
2012-03-30 17:43:09 608
原创 指针与数组
#include int main(void){ int a[5]= {1, 2, 3, 4, 5}; int *ptr = (int *)(&a + 1); // 先取地址再加1 //printf("%p, %p\n", &a+1, ptr); //将地址输出 printf("%d, %d\n", *(a + 1), *(ptr - 1));
2012-03-30 17:29:16 576
原创 数组指针和指针数组
数组指针即指向数组的指针变量, 以二维数组为例,它的一般说明形式为:类型说明符 (*指针变量名)[长度] 其中 “类型说明符”为所指数组的数据类型。 "*"表示其后的变量是指针类型。“长度”表示二维数组分解为多个一维数组时,一维数组的长度,也就是二维数组的列数。类似的,对于一个指向N维数组的指针可以这样定义: 类型说明符 (*指针变量名)[长度]
2012-03-30 17:00:10 876
原创 单个字符在内存中的存储
char ch = 'a';printf("%d\n", sizeof ch); // 结果为1再看这行代码:char ch1 = 'abcd';printf("%d\n", sizeof ch1);此时ch1存的还是a,只占一个字节,初始化时会有警告。 但是不再定义变量,直接测试 printf("%d\n", sizeof 'a');printf("
2012-03-30 16:14:18 807
原创 对数组名含义的理解
int array[3][4] = {...};区分array+1 和&array+1。 array+1是从array算起,按int[4]类型的大小,向前移动一步,此时array+1的值指在array[1]处。 而&array+1是从array算起,按int[3][4]类型的大小,向前移动一步(此步很大,整整扩过了二维数组), 此时&array+1的值指在二维数组array
2012-03-30 15:56:44 1329
原创 对数组进行“整体赋值”
数组是不可以整体赋值的,但常常需要用到数组的赋值,以避免写循环。这能否做到? C语言中能赋值的只有变量,只要让数组变量化,变量赋值时岂不捎带将数组完成了赋值?! 能含有数组的类型只有结构体。于是可以:struct name{ int array[10];}a, b;于是,在a = b;时就完成了数组的赋值。注意:切不可“自赋值”,那会造成“内存重叠”,其
2012-03-30 15:47:08 11804
原创 关于数组元素个数
编程中常常需要用到数组的元素个数,判断是否越界。推荐一个比较方便、安全的方式:#define ARRAY_TOTAL(a) (sizeof(a) / sizeof(a[0]))const INT8U array[] = {0, 1, 2, 3, 4, 5};for (INT8U i = 0; i < ARRAY_TOTAL(array); ++i){ ... ...
2012-03-30 15:36:55 1113
原创 字符数组的初始化
对字符数组初始化时,若指定元素个数,则编译器会自动加尾\0,否则不加。但若采用双引号初始化,则会加。char a1[10] = {'a', 'b', 'c', 'd'};char a2[] = {'x', 'y', 'z'};char a3[] = "hello";printf("%s\n", a1);printf("%s\n", a2);printf("%s\n", a3);
2012-03-30 14:43:48 799
原创 静态变量的初始化
静态变量的初始化只能靠常量,不能用变量、函数调用。但可以使用自身。eg:static int intsize1 = sizeof(intsize1);int main(void){ static int intsize2 = sizeof(intsize2); printf("%d\n", intsize1); printf("%d\n", intsize2)
2012-03-30 14:03:04 561
原创 函数中的数组
不要以为函数尚未调用时,数组就没规划空间。若用参数为数组指定元素个数,等函数被调用时,形参就有值了,此时创建数组m和n都已确定,于是就写成void user(int m, int n){ char A[m][n];}这种写法是错误的,数组(动态分配的除外)的大小是在编译的时候就“规划了”空间需求。尽管尚未真正分配空间。而形参变量在函数未调用时其值未定,编译器无法得到需求
2012-03-30 00:21:32 1206
原创 内存划分
内存分为四个区域在嵌入式系统中:栈区 存放程序的局部变量和形参静态区 存放程序的全局变量和静态变量堆区 存放程序动态申请的数据代码区 存放程序的代码和常量栈区、静态区和堆区统称为数据区。在windows中,常量保存在静态区,即静态区分为静态读写区,和静态只读区。栈区的大小由编
2012-03-29 23:33:10 501
原创 关于Typedef
功能:用自定义名字为已有数据类型命名。类型定义一般形式: typedef 原有类型 新别名;说明:1、typedef没有创造新数据类型。2、typedef是定义类型别名,必能定义变量。3、typedef与define不同。define预编译时处理,简单字符置换。typedef编译时处理,为已有类型命名。用处:1、用于屏
2012-03-29 23:24:52 693
原创 结构体
工程中这样使用结构体struct B{ char c1; char c2; char pading[2]; int a; float f;};
2012-03-29 23:13:31 413
原创 好的编码习惯
编写代码的时候,没做完一件事就加一个空行1)将各种输入的判断和函数主体用空行分开2)将参数判断与内部数据的【判断用空行分开3)将函数主体分成小段落 a)每一小段代码不超过7行,每段代码只做一件事 b)每一段代码是子函数的备选注释:尽量用变量名和函数名来进行自说明1)注释不要只是代码的简单重复2)在需要加注释的时候,就要想想是否应该封装
2012-03-29 21:33:15 666
原创 循环结构函数设计小结
先判断各种输入,如果不合法或不正确,直接return或return错误。1) 参数是否合法2) 函数处理需要的内部数据或状态是否正确函数主体1)如果每次循环的处理是针对不同的节点做同一件事情则, 将这件事的具体处理封装为子函数2) 如果是查找到附和提交条件的点,做一个处理即, 将该处理封装为子函数
2012-03-27 23:42:39 532
原创 顺序结构函数设计小结
先判断各种输入,如果不合法或不正确,直接return或return错误。1)参数是否合法2)函数处理需要的内部数据或状态是否正确。函数主体1)如果是并列做了几件事(可能是通信内聚或临时内聚) 就要把每件事封装成子函数2)如果是按顺序做了几件事 a) 如果几件事之间都是为了同一个目的,就是顺序内聚,要把每件事封装为子函数。 b)
2012-03-27 23:16:23 664
原创 分支结构函数设计小结
先判断各种输入,如果不合法或不正确,直接return或return错误1)参数是否合法2)函数处理需要的内部数据或状态是否正确函数主题部分1)对于if类型的,如果每个条件的处理超过2行代码,就是逻辑内聚,需要将每个条件下的处理封装为子函数2)对于switch类型的: a)如果只是根据不同的条件进行赋值,则可以用查表方式重构 b)否则就是逻
2012-03-27 23:05:14 667
原创 函数重构
函数重构发生在什么时候1、编写代码时 编写的过程中一旦发现函数逻辑有点儿复杂,就要进行函数的重构。(这应该是函数重构最重要的时刻)2、维护代码时 1) 添加功能时,如果发现函数过于复杂,要进行函数的重构。 2) 修改bug如果发现函数很难理解,很难维护,也要进行函数的重构。重构3原则原则1: 函数主题超过10行就意味着可能需要进行重构
2012-03-26 23:50:28 4900
转载 嵌入式工程师C语言面试常见的0x10个问题
1、用预处理指令#define声明一个常数,用以表明1年中有多少秒(忽略闰年问题)#define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL 要点:①#define语法的基本知识(例如:不能以分号结束、括号的使用,等等)②懂得预处理器将为你计算常数表达式的值,因此,直接写出你是如何计算一年中有多少秒而不是计算出实际的值,是更清晰而没有代价的。
2012-03-26 22:01:51 3584
转载 解决Cygwin下Emacs启动时出现Doing vfork:resource temporarily unavailable问题
If you try executing a command in emacs and receive an error similar to the following:> apply: Doing vfork: no error> apply: Doing vfork: resource temporarily unavailable [2 times] > “linked dll
2012-03-25 00:13:46 5013 2
原创 共用体的真正的妙用
union obj{ union obj *free_list_link; // 将来,用户向free_list_link链表申请“块”,成功则从链表摘下一个块。 // 它时而保存地址,时而保存用户的数据(目前是8bytes)。用户归还时就挂接在链表上。 char client_data[8];}
2012-03-24 20:24:41 1170
原创 共用体的妙用
比如,构造一个共用体:union KeyCode { short int keynum; char byte[2]; }kc;当用kc接受接盘输入的字符时,计算机将把它转换成一个双字节的整数编码,其中Byte[1]存放的是高字节的值,是键盘的扩展码; Byte[0]存放的是低字节的值,即ASCII码;而keynum则是它的整体值。用类似的
2012-03-24 17:08:05 712
原创 如何得知共用体使用的是哪个成员
下面给出一个解决方案:首先定义一个枚举类型,用以标识共用体中哪个成员是可用的:enum widget_tag {count_w, value+w, name_w};然后再用结构体将共用体和枚举包装起来:struct WIDGET{ enum widget_tag tag; union { long count;
2012-03-24 16:56:24 753
原创 结构体的可伸缩型数组成员
struct flex{ int count; double average; double scores[];};这种不给出元素个数的数组叫做可伸缩型数组成员。这种类型不能只有可伸缩型数组成员,至少应再含有一个有名成员。注意:在使用时不要声明flex类型的变量,因为其中的scores没有得到空间。只能声明flex类型的指针,由它指向堆空间。
2012-03-24 16:43:43 1258
原创 区分结构体的嵌套和组合
struct S1{ int a; /* 下面属于嵌套 */ struct S2 { double b; char c; }b; char c[4];}x = {1, {4.5}}; // OK,属于不完全初始化struct A{ int i; int j;};struct
2012-03-24 12:34:38 831
原创 一个程序员的成长阶段
一开始:把所有的功能都放在一个函数里;进步:把不同功能的代码分别放在几个函数里;成熟:最终学会了用几个不同的文件来构造函数。
2012-03-24 12:23:50 851
原创 关于“重复声明”
在同一个代码块中或在顶层,对同一个名称进行了多于一次的声明,叫“重复声明”,这种重复可能冲突。 “重复声明”有两种情况是合法的: 1、相同名称的外部引用声明可以出现多次,但外部库函数不行; 2、如果一个标识进行了外部声明,则声明后面可以出现它的定义,于是才有了“前置声明”。
2012-03-24 10:42:58 1156
原创 面向过程和面向对象的一点区别
面向过程的语言(不仅仅是C)是将程序(对数据的一些处理)中的数据和处理分开,使它们天各一方。于是数据们处于无保护、不安全的状态。处理则是凌驾其上、颐指气使、不受约束的驾驭者,而非“服务者”。 对比而言,面向对象的语言(以C++为代表)则是以数据为中心, 处理为其服务的和谐平衡状态。
2012-03-24 10:24:26 736
原创 使用枚举的好处
int main(int argc, char *argv[]){ int i; enum solution {a, b, c, d, max}; // 枚举常量a, b, c, d代表四种不同的解决方案 enum solution(a, b, c, d, e, max); // 当需要增加解决方案时,for循环次数自动调整 for (i
2012-03-24 10:06:26 2289 2
黑客与画家 epub
2012-06-15
kscope-1.6.2
2012-06-11
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人