一、 简答题。 ( 共14题 ,共0分,每题0分 )
1. int i=10, j=10, k=3; k*=i+j; k最后的值是?
答:k = 60
ok
2. 写出程序结果:
void Func(char str[100])
{                                         
  printf("%d\n", sizeof(str));
}
答:4或者8(如果操作系统为32位则为4,64位则为8
是地址吗
3. 写出sizeof(struct name2)的结果
struct name2{
    char str;
    int num;
    short x;
}
不会!看结构
答:此题考察结构对齐的知识,结果为12
4. 写出sizeof(struct name1) 的结果
struct name1{
    char str;
    short x;
    int num;
}
不会!
答:同样考察的是结构对齐的知识,结果为8
5. A.c 和B.c两个c文件中使用了两个相同名字的static变量,编译的时候会会有问题?这两个static变量会保存到哪里(栈还是堆或者其他的)?
答:没有问题,static变量只在当前文件中有效,也就是说static变量的作用域属于所在的文件域。
static变量保存在全局/静态区
6. (void *)ptr 和 (*(void**))ptr的结果是否相同?
答:相同。首先第一个(void *)ptr将ptr转换为空指针类型(一级指针),*void**))ptr相当于先将ptr转换为空类型指针(二级指针二级指针是指向指针的指针,在前面加上*解指针,也就是空类型指针了(一级指针)
7. #define DOUBLE(x) x+x ,i = 5*DOUBLE(5); i 是多少?
答: i = 5 * 5+5 = 30;看书上的结构理解下意思
8. 下面的声明都是什么意思?
const int a;
int const a;
const int *a;
int * const a;
int const * const a ;
答:第一个定义常量a,第二个也是定义常量a,三个定义常量指针a,第四个定义指针常量a五个定义指向常量的指针常量(相当于const引用)
9. 关键字const是什么含意?
答:1.const修饰基本类型,比如int类型为常量。
2.const修饰指针分为两种情况:指针常量或者常量指针。
3.const修饰类的成员函数,在此函数中无法修改类中数据成员的值。???
4.const修饰返回值意味着返回值不可被改变
5.const修饰函数参数,意味着函数参数不能被有意或者无意修改。
10. do……while和while……do有什么区别?
答:do…while先执行循环再判断条件,while…do先进行判断再执行循环。
11.语句for(;1;)有什么问题?它是什么意思?
他的意思是循环条件永远为真,不停地进行循环操作,除非循环体中有强制退出循环的语句才能终止循环,其实功能就相当于while(1)
答:无限循环
12.如何引用一个已经定义过的全局变量?
答:题目说的有点不太清楚,如果是引用其它文件中定义的全局变量用extern,如果是在本文件中引用的话用作用域运算符::  是在c++中的
13.switch()结构中条件表达式的类型可以是什么类型?
答:整型,字符型,常量,枚举类型
14..h头文件中的ifndef/define/endif的作用?
答:预编译命令,一般是用来防止头文件多重包含 结构?
二、 问答题。 ( 共63题 ,共0分,每题0分 )
1.关键字static的作用是什么?
第一:隐藏static全局变量只在本文件中可访问,其它文件无法访问。
第二:持久保存变量的内容。static变量一经初始化便到程序运行结束后才
会被释放。
第三:默认初始化为0.static变量会被编译器默认初始化为0
2.int a[3];
a[0]=0; a[1]=1; a[2]=2;
int *p, *q;
p=a;
q=&a[2];
则a[q-p]=a[2]
这段程序执行完之后数组中元素的值分别是什么?q-p=2
答:0, 1, 2
3.根据a的值,完成b的初始化,并将b的值返回
int func(float a)
{
    int b;
    switch(a)
    {
        case 1: 30;
      break;
        case 2: 20;
        case 3: 16;
        default: 0
    }
    return b;
}
此程序段有什么错误,如果有请指出
答:1.switch只能用整型或者字符型或者枚举类型,float类型不正确。
2.case后面没有加break
4. 写出程序运行结果
int sum(int a)
{
auto int c=0;
static int b=3;
c+=1;
b+=2;
return(a+b+c);
}
void main()
{
int I;
int a=2;
for(I=0;I<5;I++)
{
printf("%d,", sum(a));
}
}
答:8,10,12,14,16
5. 写出输出结果
void g(int**);
int main()
{
int line[10],i;
int *p=line;
for (i=0;i<10;i++)
{
*p=i;
g(&p);
}
for(i=0;i<10;i++)
printf("%d\n",line[i]);
return 0;
}
 
void g(int**p)
{
(**p)++;
(*p)++;
}
答:1 2 3 4 5 6 7 8 9 10
6. 写出输出结果
int main()
{
    int a[5]={1,2,3,4,5};
    int *ptr=(int *)(&a+1);//解释 解释1
printf("%d,%d",*(a+1),*(ptr-1));
}
答:2, 5
7.写出下面的结果
char str1[] = "abc";
char str2[] = "abc";
const char str3[] = "abc";
const char str4[] = "abc";
 
const char *str5 = "abc";
const char *str6 = "abc";
 
char *str7 = "abc";
char *str8 = "abc";
printf (“%d”,str1 == str2 );//数组名就是
printf (“%d”, str3 == str4);
printf (“%d”, str5 == str6 );
printf (“%d”, str7 == str8 );
答:0 0 1 1
8. 以下3个有什么区别
char * const p;
char const * p;
const char *p;
答:第一个是指针常量,第二个是常量指针,第三个也是常量指针
9.unsigned short array[]={1,2,3,4,5,6,7};
int i=3;
*(array+i)=?
答:4
10. i最后等于多少?
int i = 1;
int j = i++;
if((i>j++) && (i++ == j)) i+=j;
答:5
11. 写一个“标准”宏
1>输入两个参数,输出较小的一个
2>表明1年中有多少秒(忽略闰年问题)
答:此题的考察点是防止数据太大int类型表示不了,现在不用担心(int占4个字节)
1.#define Min(a, b) ((a) <= (b) ? (a): (b))
2.#define SECONDS_PER_YEAR (60 * 60 * 24 * 365UL
考察内容:
1). #define 语法的基本知识(例如:不能以分号结束,括号的使用,等等)
2). 意识到这个表达式将使一个16位机的整型数溢出-因此要用到长整型符号L,告诉编译器这个常数是的长整型数。
3). 如果你在你的表达式中用到UL(表示无符号长整型),那么你有了一个好的起点。
12. 什么是预编译,何时需要预编译?
答:预编译又称为预处理,主要做一些文本的替换工作。比如#include包含文件代码,#define宏定义的替换,条件编译等等。
预编译代码有助于在开发周期中缩短编译时间,特别是在以下的情况中:
1.总是使用不经常改动的大型代码体
2.程序由多个模块组成,所有模块都使用一组标准的包含文件和相同的编译选项。在这种情况下可以将所有包含文件编译为一个预编译头。
用于创建预编译头文件的第一次编译所花费的时间比后面的编译稍长一些,通过包含预编译代码可以加快后面的编译速度。
13. 阐述堆和栈的区别
答:1.申请方式。由编译器自动申请空间,需要程序员手动申请空间。
2.申请后的系统响应。的剩余空间大于所申请的空间,系统为程序提供内存,否则退出。堆申请方式是链表式申请,遍历空闲内存链表,大于申请空间的内存,空闲内存链表中删除,分配给程序。
3.申请大小的限制。栈在windows下是向低地址扩展的数据结构,是一块连续的内存区域,大小是固定的。一般是2m)堆是向高地址扩展的数据结构,
不连续的内存区域。
4.申请效率,分配速度较快,分配速度较慢,容易产生内存碎片。
还有其它的一些区别,课下大家自己去学习一下。
14. 简要描述c程序的内存分配
答:C语言内存分配主要分为5块
1.。存放局部变量,函数参数等。编译器自动申请空间,自动释放
2.堆。由程序员手动申请、释放空间。
3.常量存储区。一般是常量字符串
4.静态/全局区。存储的是静态变量或者全局变量。初始化后等到程序结束后内存才会被释放
5.程序代码区。存放函数体的二进制代码。
15. static全局变量与普通的全局变量有什么区别?static局部变量和普通局部变量有什么区别?static函数与普通函数有什么区别?
答:1.static全局变量只能在本文件中访问,而全局变量可以通过extern其它文件中访问
2.static局部变量存储在全局/静态区中,经初始化直到程序结束后才会被释放。普通的局部变量存储在栈中。
3.static函数只能在本文件中访问,普通函数可以在其它文件中访问。
16. 局部变量能否和全局变量重名,如果可以,请说明原因?
答:可以局部变量会屏蔽全局变量
17. 使用枚举的好处?
答:代码的可读性就好一些
18. 全局变量和局部变量在内存中的存储是否有区别?如果有,是什么区别?
答:全局变量存储在全局数据区,初始化后直到程序运行结束后才会释放内存。
局部变量存储在栈上,作用域在其被定义的函数或者块中,出了这个作用域就会被释放。
19. #include<file.h> 与 #include "file.h"的区别?
答:<>一般用来引用系统定义的头文件,“”一般用来引用自定义头文件。
20. “引用”与指针的区别是什么?
答:引用是变量的别名,指针保存的是变量的地址。也就是说引用是直接操作变量本身,指针是间接操作变量。
21. 已知strcpy函数的原型是:
char * strcpy(char * strDest,const char * strSrc);
1.不调用库函数,实现strcpy函数。
2.解释为什么要返回char *
答:1. char *strcpy(char *strDest, const char *strSrc)
{
    char *strDestCopy = strDest;
    if(strDest == NULL || strSrc == NULL)
    {
        throw("invalid arguments");
    }
    while ((*strDestCopy++ = *strSrc++) != '\0');
    return strDest;
}
2.支持链式表达式
22. 判断一个字符串是不是回文,当字符串是回文时,函数返回字符串:yes!,否则函数返回字符串:no。所谓回文即正向与反向的拼写都一样,例如:adgda。
答:
#include <stdio.h>
#include <string.h>
#define N 100
char *judgeStrings(char *str);
int main()
{
    char a[N];
    printf("请输入要判断的回文字符串:");
    scanf("%s", a);
    printf("%s\n", judgeStrings(a));
    return 0;
}
char *judgeStrings(char *str)
{
    if(str == NULL)
        throw "error: str is NULL";
    int len = strlen(str);
    for(int i=0; i<len/2; i++)
    {
        if(str[i] != str[len - i - 1])
            return "no";
    }
    return "yes!";
}
23. 递规反向输出字符串的例子,可谓是反序的经典例程,那么任意输入一字符串,利用递归将其反向输出.
#include <stdio.h>
#define N 20
void getReverseChar(char *str);
int main()
{
    char a[N];
    printf("请输入要反序的字符串:");
    scanf("%s", a);
    getReverseChar(a);
    printf("\n");
    return 0;
}
void getReverseChar(char *str)
{
    if(*str == '\0')
        return;
    else
    {
        getReverseChar(str+1);
        printf("%c", *str);
    }
}
24. 用指针的方法,将字符串“ABCD1234efgh”前后对调显示
#include <stdio.h>
#include <string.h>
int main()
{
    char a[] = "ABCD1234efgh";
    char *p = a;
    int len = strlen(a);
    for(int i = 0; i < len/2; i++)
    {
        char temp = a[i];
        a[i] = a[len - i - 1];
        a[len - i - 1] = temp;
    }
    printf("%s\n", a);
    return 0;
}
25. 两个字符串,s,t;把t字符串插入到s字符串中,s字符串有足够的空间存放t字符串
答:#include <stdio.h>
#include <string.h>
#define N 100
int main()
{
    char s[N] = "HelloWorld";
    char *t = "welcome to Beijing";
    int sLen = strlen(s);
    int tLen = strlen(t);
    int pos;
    printf("请输入要插入的位置:");
    scanf("%d", &pos);
    if(pos > sLen || pos < 0)
        return 0;
    //先将s字符数组后面的字符放到后面(采用前插法,从0开始)
    for (int i = 0; i < sLen - pos; i++)
    {
        s[pos + tLen + i] = s[pos + i];
    }
    //再放心的插入t字符数组
    for (int i = 0; i < tLen; i++)
    {
        s[pos+i] = t[i];
    }
   
    s[sLen + tLen] = '\0';
    printf("%s\n", s);
    return 0;
}
26. 已知strcmp的原型是
int strcmp(const char *str1, const char *str2),不调用库函数,实现strcmp函数
答:#include <stdio.h>
#include <string.h>
#define N 100
int strcmp(const char *str1, const char *str2);
int main()
{
    char s[N];
    char t[N];
    printf("请输入要比较的一个字符串:");
    scanf("%s", s);
    printf("请输入要比较的另一个字符串:");
    scanf("%s", t);
    printf("%d\n", strcmp1(s, t));
    return 0;
}
int strcmp(const char *str1, const char *str2)
{
    int len1 = strlen(str1);
    int len2 = strlen(str2);
    int maxLen = len1 > len2 ? len1 : len2;
    for (int i = 0; i < maxLen; i++)
    {
        if(str1[i] > str2[i])
            return 1;
        else if(str1[i] < str2[i])
            return -1;
    }
    return 0;
}
27. 出错误
#include “string.h”
void main(void)
{ char *src="hello,world";
char *dest=NULL;
dest=(char *)malloc(strlen(src));
int len=strlen(str);
char *d=dest;
char *s=src[len];
while(len--!=0)
d++=s--;
printf("%s",dest);
}
答:1.string.h用<>括起来。
2.dest = (char *)malloc(strlen(src));申请的空间不够,需要改为dest = (char *)malloc(strlen(src)+1);
3.int len = strlen(str);改为int len = strlen(src);
4.char *s = src[len];改为char *s = src[len -1];
5.d++ = s--;改为 *d++ = *s--;
6.需要在printf(“%s”, dest);上面加上一行代码:*d = ‘\0’;
28. 写出输出结果
#include <stdio.h>
void foo(int m, int n)
{
    printf("m=%d, n=%d\n", m, n);
}
 
int main()
{
    int b = 3;
    foo(b+=3, ++b);
    printf("b=%d\n", b);
    return 0;
}
答:此题考察的有一些难度,深入到了编译器级别。编译器实现的不一样,那么结果也是不一样的。vc6.0下面,结果为:7 4 7 在vs2012结果为 7 7 
7 xcode下面是 6 7 7.
29. 分析:
int arr[] = {6,7,8,9,10};
int *ptr = arr;
*(ptr++)+=123;
printf(“ %d %d ”, *ptr, *(++ptr));
答:此题和上一题目类似,考察的是printf()函数的参数入栈顺序,从右往左的运算。所以结果为: 8 8
30. 对下面程序进行分析,若有错误,请写出一个正确的程序段
void test2()
{
    char string[10], str1[10];
    int i;
    for(i=0; i<10; i++)
    {
        str1[i] = 'a';
    }
    strcpy( string, str1 );
}
答:错误,主要是str1[10]字符数组没哟\0。所以应该如下修改:
for(i=0; i < 9; i++)
{
    str[i] = ‘a’;
}
str[i] = ‘\0’;
31. 请问一下程序将输出什么结果?
char *RetMemory(void)
{
    char p[] = “hellow world”;
    return p;
}
void Test(void)
{
    char *str = NULL;
    str = RetMemory();
    printf(str);
}
答:此程序存在的问题是RetMemory(void)函数返回的是局部变量的地址,然后str指向这个地址,但是实际上这块地址已经让编译器给释放,编译器有可能把这块内存分配给其它的变量。所以如果内存没有被修改的话输出结果为hello world,如果被修改则输出结果未知。
32. 分析下面的程序:
void GetMemory(char **p,int num)
{
    *p=(char *)malloc(num);
}
int main()
{
    char *str=NULL;
    GetMemory(&str,100);
    strcpy(str,"hello");
    free(str);
    if(str!=NULL)
    {
        strcpy(str,"world");
    }
    printf("\n str is %s",str);
    getchar();
}
答:程序存在的问题是:GetMemory函数成功的为str分配了一块堆上的内存,但是后来被释放掉了。由于释放后没有将指针置为空,故str肯定不会为NULL。接着调用strcpy()函数为str指向的空间赋值。这是非法的,str指向的是已经被释放的内存,故拷贝会失败。
33. 下面的语句会出现什么结果?
char szstr[10];
strcpy(szstr,"0123456789");
答:编译不通过,字符数组szstr空间为10,但是字符串为11个(加上\0,故字符数组空间不够存下字符串。
34. 下面的程序会出现什么结果
#include <stdio.h>
#include <stdlib.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;
}
答:程序存在的问题是str没有指向申请出来的空间,str还是为NULL。free)函数释放堆上的空间,可是str并没有指向堆上的空间,程序会出错。
35. 请问以下代码有什么问题:
int main()
{
    char a;
    char *str=&a;
    strcpy(str,"hello");
    printf(str);
    return 0;
}
答:字符指针str指向的是一个单一的字符,调用strcpy()方法赋值的时候,只能赋一个字符,很明显程序赋的是“hello”6个字符,程序会发生错误。
36. 请出下面代码中的所有错误
说明:以下代码是把一个字符串倒序,如“abcd”倒序后变为“dcba”
1、#include"string.h"
2、main()
3、{
4、 char*src="hello,world";
5、 char* dest=NULL;
6、 int len=strlen(src);
7、 dest=(char*)malloc(len);
8、 char* d=dest;
9、 char* s=src[len];
10、 while(len--!=0)
11、 d++=s--;
12、 printf("%s",dest);
13、 return 0;
14、}
答:看上面27题
37. 有以下程序return在c语言中是什么意思
#inlcude <stdio.h>
int main() 
{
char a[7]="a0\0a0\0";
int i,j; 
i = sizeof(a);
j = strlen(a);
printf("%d %d\n",i,j);
return 0;
}此程序的输出结果是什么?
答:7 2  sizeof是求变量或者类型所占的字节数,char a[7]数组声明了7个元素的空间,7个字节, strlen()函数用来求字符串的长度,原理是字符串中的‘\0字符数组a中第三个位置到\0,返回2(不包括
\0
38. 问main函数既然不会被其它函数调用,为什么要返回1?
int main()
{
    int x=3;
    printf("%d",x);
    return 1;
}
答:main函数的返回值用于说明程序的退出状态。如果返回0表示程序正常退出;返回其它的数字的含义则由系统决定。通常,返回非0代表程序异常退出。main函数的返回值是返回给执行这个进程的进程。
39. 交换两个变量的值,不使用第三个变量。
即a=3,b=5,交换之后a=5,b=3;
答:
a = a + b;
b = a – b;
a = a – b;
40. 下面这个程序执行后会有什么错误或者效果:
#define MAX 255
int main()
{
    unsigned char A[MAX],i;//i被定义为unsigned char
    for (i=0;i<=MAX;i++)
    A[i]=i;
}
答:无限循环。此题i被定义为unsigned char类型,占一个字节,所以表示的数的个数为256个数,也就是0 ~ 255.当i = 255,此时再让i+1,则i会重新变为0.所以i永远小于等于MAX,一直循环下去。
41. 描述一下typedef的作用
答:为已知类型定义类型的别名
42. 动态内存分配(Dynamic memory allocation)
下面的代码片段的输出是什么,为什么?
char *ptr;
if ((ptr = (char *)malloc(0)) == NULL)    
    puts("Got a null pointer");
else
    puts("Got a valid pointer");
答:输出Got a valid pointer。malloc(0)不返回NULL
43. 用C语言如何实现死循环呢?
答:while(1)或者for(;1;)
44. 简述数组与指针的区别?
答:数组与指针有很大的不同。数组拥有元素的空间,指针没有,指针
能保存地址。还有,指针可以随便改变指向,但是数组不可以。
45. 已知strcmp的原型是
int strcmp(const char *str1, const char *str2)谈谈你对其参数中const的理解.
答:const用来修饰指针,常量指针,即指针的指向可以发生变化,但是无法通过*操作来修改指针所指向的变量。主要是防止在strcmp函数中,程序员有意或者无意的修改str2变量
46. 写出下列代码的输出内容
#include<stdio.h>
int inc(int a)
{
    return(++a);
}
int multi(int*a,int*b,int*c)
{
    return(*c=*a**b);
}
typedef int(FUNC1)(int in);
typedef int(FUNC2) (int*,int*,int*);
 
void show(FUNC2 fun,int arg1, int*arg2)
{
    FUNC1 *p=&inc;
    int temp =p(arg1);
    fun(&temp,&arg1, arg2);
    printf("%d\n",*arg2);
}
 
main()
{
    int a;
    show(multi,10,&a);
    return 0;
}
答:此题主要是typedef int(FUNC1)(int, int);的作用,还记得我们学过的函数指针吗?没错这就是定义一个函数指针(FUNC1是指针类型,指向返回值为int,带有两个int类型参数的函数知道了这一点,很容易计算出结果为110
47. 请写出下列代码的输出内容
#include<stdio.h>
int main()
{
    int a,b,c,d;
    a=10;
    b=a++;
    c=++a;
    d=10*a++;
    printf("b,c,d:%d,%d,%d",b,c,d);
    return 0;
}
答:10 12 120
48. 求函数返回值,输入x=9999;(如果可以,写出此程序实现的功能)
int func ( x )
{
    int countx = 0;
    while ( x )
    {
        countx ++;
        x = x&(x-1);
    }
    return countx;
}
答:这是统计9999的二进制数值中有多少个1的函数,且有
9999=9×1024+512+256+15
9×1024中含有1的个数为2;
512中含有1的个数为1;
256中含有1的个数为1;
15中含有1的个数为4;
故共有1的个数为8,结果为8。
1000 - 1 = 0111,正好是原数取反。这就是原理。
用这种方法来求1的个数是很效率很高的。
不必去一个一个地移位。循环次数最少。
49. 下面的函数实现在一个数上加一个数,有什么错误?请改正。
int add_n ( int n )
{
    static int i = 100;
    i += n;
    return i;
}
答:static变量存储在全局/静态区,只初始化一次,后面的数都是在i基础上增加的。
50. 用变量a给出下面的定义
a) 一个整型数(An integer)
b) 一个指向整型数的指针(A pointer to an integer)
c) 一个指向指针的的指针,它指向的指针是指向一个整型数(A pointer to a pointer to an integer)
d) 一个有10个整型数的数组(An array of 10 integers)
e) 一个有10个指针的数组,该指针是指向一个整型数的(An array of 10 pointers to integers)
f) 一个指向有10个整型数数组的指针(A pointer to an array of 10 integers)
g) 一个指向函数的指针,该函数有一个整型参数并返回一个整型数(A pointer to a function that takes an integer as an argument and returns an integer)
h) 一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型数( An array of ten pointers to functions that take an integer
argument and return an integer )
答:a) int a;
b)int *a;
c)int **a;
d)int a[10];
e)int *a[10];
f)int (*a)[10]
g)int (*a)(int b);
h)typedef int (*POINT)(int);
POINT a[10];
51. 求1000!的未尾有几个0(用素数相乘的方法来做,如72=2*2*2*3*3)
答:分析:先把1000! 质因数分解,其质因数中2的个数比5的个数多
因为2*5=10
所以1000!中有多少个因数5,1000!的末尾就有多少个0
因为5(1000!)=[1000/5] +[1000/25]+[1000/125]+[1000/625}
=200 + 40 + 8 + 1 =249 
所以1000!的末尾就有249个0
编程:
#include<stdio.h>
int main()
{
    int sum = 0;
    int num;
    printf("请输入数据:");
    scanf("%d", &num);
    for(int i = 5; i <= num; i= i * 5)
    {
        sum = sum + num / i;
    }
    printf("共有%d个零\n", sum);
    return 0;
}
52. 输出和为一个给定整数的所有组合
例如n=5
5=1+4;5=2+3(相加的数不能重复)(不考虑负数)
则输出
1,4;2,3。
答:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
    unsigned long int num = 0;
    scanf("%d", &num);
    int mid = 0;
    for(int i = 1; i <= num/2; i++)
    {
        mid = num - i;
        if(mid != i)
            printf("%d = %d + %d\n", num, i, mid);
    }
    return 0;
}
53. 有以下表达式:
int a=248; 
int b=4;
int const c=21;
const int *d=&a;
int *const e=&b;
int const *f  =&a;
请问下列表达式哪些会被编译器禁止?为什么?
*c=32;
d=&b;
*d=43;
e=34;
e=&a;
f=0x321f;
答:*c = 32不可以,c不是指针类型
*d = 43不可以,d是常量指针,无法修改指向的变量的值
e = 34不可以,类型不匹配
e = &a不可以,e是指针常量,无法改变指针
f = 0x321f不可以,类型不匹配
54. 编程实现:出两个字符串中最大公共子字符串,如"abccade","dgcadde"的最大子串为"cad"
答:#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 100
int main()
{
    int a[N][N];            //矩阵
    char str1[N];
    char str2[N];
    int maxSubStrLength = 0;    //最大子串的长度
    int subStringIndex = 0;        //最大子串的末尾index
    int i;
    int j;
    printf("请输入第一个字符串:");
    scanf("%s",str1);
    printf("请输入第二个字符串:");
    scanf("%s",str2);
    int strLen1 = strlen(str1);
    int strLen2 = strlen(str2);
    //构造矩形
    for(i = 0; i < strLen1; i++)
    {
        for(j = 0; j < strLen2; j++)
        {
            if(str1[i] != str2[j])
                a[i][j] = 0;
            else
            {
                if(i == 0 || j == 0)
                {
                    a[i][j] = 1;
                }
                else
                {
                    a[i][j] = a[i-1][j-1] + 1;
                }
            }
            if(a[i][j] > maxSubStrLength)
            {
                maxSubStrLength = a[i][j];
                subStringIndex = i;
            }
        }
       
    }
    //显示矩阵
    for(i = 0; i < strLen1; i++)
    {
        for(j = 0; j < strLen2; j++)
            printf("%d ", a[i][j]);
        printf("\n");
    }
    for(i = 0; i <maxSubStrLength; i++)
        printf("%c", str1[subStringIndex - maxSubStrLength + i + 1]);
    printf("\n");
    return 0;
}
55. 实现子串定位 int FindSubStr(const char *MainStr, const char *SubStr)
答:#include <stdio.h>
#include <string.h>
#define N 100
int FindSubStr(const char *MainStr, const char *SubStr);
int main()
{
    char str1[N];
    char str2[N];
    printf("输入主字符串:");
    scanf("%s", str1);
    printf("输入子字符串:");
    scanf("%s", str2);
    int index = FindSubStr(str1, str2);
    if(index == -1)
        printf("未到!\n");
    else
        printf("到,下标为:%d\n", index);
    return 0;
}
int FindSubStr(const char *MainStr, const char *SubStr)
{
    int index = 0;
    int count = 0;
    int strlen1 = strlen(MainStr);
    int strlen2 = strlen(SubStr);
    if(strlen1 < strlen2)
        return -1;
    for(int i = 0; i <= strlen1 - strlen2; i++)
    {
        for(int j = 0; j < strlen2; j++)
        {
            index = i+j;
            if(MainStr[i+j] == SubStr[j])
            {
                count++;
            }else{ count = 0;break; }
        }
        if(count == strlen2)
            return index - strlen2 + 1;
    }
56. 写一段程序,出数组中第k大小的数,输出数所在的位置。例如{2,4,3,4,7}中,第一大的数是7,位置在4。第二大、第三大的数都是4,位置在1、3随便输出哪一个均可。函数接口为:int find_orderk(const int* narry,const int n,const int k)
答:#include <stdio.h>
#include <string.h>
#include <malloc.h>
#define N 5
int find_orderk(const int* narry,const int n,const int k);
int main()
{
    int array[N];
    int k;
    printf("请输入%d个数:", N);
    for(int i = 0;i < N; i++)
        scanf("%d",&array[i]);
    printf("输入第K大小的数:");
    scanf("%d", &k);
    int n = find_orderk(array, N, k);
    printf("%d大小的数在%d位置\n", k, n);
    return 0;
}
//函数参数的意思,第一个数组名字,第二个多少个元素,第三个第k大小的数
int find_orderk(const int* narry, const int n, const int k)
{
    if(k <=0 && k > n)
        return -1;
    int *ptr = (int *)malloc(sizeof(int) * n);
    for(int i = 0; i < n; i++)
        ptr[i] = narry[i];
    for(int i = 0; i < n - 1; i++)
        for(int j = 0; j < n - i - 1;j++) 
        {
            if(ptr[j] > ptr[j+1])
            {
                int temp = ptr[j];
                ptr[j] = ptr[j+1];
                ptr[j+1] = temp;
            }
        }
    for(int i = 0; i < n; i++)
    {
        if(ptr[k-1] == narry[i] )
        {
            free(ptr);
            return i+1;
        }
    }
}
57. 已知一个单向链表的头,请写出删除其某一个结点的算法,要求,先到此结点,然后删除。
答:#include <stdio.h>
struct link
{
    char data;
    struct  link *next;
};
int main()
{
    return 0;
}
//删除某一个节点,利用值匹配来删除
void removeNode(struct link *head, char data)
{
    struct link *p = head;
    struct link *q = head;
    if(head == NULL)
        return;
    if(head->data == data)
    {
        head = head->next;
        free(q);
        q = NULL;
        return;
    }
    q = p->next;
    while(q)
    {
        if(q->data == data)
        {
            p->next = q->next;
            free(q);
            q = NULL;
            return;
        }
        p = q;
        q = q ->next;
    }
    printf("未到要删除的节点!\n");
}
58. 单链表的建立,把'a'--'z'26个字母插入到链表中,并且倒序,还要打印!
答:#include <stdio.h>
#include <stdlib.h>
struct link
{
    char data;
    struct link *next;
};
struct link *createLink();       
void displayLink(struct link *head);
void freeLink(struct link *head);
struct link *reverseLink(struct link *head);
int main()
{
    struct link *head = createLink();
    displayLink(head);
    struct link *reLink = reverseLink(head);
    displayLink(reLink);
    freeLink(reLink);
    return 0;
}
struct link *createLink()
{
    struct link *head = (struct link *)malloc(sizeof(struct link));
    head->data = 'a';
    head->next = NULL;
    struct link *p = head;
    struct link *q = head;
    for(char i = 'a'+1; i <= 'z'; i++)
    {
        q = (struct link *)malloc(sizeof(struct link));
        q->data = i;
        q->next = NULL;
        p->next = q;
        p = q;
    }
    return head;
}
void displayLink(struct link *head)
{
    while(head != NULL)
    {
        printf("%c ", head->data);
        head = head->next;
    }
    printf("\n");
}
void freeLink(struct link *head)
{
    struct link *p = head;
    while(p != NULL)
    {
        p = head->next;
        free(head);
        head = p;
    }
}
struct link *reverseLink(struct link *head)
{
    if(head == NULL && head->next == NULL)
        return head;
    struct link *p = head;
    struct link *q = head->next;
    struct link *m = NULL;
    while(q != NULL)
    {
        m = q->next;
        q->next = p;
        p = q;
        q = m;
    }
    head->next = NULL;
    return p;
}
59. 一个单向链表,不知道头节点,一个指针指向其中的一个节点,问如何删除这个指针指向的节点?
答:不知道头节点,又是单链表,肯定无法访问到此指针指向的前一个节点。怎么办呢?只能采用一种方法:此指针指向的节点的值改成此指针指向的下一个节点的值,然后将下一个节点删掉。
60. 简单介绍一下二叉树。
答:百度一下
//树结构
struct BTree
{
    struct BTree *lChild;
    struct BTree *rChild;
    char data;
};
//对树操作函数
void operateTree(BTree *tree);
void preOrder(BTree *tree);//前序遍历
void midOrder(BTree *tree);//中序遍历
void postOrder(BTree *tree);//后序遍历
int main(int argc, const char * argv[])
{
   
    return 0;
}
void operateTree(BTree *tree)
{
    printf("%c ", tree->data);
}
void preOrder(BTree *tree)
{
    if(tree == NULL)
        return;
    operateTree(tree);
    if(tree->lChild != NULL)
        preOrder(tree);
    if(tree->rChild != NULL)
        preOrder(tree->rChild);
}
void midOrder(BTree *tree)
{
    if(tree == NULL)
        return;
    if(tree->lChild != NULL)
        midOrder(tree->lChild);
    operateTree(tree);
    if(tree->rChild != NULL)
        midOrder(tree->rChild);
}
void postOrder(BTree *tree)
{
    if(tree == NULL)
        return;
    if(tree->lChild != NULL)
        postOrder(tree->lChild);
    if(tree->rChild != NULL)
        postOrder(tree->rChild);
    operateTree(tree);
}
61. 用代码实现二叉树的后序遍历。
答:
void postOrder(BTree *tree)
{
    if(tree == NULL)
        return;
    if(tree->lChild != NULL)
        postOrder(tree->lChild);
    if(tree->rChild != NULL)
        postOrder(tree->rChild);
    operateTree(tree);
}
62. 用代码实现二叉树的中序遍历。
void midOrder(BTree *tree)
{
    if(tree == NULL)
        return;
    if(tree->lChild != NULL)
        midOrder(tree->lChild);
    operateTree(tree);
    if(tree->rChild != NULL)
        midOrder(tree->rChild);
}
63. 用程序实现二叉树的前序遍历。
void preOrder(BTree *tree)
{
    if(tree == NULL)
        return;
    operateTree(tree);
    if(tree->lChild != NULL)
        preOrder(tree);
    if(tree->rChild != NULL)
        preOrder(tree->rChild);
}

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。