C指针原理(24)-C指针基础

取自netbsd中的源码,检查运算溢出,用C语言实现,方法很精妙

/*

? hide bintime for _STANDALONE because this header is used for hpcboot.exe,
?
which is built with compilers which don‘t recognize LL suffix.
?* http://mail-index.NetBSD.org/tech-userlevel/2008/02/27/msg000181.html

?*/

下面这段使用了LL后缀,要检查一下编译器是否支持,如果支持,则定义_STANDALONE。这样能容纳的时间数更大。

L是long,LL是long long

定义了bintime的结构,以及其加减运算。uint64_t类型的frac是无符号整数,下面要用到这个特性


#if !defined(_STANDALONE)
struct bintime {
time_t sec;
uint64_t frac;
};

static __inline void
bintime_addx(struct bintime *bt, uint64_t x)
{
uint64_t u;

u = bt->frac;
bt->frac += x;
if (u > bt->frac)
bt->sec++;
}

数据是以补码方式存放在内存中!无符号整数溢出表现为: x?+?y?<?x?就表示溢出了.,因此,上面才有

if (u > bt->frac)

bt->sec++;

这样的判断,很巧妙的想法,溢出了就进位。?

下面演示了加法的溢出

因为上面编译器进行编译时,char是有符号的,即signed char。

在C/C++语言中,char变量为一个字节,8位,signed char表示的范围:-128~127【-128在内存中的二进制表示为1000 0000,127在内存中的表示为0111 1111】;unsign char表示的范围:0000 0000~1111 1111,即0~255;

[email protected]:~/test/asb# gcc test1.c
[email protected]:~/test/asb# ./a.out
-46
-30
110
[email protected]:~/test/asb#

很明显,90+120已经溢出了,因为无法表达210这个有符号数,用一个8位的字节。而a+c则正常计算。

下面继续分析。

static __inline void

bintime_add(struct bintime *bt, const struct bintime *bt2)
{
uint64_t u;

u = bt->frac;
bt->frac += bt2->frac;
if (u > bt->frac)
bt->sec++;
bt->sec += bt2->sec;
}

?bintime_add也完成2个时间结构类型的加法,同样通过溢出检查来实现进位。?

下面是2个时间结构类型的减法。

static __inline void
bintime_sub(struct bintime *bt, const struct bintime *bt2)
{
uint64_t u;

u = bt->frac;
bt->frac -= bt2->frac;
if (u < bt->frac)
bt->sec--;
bt->sec -= bt2->sec;
}

9、文件指针

[email protected]:~/test1?%?vim?test2.c

#include?<stdio.h>

#include?<stdlib.h>

int?main(int?argc,char?**argv){

????????int?exit_status=EXIT_SUCCESS;

????????while?(*++argv!=NULL)

????????{

????????????????//打开文件,如果出现错误,则显示错误信息

????????????????FILE?*input=fopen(*argv,"r");

????????????????if?(input==NULL){

????????????????????????perror(*argv);

????????????????????????exit_status=EXIT_FAILURE;

????????????????????????continue;

????????????????}

????????????????printf?("\n%s内容如下:\n",*argv);

????????????????int?ch;

????????????????while((ch=fgetc(input))!=EOF){

????????????????????????printf("%c",ch);

????????????????????????}

????????????????if?(fclose(input)!=0){

????????????????????????perror(*argv);

????????????????????????exit_status=EXIT_FAILURE;

????????????????}

????????}

????????return?exit_status;

}

上面程序使用fgetc读取命令行参数中的文本文件,将它们内容输出

[email protected]:~/test1?%?cc?test2.c?-o?mytest

[email protected]:~/test1?%?./mytest?test1.c

test1.c内容如下:

#include?<stdio.h>

int?add(int?a,int?b);

int?main(void){

????????int?(*myfunc)(int?a,int?b);

????????myfunc=add;

????????int?x=myfunc(12,36);

????????printf("%d",x);

????????return?1;

}

int?add(int?a,int?b){

????????return?a+b;

}

也可一次向命令行指定更多文本文件

[email protected]:~/test1?%?./mytest?test1.c?test3.c?hello.txt

#include?<stdio.h>

int?add(int?a,int?b);

int?main(void){

????????int?(*myfunc)(int?a,int?b);

????????myfunc=add;

????????int?x=myfunc(12,36);

????????printf("%d",x);

????????return?1;

}

int?add(int?a,int?b){

????????return?a+b;

}

test3.c内容如下:


#include?<stdio.h>

int?main(int?argc,int?**argv){

????????printf?("%s","abcdefgh"+2);

}

hello.txt内容如下:

你好,各位朋友,很高兴认识大家。

Google是一家美国的跨国科技企业,致力于互联网搜索、云计算、广告技术等领域,开发并提供大量基于互联网的产品与服务,其主要利润来自于AdWords等广告服务。

也可以使用fgets函数来读取

[email protected]:~/test1?%?vim?test2.c

#include?<stdio.h>

#include?<stdlib.h>

int?main(int?argc,char?**argv){

????????int?exit_status=EXIT_SUCCESS;

????????while?(*++argv!=NULL)

????????{

????????????????//打开文件,如果出现错误,则显示错误信息

????????????????FILE?*input=fopen(*argv,"r");

????????????????if?(input==NULL){

????????????????????????perror(*argv);

????????????????????????exit_status=EXIT_FAILURE;

????????????????????????continue;

????????????????}

????????????????printf?("\n%s内容如下:\n",*argv);

????????????????char?mytext[500];

????????????????while(fgets(mytext,500,input)!=NULL){

????????????????????????printf("%s",mytext);

????????????????}

????????????????if?(fclose(input)!=0){

????????????????????????perror(*argv);

????????????????????????exit_status=EXIT_FAILURE;

????????????????}

????????}

????????return?exit_status;

}

[email protected]:~/test1?%?cc?test2.c?-o?mytest

[email protected]:~/test1?%?./mytest?hello.txt?test3.c

hello.txt内容如下:

你好,各位朋友,很高兴认识大家。

Google是一家美国的跨国科技企业,致力于互联网搜索、云计算、广告技术等领域,开发并提供大量基于互联网的产品与服务,其主要利润来自于AdWords等广告服务。

test3.c内容如下:


#include?<stdio.h>

int?main(int?argc,int?**argv){

????????printf?("%s","abcdefgh"+2);

}

[email protected]:~/test1?%

下面的例子展示了从键盘输入文字增加到文本文件后面,如果输入%end%表示输入结束。

[email protected]:~/test1?%?vim?test5.c

#include?<string.h>

#include?<stdio.h>

#include?<stdlib.h>

int?main(int?argc,char?**argv){

????????int?exit_status=EXIT_SUCCESS;

????????while?(*++argv!=NULL)

????????{

????????????????//打开文件,如果出现错误,则显示错误信息

????????????????FILE?*output=fopen(*argv,"a");

????????????????if?(output==NULL){

????????????????????????perror(*argv);

????????????????????????exit_status=EXIT_FAILURE;

????????????????????????continue;

????????????????}

????????????????char?mytext[500];

????????????????int?ch=‘\n‘;

????????????????while?(1){

????????????????????????printf("请输入文字:");

????????????????????????scanf("%s",&mytext);

????????????????????????if?(strcmp(mytext,"%end%")!=0){

????????????????????????????????fputs(mytext,output);

????????????????????????????????//scanf函数不会读取换行符,因此加上换行符

????????????????????????????????fputc(ch,output);

????????????????????????}

????????????????????????else?break;

????????????????}

????????????????if?(fclose(output)!=0){

????????????????????????perror(*argv);

????????????????????????exit_status=EXIT_FAILURE;

????????????????}

????????}

????????return?exit_status;

}

执行结果如下

[email protected]:~/test1?%?cc?test2.c?-o?mytest2

[email protected]:~/test1?%?./mytest2?hello.txt

hello.txt内容如下:

你好,各位朋友,很高兴认识大家。

Google是一家美国的跨国科技企业,致力于互联网搜索、云计算、广告技术等领域,开发并提供大量基于互联网的产品与服务,其主要利润来自于AdWords等广告服务。

[email protected]:~/test1?%

[email protected]:~/test1?%?cc?test5.c?-o?mytest5

[email protected]:~/test1?%?./mytest5?hello.txt

请输入文字:你好?,今天天气如何?

请输入文字:今天天气不错!

请输入文字:谢谢!

请输入文字:%end%

[email protected]:~/test1?%?./mytest2?hello.txt

hello.txt内容如下:

你好,各位朋友,很高兴认识大家。

Google是一家美国的跨国科技企业,致力于互联网搜索、云计算、广告技术等领域,开发并提供大量基于互联网的产品与服务,其主要利润来自于AdWords等广告服务。

你好,今天天气如何?

今天天气不错!

谢谢!

[email protected]:~/test1?%

原文地址:http://blog.51cto.com/13959448/2336619

时间: 2024-10-31 12:31:10

C指针原理(24)-C指针基础的相关文章

C指针原理(15)-C指针基础

简单C指针 指向整数的指针,以及指针的指针 [email protected]:~?%?vim?test1.c #include?<stdio.h> int?main(void){ ????????int?x; ????????x=128; ????????int?*myp=&x; ????????int?**mypp=&myp; ????????printf("x:%d\n",x); ????????printf("myp:%u\n",

C指针原理(17)-C指针基础

指针本身也是一种变量,支持常用的运算.比如加.减 #include?<stdio.h> int?main(void){ ????????int?i; ????????char?x[20]="0123456789ABCDEFGHIJ"; ????????for?(i=0;i<20;i++){ ????????printf("x[%d]:%c\n",i,x[i]); ????????} ????????char?*p_x; ????????for?(p

C指针原理(16)-C指针基础

2.指向数组的指针 #include?<stdio.h> int?main(void){ ????????int?i; ????????char?x[20]="0123456789ABCDEFGHIJ"; ????????for?(i=0;i<20;i++){ ????????printf("x[%d]:%c\n",i,x[i]); ????????} ????????char?*p_x; ????????for?(p_x=&x[0];p_

C指针原理(12)-C指针基础

tcctok.h定义了C语言的词法分析的基本元素,主要定义了关键字. / keywords /? ? ?DEF(TOK_INT, "int")? ? ?DEF(TOK_VOID, "void")? ? ?DEF(TOK_CHAR, "char")? ? ?DEF(TOK_IF, "if")? ? ?DEF(TOK_ELSE, "else")? ? ?DEF(TOK_WHILE, "while&qu

006 this指针原理

/* 目录: 一 this指针原理 */ 一 this指针原理 class CTest { public: CTest(int nNum) { this->nNum = nNum; } ~CTest() { } void Print() { cout << nNum << endl; } private: int nNum; }; int main(int argc, char *argv[], char **envp) { CTest c(0x11); c.Print();

智能指针原理与简单实现(转)

以下实现没有考虑线程安全的问题. 智能指针:它的一种通用实现方法是采用引用计数的方法.智能指针将一个计数器与类指向的对象相关联,引用计数跟踪共有多少个类对象共享同一指针. 每次创建类的新对象时,初始化指针并将引用计数置为1: 当对象作为另一对象的副本而创建时,拷贝构造函数拷贝指针并增加与之相应的引用计数: 对一个对象进行赋值时,赋值操作符减少左操作数所指对象的引用计数(如果引用计数为减至0,则删除对象),并增加右操作数所指对象的引用计数:这是因此左侧的指针指向了右侧指针所指向的对象,因此右指针所

快慢指针原理--快速找到未知长度单链表的中间节点

package com.java.dataStruct; //节点类 public class Node<E> { E item; Node next; public Node(){ } public Node(E element){ this.item = element; } public Node(E element, Node next){ this.item = element; this.next = next; } } Node p1,r1; Node L1 = new Node

Objective-C中,ARC下的 strong和weak指针原理解释

Objective-C中,ARC下的 strong和weak指针原理解释 提示:本文中所说的"实例变量"即是"成员变量","局部变量"即是"本地变量" 一.简介 ARC是自iOS 5之后增加的新特性,完全消除了手动管理内存的烦琐,编译器会自动在适当的地方插入适当的retain.release.autorelease语句.你不再需要担心内存管理,因为编译器为你处理了一切 注意:ARC 是编译器特性,而不是 iOS 运行时特性(除

C 语言实现多态的原理:函数指针

C语言实现多态的原理:函数指针 何为函数指针?答案:C Programming Language. 可以查阅下,从原理上来讲,就是一个内存地址,跳过去执行对应的代码段. 既然如此,在运行时决定跳到哪个地方去执行特定的代码即可. 一个简单的版本: 以音频解码器作为例子:AAC 解码器,Mpeg解码器,以及其他类型的解码器. 那手动的多态可能会这样实现: U32 audioHandle = AudioDecOpen(int type) { if(type == aac) return aac_ope