c语言实验7
㈠ 大学程序设计c语言 实验七的题目
第一题:
有3个错。
1.strupr(name[i]) 改为:strcpy(name[i],strupr(name[i]));
2.if(name[i]> name[j])改为:if(strcmp(name[i],name[j])>0)
3.strcpy(name[i],str );改为:strcpy(str,name[i]);
第二题:
(1)s[i] != '\0'
(2){ j ++;}else
memcpy(s[i],s[i]+1,strlen(s)-i-1)
第三题:
s[i] <= '9' && s[i] >= '0'
㈡ c语言程序设计苏小红版第七章课后实验答案
不知道你说的是不是这一次实验
2.2.7实验7:二维数组和函数综合编程练习
成绩排名次
某班期末考试科目为数学(MT)、英语(EN)和物理(PH),有最多不超过30人参加考试。考试后要求:
(1)计算每个学生的总分和平均分;
(2)按总分成绩由高到低排出成绩的名次;
(3)打印出名次表,表格内包括学生编号、各科分数、总分和平均分;
(4)任意输入一个学号,能够查找出该学生在班级中的排名及其考试分数。
【思考题】请读者思考如下问题。
①如果增加一个要求:要求按照学生的学号由小到大对学号、成绩等信息进行排序,那么程序如何修改呢?
②如果要求程序运行后先打印出一个菜单,提示用户选择:成绩录入、成绩排序、成绩查找,在选择某项功能后执行相应的操作,那么程序如何修改呢?
答案
#include <stdio.h>
#define STU 30
#define COURSE 3
void Input(long num[],int score[][COURSE],int n);
void GetSumAver(int score[][COURSE],int n,int sum[],float aver[]);
void Sort(long num[],int score[][COURSE],int n,int sum[],float aver[]);
void Print(long num[],int score[][COURSE],int n,int sum[],float aver[]);
int Search(long num[], int n, long x);
main()
{
int n, score[STU][COURSE], sum[STU], pos;
long num[STU], x;
float aver[STU];
printf("Please enter the total number of the students(n<=30):");
scanf("%d", &n); /*输入参加考试的学生人数*/
printf("Enter No. and score as: MT EN PH ");
Input(num, score, n); /*输入学生成绩*/
GetSumAver(score, n, sum, aver); /*计算总分和平均分*/
printf("Before sort: ");
Print(num, score, n, sum, aver);
Sort(num, score, n, sum, aver); /*排名次*/
printf("After sort: ");
Print(num, score, n, sum, aver);
printf("Please enter searching number:");
scanf("%ld", &x); /*以长整型格式输入待查找学生的学号*/
pos = Search(num, n, x); /*名次查询*/
if (pos != -1)
{
printf("position: NO MT EN PH SUM AVER ");
printf("%8d %4ld %4d %4d %4d %5d %5.0f ",
pos+1,num[pos], score[pos][0],score[pos][1],
score[pos][2], sum[pos],aver[pos]);
}
else
{
printf("Not found! ");
}
}
/* 函数功能:输入某班学生期末考试三门课程成绩
函数参数:长整型数组num,存放学生学号
整型数组score,存放学生成绩
整型变量n,存放学生人数
函数返回值:无
*/
void Input(long num[], int score[][COURSE], int n)
{
int i, j;
for (i=0; i<n; i++)
{
scanf("%ld", &num[i]);
for (j=0; j<COURSE; j++)
{
scanf("%d", &score[i][j]);
}
}
}
/* 函数功能:计算每个学生的总分和平均分
函数参数: 整型数组score,存放学生成绩
整型变量n,存放学生人数
整型数组sum,计算得到的每个学生的总分
实型数组aver,计算得到的每个学生的平均分
函数返回值:无
*/
void GetSumAver(int score[][COURSE], int n, int sum[], float aver[])
{
int i, j;
for (i=0; i<n; i++)
{
sum[i] = 0;
for (j=0; j<COURSE; j++)
{
sum[i] = sum[i] + score[i][j];
}
aver[i] = (float)sum[i] / COURSE;
}
}
/* 函数功能:按总分成绩由高到低排出成绩的名次
函数参数:长整型数组num,存放学生学号
整型数组score,存放学生成绩
整型变量n,存放学生人数
整型数组sum,存放每个学生的总分
实型数组aver,存放每个学生的平均分
函数返回值:无
*/
void Sort(long num[],int score[][COURSE], int n, int sum[], float aver[])
{
int i, j, k, m;
int temp1;
long temp2;
float temp3;
for (i=0; i<n-1; i++)
{
k = i;
for (j=i+1; j<n; j++)
{
if (sum[j] > sum[k]) k = j;
}
if (k != i)
{
temp1 = sum[k]; sum[k] = sum[i]; sum[i] = temp1;
temp2 = num[k]; num[k] = num[i]; num[i] = temp2;
temp3 = aver[k]; aver[k] = aver[i]; aver[i] = temp3;
for (m=0; m<COURSE; m++)
{
temp1 = score[k][m];
score[k][m] = score[i][m];
score[i][m] = temp1;
}
}
}
}
/* 函数功能: 打印名次表,表格内包括学生编号、各科分数、总分和平均分
函数参数: 长整型数组num,存放学生学号
整型数组score,存放学生成绩
整型变量n,存放学生人数
整型数组sum,存放每个学生的总分
实型数组aver,存放每个学生的平均分
函数返回值:无
*/
void Print(long num[], int score[][COURSE], int n,
int sum[], float aver[])
{
int i, j;
printf(" NO | MT EN PH SUM AVER ");
printf("---------------------------------------------------- ");
for (i=0; i<n; i++)
{
printf("%ld | ", num[i]);
for (j=0; j<COURSE; j++)
{
printf("%4d ", score[i][j]);
}
printf("%5d %5.0f ", sum[i], aver[i]);
}
}
/* 函数功能:在学号数组中顺序查找学生的学号
函数参数:长整型数组num,存放学生学号
整型变量n,存放学生人数
长整型变量x,存放待查找学生的学号
函数返回值:找到时,返回学生学号在学号数组中的下标位置,否则返回值-1
*/
int Search(long num[], int n, long x)
{
int i;
for (i=0; i<n; i++)
{
if (num[i] == x) return(i);
}
return (-1);
}
㈢ C语言实验
哈夫曼编码(Huffman Coding)是一种编码方式,以哈夫曼树—即最优二叉树,带权路径长度最小的二叉树,经常应用于数据压缩。 在计算机信息处理中,“哈夫曼编码”是一种一致性编码法(又称"熵编码法"),用于数据的无损耗压缩。这一术语是指使用一张特殊的编码表将源字符(例如某文件中的一个符号)进行编码。这张编码表的特殊之处在于,它是根据每一个源字符出现的估算概率而建立起来的(出现概率高的字符使用较短的编码,反之出现概率低的则使用较长的编码,这便使编码之后的字符串的平均期望长度降低,从而达到无损压缩数据的目的)。这种方法是由David.A.Huffman发展起来的。 例如,在英文中,e的出现概率很高,而z的出现概率则最低。当利用哈夫曼编码对一篇英文进行压缩时,e极有可能用一个位(bit)来表示,而z则可能花去25个位(不是26)。用普通的表示方法时,每个英文字母均占用一个字节(byte),即8个位。二者相比,e使用了一般编码的1/8的长度,z则使用了3倍多。倘若我们能实现对于英文中各个字母出现概率的较准确的估算,就可以大幅度提高无损压缩的比例。
本文描述在网上能够找到的最简单,最快速的哈夫曼编码。本方法不使用任何扩展动态库,比如STL或者组件。只使用简单的C函数,比如:memset,memmove,qsort,malloc,realloc和memcpy。
因此,大家都会发现,理解甚至修改这个编码都是很容易的。
背景
哈夫曼压缩是个无损的压缩算法,一般用来压缩文本和程序文件。哈夫曼压缩属于可变代码长度算法一族。意思是个体符号(例如,文本文件中的字符)用一个特定长度的位序列替代。因此,在文件中出现频率高的符号,使用短的位序列,而那些很少出现的符号,则用较长的位序列。
编码使用
我用简单的C函数写这个编码是为了让它在任何地方使用都会比较方便。你可以将他们放到类中,或者直接使用这个函数。并且我使用了简单的格式,仅仅输入输出缓冲区,而不象其它文章中那样,输入输出文件。
bool CompressHuffman(BYTE *pSrc, int nSrcLen, BYTE *&pDes, int &nDesLen);
bool DecompressHuffman(BYTE *pSrc, int nSrcLen, BYTE *&pDes, int &nDesLen);
要点说明
速度
为了让它(huffman.cpp)快速运行,我花了很长时间。同时,我没有使用任何动态库,比如STL或者MFC。它压缩1M数据少于100ms(P3处理器,主频1G)。
压缩
压缩代码非常简单,首先用ASCII值初始化511个哈夫曼节点:
CHuffmanNode nodes[511];
for(int nCount = 0; nCount < 256; nCount++)
nodes[nCount].byAscii = nCount;
然后,计算在输入缓冲区数据中,每个ASCII码出现的频率:
for(nCount = 0; nCount < nSrcLen; nCount++)
nodes[pSrc[nCount]].nFrequency++;
然后,根据频率进行排序:
qsort(nodes, 256, sizeof(CHuffmanNode), frequencyCompare);
现在,构造哈夫曼树,获取每个ASCII码对应的位序列:
int nNodeCount = GetHuffmanTree(nodes);
构造哈夫曼树非常简单,将所有的节点放到一个队列中,用一个节点替换两个频率最低的节点,新节点的频率就是这两个节点的频率之和。这样,新节点就是两个被替换节点的父节点了。如此循环,直到队列中只剩一个节点(树根)。
// parent node
pNode = &nodes[nParentNode++];
// pop first child
pNode->pLeft = PopNode(pNodes, nBackNode--, false);
// pop second child
pNode->pRight = PopNode(pNodes, nBackNode--, true);
// adjust parent of the two poped nodes
pNode->pLeft->pParent = pNode->pRight->pParent = pNode;
// adjust parent frequency
pNode->nFrequency = pNode->pLeft->nFrequency + pNode->pRight->nFrequency;
这里我用了一个好的诀窍来避免使用任何队列组件。我先前就直到ASCII码只有256个,但我分配了511个(CHuffmanNode nodes[511]),前255个记录ASCII码,而用后255个记录哈夫曼树中的父节点。并且在构造树的时候只使用一个指针数组(ChuffmanNode *pNodes[256])来指向这些节点。同样使用两个变量来操作队列索引(int nParentNode = nNodeCount;nBackNode = nNodeCount –1)。
接着,压缩的最后一步是将每个ASCII编码写入输出缓冲区中:
int nDesIndex = 0;
// loop to write codes
for(nCount = 0; nCount < nSrcLen; nCount++)
{
*(DWORD*)(pDesPtr+(nDesIndex>>3)) |=
nodes[pSrc[nCount]].dwCode << (nDesIndex&7);
nDesIndex += nodes[pSrc[nCount]].nCodeLength;
}
(nDesIndex>>3): >>3 以8位为界限右移后到达右边字节的前面
(nDesIndex&7): &7 得到最高位.
注意:在压缩缓冲区中,我们必须保存哈夫曼树的节点以及位序列,这样我们才能在解压缩时重新构造哈夫曼树(只需保存ASCII值和对应的位序列)。
解压缩
解压缩比构造哈夫曼树要简单的多,将输入缓冲区中的每个编码用对应的ASCII码逐个替换就可以了。只要记住,这里的输入缓冲区是一个包含每个ASCII值的编码的位流。因此,为了用ASCII值替换编码,我们必须用位流搜索哈夫曼树,直到发现一个叶节点,然后将它的ASCII值添加到输出缓冲区中:
int nDesIndex = 0;
DWORD nCode;
while(nDesIndex < nDesLen)
{
nCode = (*(DWORD*)(pSrc+(nSrcIndex>>3)))>>(nSrcIndex&7);
pNode = pRoot;
while(pNode->pLeft)
{
pNode = (nCode&1) ? pNode->pRight : pNode->pLeft;
nCode >>= 1;
nSrcIndex++;
}
pDes[nDesIndex++] = pNode->byAscii;
}
㈣ 请C语言高手帮忙做一下这个实验(7)
1,100
2,7,5
3,12
4,1
1
1
2
1
3
5,1
12
123
1234
CHINA
你再好好看看,有问题的话就继续追问吧哈。
㈤ C语言实验7 函数1
#include<stdio.h>
intmain()
{
intad(int);
intn;
printf("请输入一个测试数:");
while(scanf("%d",&n)==1)
if(ad(n))
printf(" %d是素数. ",n);
else
printf(" %d不是素数. ",n);
return0;
}
intad(intn)
{
intflag=1,i;
for(i=2;i<=n/2&&flag==1;i++)//这里i<=n/2就好了
if(n%i==0)
flag=0;
return(flag);
}
代码有点小问题,参看上面的注释
㈥ C语言实验报告怎么写
#include <stdio.h>
int main()
{
unsigned long a;
char c;
printf("Input a binary number: ");
for(a=0;(c=getchar())!=' ';)
a=a*2+c-'0';
printf("The number is %lu in decimal ",a);
printf("The number is %lo in octal ",a);
printf("The number is %lX in Hexadecimal ",a);
return 0;
}

㈦ C语言实验——数日子
#include <iostream.h>
struct
{ int year;
int month;
int day;
}date;
int main()
{int days;
cout<<"input year,month,day:";
char ch='\\';
cin>>date.year>>ch>>date.month>>ch>>date.day;
switch(date.month)
{ case 1: days=date.day; break;
case 2: days=date.day+31; break;
case 3: days=date.day+59; break;
case 4: days=date.day+90; break;
case 5: days=date.day+120; break;
case 6: days=date.day+151; break;
case 7: days=date.day+181; break;
case 8: days=date.day+212; break;
case 9: days=date.day+243; break;
case 10: days=date.day+273; break;
case 11: days=date.day+304; break;
case 12: days=date.day+334; break;
}
if ((date.year %4== 0 && date.year % 100 != 0
||date.year % 400 == 0) && date.month >=3)
days+=1;
cout<<date.month<<"/"<<date.day<<" is the "<<days
<<"th day in "<<date.year<<"."<<endl;
return 0;
}
㈧ 数据结构实验(C语言): 顺序表实验
//线性表函数操作
#include <stdio.h>
#include <string.h>
#define MaxSize 30
#define Error 0
#define True 1
typedef char ElemType;
typedef struct
{
ElemType elem[MaxSize];
int length;
}SqList; /*顺序表类型定义*/
void InitList(SqList * &L) /*初始化顺序表L*/
{
L = (SqList *)malloc(sizeof(SqList));
L -> length = 0;
}
void DestroyList( SqList *L ) /*释放顺序表L*/
{
free(L);
}
int ListEmpty( SqList *L ) /*判断顺序表L是否为空表*/
{
return( L -> length == 0);
}
int ListLength( SqList *L ) /*返回顺序表L的元素个数*/
{
return( L -> length);
}
void DispList( SqList *L ) /*输出顺序表L*/
{
int i;
if( ListEmpty(L))
return;
for( i = 0; i < L -> length; i++ )
printf("%c", L -> elem[i]);
printf("\n");
}
int GetElem( SqList *L, int i, ElemType &e) /*获取顺序表中的第i个元素*/
{
if( i < 1 || i > L -> elem[i])
return Error;
e = L -> elem[i - 1];
return True;
}
int LocateElem( SqList *L, ElemType e) /*在顺序表中查找元素e*/
{
int i = 0;
while( i < L -> length && L -> elem[i] != e)
i++;
if(i >= L -> length)
return Error;
else
return i+1;
}
int ListInsert( SqList * &L, int i, ElemType e) /*在顺序表L中第i个位置插入元素e*/
{
int j;
if( i < 1 || i > L -> length + 1)
return 0;
i--; /*将顺序表位序转化为elem下标*/
for( j = L -> length; j > i; j--) /*将elem[i]及后面元素后移一个位置*/
L -> elem[j] = L -> elem[j - 1];
L -> elem[i] = e;
L -> length++; /*顺序表长度增1*/
return True;
}
int ListDelete( SqList * &L, int i, ElemType &e) /*顺序表L中删除第i个元素*/
{
int j;
if( i < 1 || i > L -> length)
return Error;
i--; /*将顺序表位序转化为elem下标*/
e = L -> elem[i];
for(j = i; j < L -> length - i; j++)
L -> elem[j] = L -> elem[j + 1];
L -> length--; /*顺序表长度减1*/
return True;
}
void main()
{
SqList *L;
ElemType e;
printf("(1)初始化顺序表L\n");
InitList(L);
printf("(2)依次采用尾插法插入a,b,c,d,e元素\n");
ListInsert(L, 1, 'a');
ListInsert(L, 2, 'b');
ListInsert(L, 3, 'c');
ListInsert(L, 4, 'd');
ListInsert(L, 5, 'e');
printf("(3)输出顺序表L:");
DispList(L);
printf("(4)顺序表L长度 = %d\n", ListLength(L));
printf("(5)顺序表L为%s\n", (ListEmpty(L) ?"空" :"非空"));
GetElem(L, 3, e);
printf("(6)顺序表L的第3个元素 = %c\n", e);
printf("(7)元素a的位置 = %d\n", LocateElem(L,'a'));
printf("(8)在第4个元素位置上插入f元素\n");
ListInsert(L, 4, 'f');
printf("(9)输出新的顺序表L:");
DispList(L);
printf("(10)删除L的第3个元素\n");
ListDelete(L, 3, e);
printf("(11)输出新的顺序表L:");
DispList(L);
printf("(12)释放顺序表L\n");
DestroyList(L);
}
㈨ C语言实验题求解(。)
第1题
1.改为while(n<=7)
2.改为while(a<1||a>50)
3.改为i=1
㈩ c语言实验报告心得
c语言实验心得:
1、只有频繁用到或对运算速度要求很高的变量才放到data区内,如for循环中的计数值。
2、其他不频繁调用到和对运算速度要求不高的变量都放到xdata区。
3、常量放到code区,如字库、修正系数。
4、逻辑标志变量可以定义到bdata中。
在51系列芯片中有16个字节位寻址区bdata,其中可以定义8*16=128个逻辑变量。这样可以大大降低内存占用空间。定义方法是: bdata bit LedState;但位类型不能用在数组和结构体中。
5、data区内最好放局部变量。
因为局部变量的空间是可以覆盖的(某个函数的局部变量空间在退出该函数是就释放,由别的函数的局部变量覆盖),可以提高内存利用率。当然静态局部变量除外,其内存使用方式与全局变量相同;
6、确保程序中没有未调用的函数。
在Keil C里遇到未调用函数,编译器就将其认为可能是中断函数。函数里用的局部变量的空间是不释放,也就是同全局变量一样处理。这一点Keil做得很愚蠢,但也没办法。
7、如果想节省data空间就必须用large模式。
将未定义内存位置的变量全放到xdata区。当然最好对所有变量都要指定内存类型。
8、使用指针时,要指定指针指向的内存类型。
在C51中未定义指向内存类型的通用指针占用3个字节;而指定指向data区的指针只占1个字节;指定指向xdata区的指针占2个字节。如指针p是指向data区,则应定义为: char data *p;。还可指定指针本身的存放内存类型,如:char data * xdata p;。其含义是指针p指向data区变量,而其本身存放在xdata区。
以前没搞过C51,大学时代跟单片机老师的时候也是捣鼓下汇编,现在重新搞单片机,因为手头资料不多,找到一些C51的程序,发现里面有这些关键字,不甚明了,没办法只好找了下,发现如下描述:
从数据存储类型来说,8051系列有片内、片外程序存储器,片内、片外数据存储器,片内程序存储器还分直接寻址区和间接寻址类型,分别对应code、data、xdata、idata以及根据51系列特点而设定的pdata类型,使用不同的存储器,将使程序执行效率不同,在编写C51程序时,最好指定变量的存储类型,这样将有利于提高程序执行效率(此问题将在后面专门讲述)。与ANSI-C稍有不同,它只分SAMLL、COMPACT、LARGE模式,各种不同的模式对应不同的实际硬件系统,也将有不同的编译结果。
在51系列中data,idata,xdata,pdata的区别
data:固定指前面0x00-0x7f的128个RAM,可以用acc直接读写的,速度最快,生成的代码也最小。
idata:固定指前面0x00-0xff的256个RAM,其中前128和data的128完全相同,只是因为访问的方式不同。idata是用类似C中的指针方式访问的。汇编中的语句为:mox ACC,@Rx.(不重要的补充:c中idata做指针式的访问效果很好)
xdata:外部扩展RAM,一般指外部0x0000-0xffff空间,用DPTR访问。
pdata:外部扩展RAM的低256个字节,地址出现在A0-A7的上时读写,用movx ACC,@Rx读写。这个比较特殊,而且C51好象有对此BUG,建议少用。但也有他的优点,具体用法属于中级问题,这里不提。
三、有关单片机ALE引脚的问题
"单片机不访问外部锁存器时ALE端有正脉冲信号输出,此频率约为时钟振荡频率的1/6.每当访问
外部数据存储器是,在两个机器周期中ALE只出现一次,即丢失一个ALE脉冲."这句话是不是有毛
病.我觉得按这种说法,应该丢失3个ALE脉冲才对,我一直想不通是怎么回事,希望大虾们帮帮我.
小弟感激涕零.
答:
其他所有指令每6个机器周期发出一个ALE,而MOVX指令占用12个机器周期只发出一个ALE
四、如何将一个INT型数据转换成2个CHAR型数据?
经keil优化后,char1=int1/256,char2=int1%256或char1=int1>>8,char2=int1&0x00ff效率是一样的。
五、在KEIL C51上仿真完了,怎样生成HEX文件去烧写??
右键点项目中Target 1,选第二个,在OUTPUT中选中CREAT HEX
六、typedef 和 #define 有何不同??
typedef 和 #define 有何不同》》》 如
typedef unsigned char UCHAR ;
#define unsigned char UCHAR ;
typedef命名一个新的数据类型,但实际上这个新的数据类型是已经存在的,只不过是定义了
一个新的名字.
#define只是一个标号的定义.
你举的例子两者没有区别,但是#define还可以这样用
#define MAX 100
#define FUN(x) 100-(x)
#define LABEL
等等,这些情况下是不能用typedef定义的
七、请问如何设定KELC51的仿真工作频(时钟)
用右键点击左边的的target 1,然后在xtal一栏输入
八、不同模块怎样共享sbit变量,extern不行?
把SBIT定义单独放到一个.H中,每个模块都包含这个.h文件
九、C51中对于Px.x的访问必须自己定义吗?
是的。
如sbit P17 = 0x97;即可定义对P1.7的访问
十、SWITCH( )语句中表达式不可以是位变量对吗?
可以用位变量:
#include
#include
void main()
{
bit flag;
flag=0;
switch(flag)
{
case '0':{printf("0\n");break;}
case '1':{printf("1\n");break;}
default:break;
}
}
bit 变量只有两种状态,if 语句足够啦,!!!
十一、const常数声明占不占内存???
const 只是用来定义“常量”,所占用空间与你的定义有关,如:
const code cstStr[] = {"abc"};
占用代码空间;而如:
const char data cstStr[] = {"abc"};
当然占用内存空间。
另外,#define 之定义似乎不占用空间。
十二、philips的单片机P89C51RD+的扩展RAM在C51中如何使用?
试一试将auxr.1清0,然后在c语言中直接声明xdata类型的变量
十三、BUG of Keil C51
程序中用如下语句:
const unsigned char strArr[] = {"数学"};
结果发现strArr[] 内容为 {0xCA,0xD1,0xA7},真奇怪!
凡是有0xfd,则会通通不见了,所以只能手工输入内码了,例如 uchar strArr[]=
{0xCA,0xfd,0xd1,0xa7}(用Ultraedit会很方便)。
十四、Keil C51中如何实现代码优化?
菜单Project下Option for target "Simulator"的C51.
看到Code optimization了吗?
十五、请教c的!和 ~ 符号有甚区别??
!是逻辑取反,~是按位取反。
十六、c51编程,读端口,还要不要先输出1?
我怎么看到有的要,有的不要,请高手给讲讲,到底咋回事?谢了
要输出1的,除非你能保证之前已经是1,而中间没有输出过其他值。
十七、当定时器1(T1)用于产生波特率时,P3^5还是否可以用作正常的I/O口呢?
p3.5完全可以当普通的io使用
十八、C51中 INT 转换为 2个CHAR?
各位高手:
C51中 INT 转换为 CHAR 如何转换诸如:
X = LOW(Z);
Y = HIGH(Z);
答:
x=(char)z;
y=(char)(z>>8);
十九、如果我想使2EH的第7位置1的话,用位操作可以吗?
现在对位操作指令我一些不太明白请各位多多指教:
如 SETB 07H 表示的是20H.7置1,对吗?(我在一本书上是这么看到的)
那么如果我想使2EH的第7位置1的话,象我举的这个例子怎么表示呢?谢谢!
SETB 77H
setb (2eh-20h)*8+7
20h-2fh每字节有8个可位操作(00h-7fh),其它RAM不可位直接操作
二十、char *addr=0xc000 和char xdata *addr=0xc000有何区别?
char *addr=0xc000;
char xdata *addr=0xc000;
除了在内存中占用的字节不同外,还有别的区别吗?
char *addr=0xc000; 是通用定义,指针变量 addr 可指向任何内存空间的值;
char xdata *addr=0xc000; 指定该指针变量只能指向 xdata 中的值;
后一种定义中该指针变量(addr)将少占用一个存储字节。
uchar xdata *addr=0xc000;指针指向外ram;
如果:data uchar xdata *addr=0xc000;指针指向外ram但指针本身存在于内ram(data)
中
以此类推可以idata uchar xdata *addr=0xc000;pdata uchar xdata *addr=0xc000;
data uchar idata *addr=0xa0;.........
二十一、while(p1_0)的执行时间?
假设,P1_0为单片机P1口的第一脚,请问,
while(P1_0)
{
P1_0=0;
}
while(!P1_0)
{
P1_0=1;
}
以上代码,在KEIL C中,需要多长时间,执行完。能具体说明while(P1_0)的执行时间吗?
仿真运行看看就知道了,
我仿真了试了一下,约14个周期
二十二、怎样编写C51的watchdog程序?
各位大虾,我用KEIL C51 编写了一个带外部开门狗的程序,可程序无法运行起来,经过查
找,发现程序在经过C51编译后,在MAIN()函数的前部增加了一端初始化程序,等到进入
主程序设置开门狗时,开门狗已经时间到,将我的程序复位了,请问我怎样才能修改这一端
初始花程序,使他一运行,就设置开门狗?
可以在startup.a51中加入看门狗刷新指令,当然用汇编,然后重新编译startup.a51
,将他和你的程序连接即可。新的startup.a51会自动代替系统默认的启动模块。
二十三、keil C51 怎样把修改的startup.a51 加到工程文件中
直接加入即可
注意不要改动?STACK,?C_START,?C_STARTUP等符号。startup.a51直接加入项目,不用修改也可。可在内面自己修改汇编的一些限制或堆栈指针。
二十四、关于波特率的设置
我在设定串口波特率时发现一个问题:在晶体震荡器为11.0592MHz时,若设9600BPS的话,
TH1=0XFD,TL1=0XFD,而要设19200BPS的话,TH1、TL1有否变化,如果没变,为什么?
如果变了,又为什么?(因为我看书上俩个是一样的),希望大家点拨。
答:
当电源控制寄存器(PCON)第BIT7(SMOD)为1时波特率加倍。
TH1和TL1的值不变.
二十五、如何在C中声明保留这部分RAM区不被C使用?
我不知道在C源程序中怎么控制这个,但在汇编程序中加入下面一段就行:
DSEG AT 20H
AA: DS 10
这样C51就不会占用20H--29H了
或者在c51里这样定义:
uchar data asm_buff[10] _at_ 0x20;
二十六、问浮点运算问题
我在用C51时发现它对传递浮点参数的个数有限制,请问:
1)参数是以全局变量的形式传递的,请问以全局变量的形式传递的参数也有限制吗?
2)这种传递浮点参数的限制有多少呢?
3)float*float的结果是float类型还是double类型?能否直接赋值给float类型的变量?
答:
由于KEIL C51的参数传递是通过R0-R7来传递的,所以会有限制。
不过KEIL提供了一个编译参数,可以支持更多参数的传递。具体
的内容见KEIL的PDF文档。
我建议你把多个要传递的参数定义到指针或结构体中去,传递参
数通过指针或结构进行,这样好一些。
第3个问题回答是YES,你自己试试不就知道了。
二十七、如何在某一个地址定义ram
用_at_ 命令,这样可以定位灵活一点的地址
uchar xdata dis_buff[16] _at_ 0x6020 ;//定位RAM
将dis_buff[16]定位在0x6020开始的16个字节
二十八、keil c中,用什么函数可以得到奇偶校验位?
例如32位数据,将四个字节相互异或后检查P即可,若耽心P被改变,可用内嵌汇编。
#include
unsigned char parity(unsigned char x){
x^=x;
if(P)return(1);
else return(0);
}
unsigned char parity2(unsigned int x){
#pragma asm
mov a,r7
xrl ar6,a
#pragma endasm
if(P)return(1);
else return(0);
}
