
c语言
vinnyjia
这个作者很懒,什么都没留下…
展开
-
递归函数
递归函数就是直接或间接调用自身的函数1.一个简单的递归函数与其调用流程#include#includevoid recursion(int a){if (a == 1){printf("%d\n", a);return;}else{recursion(a - 1);printf("%d\n", a);}}int main(){原创 2017-04-15 20:13:41 · 414 阅读 · 0 评论 -
const关键字
1.const修饰变量const代替#define,const有类型,#define无类型,const节省空间,避免不必要的内存分配。const定义的常量在程序运行的过程中,只有一份拷贝,#define定义的常量在内存中有若干个拷贝。编译器一般不会为const常量分配内存,而是将它们保存在符号表中,这使得它成为一个在编译期间的常量。Int a=100;Const int c=3原创 2017-04-04 21:33:53 · 221 阅读 · 0 评论 -
extern关键字
extern关键字置于变量或函数前,用来标志变量或函数的定义在其它文件中,当编译器遇到被extern修饰的变量或函数时,会到其它文件寻找其定义。1.extern 关键字与全局变量。1.1在main.h中声明变量extern int a;//main.hextern int a;在main.cpp中包含main.h头文件,就可以使用全局变量a.//main.cpp#inc原创 2017-04-02 16:08:14 · 291 阅读 · 0 评论 -
二维数组的遍历与利用sizeof关键字求数组的行数,列数,元素总数
在内存中并不存在二维数组,二维数组实际的硬件存储器是连续编址的,也就是说内存中只有一维数组。定义一个数组a[2][3],那么a[0],a[1],分别表示数组第一行和第二行的首地址。遍历二维数组a[L][C]的几种方法:int main(){int a[3][4] = { 0 };int i, j;//数组下标遍历for (i = 0; i {for (j =原创 2017-03-20 20:17:50 · 2255 阅读 · 0 评论 -
c语言常见的字符串处理函数
1.char* gets(char* s),从stdin读入字符,并保存到s指定的内存空间,直到出现换行符或读到文件结束为止。(gets()读取的字符串内可以有空格,scanf()读取的字符串内不可以有空格).读取成功,返回读入的字符串,失败,返回NULL。2.Char* fgets(char* s,int size,FILE* stream);从stream指定的文件读入字符,保存到s指定的原创 2017-03-18 10:14:22 · 502 阅读 · 0 评论 -
字符串与字符数组
C语言中没有字符串这一个数据类型,字符串可用字符数组表示。一个char型数组,如果以‘\0’结束,这个数组就是一个字符串。Char str[]={‘a’,’b’,’c’,’d’};Printf(“%s”,str);//输出乱码Char str[]={‘a’,’b’,’c’,’d’,’\0’};Printf(“%s”,str);//输出abcdChar str原创 2017-03-18 09:52:07 · 288 阅读 · 0 评论 -
有符号数和无符号数
无符号数永远大于0!!!#include#includeint main(){unsigned int a = -1;int b = -1;if (b printf("belseprintf("b!if (a printf("aelseprintf("a!system("pause");return 0;}输出b如果将原创 2017-03-14 20:55:05 · 329 阅读 · 0 评论 -
补码存在的意义
在计算机中,所有的数值都以补码形式存储。正数的补码等于它本身,负数的补码=其反码+1.其原因是:1、采用补码统一了0的编码。 +00000 0000原码0000 0000反码0000 0000补码 -01000 0000原码原创 2017-03-14 19:54:32 · 2417 阅读 · 0 评论 -
C语言的编译步骤
C语言代码翻译成可执行程序,需要经过四个步骤。1.预处理:宏定义展开,头文件展开,条件编译等,同时将代码中的注释删除。2.编译:检查语法,将预处理后的文件编译生成汇编文件。3.汇编:将汇编文件生成目标文件。4.链接:将所需要的库链接到最终的可执行程序中。原创 2017-03-01 14:08:12 · 377 阅读 · 0 评论 -
几种链表的示意图
带头链表:固定一个节点作为头结点(数据域不保存有效数据),起一个标志位的作用,以后不管链表节点如果改变,此头结点固定不变。不带头链表:头结点不固定,根据实际需要变换头结点(如在原来头结点前插入新节点,然后,新节点重新作为链表的头结点)。单向链表:节点中的指针域中只有一个指针,只能从一个方向进行查询,遍历双向链表:节点的指针域有两个指针,可以从正反原创 2017-04-13 17:12:32 · 3897 阅读 · 0 评论 -
c语言变量的作用域
1.代码块作用域{}之间的一段代码,其特点:在一个函数内定义,只在函数范围内有效。2.复合语句作用域if(a){int b=0;}//只在复合语句中有效3.函数作用域void fun(){int a=0;//a的作用域仅限于fun函数}4.文件作用域原创 2017-04-04 21:49:12 · 283 阅读 · 0 评论 -
static关键字
1.静态局部变量static局部变量的作用域也是在定义的函数内有效,但其生命周期和程序运行周期一致,static局部变量的值只初始化一次,但可多次赋值,若未初始化,数值型变量自动赋值为0,字符型变量赋值为空字符‘\0’。void fun(){static int a;cout}void fun2(){static int b=1;++b;cout}原创 2017-04-04 21:50:48 · 204 阅读 · 0 评论 -
Windows下动态库的生成和使用
1.动态库的创建项目属性--常规--配置类型--选择动态库。编译成功后,动态库即生成。__declspec(dllexport):动态链接库中定义有两种函数:导出函数(export)和内部函数(inner),导出函数可以被其它模块调用,内部函数只能在定义它们的dll中使用。动态库生成后,可以看到除了生成.dll文件外,也生成了.lib文件。虽然文件扩展名和静态库相同,但这个.lib原创 2017-04-15 10:58:30 · 737 阅读 · 0 评论 -
windows下静态库的生成和使用
1.静态库的创建配置项目属性,在项目属性的配置属性下选择常规,在其下的配置类型中选择静态库。在源文件写完以后,进行编译,编译以后机会生成相应的.lib静态库文件。2.静态库的使用方法一:方法二:方法三:3.静态库的优缺点原创 2017-04-15 09:47:16 · 1046 阅读 · 0 评论 -
四个特殊的宏定义
__FILE__//宏所在的文件的文件名__LINE__//宏所在的行号__DATE__//代码编译的日期__TIME__//代码编译的时间void fun(){printf("%s\n",__FILE__);printf("%d\n",__LINE__);printf("%s\n",__DATE__);printf("%s\n",__TIME__);原创 2017-04-15 09:43:03 · 274 阅读 · 0 评论 -
带参数的宏定义(宏函数)
宏函数没有普通函数压栈、跳转、返回等的开销,可以提高程序的效率。宏的名字中不能有空格;用括号括住每一个参数,并括住宏的整体定义;用大写字母表示宏的函数名。#define SUM(a,b) ((x)+(y))在程序中执行:int ret=SUM(1,2);//则该语句被替换为int ret=((1)+(2)),宏函数不进行计算。原创 2017-04-15 09:38:37 · 4400 阅读 · 0 评论 -
链表的几种操作
//链表的几种操作,包括,创建链表,插入节点,遍历链表,删除节点,链表排序,链表逆序,销魂链表,获取链表长度#define _CRT_SECURE_NO_WARNINGS#include#include#includetypedef struct student{int id;struct student* next;}STU;//创建头节点STU* c原创 2017-04-14 23:55:00 · 408 阅读 · 0 评论 -
共用体/联合体的使用
共用体也称为联合体,是一个能在同一个存储空间存储不同数据的类型。1.定义一个共用体类型:union un{unsigned char a;//1字节unsigned int b;//4字节unsigned short c;//2字节};//各数据类型的内存大小受操作系统影响,视具体情况而定2.共用体所占的内存大小等于其最长成员的长度sizeof(union原创 2017-04-06 14:14:46 · 1960 阅读 · 0 评论 -
结构体嵌套一级指针
truct person{int age;char* name;};int main(){struct person *p1=(struct person*)malloc(sizeof(struct person));p1->name=(char*)malloc(20);memset(p1->name,0,10);strcpy(p1->name,”jack”原创 2017-04-06 14:12:30 · 309 阅读 · 0 评论 -
内存分区
1.程序未运行前分为代码区(text),数据区(data)和未初始化数据区(bss),数据区和未初始化数据区合起来成为静态区或全局区。代码区:存放CPU执行的机器指令。代码区通常是共享的,使其共享的目的是对于被执行的程序,只需在内存中有一份代码即可。为了防止程序意外地修改指令,代码区通常是只读的。全局初始化数据区/静态数据区:该区包含了在程序中明确被初始化的全局变量,已经初始化的静原创 2017-04-06 13:33:36 · 340 阅读 · 0 评论 -
防止头文件重复包含
1.#ifndef __name_H__#define __name_H__//声明#endif2.#pragma once原创 2017-04-04 22:01:35 · 235 阅读 · 0 评论 -
静态链表与动态链表
静态链表:所有的节点都是在程序中定义的,不是临时开辟的,也不能用完后释放,这种链表成为静态链表。typedef struct student{int id;char name[30];struct student* next;}STU;void chainprint(STU stu){STU* pstu = &stu;while (pstu){p原创 2017-04-13 16:29:26 · 435 阅读 · 0 评论 -
链表与数组的区别
1.链表节点结构体可以嵌套其他类型的结构体,但不能嵌套它自己本身,因为在结构体成员不确定的情况下,编译器无法给它分配内存。但是结构体可以嵌套本类型的指针,因为任何类型的指针,其所占内存的大小都是可以确定的。一个嵌套有本结构体类型的结构体,就可以称为链条的节点。链表节点本质上是结构体体变量,此结构体包含数据域和指针域。数据域用来存放数据,指针域用于和下一个或上一个节点联系。2.链表与原创 2017-04-13 16:08:10 · 296 阅读 · 0 评论 -
回调函数
函数参数也可以是函数指针变量。指针变量的常见用途之一就是把指针作为参数传递到其他函数,指向函数的指针也可以作为参数,以实现函数地址的传递。#include#includeint add(int a,int b){return a+b;}int sub(int a, int b){return a - b;}int mul(int a, int b){原创 2017-04-13 15:17:56 · 167 阅读 · 0 评论 -
使用位运算实现判断一个数是否是2的n次方,实现不需要中间变量进行两个变量值的交换
1.按位取反,将每个0变成1,每个1变成0char ch=’a’;char ch2=~a;2.位与,两个操作数的对应位数都是1时,结果才为1.int a=0,b=1;int c=a&b;3.位或,两个操作数的对应位数,只要有一个是1,结果就为1int a=1,b=2;int c=a|b;4.位异或,两个操作数的对应位数相同则为0,不同则为1int a=0,b原创 2017-04-10 22:03:30 · 1350 阅读 · 0 评论 -
指针的输入特性和输出特性
指针的意义指针做函数参数,输入和输出特性void fun(char* p){strcpy(p,”123”);//输入特性,给p指向的内存区域拷贝内容。}void fun1(char** p,int *len){char* tmp=(char*)malloc(10);strcpy(tmp,”123”);*p=tmp;//输出特性*len=s原创 2017-04-09 21:25:40 · 766 阅读 · 0 评论 -
sprintf与sscanf
int sprintf(char* str,const char* format,...);根据参数format字符串来转换并格式化数据,然后将结果输出到str指定的空间中,直到出现字符串结束符‘\0’为止。str字符串首地址,format字符串格式。返回值,成功,返回实际格式化的字符个数,失败,返回-1.sprintf1.格式化字符串sprintf(buf,”hello %s”,”l原创 2017-04-09 21:21:50 · 540 阅读 · 0 评论 -
函数变量的传递
1.main函数在栈区开辟的内存,所有子函数都可以使用2.main函数在堆区开辟的内存,所有子函数都可以使用3.子函数在栈区开辟的内存,子函数本身和子函数的子函数可以使用4.子函数在堆区开辟的内存,子函数和main函数都可以使用原创 2017-04-08 19:41:35 · 439 阅读 · 0 评论 -
函数的调用惯例
函数在被调用时,函数的调用方和被调用方对于函数时如何调用的必须有一个明确的规定。只有双方同时遵循同样的规定,函数才能够被正确调用。这样的规定被称为:调用惯例。函数的调用惯例包含两个方面:1.函数参数的传递顺序和方式函数的传递有很多种方式,最常见的是通过栈传递。函数的调用方将参数压入栈中,函数自己再从栈中将参数取出。对于有多个参数的函数,调用惯例要规定函数调用方将参数压栈的顺序,是从左往原创 2017-04-08 19:35:11 · 787 阅读 · 0 评论 -
文件缓冲区
系统自动在内存区为程序中每一个正在使用的文件开辟一个文件缓冲区从内存向磁盘输出数据,必须先送到内存中的缓冲区,装满缓冲区后才一起送到磁盘。如果从磁盘向计算机读入数据,则一次从磁盘文件将一批数据输入到内存缓冲区,然后再从缓冲区逐个地将数据送到程序数据区。int fflush(FILE* fp);更新缓冲区,让缓冲区的文件立即写入到文件中。成功,返回0,失败,返回-1.原创 2017-04-08 16:20:16 · 1513 阅读 · 1 评论 -
Windows与Linux文件的不同
Linux下,换行符是\n,Windows下换行符是\r\n。在Windows下,以文本方式打开文件:当读取文件的时候,系统将所有的\r\n换成\n,当写入文件的时候,系统会将\n换成\r\n;以二进制方式打开文件,则不会进行这样的转换。在Linux下,文本方式与二进制方式没有区别。\r\n作为两个字符原样输出。路径:“\\” 这样的路径形式,只能在Windows下使原创 2017-04-08 15:53:38 · 293 阅读 · 0 评论 -
c语言文件操作函数
1.fopenFILE* fopen(const char* filename,const char* mode);filename文件路径+文件名,mode,文件打开方式。返回值,成功,返回文件指针,失败,返回NULL。mode的值:r/rb只读方式打开一个文本文件,文件不存在,报错w/wb写方式打开文件,文件存在则清空原创 2017-04-08 15:05:05 · 199 阅读 · 0 评论 -
typedef与#define的不同
typedef为已存在的一种数据类型定义一个新名字。#define定义一个常量。typedef仅限于数据类型,不能是表达式或具体的值。#define发生在预处理,typedef发生在编译阶段。原创 2017-04-07 22:19:52 · 250 阅读 · 0 评论 -
使用指针时,容易出错的几个地方
1.越界void testptr(){char str[4]=”abcd”;printf(“%s”,str);//str[]没有\0}2.返回局部变量地址char* testptr(){char str[]=”jsdafj”;return str;//str在栈区,函数执行完即释放}3.同一块内存释放多次void testptr(){ch原创 2017-04-10 22:05:29 · 575 阅读 · 0 评论 -
数组名的本质
1.数组名本质上是一个常量指针int b[10];在数组表达式中,数组名的值是一个指针常量,指向数组第一个元素的地址。它的类型取决于数组元素的类型。指针和数组的区别:数组名在表达式中使用的时候,编译器才会产生一个指针常量。但当数组名作为sizeof操作符的操作数的时候,不能指针常量看待,此时sizeof返回的是整个数组的长度,而不是指针的长度。当数组名作为&操作符的操作数的时候,返原创 2017-04-11 20:15:46 · 2575 阅读 · 0 评论 -
函数指针数组
函数指针数组:数组中的每一个元素都是函数指针。函数指针调用函数的方法:void fun(int a){}void(*pfun)(int)=fun;//第一种方法pfun(1);//第二种方法(*pfun)(2);函数指针数组:#include#includevoid fun1(int a){printf("fun1:%d\n", a)原创 2017-04-13 14:42:02 · 338 阅读 · 0 评论 -
函数名与函数指针
函数名:函数名代表函数的入口地址。函数指针:指向函数的指针typedef函数类型1.先定义函数类型,通过类型typedef int f(int,int);//f为函数类型void fun(int a,int b){printf(“fun(%d,%d)\n”,a,b);}void test(){f* pfun;pfun=fun;//函数指针初始化p原创 2017-04-13 11:25:47 · 279 阅读 · 0 评论 -
用文件操作函数获取文件的大小,行数
#define _CRT_SECURE_NO_WARNINGS#include#includestruct fileinfo//文件大小,行数结构体{int lines;int size;};struct fileinfo countline(const char* filename){FILE* fp;struct fileinfo info;fp原创 2017-04-12 22:32:27 · 849 阅读 · 0 评论 -
VS下的FILE型结构体
不同的编译器对FILE结构体有不同的定义,在VS下,FILE结构体的成员如下:typedef struct _iobuf{char* _ptr;//文件输入的下一个位置int _cnt;//剩余多少个字符未被读取char* _base;//基础位置(文件的起始位置)int _flag;//文件标志int _file;//文件的有效性验证int _charbuf;//原创 2017-04-12 21:49:02 · 801 阅读 · 0 评论 -
换行符与回车符
换行符是 \n,作用是将当前位置移到下一行行首。回车符是 \r,作用是将当前位置移到本行行首。为了明白二者之间的差别,可以写一个小程序运行一下:void test03(){printf("*\n*");//输出两行,每行各有一个*号printf("\n------------------\n");printf("*\r);//什么都不输出,*号被换行符覆盖print原创 2017-04-12 20:13:11 · 571 阅读 · 0 评论