c错误笔记_选填版(未完待续...)

1.while(true) while(false)

/*===============================================
*   文件名称:1_while.c
*   创 建 者:     
*   创建日期:2022年04月11日
*   描    述:
================================================*/
#include <stdio.h>

int main(int argc, char *argv[])
{
    int t=0;
    while(printf("*"))
    {
        t++;
        if(t<3)
            break;
    }
    printf("%d\n",t);

    return 0;
} 
root@ubuntu:/C# ./a.out
*1

//打印 * 号,成功执行循环体内语句,失败不执行

/*===============================================
*   文件名称:1_while.c
*   创 建 者:     
*   创建日期:2022年04月11日
*   描    述:
================================================*/
#include <stdio.h>

int main(int argc, char *argv[])
{
    int t = 'E';
    int m = 'A';
    while(!t) // while(!E)
    {
        t++;
    }
    printf("%d\n",t);
    printf("%d\n",m);

    return 0;
}
root@ubuntu:/C# ./a.out
69
65

//字符为小整数 while(!E); 等价于 while(!1);

/*===============================================
*   文件名称:1_while.c
*   创 建 者:     
*   创建日期:2022年04月11日
*   描    述:
================================================*/
#include <stdio.h>

int main(int argc, char *argv[])
{
    int a=1,b=2,c=2;
    while(a<b<c)    //多次循环
    {
     int t=a;
         a=b;
         b=t;
         c--;
    }

    printf("%d,%d,%d\n",a,b,c);

    return 0;
} 

root@ubuntu:/C# ./a.out
1,2,0

// a<b<c  先比较a<b,true,为1,然后比较 1<c,true,a、b交换,然后继续比较第二轮

2.若已有定义:float  x;,则下列对指针变量p进行定义且赋初值的语句中,正确的是( D )。

A) float *p=1024;

B) int *p=(float)x;

C) float p=&x;

D) float *p=&x;

3.以下叙述中正确的是(C

 A)如果p是指针变量,则&p;是不合法的表达式

 B)如果p是指针变量,则*p表示变量p的地址值

 C)在对指针进行加、减算术运算时,需要考虑指针所指的类型才能确定具体偏移量

 D)如果p是指针变量,则*p+1和*(p+1)的效果是一样的

 注意:这是对单个指针操作,两个指针相减是没有意义的

4.设有定义:char p[]={’1’,’2’,’3’},*q=p; ,以下不能计算出一个char型数据所占字节数的表

达式是(  A )

A)sizeof(p)               B)sizeof(char)     C) sizeof(*q)        D)sizeof(p[0])

sizeof(a)/sizeof(a[0])    sizeof(a[0])/sizeof(int)     sizeof(a)/sizeof(int)二维

 注意:这是计算char型数据所占字节数,不是求char型数据所占元素个数

* 和 [] 都是一维的,某些时候可以相互替换 ,这里sizeof(*q)等价sizeof(p[0])等价sizeof(char)

5.若有定义语句:int a[2][3],*p[3];  ,则以下语句中正确的是(C )

A)p=a;     B)p[0]=a;       C) p[0]=&a[1][2];       D)p[1]=&a;

维度:p,a二维        二维数组、指针数组(数组存放指针)

 p:数组名,常量

6.以下叙述中正确的是( D

A)预处理命令行必须位于源文件的开头 

B)在源文件的一行上可以有多条预处理命令 

C)宏名必须用大写字母表示  (推荐)

D)宏替换不占用程序的运行时间  宏替换是在预处理的时候占用的是编译的时间,不占用运行时间。   

①预处理指令是指在程序正式编译前就由编译器进行的操作,可放在程序中任何位置。 预处理是C语言的一个重要功能,它由预处理程序负责完成。 当对一个源文件进行编译时,系统将自动引用预处理程序对源程序中的预处理部分作处理,处理完毕自动进入对源程序的编译

②预处理:展开头文件、宏替换、去掉注释、条件编译

③编译:检查语法,生成汇编  -S

④汇编:汇编代码转换成机器码  -C

⑤链接:链接在一起生成可执行文件a.out(动态、静态链接库)

编译阶段的四步:预处理、编译、汇编、链接

7.C语言规定,程序中各函数之间 【 A  】

 A) 既允许直接递归调用也允许间接递归调用   

B) 不允许直接递归调用也不允许间接递归调用

C) 允许直接递归调用不允许间接递归调用

 D) 不允许直接递归调用允许间接递归调用 

8.sizeof(float)是【 C  】

        A) 一种函数调用                B) 一个不合法的表示形式

        C) 一个整型表达式              D) 一个浮点表达式

9. 对于基类型相同的两个指针变量之间,不能进行的运算是 【C 】

        A) <        B) =        C) +        D) -

10.已有定义int k=2;int *ptr1,*ptr2;且ptr1和ptr2均已指向变量k,下面不能正确执行的赋值语句是【 B  】 。

        A)k=*ptr1+*ptr2     B)ptr2=k       C)ptr1=ptr2     D)k=*ptr1*(*ptr2)

11.        注意字符串常量区

void fun(char* str1, char* str2)
{
static char buffer[21];
strncpy(buffer, str1, 10);
strncat(buffer, str2, 10);
*str1 = *str2;
str1 = buffer;

}
main()
{
char *str1="ABC\n";
char *str2="BCD\n";
fun(str1, str2);
printf(str1);
printf(str2);
}
程序运行结果是   Segmentation fault (core dumped)

12.        强转过后求字节

main()
{
short *p, *q;
short ar[10]={0};
p = q = ar;
p++;
printf("%5d", p-q);   
printf("%5d", (char*)p - (char*)q);   
printf("%5d", sizeof(ar)/sizeof(*ar));  20/2
}
假设sizeof(short)==2
程序运行结果是   1 2 10 

13.         注意逗号表达式        函数指针变量

int sub(int a, int b)
{
return a-b;
}

main()
{
typedef int (*SUB)(int, int);
SUB psub=sub;
/* psub++; */
printf("%d", psub(10,(10,5)));
}

运行结果  5

如果将中间注释掉的语句加上, 编译为什么会报错?
因为 typedef int (*SUB)(int,int)是将SUB这个指针指向这个函数,push是用来指向函数的入口地址,而函数是独立不连续的,因此不能用psub++来指向下一个函数的入口地址,也找不到下一个函数的入口地址。

push++    移动八个字节

14.    注意指针指向

main()
{
char* pstrar[3];
int i;
for(i=1; i<3; i++)
{
pstrar[i]=" "; //指向同一片空间
}
strcpy(pstrar[1], "你好");
/* strcpy(pstrar[0], "世界"); */
printf(pstrar[2]);
}
假设编译器设置字符串常量为可读写,则程序结果是__你好__

正常情况下Segmentation fault (core dumped)
为什么说注释掉的程序语句是不正确的?
因为pstrar[0]这个指针没有指向,是一个野指针,等价于  *p = 15;

15.          注意变量范围

main()
{
char *p1,*p2;
{
char* pchar;
char charar[] = "你好,世界";
pchar = "Hello,World!";
}

p1 = pchar;
p2 = charar;

printf(p1);
printf(p2);
}
说出此程序的错误之处?

最里面那个括号是局部变量,生命周期仅在那括号内,不能在拿在外面使用,static除外

16.        putchar() : 放入一个字符   指针数组:存放首地址

main()
{
int i;
char **p;
int msg[16]={0x40, 0x41, -1, 0x00, 0x01, -1, 0x12, -1, 0x20, 0x27, 0x41, 0x35, -1, 0x51, 0x12, 0x04};
char* strar[]={"bejing", "shanghai", "guangzhou", "guangdong", "Tokyo", "American"};
char* (*pstrar)[6];        //指针数组指针,一个二级指针
//一个指针指向一个指向数组的指针
pstrar = &strar;
p = strar;

for(i=0; i<16; i++)
{
        if(msg[i] == -1){
                putchar(' ');
                continue;
        }else if(msg[i]&0xF0 == 0x40){
                putchar(p[msg[i]>>4][msg[i]&0x0F]);
                continue;
        }else if(msg[i]&0xF0 == 0x30){
                putchar(*(strar[msg[i]>>4]+(msg[i]&0x0F)));
                continue;
        }else{
                putchar(*(*(*pstrar+((msg[i]&0xF0)>>4)+(msg[i]&0x0F)));
        }
}
}
此题有故弄玄虚之处,但如理解指针,不难解出.
请问此题的运行结果是__To be a good man__________

17.通过代码使程序跳转到0x10000地址去执行

         typedef void (*P)(void);

        P p = (P)0x10000;

        p();

=====================================================================

在绝对地址0xbfda87a8上写入字符'a'的语句是______.

char *ptr;

ptr = (char *)0xbfda87a8;

*ptr = 'a';

亦或者

*(char *)0xbfda87a8 = 'a';

写上整数100则是:*(int *)0xbfda87a8 = 100;

18.        int  a[5] = {1,2,3,4,5}; 

             printf("%d\n", *(int *)((a+1)-1));

             printf("%d\n", *((int *)(&a+1)-1));   

运行结果是          1        5

19. 下面函数的功能是( A)。

int fun (char*x)

{

        char *y=x;

        while(*y++);

        return(y-x-1);

}

[A] 求字符串的长度

[B] 比较两个字符串的大小

[C] 将字符串x复制到字符串y

[D] 将字符串x连接到字符串y后面

20. 执行下面语句后的输出结果为( D)。        if无花括号的范围

int i = -1;

          if (i < =0)

              printf(“****\n”);

               i = 2;

        else

              printf(“%%%%\n”);

[A] ****    [B] %%     [C] %%%%     [D] 有语法错误。不能正确执行

21. 下述程序的输出结果是( C)。

int main(void)

{

        int Y=100;

        while(Y--);

        printf(“Y=%d”,Y);

}

  7 #include <stdio.h>
  8 
  9 int main(int argc, char *argv[])
 10 {
 11     int Y=100;
 12     while(Y--);
 13 
 14 //    while(Y){
 15 //        Y--;
 16 //    }这里Y=0,侧面可以说明while(Y--);在Y=0过后,
    还减了一次
 17     printf("Y=%d\n",Y);
 18     return 0;
 19 }

root@ubuntu:/mnt/U_share/caogao# gcc while_.c
root@ubuntu:/mnt/U_share/caogao# ./a.out
Y=-1

  7 #include <stdio.h>
  8 
  9 int main(int argc, char *argv[])
 10 {
 11     int Y=100;
 12 //    while(Y--);
 13 
 14     while(Y){
 15         Y--;
 16     }
 17 //这里Y=0,侧面可以说明while(Y--);在Y=0过后,还减>    了一次
 18     printf("Y=%d\n",Y);
 19     return 0;
 20 } 

root@ubuntu:/mnt/U_share/caogao# gcc while_.c
root@ubuntu:/mnt/U_share/caogao# ./a.out
Y=0

[A] Y=0     [B] Y=1     [C] Y=-1     [D] Y=随机数

 22.下述程序第二次的输出结果为( B )

int main(void)  
{  
        extern   int   a;        
        int   b=0;  
        static int   c;        
        a+=3;                     
        other();            
        b+=3;               

        other();  
 }      
 int   a=5;  

 other()  
 {  
        int   b=3;          
        static   int   c=2;  
        a+=5; b+=5; c+=5;        

        printf("%d,%d,%d\n",a,b,c);  
        c=b;  
  }

[A] 13,0,13     [B] 18,8,13     [C] 13,8,13     [D] 18,8,0

注意考虑销毁,亦或者变量存储区域

简述static 和 extern的区别

static全局变量:生命周期为本文件,存放在全局变量(BSS、data)区,初始化默认为0,不能被extern引入

static局部变量:生命周期为本文件,且初始化为静态变量,只是作用域为函数内部

extern:可以引用其他文件的变量,不过要事先声明

23. 下述程序输出结果为 ( D )

int main (int argc, char *argv[])

{

        int a[ ][2] = {(1,2),(3,4),(5,6)};        2 4 6 0

        int *p = a[0];

        printf("%d\n",p[0]);      2

        printf("%d\n", p[1]);      4

        printf("%d\n", sizeof(a));      4*4=16

        return 0;

}

[A]  1,2,12        [B]  1,2,24

[C]  1,3,24        [D] 2,4,16

逗号运算符

24. Shell是一个命令编译器,将用户命令编译成二进制程序,交给操作系统执行。( 错 )

Shell是一个命令行解释器,没有编译,直接运行

25.在默认情况下,所定义的Shell变量的作用域是局部有效。( 错 )

Shell变量的作用域可以分为三种:

有的变量可以在当前Shell会话中使用,这叫做全局变量(globalvariable);

有的变量只能在函数内部使用,这叫做局部变量(localvariable);需要用 function 改变

而有的变量还可以在其它 Shell 中使用,这叫做环境变量(environmentvariable)。

 linux shell变量作用域,Shell变量的作用域:Shell全局变量、环境变量和局部变量_Yuki酱酱的博客-CSDN博客

26. 网络ip地址,分为主机号+网络号两部分。( 错 )反过来才行

 27.若有以下定义和语句,        时刻注意指针的指向

则*p[0]引用的是a数组元素中的( a[0] ),

*(p[1]+1)引用的是a数组元素中的(  a[3]  ).        int *(p[1]+1)指p[1]偏移4个字节《=》p[1][1]

int *p[3], a[6], i;         

for( i = 0; i < 3; i++)

p[i] = &a[2*i];    ==>p[0]=a[0],p[1]=a[2],p[2]=a[4]

28.下述程序运行的结果为(  ).       0x100w或者0x200w        0x01000000        0x02000000

int main(int argc, char *argv[])       整型地址+1=》移2位(16进制)

{

int buff[] = {1, 2};    

int *p = buff;

printf("%x\n", *(int *)((int)p + 1)); 地址p先强转位int整数,后+1,再强转成指针,最后*求值

return 0;

}        //十六进制的地址=》整数值=》十六进制的地址        //0x112233  高位:11  低位:33

 本题考查的是大小端存储

大端存储:高位存低地址

小端存储:高位存高地址

小端(用16进制):(高位)00 00 00 02(低)   (高)00 00 00 01(低位)        p指向01,p+1:向前移动一个格子(两个十六进制位),即 02 00 00 00,也就是0x200w       

数组低位开始,也就是先存1,再存2,依次类推

大端(用16进制):(高位)20 00 00 00    10 00 00 00(低位)        p指向20,p+1:向后移动一个格子,即 00 00 00 10,这时候请注意,要从右向左看,也就是0x100w        

为什么移动一个格子呢?

因为 0000 0001 等价  0x01,也就是四个字节一个十六进制位

=====================================================================

int main()
//258: 0000 0000  0000 0000  0000 0001  0000 0010
{
    int x=258;                                                   
    char *p = (char *)&x;

    printf("%d ",*p);
    printf("%d ",*(++p));
}
//程序结果:2,1或者0,0    大小端

29.int (*s[10])(int)  表示的是什么   int型的函数指针数组  

30. 给定结构struct A
{
    char t:4;       位域运算符 32位机 占四个二进制位
    char k:4;
    unsigned short i:8;
    unsigned long m;        总共6个字节,字节对齐
}; 问sizeof(A) =      8    

31. void func(char buf[100]){ ...... },请问 sizeof(func) =   4或者8  错误 ,正确显示为1

函数名的所占字节数,是一个地址,但是函数体内无语句,也就没有开辟空间,导致结果

运行显示为1,因为只是函数名,结构体内为空,也就是没开辟空间,输出1表示占位符,实际上是0

struct a{}; sizeof(a) = 0;     结构体不一样,编译器会认为结构体里面没有东西,所以是直接显示为0

 32.下面程序段的运行结果是  C        //机器人思想,一步一步跟着走,切记非熟跳过

  7 #include <stdio.h>
  8 
  9 int main(int argc, char *argv[])
 10 {
 11     int n=2;
 12     while(n++<=2);
 13     printf("%d\n",n);
 14     return 0;
 15 }

A) 2        B)3        C)4        D)语法错误

33. 下面程序的功能是在输入一批正整数中求出最大者,输入0结束循环,请选择填空

  7 #include <stdio.h>
  8 
  9 int main(int argc, char *argv[])
 10 {
 11     int a,max=0;
 12     scanf("%d",&a);
 13     while(____){        //    a
 14         if(max<a)
 15             max=a;
 16         scanf("%d",&a);
 17     }
 18     printf("max:%d\n",max);
 19     return 0;
 20 }

A)  a==0        B)  a        C)  a==1        D)  !a

虽然while循环条件是true和false,但是在比较的时候,不是随便一个非零字符都代表着1,比如说:while(a == c),其结果为false,而while(a),其结果有代表着true.

34.对for(表达式1;;表达式3) 可理解为_____.                B,为空则表示所有皆可

A)  for(表达式1;0;表达式3)                B)  for(表达式1;1;表达式3)

C)  for(表达式1;null;表达式3)            C)     缺少一个表达式

35.以下不是无限循环的语句为____. C          溢出

A)int i=100;
  while(1){
    i = i%100+1;
    if(i>100)
        break;
  }
B)for(;;);
C)int k=0;
  do{
      ++k;
  }while(k>=0);
D)int s=36;
  while(s);
  --s;

36. 区别  for(int i=1;i++<4;)与for(int i=1;i<4;i++)       

注意:if(!((i-3)%7))...

break statement not within loop or switch:break只能在循环和switch语句中使用

37. 

char *a[3]={"hello","world","china"};

请问a的类型( char **(二级指针) ),以及&a的类型(  char * (*) [3](指针数组指针))

int a[10];

请问&a的类型( int (*)[10](数组指针))

a)一个整型数(An integer)

b)一个指向整型数的指针( A pointer to an integer)

c)一个指向指针的的指针,它指向的指针是指向一个整型数( A pointer to a pointer to an intege)

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); 

h) int (*a[10])(int);

38. 

int a[5][5];

int (*p)[4];

p = a;

求: &p[4][2] - &a[4][2]?

思路:

首先需要理解 a[1][1] == *(*(p+1)+1),拓展可得 a[i][j] == *(*(p+i)+j).

其次需要理解 int (*p)[4] 是该表达式表示行指针为 *p ,列数有4列

=====================================================================

a[5][5]:

p[0][0]  p[0][1]  p[0][2]  p[0][3]  p[1][0]

p[1][1]  p[1][2]  p[1][3]  p[2][0]  p[2][1]

p[2][2]  p[2][3]  p[3][0]  p[3][1]  p[3][2]

p[3][3]  p[4][0]  p[4][1]  p[4][2]  p[4][3]

p[5][0]  p[5][1]  p[5][2]  p[5][3]  p[6][0]

其中:

a[0][0] == *(*(p+0)+0)

a[0][1] == *(*(p+0)+1)

a[0][4] == *(*(p+1)+0)

也可以这样理解:00===================这代表内存中的物理存储空间,其中a和p都指向第一个0,也就是相对对齐,然后各自向后移动,移动完后面的距离便是结果,小减大为负

那么:&p[4][2] == &a[3][3],这样便能转化成 &a[3][3] - &a[4][2] == -4.

规律:

(4 * 4 +3)-  (4 * 5 + 3) == 19 - 23 == -4.

亦或者        (4 * 5 -1)  - (5 * 5 -2)  == -4.

扩展问题:

int  a[12][12];

int  (*p)[3]  = a;

&p[5][1]  -  &a[3][8]的结果?        -28

=====================================================================

39. 32位小端字节序的机器上,如下代码:

void main (void)

{

    char array[12]={0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08};

    short *pshort=(short *)array;

    int *pint=(int *)array;

    int64 *pint64=(int64 *)array;

    printf("0x%x, 0x%x, 0x%x, 0x%x\n", *pshort, *(pshort+2), *pint64, *(pint+2));

}

输出?

答:0x201, 0x605, 0x4030201, 不确定,如果是*(pint+1)=0x08070605

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值