C和指针课后练习题3

1、在你的机器上,字符的范围有多大?有那些不同的整数类型以及他们的范围?

C语言中数据输入输出格式:

%d 有符号10进制整数
%i 有符号10进制整数
%o 无符号8进制整数
%u 无符号10进制整数
%x 无符号的16进制数字,并以小写abcdef表示
%X 无符号的16进制数字,并以大写ABCDEF表示
%F/f 浮点数
%E/e 用科学表示格式的浮点数
%g使用%f和%e表示中的总的位数表示最短的来表示浮点数 G 同g格式,但表示为指数
%c 单个字符
%s 字符串  

 

我们通过下面的代码可以看到自己操作系统的字符范围:

#include<stdio.h>

#include<string.h>

int main()

{

  printf("signed char min: %d\n",-(char)((unsigned char)~0>>1));

  printf("signed char max: %d\n",(char)((unsigned char)~0>>1));

  return 0;

}

#include<stdio.h>
#include<string.h>
#include<limits.h>
 int main()
{
        printf("signed char min:%d,max:%d,unsigned char max:%u\n",SCHAR_MIN,SCHAR_MAX,UCHAR_MAX);
        printf("signed short int min:%d,max:%d,unsigned short int max:%u\n",SHRT_MIN,SHRT_MAX,USHRT_MAX);
        printf("signed int min:%d,max:%d,unsigned int max:%u\n",INT_MIN,INT_MAX,UINT_MAX);
//      printf("signed long int min:%ld,max:%ld,unsigned long int max:%lu\n",LONG_MIN,LONG_MAX,ULONG_MAX);

  return 0;

}


注意:1、signed 类型时是Int、char 、short 打印最大值的时候都可以用%d,但是long不可以应为它比Int还要大用%ld;

   2、unsigned类型时Int 、char、 short 打印最大值的时候都可以用%u,但是long不可以应为它比Int还要大用%lu;

整数类型:字符、短整型、整型、长整型;他们都分为有符号和无符号两种。

类型 最小范围
char 0~127
signed char -128~127
unsigned char 0~255
short int -32767~32767(2^15-1)
unsigned short int 0~65535(2^16-1)
int -32767~32767
unsigned int 0~65535
long int -2147483647~2147483647
unsigned long int 0~4294967295

 

 

 

 

 

 

 

 

 

 

 

 

2、在你的机器上,各种不同类型的浮点数的范围怎么样?

浮点数类型:float, double, long double三种。

代码求其范围:

#include<stdio.h>
#include<float.h>

int main()
{
        printf("folat min:%f,max:%f\n",FLT_MIN,FLT_MAX);
        printf("double min:%f,max:%f\n",DBL_MIN,DBL_MAX);
        printf("long double min:%Lf,max:%Lf\n",LDBL_MIN,LDBL_MAX);
        return 0;
}

3、假设你编写的程序要运行于两台机器,这两台机器在整型缺省情况下,一个为16位,一个为32位;长整型分别为:32位和64位。如何让你的程序中`的变量在任一台机器上都可以用。

 

为每台机器创建一个头文件,用typedef或#define,为创建的类型名字选择最合适的整型长度。

16位机器上:

typedef signed char  int8;

typedef int      int16;

typedef long int    int32;

typedef int      defint8;

typedef int      defint16;

typedef long int    defint32;

32位机器上:

typedef signde char  int8;

typedef short int     int16;

typedef int      int32;

typedef int      defint8;

typedef int      defint16;

typedef int      defint32;

 

注意:typedef int size; typedef并没有创建新的类型,它仅仅为现有类型添加一个同义字;你可以在任何需要int的上下文中使用size。上面定义的typedef int  ××;都是int类型,后面的名字只不过为了区分8位、16位、32位的整数。

6、编写一个枚举类型,定义硬币的值。

enum Dcoins {PENNY, NICKEL, DIME, QUARTER };  //只定义了枚举的类型

enum Dcoins {PENNY, NICKEL, DIME, QUARTER } coins; //既定义了枚举类型,又定义了枚举变量

8、你所使用的C编译器是否允许程序修改字符串常量?是否存在编译器选项,允许或禁止你修改字符串常量?

字符串常量不能修改;不存在编译器选项,允许或禁止修改字符串常量

9、如果整数类型在正常情况下是有符号的类型,那么关键子signed的目的何在?

如果显式声明signed,可以是程序更好移值。

10、一个无符号变量可以比相同长度的有符号变量容纳更多的值么?

否。给定任意的一个n位数值,他只能组合2^n种组合,他们容纳的数值是一样多的。一个有符号值和无符号值仅有的区别在于它的一半值是如何解释的。在一个有符号值中,它们是负值。在一个无符号值中,它们是一个更大的正值。

11、假如int和float类型都是32位,那种类型所能容纳的精度更大?

float的范围比int大,但如果它的位数不比int更多,它并不能比int表示更多不同的值。在float前一个问题的答案已经提示了它们应该能够表示的不同值得数量是相同得,但在绝大多数浮点系统中,这个答案是错误的。零通常有许多表示形式,而且通过使用不规范的小数形式,其他值也具有多种不同的表示形式。因此,float能够表示的不同值的数量比int少。

float类型
S(符号位) E(阶码) M(尾数)
0 0000 0000 0000 0000 0000 0000 0000 0000 0000 000

32位的float类型,有效位只有24位;而int有效位有32位(关于float可以参考:https://zhuanlan.zhihu.com/p/84453627)

12、下面是两个代码片段,取自一个函数的起始部分。

1)int a = 25;

2)int a;
   a = 25;

它们完成任务的方式有何不同?

 

1)直接把变量a初始化为25;   2)先把a初始化为0; 然后再赋值为25。

 

13、如果问题12中代码片段的声明中包含有const关键字,它们完成任务的方式又有何不同?

1)int const a = 25;

2)int const a;
   a = 25;

  1)a被定义常量,初始化值为25;   2)代码运行会出错,因为此时a被定义为常量,只能初始化,不能被赋值

14、在一个代码块内部声明的变量可以从该代码块的任何位置根据名字来访问,对还是错?

 

  如果代码块内部嵌套了一个相同名字的变量,嵌套外的变量在嵌套内就会被隐藏。如:

1){  int a;

2)  int const b;

 

 

3)  extern int c=5;

4)  {

5)    int b=2;

6)    int h=2

7)  }

8)

9)  {

10)    extern int h=5;

11)  }

12)}

上面代码块各个变量作用域:

a:  1) ~ 12)

第一个b:  2) ~ 4)  8) ~ 12)

c:  3) ~ 12)

第二个b: 5) ~ 7)

第一个h: 6) ~ 7)

第二个h: 10)~12)

15、假定函数a声明了一个自动整型变量x,你可以在其他函数内访问变量x,只要你使用了下面这样的声明:
extern int x;
对还是错?

  错。自动整型变量只能在函数内被访问。已经默认是auto局部变量类型了,不可以再加extern修饰。变量要定义为全局变量,就是要在函数体外面定义变量。

#include<stdio.h>

int sum(int a,int b)
{
        extern int c;
        c=a+b;
        int print(int l)
                {
                        int g;
                        g=l+c;
                        printf("g=%d\n",g);
                        return 0;
                }
        print(a);
        return c;
}

int diff(int m,int n)
{
        int d;
        d=m-n;
        return d;

}

int main ()
{
        int s,p,a=4,b=6;
        s=sum(a,b);
        p=diff(a,b);
        printf ("s=%d,p=%d\n",s,p);
        return 0;
}

  

16、假定问题15的变量x被声明为static。你的答案会不会发生变化?

  不会变化。

17、假定文件a.c的开始部分有下面这样的声明:  int x;
如果你希望从同一个源文件后面出现的函数中访问这个变量,需不需要添加额外的声明,如果需要的话,应该添加什么样的声明?

  位于同一个源文件,不需要添加额外声明。

18、    假定问题17中的声明包含了关键字static。你的答案会不会有所变化?

    不会

19、假定文件a.c的开始部分有下面这样的声明:int x;
    如果你希望从不同的源文件的函数中访问这个变量,需不需要添加额外的声明,如果需要的话,应该添加什么样的声明?

答:不同源文件,要用:extern int x;属于external连接属性的标识符无论声明多少次,位于几个源文件都表示一个实体。

20、假定问题19的声明包含了关键字static。你的答案会不会有所变化?

  会有变化,此时x变量就能被其它文件访问。staitic用于修改标识符的连接属性,从external改为internal,标识符的存储类型及作用域不变; 但是这种形式声明的函数或变量只能在声明他们的同一个源文件中使用。

 21、假定一个函数包含了一个自动变量,这个函数在同一行中被调用了两次。试问,在函数第二次调用开始时该变量的值和函数第一次调用即将结束时的值有无可能相同?

    有可能相同

  如:

  #include<stdio.h>

  int test(int n)

  {
        int x;
        x+=n;
        return x;
  }

  int main()
  {
        int n=10;
        printf("first=%d,last=%d\n",test(n),test(n));
        return 0;
  }
运行结果:first=10,last=10

#include<stdio.h>

  int test(int n)

  {
        static int x;
        x+=n;
        return x;
  }

  int main()
  {
        int n=10;
        printf("first=%d,last=%d\n",test(n),test(n));
        return 0;
  }

运行结果:first=20,last=10

22、当下面的声明出现于某个代码块内部和出现于任何代码块外部时,它们在行为上有何不同?
    int a = 5

  在任何代码块外部的变量存储于静态内存中,在程序运行之前创建,在程序整个执行期间始终存在,它始终保持原先的值,除非给它一个不同的值或者程序结束。作用域从声明位置到整个程序尾部,但是如果内层代码块有一个标识符名字与外层这个变量相同,它将会隐藏外层标识符--外层标识符无法在内层代码块中通过名字访问。
  代码块内部的变量存储与堆栈中,在程序执行到声明时,才被创建,当程序的执行流离开该代码块就会自行销毁; 如果代码块被多次执行,这个变量就会被重新创建。它的作用域到达该代码块的尾部便告终。

 

23、假定你想在同一个源文件中编写两个函数x和y,需要使用下面的变量:
    在这里插入图片描述你应该怎么样编写这些变量?应该在什么地方编写?注意:所有初始化必须在声明中完成,而不是通过函数中的任何可执行语句完成。

代码如下:

static char b='2';
void y()
        {
                printf("%c\n",b);
        }

        static int a=1;
        void x()
        {
                int c=3;
                static float d=4;
        }

备注:1.链接属性分为external,internal,none三种。

   2.全局变量默认拥有external链接属性;

          static修饰的变量拥有internal链接属性;

          函数体中的变量用于none链接属性。

       3.拥有external链接属性的变量可被所有文件访问,只需要声明下即可(extern int b;)

          拥有internal属性的变量只能在其定义的文件中被访问(static int sta_c;)

          拥有none属性的变量只能在其定义开始处到代码块作用域结束处被访问。

 

24、确定下面程序中存在的任何错误。去除所有错误后,确定所有标识符的存储类型、作用域、连接属性。每个变量的初始值?程序中同名的标识符,他们代表相同的变量还是不同的变量?程序中每个函数从哪个位置可以被调用?

1.  static int w=5;
2.  extern int x;
3.  static float

4.  func1(int a,int b,int c)
5.  {
6.          int c,d,e=1;
7.     ....... 

8.        {
9.                  int d,e,w;
10.      .......

11.                  {
12.                          int b,c,d;
13.                          static int y=2;

14.          .......
15.                  }
16.         }
17.   ..... 

18.         {
19.                register int a,d,x;
20.                extern int y;
21.     .....

22.          }
23.  }

24.  static int y;
25.  float
26.  func2(int a)
27.  {
28.          extern int y;
29.          static int z;

30.    .....
31.  }

错误:第6行:“c”重新声明为不同类型的符号,在第4行已经定义的变量c。

标识符 存储类型 作用域 链接属性 初始值
w(1) static 1~8  17~31 internal 5
x(2) static 2~18 23~31 external  
func1(4)   4~31 external  
a(4) auto 5~18  23 none  
b、c(4) auto 5~11  16~23 none  
d(6) auto 6~8   17  23 none  
e(6) auto 6~8  17~23 none  
d(9) auto 9~11  16 none  
e、w(9) auto 9~16 none  
b、c、d(12) auto 12~15 none  
y(13) static 13~15 none 2
a、d、x(19) register 19~22 none  garbage
y(20) static 20~22 external  
y(24) static 24~31 internal 0
func2(26)   26~31 external  
a(26) auto 27~31 none  
y(28) static 28~31 external  
z(29) static 29~31 none 0
posted @ 2020-07-10 15:41  W_柠檬草的味道  阅读(434)  评论(0编辑  收藏  举报