【C语言】C语言的基础知识以及基础试题(对基本知识点的掌握)

【C语言】C语言的基础知识以及基础试题(对基本知识点的掌握),第1张

  1. 以下为Linux下的32 位C 程序,请计算sizeof 的
    值。
char  str[] = “Hello” ;                               
char   *p = str ;                                      
int    n = 10;  

请计算
(1)sizeof (str ) = (2)s i zeof ( p ) =
(3)sizeof ( n ) =
(4)void Func ( char str[100])
(5)void * p = malloc( 100 );
请计算sizeof( str ) =
【标准答案】(1)6、(2)4 、(3 )4、(4)4、(5)4
2. 用变量a 给出下面的定义
e) 一个有10个指针的数组,该指针是指向一个整型数
的;
f) 一个指向有10个整型数数组的指针;
g) 一个指向函数的指针,该函数有一个整型参数并返
回一个整型数;
h) 一个有10个指针的数组,该指针指向一个函数,该
函数有一个整型参数并返回一个整型数;
【标准答案】e)int * a[10]、 f)int (*a)[10]、 g)int (*a)(int)、 h) int (*a[10])(int)
3. 设有以下说明和定义:

typedef u nion {long i; int k[5]; char c;} DATE;    // 20
struct data { int cat; DATE cow; double dog;} too;  // 32
DATE max;

则语句printf(“%d”,sizeof(struct date)+sizeof(max)); 的
执行结果是:_____
【标准答案】DATE是一个union, 变量公用空间. 里面最大的变量类型是int[5], 占用20个字节. 所以它的大小是20.
data 是一个struct, 每个变量分开占用空间. 依次为int4 + DATE20 + double8 =32. 所以结果是32+ 20 = 52.
4. 请问以下代码有什么问题:

int main()
{
    char a;
    char *str=&a;  //错误,没有为str分配内存空间
    strcpy(str,"hello");  //错误,越界
    printf(str);
    return 0;
}

【标准答案】没有为str分配内存空间,将会发生异常
问题出在将一个字符串复制进一个字符变量指针所指地址。虽然可以正确输出结果,但因为越界进行内在读写而导致程序崩溃。
5.

char* s="AAA";  //错误
printf("%s",s);
s[0]='B';  //错误
printf("%s",s);

有什么错?
【标准答案】“AAA” 是字符串常量。s是指针,指向这个字符串常量,所以声明s的时候就有问题。cosnt char* s=“AAA”;
然后又因为是常量,所以对是s[0] 的赋值 *** 作是不合法的。
6. int (*s[10])(int) 表示的是什么啊
【标准答案】int (*s[10])(int) 函数指针数组,该函数有一个整型参数并返
回一个整型数;
7.

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( str )后, str并未产生变化,依然是NULL.只是改变的str的一个拷贝的内存的变化,getmemory中的malloc 不能返回
动态内存,free ()对str *** 作很危险。
8.

void main()
{
    char aa[10];
    printf(%d”,strlen(aa));
}           

会出现什么问题?打印结果是是多少?
【标准答案】sizeof()和初不初始化,没有关系,strlen()和初始化有关,打印结果值未知。
9. 32位编译器
• char :1个字节 char*(即指针变量): 4个字节
• short int : 2个字节 int: 4个字节 unsigned int : 4个字节
• float: 4个字节 double: 8个字节
• long: 4个字节 unsigned long: 4个字节 long long: 8个字节
10. 给定结构

struct A
{
     char t:4;    1字节占4bite
     char k:4;    1字节占4bite
     unsigned short i:8;     2字节占8bite
     unsigned long m;      4字节
};

问sizeof(A) = ?
【标准答案】8
11. 程序哪里有错误

swap( int* p1,int* p2 )
{
    int * p;
    *p = *p1;
    *p1 = *p2;
    *p2 = *p;
}

【标准答案】p 为野指针(指向一个已删除的对象或未申请访问受限内存区域的指针)
12. (void )ptr 和((void**))ptr 的结果是否相同?其中ptr为同一个指针。
【标准答案】(void )ptr 和((void**))ptr 值是相同的
(void )ptr 强制转化为void的一级指针。
(
(void**))ptr: void是一个指向空类型指针的指针(-》一级指针-》地址),
然后*(一个指向空类型指针的指针)=指向空类型的一级指针(取地址)。
(void )ptr 将变量ptr的值强制转换为 void(无类型)的指针
(
(void))ptr 将变量ptr的值强制转换为 (void*),即把一个指向(void类型指针)的指针,求他的值,结果相当于括号里面的(void类型指针)
这两个的效果是完全一样的,用前面那种就可以了
13. 用宏定义写出swap(x,y),即交换两数。
【标准答案】

#define swap(x, y) (x)=(x)+(y);(y)=(x)(y);(x)=(x)(y);
  1. 写一个“标准”宏,这个宏输入两个参数并返回较小的一个。
    【标准答案】
#define Min(X, Y) ((X)>(Y)?(Y):(X))    // 结尾 没有 ;
  1. 已知一个数组tabl e ,用一个宏定义,求出数据的元素个数。
    【标准答案】
#define NTBL(table) (sizeof(table)/sizeof(table[0]))
  1. A.c 和B.c两个c文件中使用了两个相同名字的static变量,编译的时候会不会有问题?这两个static变量会保存到哪里(栈还是堆或者其他的)?
    【标准答案】static的全局变量,表明这个变量仅在本模块中有意义,不会影响其他模块。
    他们都放在静态数据区,但是编译器对他们的命名是不同的。
    如果要使变量在其他模块也有意义的话,需要使用extern 关键字。
  2. 用两个栈实现一个队列的功能?要求给出算法和思路!
    【参考答案】设2个栈为A,B, 一开始均为空.
    入队:
    将新元素push入栈A;
    出队:
    (1)判断栈B 是否为空;
    (2)如果不为空,则将栈A中所有元素依次pop 出并
    push到栈B;
    (3)将栈B 的栈顶元素pop 出;
  3. 在C++ 程序中调用被C 编译器编译后的函数,为什么要加extern “C”?
    【标准答案】C++ 语言支持函数重载,C 语言不支持函数重载。
    函数被C++ 编译后在库中的名字与 C 语言的不同。假设某个函数的原型为:void foo(int x, int y); 该函数被C 编译器编译后在库中的名字为_foo ,而
    C++ 编译器则会产生像_foo_int_int之类的名字。 C++提供了C 连接交换指定符号extern“C”来解决名字匹配问题。
#include 
int main()
{
    int a,b,c,d;
    a=10;
    b=a++;  //b=a=10,完了之后,a++等于11
    c=++a;  //a=11,先加1, c=12
    d=10*a++; //先10*a(12)=120,d=120,执行完,a再++
    printf("b,c ,d:%d,%d,%d",b,c,d );
    return 0;
}

【标准答案】10,12,120
20.

unsigned char *p1;
unsigned long *p2;
p1=(unsigned char *)0x801000;
p2=(unsigned long *)0x810000;

请问p1+5= ; //p1是char,加5就是15=5个字节
p2+5= ; //p2是long,加5就是4
5=20个字节
【标准答案】0x801005、0x810014
p1指向字符型,1个字节;p1+5后移5个字节,16进制表示为5;
p2指向长整型,4个字节,p2+5后移20字节,16进制表示为14。
{ char每次移动1个字节;short移动2个字节 ;int , long ,float移动4个字节 ;double移动8个字节}
21. int a[10],a代表什么,sizeof(a)=?
【标准答案】40
int a[10]:声明了一个有10个int类型元素的数组, 数组下标从0~9, 所以a是数组名, 代表数组的首地址, 也就是&a[0], sizeof(a)返回数组a在内存中所占的空间大小,以字节为单位, 也就是sizeof(a) = sizeof(int) * 10 = 4 * 10 = 40bytes
22. 一维数组

int main()
{
    int a[5]={1,2,3,4,5};
    printf(%d”, a);     //a是数组首地址  004EFD18
	printf(%d”, &a);   //&a是数组首元素的地址  004EFD18
	printf(%d”, a+1);     //a+1:就是数组首地址加上一个元素所占的地址大小,这里int是4个字节,所以加上1x4.  004EFD1C
	printf(%d”, &a+1);   //&a+1:代表的是加上整个数组的大小,数组大小是3,所以+1代表的是地址加上3x4    004EFD24
	printf(%d”, *a+1);  //*a+1代表的是数组第二个元素的值  2
	printf(%d”, *(a+1));  //*(a+1)代表的是数组第二个元素的值  2
	printf(%d”, *(&a+1));  //*(&a+1):代表&a+1地址的值,未知
	int * ptr=(int*)(&a+1);
	printf(%d”, *(ptr-1));  // *(ptr-1) == *(*(&a + 1)-1) : 表示&a+1地址的前一个元素的地址   5
  1. 二维数组 a[i][j]
    [1] *a:以a[0][0]为首元素的一维数组.可带一个索引:(a)[i] 即a[0][i]
    [2] a:以a[0][0]为首元素的二维数组.可带两个索引:a[i][j]
    [3] a[0]:同
    a
    [4] a[0][0]:首元素
    [5] a[1]:以a[1][0]为首元素的一维数组. 代表第二行的首地址
    [6] &a[1]:以a[1][0]为首元素的二维数组.可带两个索引:(&a[1])[i][j]即a[i+1][j]
    [7] *(*a+1)—等价于a[0][1] a[0][i]
    [8] ((a+1))—等价于a[1][0] a[i][0]
    [9] *(&a[0][0]+1)–等价于a[0][1]
    [10] *(a[1]+1) --等价于a[1][1]
    [11] *(a+1)是数组元素。但a是二维数组,那你就要再进一步理解了。
    因为a是二维数组名,即是一维数组a[0] 、a[1] 、a[2] 的首地址。
    a+1就是 a[1]的地址。
    是取指针的值。
    那么
    (a+1)就是取 a[1]的值。
    它是什么呢?它又是一个数组: a[1][0], a[1][1] ,a[1][2]。
    而且 a[1]是它们的首地址。
    即 a[1]的值就是 a[1][0]的地址。

  2. 若有说明:int a[3][4];则对a数组元素的非法引用是( D )
    A:a[0][2*1]
    B:a[1][3]
    C:a[4-2][0]
    D:a[0][4]
    对于 a[3][4]说明有12元素,行从0到2,列从0到3。a[0][4]的列超界。

  3. 若二维数组a有m列,则计算任一元素a[i][j]在数组中是第( A )个数
    A:i * m + j B:j * m + i
    C:i * m + j – 1 D:i * m + j + 1

    a[2][3]将获取数组中第 3 行第 4 个元素。第12个数,2*4+3+1=12

	int modifyvalue()
{ 
    return(x+=10);
}
int c hangevalue(int x )
{
    return(x+=1);
}
void m ain()
{
    int x =10;    // 10
    x++;        // 11
    changevalue(x); //传递形参不改变实参,x还是11
    x++;        // 12
    modifyvalue();
    printf("First output:%dn",x);   // 12
    x++;         // 13
    changevalue(x);
    printf("Second output:%dn",x);   // 13
    modifyvalue();
    printf("Thirdoutput:%dn",x);     // 13
}

输出?
【标准答案】12、13、13
27. 下面的代码输出是什么,为什么?

void foo(void)
{
    unsigned int a = 6;
    int b = -20;
    (a+b> 6)? puts("> 6") : puts("<= 6");
}

【参考答案】这个问题测试你是否懂得C 语言中的整数自动转换原则,
我发现有些开发者懂得极少这些东西。不管如何,这无符号整型问题的答
案是输出是“>6” 。
原因是当表达式中存在有符号类型和无符号类型时所有的数都自动转换为无符号类型。因此-20 变成了一个非常大的正整数,所以该表达式计算出的结果大于6 。这一点对于应当频繁用到无符号数据类型的嵌入式系统来说是丰常重要的。
28. 评价下面的代码片断:
unsigned int zero = 0;
unsigned int compzero = 0xFFFF; //错误
【参考答案】对于一个int型不是16位的处理器为说,上面的代码是不正
确的。应编写如下:unsigned int compzero = ~0;
~是位运算符,是取反的意思,即二进制位0变1,1变0;
unsigned int compzero = 0xFFFF;表示1111 1111 1111 1111,对于int型不是16位的处理器来说,上面的代码是不正确的。
unsigned int compzero=~0;(以16位处理器来说明)表示将0的二进制位0000000000000000取反,变成1111111111111111,对不是16位处理器的也是正确的。
29. 下面的代码片段的输出是什么,为什么?

char *ptr;
if ((ptr = (char *)malloc(0)) == NULL)
    puts("Got a null pointer");
else
    puts("Got a valid pointer");

【参考答案】
malloc申请一段长度为0的空间,malloc依然会返回一段地址,还有一段地址空间,所以ptr不等于NULL。
malloc这个函数,会有一个阈值,申请小于这个阈值的空间,那么会返回这个阈值大小的空间。
如阈值为24,那么申请小于24的值就会返回24
这个阈值会随着编译器的不同而不同
如,在编译后,运行结果会返回12
如果申请一个负数,那么返回的是0 ,因为malloc规定不可以申请一个负数
30. 请编写一个C 函数,该函数将给定的一个字符串转换成整数。atoi
【参考答案】

int Invert(char* str) 
{ 
    int num =0; 
    while(*str!=')'//将字符串每个位置的字符进行对应的ASCII码转换 
    { 
int
        = digital*-str48;//字符 '0'-'9' 对应的十进制整数是48~57,   48
将对应的整数减去=就得到了对应的整数
        num*num10+;digital= 
        str+str1;} 
    return 
    ; num} 
void 
  1. 请编写一个C 函数,该函数将给定的一个整数转换成字符串。itoa
    【参考答案】
IntToCharChange (int, numchar  *) pvalchar 
{ 
    [ strval100];int 
    , i ; jint 
    = val0 0 ;int 
    = val1 0 ;= 
    val0 ; numfor 
    (=i0;< i100;++ i)= 
    { 
        val1 % val0 10 ;//取余 =
        val0 / val0 10 ;// 取整 [
        strval]i= + val1 48 ;// 数字—字符  if
        (<val0 10 )++ 
        { 
            i;[ 
            strval]i= + val0 48 ;break 
            ;} 
        } 
    for 
    (=j0;<= j;i++ j)// 倒置  [
    	pval]j= [ strval-i]j;[ 
    pval]j= ';' }
  • 以下程序的功能是将字符串s中所有的字符c删除,那么空白处缺少的语句为:( A )。
  • #
      include
    intmain 
    ( void)char[
    {
        80 s];int ,
        ; igets j (
        );sfor (
        = = i 0 j ; [ ] s !=i/ 0;++' ) iif (
        [ ] s !=i) ; ‘c' [
              ]
        s = j / 0;puts' (
        ) ; s return 0
        ; } #
    include
    

    A: s [ j++] = s [ i ] B:s [ ++j ] = s [ i ]
    C:s [ j ] = s [ i ]; j++ D:s [ j ] = s [ i ]
    33.

    .int stdiomainh
    ( void)int=
    {
        2 a , ;for i(
        =0 i ; <3 i ; ++) iprintf ( 
            "%4d",f())a;//%4d  输出宽度为4,且右对齐//%-4d  输出宽度为4,且左对齐  }
    int
    f
    ( int)int a=
    {
        0 b ; staticint
        = 3 c ; ++;
        b++; creturn(
        ++a)b;c}void
    sub
    

    A:7 7 7 B:7 10 13
    C:7 9 11 D:7 8 9
    【参考答案】 D
    每次调用函数f的参数都是a=2,三次参与a+b+c运算时都是a=2
    b是局部变量, 每次初始化为0,之后自加为1。三次参与a+b+c运算时都是b=1
    c是静态变量, 每次是上次退出值。 每次调用c自加。 所以三次参与a+b+c运算时, c依次为4 5 6
    于是返回值依次为7 8 9
    34. 以下程序的运行结果为( B )。

    ( int,int x, int y* ) *z=
    { -z ; y } x int main
    ( void)int,
    {
    , a;bsubc (
    10,5, &) ;a//传地址 sub  (
    7,,& a) ;bsub (
    ,,a& b) ;cprintf (
    "%4d,%4d, %4d/n", ,,a)b;c}
    
    

    A:5, 2, 3 B:-5, -12, -7
    C:-5, -12, -17 D:5, -2, -7
    35. 有如下语句int a = 10, b = 20, *p1, *p2; p1 = &a; p2 = &b;变量与指针的关系如图1所示;若要实现图2所示的存储结构,可选用的赋值语句为( B )

    A:*p1 = *p2 B:p1 = p2
    C:p1 = *p2 D:*p1 = p2
    *p1 = *p2; // 等效于 a = b;
    p1 = *p2; // 类型失配,编译出错或警告
    *p1 = p2; // 将b的地址转化为整数赋给a
    p1=p2,p1=&b都可以啊

    欢迎分享,转载请注明来源:内存溢出

    原文地址:https://54852.com/langs/873247.html

    (0)
    打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
    上一篇 2022-05-13
    下一篇2022-05-13

    发表评论

    登录后才能评论

    评论列表(0条)

      保存