C语言
文章平均质量分 81
梦想与坚持
勤能补拙是良训,每个人生来都不是优秀的。
展开
-
#ifdef、#if defined、#ifndef的使用
1.#ifdef和#if defined 注意两者都有个define的作用,区别在于使用方式上。前者的通常用法是:#ifdef X ....#else ....#endif 只能在两者中选择是否有定义。对于后者,常用法是:#if defined x1 ....#elif defined x2 ....#elif de原创 2014-11-21 14:47:45 · 2081 阅读 · 0 评论 -
C语言中宏定义使用方法详解
C语言中的宏替换详解首先看一个问题:#include #define PRINT_CLINE() printf("%d", ______)int main(void) { PRINT_CLINE(); PRINT_CLINE(); return 0;}在横线处填上适当的代码,使得上面这段代码的输出为34。原创 2014-09-20 21:56:45 · 3465 阅读 · 1 评论 -
C语言中的零长度数组使用说明
C语言中的零长度数组用法详解 在C语言中允许在结构体和联合体中定义零长度的数组,写法可以是以下两种:char p[]或者char p[0],这个数组定义在结构体或者联合体中,不占用空间大小。这是个广泛使用的常见技巧,常用来构成缓冲区。比起指针,用空数组有这样的优势: 1.不需要初始化,数组名直接就是所在的偏移; 2.不占任何空间,指针需要占用int长度空间,空数组不占原创 2014-09-20 23:35:35 · 3105 阅读 · 0 评论 -
const int *p,const * int p,int const *p
1 从const int i 说起 有了const修饰的ic 我们不称它为变量,而称符号常量,代表着20这个数。这就是const 的作用。ic是不能在它处重新赋新值了。 认识了const 作用之后,另外,我们还要知道格式的写法。有两种:const int ic=20;与int const ic=20;。它们是完全相同的。这一点我们是要清楚。总之,你务必要记住const 与转载 2014-02-13 16:45:46 · 699 阅读 · 0 评论 -
第四章 高质量C编程规范表达式和基本语句
1.运算符的优先级高质量C编程规范表达式和基本语句" TITLE="第四章 高质量C编程规范表达式和基本语句" /> 注意:(1)强制类型转换和sizeof是单目运算符。(2)移位运算符的优先级低于双目运算符。(3)>>之后是>之后是&之后是&&。2.规则(1)如果代码行中的运算符比较多,用括号确定表达式的操作顺序,避免使用默认的优先级。(2)将整型变量用“==”或“!=”直原创 2014-01-03 21:49:08 · 904 阅读 · 0 评论 -
C语言笔记系列之三——运算符
1.运算符的分类:单目运算符,双目运算符,三目运算符。2.任何一个表达式都是栈式运算,先进后出,后进先出。例如:计算2 + 3 * 5的动态过程,会被转换为2 3 5 *+的顺序输入栈中,但是有一个规则是碰见数就往栈中存储,碰见一个运算符就从栈中取出两个数。所以首先2和3入栈,然后5入栈,碰到*号,3和5出栈做*运算,运算结果放入栈中,然后碰到+号,然后从栈中取出2和3*5的值,做加运算。原创 2014-01-03 21:47:52 · 1470 阅读 · 0 评论 -
多层循环嵌套结构的设计
在很多编程的书籍中会给出这样的建议: 在多重循环中,如果有可能,应当将最长的循环放在最内层,最短的循环放在最外层,以减少CPU 跨切循环层的次数。 这个“跨循环层”的概念本身是说,由外层循环进入内层循环是要重新初始化循环计数器的,包括保存外层循环的计数器和加载内层循环计数器,退出内层的时候再恢复外层循环计数器。把长循环放在里面可以显著减小这些操作的数量。看下面两个循环结构:原创 2014-09-05 16:07:32 · 3133 阅读 · 0 评论 -
数组名的理解
数组名的再理解先看下面的这段代码,程序会输出什么结果?#include int main(){ int a[5] = {1, 2, 3, 4, 5}; int *p = (int *)(&a+1); printf("%d %d\n", *(a+1), *(p-1)); return 0;}答案详见本文的最后。先来一步步原创 2014-09-04 23:03:10 · 688 阅读 · 0 评论 -
在C语言中实现面向对象
C语言是结构化和模块化的语言,它是面向过程的。但它也可以模拟C++实现面向对象的功能。那么什么是对象呢?对象就是一个包含数据以及于这些数据有关的操作的集合,也就是包含数据成员和操作代码(即成员函数)。用C语言实现面向对象功能主要就是实现拟“类”的继承,函数的重载等操作,这些主要是通过结构体和指针函数实现的。 在C++和Java中,多态行为是由一种动态连接机实现的,比如,在C++中定义转载 2014-02-13 17:09:18 · 831 阅读 · 0 评论 -
C语言笔记系列之二——变量
1.变量:内存中的一个存储单元称之为一个变量。2.变量名 命名法:由数字、字母以及下划线构成,以字母或下划线作为起始,可包含其中的一种两种或者三种。 变量值:变量单元中存储的常量值。 注意:在C语言中不可以定义同名变量,命名变量名时不可以和保留字相同。3.变量的定义:int a;int提供大小,变量名提供名称。4.如下程序片段:int x = 32767; x = x +原创 2014-01-03 21:47:50 · 836 阅读 · 0 评论 -
C语言笔记系列之十——结构体
1.基本格式struct student{ int age; char sex; float height;};struct student s1,s2,s3;2.结构体成员的引用变量名.成员名数组名[下标].成员名(*指针变量).成员名:点运算符的优先级高于*运算符,所以必须要加括号。指针变量->成员名3.同类型的结构体变量之间可以直接赋值。struct原创 2014-01-03 21:48:07 · 683 阅读 · 0 评论 -
C语言指针——指针和数组
先看一个常用的例子:#include int main(void){ int a[3] = {1,2,3}; int *p = a; printf("%d ", p[0]); return 0;} 这段代码编译和运行都没有任何问题,程序会打印出1这个值,但是为什么可以这样用呢?p明明是一个int类型的指针,这里怎么可以使用p[0]这原创 2014-09-26 09:35:14 · 1625 阅读 · 0 评论 -
《C陷阱和缺陷》整理四
1.assert宏的定义#define assert(e) \ ((void)((e) || _assert_error(__FILE__, __LINE__))) 库里面对这个宏做了这样的定义,当宏参数(或表达式)e为真的时候由||运算符的运算规则会执行_assert_error(__FILE__, __LINE__)从而打印一条报警信息。所以整个表达原创 2014-10-16 00:26:00 · 1299 阅读 · 0 评论 -
《C陷阱与缺陷》整理三
1.大多数C语言的实现都通过函数main的返回值来告诉操作系统该函数的执行是成功还是失败。典型的处理方案是,返回值为0代表程序执行成功,返回值非0则表示程序执行失败。如果一个程序的main函数并不返回任何值,那么有可能看上去执行失败。所以建议我们的C程序的main函数应该如下编写:int main(){ return 0;}当然如果main函数需要接受参数的话将参数声明加原创 2014-10-13 14:59:59 · 1071 阅读 · 0 评论 -
《C陷阱与缺陷》整理一
1.词法分析中的“贪心法” C语言的某些符号,例如/、*和=,只有一个字符长,称为单字符符号。而C语言中的其他符号,例如/*和==,以及标识符等都包含了多个字符,称为多字符符号。当C编译器读入一个字符'/'后又跟了一个字符'*',那么编译器就必须做出判断:是将其作为两个分别的符号对待,还是合起来作为一个符号来对待。C语言对这个问题的解决方案可以归纳为一个很简单的规则:每一个符号应该包含尽原创 2014-10-11 08:17:01 · 1211 阅读 · 0 评论 -
《C和指针》整理一
1.C语言的注释 在C语言中,如果需要注释掉一段代码,且代码中可能会已经存在/**/注释形式,那么可以使用:#if 0 statements#endif 这种形式来注释掉这段代码(statements代表这段代码)。这样做的原因是C语言不允许嵌套注释,也就是说第一个/*和第一个*/符号之间的内容都被看作注释,不管里面还有多少个/*符号。2.换行符的处理原创 2014-10-28 10:45:23 · 1024 阅读 · 0 评论 -
《C陷阱与缺陷》整理二
1.在C语言中,我们没有办法将一个数组作为函数参数传递,如果我们使用数组名作为参数,这个时候数组名立刻会被转换为指向该数组的第一个元素的指针。 关于这一点的理解可以向前深入一步,比如定义的数组为int a[3],那么a作为参数传递之后会变为int *类型;如果定义的数组为int a[3][4],那么a作为参数传递之后被变为int (*)[4];如果定义的数组为int a[3][4][5]原创 2014-10-11 16:24:05 · 981 阅读 · 0 评论 -
C语言中main函数的参数详解
main函数的定义形式 main函数可以不带参数,也可以带参数,这个参数可以认为是 main函数的形式参数。C语言规定main函数的参数只能有两个,习惯上这两个参数写为argc和argv。所以C99标准中规定只有以下两种定义方式是正确的: int main(void) //无参形式 int main(int argc, char *argv[]) //有参形式原创 2014-09-17 09:33:55 · 6312 阅读 · 1 评论 -
指针数组和数组指针详解
指针数组和数组指针1.定义int *p[4]; //定义了一个指针数组p,p一共有4个单元,每个单元都是一个int型的指针int (*p)[4]; //定义了一个数组指针p,p可以指向一个拥有4个单元的int型数组2.指针数组的用法#include int main(){ int *p[4]; int a=1, b=2, c=3, d=4;原创 2014-09-12 16:14:03 · 1069 阅读 · 0 评论 -
C语言指针——指针的运算
说指针之前,先说两个比较不相关的东西,也当做是一种知识的补充。看下面的代码:#include int main(void) { char *s = "Hello world."; printf(s);}运行这段代码,会出现错误吗?如果出现错误,是什么错误? 分析:printf一种常规的用法就是printf("Please input a原创 2014-09-25 22:31:57 · 1796 阅读 · 0 评论 -
你必须知道的495个C语言问题整理三
1.为什么大家都说不要使用gets()?跟fgets() 不同, gets() 不能被告知输入缓冲区的大小,因此不能避免缓冲区的溢出。标准库的fgets() 函数对gets() 作了很大的改进, 尽管它仍然不完善。2. fgetops/fsetops 和ftell/fseek 之间有什么区别? fgetops()和fsetops() 到底有什么用处?ftell() 和fseek() 用长原创 2014-01-03 21:50:18 · 943 阅读 · 1 评论 -
C语言文件操作
c语言文件操作13.3 文件的打开与关闭 文件在进行读写操作之前要先打开,使用完毕要关闭。所谓打开文件,实际上是建立文件的各种有关信息,并使文件指针指向该文件,以便进行其它操作。关闭文件则断开指针与文件之间的联系,也就禁止再对该文件进行操作。在C语言中,文件操作都是由库函数来完成的。在本章内将介绍主要的文件操作函数。13.3.1 文件的打开(fopen函数)转载 2014-01-08 09:45:23 · 1424 阅读 · 0 评论 -
C语言笔记系列之十一——位段+联合体+枚举
1.编译指令:gcc 文件名 –o 执行文件 //o要小写执行指令:./执行文件2.数组的初始化时候不能使用a[5] = {1, 2, , , 4, 5}这种语句是错误的;如果只对数组的部分元素初始化(从前往后)那么后面未被初始化的元素自动赋0。3.sizeof(数组名)在数组可见范围内得到的结果是数组的大小,如果是传递参数得到的数组名,那么测试出来的大小是数组第一个单元的大小。原创 2014-01-03 21:48:29 · 1144 阅读 · 0 评论 -
C语言笔记系列之九——指针
1.将一个内存单元的地址称为该内存单元的指针。指针的指向即该指针所表示的存储单元。2.指针变量的定义int * p;p就是一个int型的指针变量,*表示其后的变量为指针变量。3.当指针p指向数组的首地址时,元素a[i]可以表示为*(a+i), *(p+i),p[i]。4.指向字符串的指针char *p = “china”;这种定义不同于定义一个字符型数组来存放这个字符串!5.二级指针原创 2014-01-03 21:48:05 · 520 阅读 · 0 评论 -
C语言笔记系列之八——函数
1.函数若无返回值,即无return语句——void类型。void类型表示:无返回值类型。若函数的返回值类型为void型,那么函数体中一定无return语句。2.若函数缺少数据类型,则默认为int型。3.系统函数的调用优先于自定义函数。4.被调函数运行完成后若带值返回,只允许返回一个值。5.形参和实参(1)只有在发生函数调用时若发生数据传递,才可能存在实参和形参,实参和形参是一对概念,原创 2014-01-03 21:48:03 · 523 阅读 · 0 评论 -
C语言笔记系列之七——字符串
1.字符串末尾会存放一个‘\0’,其ASCII值为0。2.\\表示斜杠字符,单个的\表示转义符号。3.“china\0”有效字符数为5个,其后仍会被系统添加\0。4.“”表示空串,被存储为\0。5.字符串常量可以为空串,字符常量不能为空。6.一个字符型数组是否存储字符串取决于数组中是否存在\0字符。7.一维字符数组的初始化char a[]10] = {'c','h','i','n',原创 2014-01-03 21:48:01 · 622 阅读 · 0 评论 -
C语言笔记系列之六——数组及冒泡排序
1.数组:分配的内存中一块连续的单元。数组元素的地址:&数组名[下标] 或者 数组名+ 下标。在C语言中数组名用来表示数组第一个单元的地址,也就是数组名表示数组的首地址。2.冒泡排序法for(i = 0; i { for(j = i + 1; j { if(a[i] <a[j]){交换;} }}思想:从数组中第一个数起,将第一个位置的数据与后面的数据依次比原创 2014-01-03 21:47:58 · 801 阅读 · 0 评论 -
C语言笔记系列之五——条件判断语句
1.一个#include只能加载一个头文件,一般一行只写一个头文件,写多个只要有多个#include也不会报错。2.if为真语句若有多个语句构成的一个整体时,必须加大括号,否则计算机只将第一条语句作为为真语句。3.if必须要跟为真语句,可以是空语句,但是不能不跟语句。4.if-else一个整体是一条语句,不是两条语句。5.while语句是一条单语句,while语句必须要有循环体语句,wh原创 2014-01-03 21:47:56 · 1471 阅读 · 0 评论 -
C语言笔记系列之四——输入输出控制
1.%输出格式:%d:整型%o:字母o,不是数字0,八进制%x:十六进制%u:无符号整型%ld:有符号长整型%e:以指数形式输出%g:有选择的以%f或者%e格式输出实数2.输出列宽控制:(o,x,u,c,d)%+/-md:m表示数据输出时的列宽,当m大于数据的实际列宽则加补空格,如果m小于数据的实际列宽则以数据的实际列宽输出。加补空格规则:+号表示左边补空格,-号表示右边补空格原创 2014-01-03 21:47:54 · 640 阅读 · 0 评论 -
C语言笔记系列之一——常量
1.常量:在程序的运行过程中不改变的量。 一个数据的类型决定了存储空间的大小。2.八进制的表示方法:075, -072,正负号+零+八进制数 十六进制的表示方法:0x75,0xfd,正负号+零+x+十六进制数3.整型常量的存储:在计算机内存中以补码的形式存储。 正数补码:就是原码。 负数补码:先找到原码,然后除符号位以外各位取反,最后加1。4.负数由补码找原码:从该数的原原创 2014-01-03 21:47:48 · 619 阅读 · 0 评论 -
realloc关键字
原型:extern void *realloc(void *mem_address,unsigned int newsize);语法:指针名=(数据类型*)realloc(要改变内存大小的指针名,新的大小)。//新的大小一定要大于原来的大小,不然的话会导致数据丢失!头文件:#include 有些编译器需要#include,在TC2.0中可以使用alloc.h头文件功能:先判断当前的指针原创 2014-01-03 21:47:44 · 516 阅读 · 0 评论 -
第一章 高质量C编程规范&文件结构
1.版权和版本的声明版权和版本的声明位于头文件和定义文件的开头(参见示例1-1),主要内容有:(1)版权信息。(2)文件名称,标识符,摘要。(3)当前版本号,作者/修改者,完成日期。(4)版本历史信息。示例1 2. 头文件的结构头文件由三部分内容组成:(1)头文件开头处的版权和版本声明(参见示例1-1)。(2)预处理块。(3)函数和类结构声明等。说明:为了防止头文件被重复引原创 2014-01-03 21:49:02 · 623 阅读 · 0 评论 -
第二章 高质量C编程规范程序的版式
1.空行空行不会浪费内存,在适当的地方加上空行会提高程序的可读性。(1)在每个类声明之后、每个函数定义结束之后都要加空行。(2)在一个函数体内,逻揖上密切相关的语句之间不加空行,其它地方应加空行分隔。比如变量定义后,if语句之后等。2.代码行(1)一行代码只做一件事情,如只定义一个变量,或只写一条语句。这样的代码容易阅读,并且方便于写注释。例如:int width;原创 2014-01-03 21:49:04 · 589 阅读 · 0 评论 -
你必须知道的495个C语言问题整理二
1.在调用malloc() 的时候, 错误“不能把void * 转换为int *”是什么意思?说明你用的是C++ 编译器而不是C 编译器。2. 我用一行这样的代码分配一个巨大的数组, 用于数字运算: double*array =malloc(300 * 300 * sizeof( double )); malloc() 并没有返回null,但是程序运行得有些奇怪, 好像改写了某些内存,原创 2014-01-03 21:50:16 · 828 阅读 · 0 评论 -
你必须知道的495个C语言问题整理一
1.在使用全局变量时,一般将定义放在.c文件中,而将声明放在.h文件中,定义变量的.c文件也应该包含该头文件, 以便编译器检查定义和声明的一致性。2. 永远不要把外部函数的原型放到.c 文件中: 通常它与定义的一致性不能得到检查,而矛盾的原型比不用还糟糕。3. 在函数外声明的变量和有静态存储类型的变量可以确保初始值为零, 就像程序员键入了“=0”一样。因此, 这些变量如果是指针会被初始化原创 2014-01-03 21:50:10 · 1407 阅读 · 0 评论 -
第十章 高质量C编程规范其他经验
1. const 只能修饰输入参数:如果输入参数采用“指针传递”,那么加const修饰可以防止意外地改动该指针,起到保护作用。例如StringCopy 函数:void StringCopy(char *strDestination, const char*strSource);其中strSource 是输入参数,strDestination 是输出参数。给strSource加上cons原创 2014-01-03 21:49:22 · 654 阅读 · 0 评论 -
第九章 高质量C编程规范类的构造函数、析构函数与赋值函数
1.每个类只有一个析构函数和一个赋值函数,但可以有多个构造函数(包含一个拷贝构造函数,其它的称为普通构造函数)。对于任意一个类A,如果不想编写上述函数,C++编译器将自动为A产生四个缺省的函数,如A(void); // 缺省的无参数构造函数A(const A &a); // 缺省的拷贝构造函数~A(void); // 缺省的析构函数A & operate =(const A&a);原创 2014-01-03 21:49:20 · 577 阅读 · 0 评论 -
第八章 高质量C编程规范C++函数的高级特性
1. 如果同名函数仅仅是返回值类型不同,有时可以区分,有时却不能。在C++/C程序中,我们可以忽略函数的返回值。所以只能靠参数而不能靠返回值类型的不同来区分重载函数。2. 如果C++程序要调用已经被编译后的C 函数,该怎么办?假设某个C 函数的声明如下:void foo(int x, int y);该函数被C编译器编译后在库中的名字为_foo,而C++编译器则会产生像_foo_int_原创 2014-01-03 21:49:17 · 783 阅读 · 0 评论 -
第七章 高质量C编程规范内存管理
1.内存分配方式(1)从静态存储区域分配。例如全局变量,static 变量。(2)在栈上创建。例如局部变量。(3)从堆上分配,亦称动态内存分配。例如malloc、free以及new、delete。2.常见的内存错误及其对策(1)内存分配未成功,却使用了它。常用解决办法是,在使用内存之前检查指针是否为NULL。可以用判断空或者断言检查。(2)内存分配虽然成功,但是尚未初始化就引用它。原创 2014-01-03 21:49:15 · 700 阅读 · 0 评论 -
第六章 高质量C编程规范函数设计
1. C 语言中,函数的参数和返回值的传递方式有两种:值传递(pass byvalue)和指针传递(pass by pointer)。C++ 语言中多了引用传递(pass by reference)。2.参数的规则(1)参数的书写要完整,不要贪图省事只写参数的类型而省略参数名字(指的是在函数声明的时候)。如果函数没有参数,则用void填充。(2)参数命名要恰当,顺序要合理。一般地,应将原创 2014-01-03 21:49:13 · 917 阅读 · 0 评论