樓主,第三個參數(shù)有點看不懂、、
創(chuàng)新互聯(lián)建站是一家專業(yè)提供遜克企業(yè)網(wǎng)站建設,專注與成都網(wǎng)站制作、成都網(wǎng)站設計、H5響應式網(wǎng)站、小程序制作等業(yè)務。10年已為遜克眾多企業(yè)、政府機構等服務。創(chuàng)新互聯(lián)專業(yè)的建站公司優(yōu)惠進行中。
我用前兩個參數(shù)來完成你的函數(shù)吧
int count(char* s, char c)
{
int i;
int num = 0;
for(i = 0; i strlen(s); i++)
{
if(s[i] == c)
num++;
}
return num;
}
樓主可以參考我的將第三個參數(shù)放進去,如果還不會就將第三個參數(shù)講明白點,我看懂了幫你加
c語言實驗心得:
1、只有頻繁用到或對運算速度要求很高的變量才放到data區(qū)內,如for循環(huán)中的計數(shù)值。
2、其他不頻繁調用到和對運算速度要求不高的變量都放到xdata區(qū)。
3、常量放到code區(qū),如字庫、修正系數(shù)。
4、邏輯標志變量可以定義到bdata中。
在51系列芯片中有16個字節(jié)位尋址區(qū)bdata,其中可以定義8*16=128個邏輯變量。這樣可以大大降低內存占用空間。定義方法是: bdata bit LedState;但位類型不能用在數(shù)組和結構體中。
5、data區(qū)內最好放局部變量。
因為局部變量的空間是可以覆蓋的(某個函數(shù)的局部變量空間在退出該函數(shù)是就釋放,由別的函數(shù)的局部變量覆蓋),可以提高內存利用率。當然靜態(tài)局部變量除外,其內存使用方式與全局變量相同;
6、確保程序中沒有未調用的函數(shù)。
在Keil C里遇到未調用函數(shù),編譯器就將其認為可能是中斷函數(shù)。函數(shù)里用的局部變量的空間是不釋放,也就是同全局變量一樣處理。這一點Keil做得很愚蠢,但也沒辦法。
7、如果想節(jié)省data空間就必須用large模式。
將未定義內存位置的變量全放到xdata區(qū)。當然最好對所有變量都要指定內存類型。
8、使用指針時,要指定指針指向的內存類型。
在C51中未定義指向內存類型的通用指針占用3個字節(jié);而指定指向data區(qū)的指針只占1個字節(jié);指定指向xdata區(qū)的指針占2個字節(jié)。如指針p是指向data區(qū),則應定義為: char data *p;。還可指定指針本身的存放內存類型,如:char data * xdata p;。其含義是指針p指向data區(qū)變量,而其本身存放在xdata區(qū)。
以前沒搞過C51,大學時代跟單片機老師的時候也是搗鼓下匯編,現(xiàn)在重新搞單片機,因為手頭資料不多,找到一些C51的程序,發(fā)現(xiàn)里面有這些關鍵字,不甚明了,沒辦法只好找了下,發(fā)現(xiàn)如下描述:
從數(shù)據(jù)存儲類型來說,8051系列有片內、片外程序存儲器,片內、片外數(shù)據(jù)存儲器,片內程序存儲器還分直接尋址區(qū)和間接尋址類型,分別對應code、data、xdata、idata以及根據(jù)51系列特點而設定的pdata類型,使用不同的存儲器,將使程序執(zhí)行效率不同,在編寫C51程序時,最好指定變量的存儲類型,這樣將有利于提高程序執(zhí)行效率(此問題將在后面專門講述)。與ANSI-C稍有不同,它只分SAMLL、COMPACT、LARGE模式,各種不同的模式對應不同的實際硬件系統(tǒng),也將有不同的編譯結果。
在51系列中data,idata,xdata,pdata的區(qū)別
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個字節(jié),地址出現(xiàn)在A0-A7的上時讀寫,用movx ACC,@Rx讀寫。這個比較特殊,而且C51好象有對此BUG,建議少用。但也有他的優(yōu)點,具體用法屬于中級問題,這里不提。
三、有關單片機ALE引腳的問題
"單片機不訪問外部鎖存器時ALE端有正脈沖信號輸出,此頻率約為時鐘振蕩頻率的1/6.每當訪問
外部數(shù)據(jù)存儲器是,在兩個機器周期中ALE只出現(xiàn)一次,即丟失一個ALE脈沖."這句話是不是有毛
病.我覺得按這種說法,應該丟失3個ALE脈沖才對,我一直想不通是怎么回事,希望大蝦們幫幫我.
小弟感激涕零.
答:
其他所有指令每6個機器周期發(fā)出一個ALE,而MOVX指令占用12個機器周期只發(fā)出一個ALE
四、如何將一個INT型數(shù)據(jù)轉換成2個CHAR型數(shù)據(jù)?
經(jīng)keil優(yōu)化后,char1=int1/256,char2=int1%256或char1=int18,char2=int10x00ff效率是一樣的。
五、在KEIL C51上仿真完了,怎樣生成HEX文件去燒寫??
右鍵點項目中Target 1,選第二個,在OUTPUT中選中CREAT HEX
六、typedef 和 #define 有何不同??
typedef 和 #define 有何不同》》》 如
typedef unsigned char UCHAR ;
#define unsigned char UCHAR ;
typedef命名一個新的數(shù)據(jù)類型,但實際上這個新的數(shù)據(jù)類型是已經(jīng)存在的,只不過是定義了
一個新的名字.
#define只是一個標號的定義.
你舉的例子兩者沒有區(qū)別,但是#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 變量只有兩種狀態(tài),if 語句足夠啦,!!!
十一、const常數(shù)聲明占不占內存???
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[] = {"數(shù)學"};
結果發(fā)現(xiàn)strArr[] 內容為 {0xCA,0xD1,0xA7},真奇怪!
凡是有0xfd,則會通通不見了,所以只能手工輸入內碼了,例如 uchar strArr[]=
{0xCA,0xfd,0xd1,0xa7}(用Ultraedit會很方便)。
十四、Keil C51中如何實現(xiàn)代碼優(yōu)化?
菜單Project下Option for target "Simulator"的C51.
看到Code optimization了嗎?
十五、請教c的!和 ~ 符號有甚區(qū)別??
!是邏輯取反,~是按位取反。
十六、c51編程,讀端口,還要不要先輸出1?
我怎么看到有的要,有的不要,請高手給講講,到底咋回事?謝了
要輸出1的,除非你能保證之前已經(jīng)是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)(z8);
十九、如果我想使2EH的第7位置1的話,用位操作可以嗎?
現(xiàn)在對位操作指令我一些不太明白請各位多多指教:
如 SETB 07H 表示的是20H.7置1,對嗎?(我在一本書上是這么看到的)
那么如果我想使2EH的第7位置1的話,象我舉的這個例子怎么表示呢?謝謝!
SETB 77H
setb (2eh-20h)*8+7
20h-2fh每字節(jié)有8個可位操作(00h-7fh),其它RAM不可位直接操作
二十、char *addr=0xc000 和char xdata *addr=0xc000有何區(qū)別?
char *addr=0xc000;
char xdata *addr=0xc000;
除了在內存中占用的字節(jié)不同外,還有別的區(qū)別嗎?
char *addr=0xc000; 是通用定義,指針變量 addr 可指向任何內存空間的值;
char xdata *addr=0xc000; 指定該指針變量只能指向 xdata 中的值;
后一種定義中該指針變量(addr)將少占用一個存儲字節(jié)。
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)的執(zhí)行時間?
假設,P1_0為單片機P1口的第一腳,請問,
while(P1_0)
{
P1_0=0;
}
while(!P1_0)
{
P1_0=1;
}
以上代碼,在KEIL C中,需要多長時間,執(zhí)行完。能具體說明while(P1_0)的執(zhí)行時間嗎?
仿真運行看看就知道了,
我仿真了試了一下,約14個周期
二十二、怎樣編寫C51的watchdog程序?
各位大蝦,我用KEIL C51 編寫了一個帶外部開門狗的程序,可程序無法運行起來,經(jīng)過查
找,發(fā)現(xiàn)程序在經(jīng)過C51編譯后,在MAIN()函數(shù)的前部增加了一端初始化程序,等到進入
主程序設置開門狗時,開門狗已經(jīng)時間到,將我的程序復位了,請問我怎樣才能修改這一端
初始花程序,使他一運行,就設置開門狗?
可以在startup.a51中加入看門狗刷新指令,當然用匯編,然后重新編譯startup.a51
,將他和你的程序連接即可。新的startup.a51會自動代替系統(tǒng)默認的啟動模塊。
二十三、keil C51 怎樣把修改的startup.a51 加到工程文件中
直接加入即可
注意不要改動?STACK,?C_START,?C_STARTUP等符號。startup.a51直接加入項目,不用修改也可??稍趦让孀约盒薷膮R編的一些限制或堆棧指針。
二十四、關于波特率的設置
我在設定串口波特率時發(fā)現(xiàn)一個問題:在晶體震蕩器為11.0592MHz時,若設9600BPS的話,
TH1=0XFD,TL1=0XFD,而要設19200BPS的話,TH1、TL1有否變化,如果沒變,為什么?
如果變了,又為什么?(因為我看書上倆個是一樣的),希望大家點撥。
答:
當電源控制寄存器(PCON)第BIT7(SMOD)為1時波特率加倍。
TH1和TL1的值不變.
二十五、如何在C中聲明保留這部分RAM區(qū)不被C使用?
我不知道在C源程序中怎么控制這個,但在匯編程序中加入下面一段就行:
DSEG AT 20H
AA: DS 10
這樣C51就不會占用20H--29H了
或者在c51里這樣定義:
uchar data asm_buff[10] _at_ 0x20;
二十六、問浮點運算問題
我在用C51時發(fā)現(xiàn)它對傳遞浮點參數(shù)的個數(shù)有限制,請問:
1)參數(shù)是以全局變量的形式傳遞的,請問以全局變量的形式傳遞的參數(shù)也有限制嗎?
2)這種傳遞浮點參數(shù)的限制有多少呢?
3)float*float的結果是float類型還是double類型?能否直接賦值給float類型的變量?
答:
由于KEIL C51的參數(shù)傳遞是通過R0-R7來傳遞的,所以會有限制。
不過KEIL提供了一個編譯參數(shù),可以支持更多參數(shù)的傳遞。具體
的內容見KEIL的PDF文檔。
我建議你把多個要傳遞的參數(shù)定義到指針或結構體中去,傳遞參
數(shù)通過指針或結構進行,這樣好一些。
第3個問題回答是YES,你自己試試不就知道了。
二十七、如何在某一個地址定義ram
用_at_ 命令,這樣可以定位靈活一點的地址
uchar xdata dis_buff[16] _at_ 0x6020 ;//定位RAM
將dis_buff[16]定位在0x6020開始的16個字節(jié)
二十八、keil c中,用什么函數(shù)可以得到奇偶校驗位?
例如32位數(shù)據(jù),將四個字節(jié)相互異或后檢查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);
}
//線性表函數(shù)操作
#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的元素個數(shù)*/
{
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);
}
又是課堂作業(yè),做了n遍,練練手把
1.判斷素數(shù)
#includestdio.h
int is_prime(int num)
{
int i=0;
for(;inum/2;i++)
{
if(num%i==0)
{
break;
}
}
if(i=num/2)
{
return -1;//不是素數(shù)返回-1
}
else
{
return 0;//如果是素數(shù)返回0
}
}
int main(void)
{
printf("請輸入一個正整數(shù):");
int x;
scanf("%d",x);
if(x=0)
{
printf("輸入的不是正整數(shù)");
}
else
{
if(is_prime(x)==-1)
printf("輸入的是素數(shù)");
if(is_prime(x)==0)
printf("輸入的不是素數(shù)");
}
}
2.scopy函數(shù)
#includestdio.h
void myscopy(char *des, const char* src)
{
while(*src!='\0')
{
*des++=*src++;
}
}
int main(void)
{
char a[20]="hello";
char b[20]="myworld";//注意這個地方數(shù)組的長度要適當大,要不然可能出現(xiàn)越界!
printf("拷貝之前,a是%s,b是%s",a,b);
myscopy(a,b);
printf("拷貝之后,a是%s,b是%s"a,b);
return 0;
}
3.矩陣相加
int **res addmatrix(int a[][],int b[][])
{
int sum[5][5];
int i=0;
int j=0;
for(;i5;i++)
{
for(;j5;j++)
{
sum[i][j]=a[i][j]+b[i][j];
}
}
return sum;
}
int main(void)
{
int a[5][5]={},b[5][5]={};//初始化可以隨意,注意列數(shù)要求就行了
int i=0;
int j=0;
int mysum[5][5]=addmatrix(a,b);
for(;i5;i++) //輸出
{
for(;j5;j++)
{
printf("%2d ",mysum[i][j]);
}
printf("\n");
}
}
4.遞歸求斐波那契數(shù)列
#includestdio.h
static buf[100];//這個主要是用來存數(shù)列的中間結果的,為了提高遞歸算法的效率,否則會運行得很慢
int Febanaci(int num)
{
if(num=1||num=2)
{
return num;
}
else
{
buf[num-1]=Febanaci(num-1);
buf[num-2]=Febanaci(num-2);
buf[num]=buf[num-1]+buf[num-2];
return buf[num];
}
}
int main(void)
{
int i=1;
int count=0;
for(;i21;i++)
{
printf("%5d ",Febanaci(i));
count++;
if(count==3)
{
count=0;
printf("\n");
}
}
return 0;
}
5.統(tǒng)計字符數(shù)
void cnt(const char *src)
{
int num;
int alpha;
int space;
int others;
while(*src!="\0")
{
if(isdigit(*src))
{
num++;
}
else if(isalpha(*src))
{
alpha++;
}
else if(*src=" ")
{
space++;
}
else
{
others;
}
src++;
}
printf("該字符串中數(shù)字有%d個,字母有%d個,空格有%d個,其他字符有%d個",num,alpha,space,others);
}
int main(void)
{
printf("請輸入要統(tǒng)計的字符串:");
char mystr[100];//注意輸入的時候不要越界;
gets(mystr);
cnt(mystr);
}