博文

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;......

阅读全文(1847) | 评论: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");

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

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

摘要:#include<stdio.h>
#include<string.h>
#define LENGTH 20
#define N 5
void 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 ......

阅读全文(1686) | 评论: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*/ ......

阅读全文(2912) | 评论: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];
              ......

阅读全文(2000) | 评论: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));
 }
}......

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

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

摘要: 魔方阵的c语言算法:
#include "stdio.h"
#define Q 100
int 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步: 中间填 1
x  1  x
x  x  x
x  x  x
第2步:数2应向1的右上角填但是没地方了就移到右下角
x  1  x
x  x  x
x  x  2
第3步:数3应向2的右上角填但是没地方了就移到2上一行的最左边
x  1  x
3  x  x
x  x  2
第4步:数4应向3的右上角填但是这个地方已经有数字1了就移到3下边
x  1  x
3  x  x
4  x  2
第5步:数5向4的右上角填
x  1  x
3  5  x
......

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