博文

C++ volatile用法(转)(2008-05-13 19:00:00)

摘要:一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值(From Memory),而不是使用保存在寄存器里的备份。下面是volatile变量的几个例子:1) 并行设备的硬件寄存器(如:状态寄存器)2) 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)3) 多线程应用中被几个任务共享的变量回答不出这个问题的人是不会被雇佣的。我认为这是区分C程序员和嵌入式系统程序员的最基本的问题。搞嵌入式的家伙们经常同硬件、中断、RTOS等等打交道,所有这些都要求用到volatile变量。不懂得volatile的内容将会带来灾难。假设被面试者正确地回答了这是问题(嗯,怀疑是否会是这样),我将稍微深究一下,看一下这家伙是不是直正懂得volatile完全的重要性。1)一个参数既可以是const还可以是volatile吗?解释为什么。2); 一个指针可以是volatile 吗?解释为什么。3); 下面的函数有什么错误:int square(volatile int *ptr){return *ptr * *ptr;}下面是答案:1)是的。一个例子是只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。2); 是的。尽管这并不很常见。一个例子是当一个中服务子程序修该一个指向一个buffer的指针时。3) 这段代码有点变态。这段代码的目的是用来返指针*ptr指向值的平方,但是,由于*ptr指向一个volatile型参数,编译器将产生类似下面的代码:int square(volatile int *ptr){int a,b;a = *ptr;b = *ptr;return a * b;}由于*ptr的值可能被意想不到地该变,因此a和b可能是不同的。结果,这段代码可能返不是你所期望的平方值!正确的代码如下:long square(volatile int *ptr){int a;a = *ptr;return a * a;} ......

阅读全文(1930) | 评论:0

链表中建立,删除,插入操作(2007-12-20 16:35:00)

摘要:/*学生结构体包括number,sex,age,score,*p几个成员*/#include<stdio.h>#include<malloc.h>#define NULL 0#define LENGTH sizeof(struct student)struct student{ int number; char sex;/*M(male) or F(famal)*/ int age; double score; struct student *next;};void main(){  struct student *del(struct student *del,int key);/*删除链表中key这个结点值*/ void output(struct student *P);/*输出一个链表的函数*/ struct student *insert(struct student *head,struct student *in);/*插入一个结点放在此链表的最后面*/ struct student *creat(int m);/*创建一个新的链表*/ void start(); struct student *new_list=NULL; struct student plug;/*插入的结点*/ char select;/*输入界面的先择*/ int b=0;/*删除链表中的结点的number*/ int s=0; /*创建链表时的结点数*/ printf("**学生结构体包括number,sex(M or F),age,score,*p几个成员**\n"); printf("***输入时请注意:number age 请输入整数***\n"); printf("***score输入整数或小数\t sex输入M或F***\n"); start();/*进入时的界面*/ select=getchar(); switch(select) { case 'C':  {  &......

阅读全文(3305) | 评论:1

字符串的排序(2007-12-17 15:44:00)

摘要:#include<stdio.h>#include<string.h>#define LENGTH 20#define N 5void main(){void sort(char *name[],int n);void print(char *name[],int n);int i;char string[N][LENGTH];char *p;char *temp[N];  for(i=0;i<N;i++)  {  printf("Please input the %d compare string:\n",i+1);  p=*(string+i);/*二维数组对应一行的首地址传给一个指针*/  gets(p);  temp[i]=p;  }  sort(temp,N);  print(temp,N);}void sort(char *name[],int n)/*从小到大排序的函数*/{char *temp;int i,j,k;for(i=0;i<n-1;i++) { k=i; for(j=i+1;j<n;j++)  {  if(strcmp(name[k],name[j])>0)   k=j;  if(k!=i)/*只有上一个if成立才执行*/   {   temp=name[i];   name[i]=name[k];   name[k]=temp;   }  } }}void print(char *name[],int n)/*用于输出的函数*/{ int i; printf("The compared strings is:\n"); for(i=0;i<n;i++) printf("%s\n",name[i]);}......

阅读全文(1777) | 评论:0

将整数转化为一个字符串(2007-12-16 18:13:00)

摘要:#include<stdio.h> #define LENGTH 10 void IntToChar(int *p,int k,int n) {   if(k!=0)  { *(p+k--)=n%10+48;/*在ascii中的码的顺序,相差的值为48*/  IntToChar(p,k,n/10); }  else  { *(p+k)=n+48; return; } /*如果n是一位数,则*(p+0),即a[0]等于此数,对于多位数,已除到数的最高位*/ } void main() {  int a[LENGTH],i,j=0,n,m; /*j用于判断输入数n是几位数*/  printf("Please input the integer wanted to change:\n"); scanf("%d",&n);  m=n; /*m仅为方便下步while循环中判断n为几位数的参数*/  while(m/10!=0) /*while循环中判断n为几位数*/   { m=m/10;   j++;   }  IntToChar(a,j,n); /*a[LENGTH]为存储转化后字符的数组*/  printf("The changed char is:\n"); for(i=0;i<=j;i++) printf("%c",a[i]); } /*说明:*//*由于各种c编译器对int型数据的取值范围不一样,可能会有不同的结果*/ /*Turbo C 中int的范围为不能超过32767*/ ......

阅读全文(2996) | 评论:0

关于冒泡法(2007-11-27 11:11:00)

摘要:看了文涛的blog,感触很深,觉得程序的有些细节问题可以自己通过编程来了解,也更细致地了解它的执行过程,同时也当作是一种测试,下面是一个排序的测试程序     #include <stdio.h>void main(){    int a[11]; /* 第0号元素不用 */    int i, j,k, cup;    printf("Input 10 numbers:\n");     for(i = 1; i < 11; i++)        scanf("%d", &a[i]);    for(i = 1; i <= 9; i++)           /* 趟数 */ {  printf("i=%d\n\n",i);  for(j = 1; j <= 10 - i; j++)  /* 每趟要比较数 */  {  if(a[j] > a[j+1])         /* 前面数大于后面数刚对调 */            {                cup = a[j];                a[j] = a[j+1];     &nbs......

阅读全文(2069) | 评论:0

猴子吃桃问题代码(2007-10-26 20:32:00)

摘要:#include <stdio.h>int remain(int i){ int j; if(i==10)  j=1; else if(i<10&&i>0)  j=(2*remain(i+1))+2; else if (i<=0)  j=remain(1); else if(i>10)  j=0; return(j);}void main(){int a,b;printf("please input the day you want to kown how many peach remained:\n");scanf("%d",&a);if(a>10)printf("The peach is eaten out.\n");else if(a<=0)printf("The peach is not eatean,so have %d peach.\n",remain(1));else { for(b=a;b>=1;b--) printf("The %d day reamins %d peach.\n",b,remain(b)); }}......

阅读全文(2238) | 评论:0

魔方阵的c语言算法(2007-09-26 16:41:00)

摘要: 魔方阵的c语言算法:#include "stdio.h"#define Q 100int a[Q][Q];FILE *fp;void swap(int *a,int *b)/*交换函数*/{  int t;  t=*a;  *a=*b;  *b=t;} void Magic2Kplus1(int t,int H,int L,int N){/*   阶数N是奇数魔方阵   其中int t,表示:从t开始向魔方阵中填数   int H,int L分别表示从从魔方阵中的哪个位置开始填数   int N 表示魔方阵的阶数下面举例子说明以3阶魔方阵为例第1步: 中间填 1x  1  xx  x  xx  x  x第2步:数2应向1的右上角填但是没地方了就移到右下角x  1  xx  x  xx  x  2第3步:数3应向2的右上角填但是没地方了就移到2上一行的最左边x  1  x3  x  xx  x  2第4步:数4应向3的右上角填但是这个地方已经有数字1了就移到3下边x  1  x3  x  x4  x  2第5步:数5向4的右上角填x  1  x3  5  x4  x  2第6步  数6向5的右上角填x  1  63  5  x4  x  2第7步:数7应向6的右上角填但是没地方了......

阅读全文(7131) | 评论:0