一、下面的程序會出現什麼結果
#include <stdio.h>
#include <stdlib.h>linux
#include <string.h>
void getmemory(char *p)
{
p=(char *) malloc(100);
strcpy(p,」hello world」);
}
int main( )
{
char *str=NULL;
getmemory(str);
printf(「%s/n」,str);
free(str);
return 0;
}
程序崩潰,getmemory中的malloc 不能返回動態內存, free()對str操做很危險c++
2、(void *)ptr 和 (*(void**))ptr的結果是否相同?
答:ptr爲同一個指針
(void *)ptr 和 (*(void**))ptr值是相同的面試
三、對絕對地址0×100000賦值且想讓程序跳轉到絕對地址是0×100000去執行
(unsigned int*)0×100000 = 1234;
首先要將0×100000強制轉換成函數指針,即:
(void (*)())0×100000
而後再調用它:
*((void (*)())0×100000)();
用typedef能夠看得更直觀些:
typedef void(*)() voidFuncPtr;
*((voidFuncPtr)0×100000)();算法
四、下面的函數實如今一個數上加一個數,有什麼錯誤?請改正。
int add_n ( int n )
{
static int i = 100;
i += n;
return i;
}
當你第二次調用時得不到正確的結果,難道你寫個函數就是爲了調用一次?問題就出在 static上數組
五、下面這個程序執行後會有什麼錯誤或者效果:
#define MAX 255
int main()
{
unsigned char A[MAX],i;//i被定義爲unsigned char
for (i=0;i<=MAX;i++)
A[i]=i;
}
解答:死循環加數組越界訪問(C/C++不進行數組越界檢查)
MAX=255
數組A的下標範圍爲:0..MAX-1,這是其一
其二、當i循環到255時,循環內執行:
A[255]=255;
這句自己沒有問題,可是返回for (i=0;i<=MAX;i++)語句時,
因爲unsigned char的取值範圍在(0..255),i++之後i又爲0了..無限循環下去.安全
六、請問一下程序將輸出什麼結果?
char *RetMenory(void)
{
char p[] = 「hellow world」;
return p;
}
void Test(void)
{
char *str = NULL;
str = RetMemory();
printf(str);
}
RetMenory執行完畢,p資源被回收,指向未知地址。返回地址,str的內容應是不可預測的, 打印的應該是str的地址ide
七、對下面程序進行分析
void test2()
{
char string[10], str1[10];
int i;
for(i=0; i<10; i++)
{
str1[i] = 'a';
}
strcpy( string, str1 );
}
解答:函數
字符數組str1不能在數組內結束工具
strcpy(string, str1)調用使得從str1內存起復制到string內存起所複製的字節數具備不肯定性spa
指出庫函數strcpy工做方式
str1不能在數組內結束:由於str1的存儲爲:{a,a,a,a,a,a,a,a,a,a},沒有'\0'(字符串結束符),因此不能結束
strcpy( char *s1,char *s2)他的工做原理是,掃描s2指向的內存,逐個字符付到s1所指向的內存,直到碰到'\0',由於str1結尾沒有'\0',因此具備不肯定性,不知道他後面還會付什麼東東。
正確應以下
void test2()
{
char string[10], str1[10];
int i;
for(i=0; i<9; i++)
{
str1[i] = 'a'+i; //把abcdefghi賦值給字符數組
}
str[i]='\0';//加上結束符
strcpy( string, str1 );
}
八、分析下列代碼輸出的值
int arr[] = {6,7,8,9,10};
int *ptr = arr;
*(ptr++)+=123;
printf(「 %d %d 」, *ptr, *(++ptr));
輸出:8 8
過程:對於*(ptr++)+=123;先作加法6+123,而後++,指針指向7;對於printf(「 %d %d 」, *ptr, *(++ptr));從後往前執行,指針先++,指向8,而後輸出8,緊接着再輸出8
九、分析下面的代碼:
char *a = "hello";
char *b = "hello";
if(a= =b)
printf("YES");
else
printf("NO");
輸出YES
"hello"是一個常量字符串,位於靜態存儲區,在程序生命期內恆定不變,a和b同時指向同一個hello的。
十、已知strcpy函數的原型是:
char * strcpy(char * strDest,const char * strSrc);
不調用庫函數,實現strcpy函數。
解釋爲何要返回char *。
解答:
strcpy實現代碼:
char * strcpy( char *strDest, const char *strSrc )
{
assert( (strDest != NULL) && (strSrc != NULL) );
char *address = strDest;
while( (*strDest++ = * strSrc++) != '’ );
return address;
}
十一、判斷一個字符串是否是迴文
int IsReverseStr(char *aStr)
{
int i,j;
int found=1;
if(aStr==NULL)
return -1;
j=strlen(aStr);
for(i=0;i<j; i++)
if(*(aStr+i)!=*(aStr+j-i-1))
{
found=0;
break;
}
return found;
}
十二、寫一個函數比較兩個字符串str1和str2的大小,若相等返回0,若str1大於
str2返回1,若str1小於str2返回-1
int strcmp ( const char * src,const char * dst)
{
int ret = 0 ;
while( ! (ret = *(unsigned char *)src – *(unsigned char *)dst) && *dst)
{
++src;
++dst;
}
if ( ret < 0 )
ret = -1 ;
else if ( ret > 0 )
ret = 1 ;
return( ret );
}
1三、給定字符串A和B,輸出A和B中的最大公共子串。
好比A="aocdfe" B="pmcdfa" 則輸出"cdf"
*/
//Author: azhen
#include
#include
#include
char *commanstring(char shortstring[], char longstring[])
{
int i, j;
char *substring=malloc(256);
if(strstr(longstring, shortstring)!=NULL)
return shortstring;
for(i=strlen(shortstring)-1;i>0; i–) //不然,開始循環計算
{
for(j=0; j<=strlen(shortstring)-i; j++)
{
memcpy(substring, &shortstring[j], i);
substring[i]='\0';
if(strstr(longstring, substring)!=NULL)
return substring;
}
}
return NULL;
}
int main()
{
char *str1=malloc(256);
char *str2=malloc(256);
char *comman=NULL;
gets(str1);
gets(str2);
if(strlen(str1)>strlen(str2)) //將短的字符串放前面
comman=commanstring(str2, str1);
else
comman=commanstring(str1, str2);
printf(「the longest comman string is: %s\n」, comman);
}
14、編寫一個 C 函數,該函數在一個字符串中找到可能的最長的子字符串,且該字符串是由同一字符組成的。
char * search(char *cpSource, char ch)
{
char *cpTemp=NULL, *cpDest=NULL;
int iTemp, iCount=0;
while(*cpSource)
{
if(*cpSource == ch)
{
iTemp = 0;
cpTemp = cpSource;
while(*cpSource == ch)
++iTemp, ++cpSource;
if(iTemp > iCount)
iCount = iTemp, cpDest = cpTemp;
if(!*cpSource)
break;
}
++cpSource;
}
return cpDest;
}
1五、不用庫函數,用C語言實現將一整型數字轉化爲字符串
int getlen(char *s)
{
int n;
for(n = 0; *s != '\0'; s++)
n++;
return n;
}
void reverse(char s[])
{
int c,i,j;
for(i = 0,j = getlen(s) - 1; i < j; i++,j--)
{
c = s[i];
s[i] = s[j];
s[j] = c;
}
}
void itoa(int n,char s[])
{
int i,sign;
if((sign = n) < 0)
n = -n;
i = 0;
do{/*以反序生成數字*/
s[i++] = n%10 + '0';/*get next number*/
}while((n /= 10) > 0);/*delete the number*/
if(sign < 0)
s[i++] = '-';
s[i] = '\0';
reverse(s);
}
1六、請說出const與#define 相比,有何優勢?
答:const做用:定義常量、修飾函數參數、修飾函數返回值三個做用。被Const修飾的東西都受到強制保護,能夠預防意外的變更,能提升程序的健壯性。
A、const常量有數據類型,而宏常量沒有數據類型。編譯器能夠對前者進行類型安全檢查。而對後者只進行字符替換,沒有類型安全檢查,而且在字符替換可能會產生意料不到的錯誤。
B、有些集成化的調試工具能夠對const 常量進行調試,可是不能對宏常量進行調試。
1七、編寫用C語言實現的求n階階乘問題的遞歸算法:
答:
long int fact(int n)
{
if(n==0||n==1)
return 1;
else
return n*fact(n-1);
}
1八、二分查找算法:
A遞歸方法實現:
int BSearch(elemtype a[],elemtype x,int low,int high)
/*在下界爲low,上界爲high的數組a中折半查找數據元素x*/
{
int mid;
if(low>high)
return -1;
mid=(low+high)/2;
if(x == a[mid])
return mid;
if(x<a[mid])
return(bsearch(a,x,low,mid-1));
else
return(BSearch(a,x,mid+1,high));
}
B、非遞歸方法實現:
int BSearch(elemtype a[],keytype key,int n)
{
int low,high,mid;
low=0;high=n-1;
while(low<=high)
{
mid=(low+high)/2;
if(a[mid].key==key)
return mid;
else if(a[mid].key<key)
low="mid+1;</font">
else
high=mid-1;
}
return -1;
}
1九、遞歸計算以下遞歸函數的值(斐波拉契)
f(1)=1
f(2)=1
f(n)=f(n-1)+f(n-2) n>2
解:
A、非遞歸算法
int f(int n)
{
int i,s,s1,s2;
s1=1;/*s1用於保存f(n-1)的值*/
s2=1;/*s2用於保存f(n-2)的值*/
s=1;
for(i=3;i<=n;i++)
{
s=s1+s2;
s2=s1;
s1=s;
}
return(s);
}
B、遞歸算法
int f(int n)
{
if(n==1||n==2)
rerurn 1;
else
return f(n-1)+f(n-2);
}
20、如何判斷一段程序是由C 編譯程序仍是由C++編譯程序編譯的?
答:
#ifdef __cplusplus
cout<<"c++";
#else
cout<<"c";
#endif
2一、結構與共用體有和區別?
答:
A、結構和共用體都是由多個不一樣的數據類型成員組成, 但在任何同一時刻, 共用體中只存放了一個被選中的成員(全部成員共用一塊地址空間), 而結構的全部成員都存在(不一樣成員的存放地址不一樣)。
B、對於共用體的不一樣成員賦值, 將會對其它成員重寫, 原來成員的值就不存在了, 而對於結構的不一樣成員賦值是互不影響的