博文
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;......
链表中建立,删除,插入操作(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");
字符串的排序(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 ......
将整数转化为一个字符串(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*/ ......
关于冒泡法(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];
 ......
猴子吃桃问题代码(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));
}
}......
魔方阵的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
......