随笔分类 -  C

摘要:ANSIC标准定义了以下6种可供C语言使用的预定义宏:__LINE__ 在源代码中插入当前源代码行号__FILE__ 在源代码中插入当前源代码文件名__DATE__ 在源代码中插入当前编译日期〔注意和当前系统日期区别开来〕__TIME__ 在源代码中插入当前编译时间〔注意和当前系统时间区别开来〕 __STDC__ 当要求程序严格遵循ANSIC标准时该标识符被赋值为1。__cplusplus标识符__LINE__和__FILE__通常用来调试程序;标识符__DATE__和__TIME__通常用来在编译后的程序中加入一个时间标志,以区分程序的不同版本;当要求程序严格遵循ANSIC标准时,标识符__ 阅读全文
posted @ 2011-07-21 16:20 hnrainll 阅读(1484) 评论(0) 推荐(0)
摘要:#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>int main(int argc, char *argv[]){ char buf[100]; char str[20] = "helloworld 100"; int num; sscanf(str,"%s %d",buf,&num); printf("the buf:%s %d\n",buf,num); return 0;}和 阅读全文
posted @ 2011-07-18 14:26 hnrainll 阅读(2237) 评论(0) 推荐(1)
摘要:#include <stdio.h>#include <stdlib.h>#include <unistd.h>int main(int argc, char *argv[]){char out_buf[100];char *str="hello world";int num=110;sprintf(out_buf,"%s.%d",str,num);printf("%s\n",out_buf);return 0;} sprintf和printf的不同点:printf是将数据打印到标准输出中.spri 阅读全文
posted @ 2011-07-18 12:41 hnrainll 阅读(2744) 评论(1) 推荐(0)
摘要:在C语言中,函数参数的传递方式有值传和址传.值传是把实参的一个专用的、临时的复制值给被调函数中相应的形参被调用函数使用、修改这个传来的复制值,不会影响实参的值.址传则是把变量(实参)的地址传给被调函数.被调函数通过这个地址找到该变量的存放位置,直接对该地址中存放的变量的内容进行存取操作.因此,在被调用函数中可以修改实参的值.这也是函数参数址传的优点.无论是值传还是址传,都要求实参的数目及类型与形参要完全一致.在一般的程序设计语言中,函数参数的数目及类型是不可变的.即函数被设计之后,只能接收已固定个数和固定类型的实参.这样在编译时,函数形参的存储空间便于确定.但是在C语言中,不但参数的类型可变, 阅读全文
posted @ 2011-07-06 19:10 hnrainll 阅读(469) 评论(0) 推荐(0)
摘要:1 函数声明 首先,要实现类似printf()的变参函数,函数的最后一个参数要用 ... 表示,如 int log(char * arg1, ...)这样编译器才能知道这个函数是变参函数。这个参数与变参函数的内部实现完全没有关系,只是让编译器在编译调用此类函数的语句时不计较参数多少老老实实地把全部参数压栈而不报错,当然...之前至少要有一个普通的参数,这是由实现手段限制的。2 函数实现 C语言通过几个宏实现变参的寻址。下面是linux2.18内核源码里这几个宏的定义,相信符合C89,C99标准的C语言基本都是这样定义的。 typedef char *va_list;/* Storage ali 阅读全文
posted @ 2011-07-06 19:09 hnrainll 阅读(5960) 评论(1) 推荐(1)
摘要:在c/c++标准库中,变参函数很特别。printf, fprintf, sprintf等都属于变参函数。如果自己要写类似的参数可变的函数,通常会用到下面三个函数: #include <stdarg.h>void va_start(va_list ap, last);type va_arg(va_list ap, type);void va_end(va_list ap);一般的用法是这样:va_list args; //声明变量va_start(args, fmt); //开始解析。args指向fmt后面的参数TYPE var = va_arg(args, TYPE); //取下一 阅读全文
posted @ 2011-07-06 19:05 hnrainll 阅读(1399) 评论(0) 推荐(0)
摘要:C语言中的移位操作,内容不多。不过有些地方你不注意,就疏忽了。 先做两个小题先。 (1)unsigned char x=3; x>1是多少? (2)char x=3; x>1是多少? (3)char x=-3; x>1是多少? 3写成二进制数是00000011;-3写成二进制数是(补码)11111101。 程序执行的时候,操作的是数值的编码表示,也就是数值在内存中的二进制表示。比如说,程序取-3的时候,就去取11111101。 (1)对无符号数3来说,x>1往右边移一位,由于是无符号数,所以逻辑右移,最右边一位移掉,最左边移进来的位补零,变成00000001,所以结果是 阅读全文
posted @ 2011-07-06 14:06 hnrainll 阅读(637) 评论(0) 推荐(0)
摘要:在C语言中,涉及位移的运算符有2个,>>表示右移,<<则表示左移。而汇编指令中,SHL和SHR表示逻辑左移和逻辑右移,SAR和SAL表示算术左移和算术右移。其中,逻辑左移和算术左移都是寄存器二进制位整体向左移动,并在右边补0。而右移则不同,逻辑右移是整体向右移,并在左边补0,而算术左移则是根据原符号位的值补与其相同的值。那么如何在C语言中分别实现逻辑和算术位移呢?根据C标准,如果在位移运算符左边的变量是有符号数,如int,char,short等,编译产生的汇编指令是算术位移指令,如果该变量是无符号数,如unsigned int,unsigned char等,编译产生的汇 阅读全文
posted @ 2011-07-06 12:05 hnrainll 阅读(5917) 评论(0) 推荐(0)
摘要:引自 http://topic.csdn.net/t/20010521/10/128376.htmlint型变量有时候占4个字节(在Win32),有时候占2个字节(在DOS) 这个int类型的大小到底是跟编译器有关,还是跟CPU有关,还是跟操作系统有关?所谓的16位32位64位系统是由cpu决定的,由机器指令的寻址、寄存器位数决定的 os受cpu的限制,但在32位的cpu下16位的os也可以跑(就向上面提到的所谓纯dos) 很多os是向前兼容的,就是使以前的程序也能运行,如果编译器本身是16位时代做的,那么os会提供一个模拟16位的子环境供这个编译器使用 int和void*长度应该是一样的(1 阅读全文
posted @ 2011-07-06 11:06 hnrainll 阅读(28143) 评论(2) 推荐(0)
摘要:ioctl函数本函数影响由fd参数引用的一个打开的文件。#include<unistd.h>intioctl( int fd, int request, .../* void *arg */ );返回0:成功 -1:出错第三个参数总是一个指针,但指针的类型依赖于request参数。我们可以把和网络相关的请求划分为6类:套接口操作文件操作接口操作ARP高速缓存操作路由表操作流系统下表列出了网络相关ioctl请求的request参数以及arg地址必须指向的数据类型:类别Request说明数据类型套接口SIOCATMARKSIOCSPGRPSIOCGPGRP是否位于带外标记设置套接口的进 阅读全文
posted @ 2011-07-01 11:42 hnrainll 阅读(3178) 评论(0) 推荐(0)
摘要:前些天,编程序是用到了很久以前写的C程序,想把里面的函数利用起来,连接发现出现了找不到具体函数的错误:以下是假设旧的C程序库C的头文件/*-----------c.h--------------*/#ifndef _C_H_#define _C_H_extern int add(int x, int y);#endifC的源文件/*-----------c.c--------------*/int add(int x, int y){ return x+y;}C++的调用/*-----------cpp.cpp--------------*/#include "c.h"vo 阅读全文
posted @ 2011-06-29 20:29 hnrainll 阅读(454) 评论(0) 推荐(0)
摘要:inline 关键字用来定义一个类的内联函数,引入它的主要原因是用它替代C中表达式形式的宏定义。注意inline在c中最好写成__inline,否则编译会出错! 表达式形式的宏定义一例: #define ExpressionName(Var1,Var2) (Var1+Var2)*(Var1-Var2) 为什么要取代这种形式呢,且听我道来: 1. 首先谈一下在C中使用这种形式宏定义的原因,C语言是一个效率很高的语言,这种宏定义在形式及使用上像一个函数,但它使用预处理器实现,没有了参数压栈,代码生成 等一系列的操作,因此,效率很高,这是它在C中被使用的一个主要原因。 2. 这种宏定义在形式上类似于 阅读全文
posted @ 2011-06-21 19:40 hnrainll 阅读(589) 评论(0) 推荐(0)
摘要:char * strtok ( char *string, const char *delimiters);Sequentially truncate string if delimiter is found. Ifstringis notNULL, the function scansstringfor the first occurrence of any character included indelimiters. If it is found, the function overwrites the delimiter instringby a null-character and 阅读全文
posted @ 2011-06-07 15:17 hnrainll 阅读(1791) 评论(0) 推荐(0)
摘要:位运算 位运算的运算分量只能是整型或字符型数据,位运算把运算对象看作是由二进位组成的位串信息,按位完成指定的运算,得到位串信息的结果。 位运算符有: &(按位与)、|(按位或)、^(按位异或)、~ (按位取反)。 其中,按位取反运算符是单目运算符,其余均为双目运算符。 位运算符的优先级从高到低,依次为~、&、^、|, 其中~的结合方向自右至左,且优先级高于算术运算符,其余运算符的结合方向... 阅读全文
posted @ 2011-05-27 09:10 hnrainll 阅读(51367) 评论(0) 推荐(0)
摘要:#include <stdio.h>#include <stdlib.h>#include <string.h>int myatoi( const char *str ){ if (str == 0 ) return 0; char c; int nRet = -1; for (;;) { c = *(str++); if ( c >= '0' && c <= '9') { if (nRet==0 || nRet==-1) {nRet = c - '0';}// 正数第一个数字 el 阅读全文
posted @ 2011-05-15 15:53 hnrainll 阅读(1429) 评论(1) 推荐(1)
摘要:这需要进行位操作,必较麻烦的, 在学习程序语言和进行程序设计的时候,交换两个变量的值是经常要使用的。通常我们的做法是(尤其是在学习阶段):定义一个新的变量,借助它完成交换。代码如下: int a,b; a=10; b=15; int t; t=a; a=b; b=t; 这种算法易于理解,特别适合帮助初学者了解计算机程序的特点,是赋值语句的经典应用。在实际软件开发当中,此算法简单明了,不会产生歧义,便于程序员之间的交流,一般情况下碰到交换变量值的问题,都应采用此算法(以下称为标准算法)。 上面的算法最大的缺点就是需要借助一个临时变量。那么不借助临时变量可以实现交换吗?答案是肯定的!这里我们可以用 阅读全文
posted @ 2011-05-15 13:57 hnrainll 阅读(6384) 评论(1) 推荐(2)
摘要:我们经常在题目中有要求,输入一个整数,然后以这个整数作为数组的元素个数,下面的程序代码是错误的。intn,array[n];scanf(%d,&n);在TurboC中,不允许出现动态数组。那么如果必须需要这样时,就只能使用链表了。一、堆堆是一种动态存储结构,实际上就是数据段中的自由存储区,它是C语言中使用的一种名称,常常用于动态数据的存储分配。堆中存入一数据,总是以2字节的整数倍进行分配,地址向增加方向变动。堆可以不断进行分配直到没有堆空间为止,也可以随时进行释放、再分配,不存在次序问题。所谓动态数组是指在程序运行期间确定其大小的,如常用到的动态数组,它们是在程序执行过程中动态进行变化 阅读全文
posted @ 2011-05-12 18:09 hnrainll 阅读(823) 评论(0) 推荐(0)
摘要:假设链表节点的数据结构为:struct node {int data;struct node* next;};创建单链表的程序为:struct node* create(unsigned int n){//创建长度为n的单链表assert(n > 0);node* head;head = new node;head->next = NULL;cout << "请输入head节点的值(int型):";cin >> head->data;if (n == 1){ return head;}node* p = head;for (unsi 阅读全文
posted @ 2011-05-12 15:08 hnrainll 阅读(778) 评论(0) 推荐(0)
摘要:转自:http://coolshell.cn/articles/945.html这几天,本站推出了几篇关于C语言的很多文章如下所示:语言的歧义 [酷壳链接] [CSDN链接]谁说C语言很简单? [酷壳链接] [CSDN链接]6个变态的C语言Hello World程序 [酷壳链接] [CSDN链接]如何加密/弄乱C源代码 [酷壳链接] [CSDN链接]C语言的谜题 [酷壳链接] [CSDN链接]我们可以看到很多C语言相关的一些东西。比如《语言的歧义》主要告诉了大家C语言中你意想不到的错误以及一些歧义上的东西。而《谁说C语言很简单》则通过一些看似你从来不可能写出的代码来告诉大家C语言并不是一件容易 阅读全文
posted @ 2011-05-11 12:21 hnrainll 阅读(494) 评论(0) 推荐(0)
摘要://大小端测试程序#include <stdio.h>#include <stdlib.h>void checkCPUendian();int main(){ checkCPUendian(); return 0;}void checkCPUendian(){ union{ unsigned int i; unsigned char s[4]; }c; c.i = 0x12345678; printf("%s\n", (0x12 == c.s[0]) ? "大端模式" : "小端模式");} 阅读全文
posted @ 2011-05-08 13:52 hnrainll 阅读(3091) 评论(0) 推荐(0)