C语言复习

好久没有看C语言了 从大一上学期开始学C,隔了这么长时间快到找工作的时候才想起看看

哎,自己真是够懒的,

看到了些知识点 都忘记了 悲催  做了几道题都不小心做错了  这么简单的题都错  那么笔试面试怎么办  贴出来自勉,以示警示


1. 判断int x = 0xaffbc;x的结果是(  D ) 。
A.赋值非法  B.溢出  C.为affb  D.为ffbc


2.记住A的ascll码65  a 97 0 48


3.并不是任何对象都可以作为左值的,运算表达式和常变量就不能作为左值。任何左值都可做右值。


4.赋值表达式具有计算和赋值双重功能。程序中的计算功能主要是由赋值语句来完成。


5.C语言的赋值语句与其他高级语言的赋值语句之间的差异:
  (1) C语言中的赋值号“=”是一个运算符,在其他大多数语言中赋值号不是运算符。 
  (2) 要区别赋值表达式和赋值语句。其他多数高级语言没有“赋值表达式”这一概念。


printf是C语言提供的输出函数;这句话是错误的  printf函数并不是C语言的一部分 C语言本身并没有输入输出函数


6.已有定义,int a=5,b=6,c=7,d=8,m=2,n=2,则逻辑表达式(m=a>b) && (n=c>d)运算后,n的值为()
解:因为m=a>b值为1  因此&&后面的表达式不执行计算  因此n还是为2


7.break语句不能用于循环语句和switch语句之外的任何其他语句中。


8.设有程序段
 int k=10;
 while(k=0)k=k-1;
 这下面描述中正确的是___C______.
 (A)while循环执行10次         (B)循环是无限循环
 (C)循环体语句一此也不执行      (D)循环体语句执行一次
 虽然赋值为真   但是k的值还是为0 所以一次也不执行


9.下面程序的执行结果是_____B_____。
#include<stdio.h>
void main()
{
int y = 10;
do 
y - -;
while(y--);
printf(" %d \n" , y--);
}
(A)程序错误       (B)死循环      (C)-1   (D)0
这是一个死循环 while(9->7->5->3->1->-1) 


10.下面程序段的运行结果是____C______.
  int n=0;
  while(n++<=2);
printf("%d",n);
(A)2   (B)3  (C)4   (D)有语法错




11.定义数组元素的个数必须使用常量表达式,而不能使用变量。
int i,j;  a[i][j]  这样是不对的


12.如果对数组全部元素赋初值,第一个下标可省略,但第二个下标不可省略。       
可写成  a[ ][4]={0,1,3,1,2,1,0,2,1,1,2,0};


13.强调:字符串实际占有单元的数量等于字符串长度+1。
定义时应注意考虑元素总个数应比实际长度多1。


14.scanf("%s",a);   
只能输入不包括空格、\t和\n的字符串;空格、跳格和回车是输入数据的结束标志.
若要输入空格,用gets函数;
数组名前不加 &符号。


15.char str[10];str="string"; 这样的赋值方式是不正确的


16.strcmp函数  strcmp(s1,s2) = 0 s1 ==s2
          = 正整数  s1>s2
  = 负整数  s1<s2


17.char c[10];c[10] = "string";//这样赋值是不正确的


18.. 数组char myArray[6]=”long a”,则printf("%s",myArray)的输出结果是(D)
A. long a  B. long  C. lon  D. 以上都不对
//因为没有遇到'\0'读取就不会结束  也可能是A  但是后面跟着别的时候就不是A了
eg:char c[6] = "long a";
    char * f="sdfjsdf";
    printf("%s",c);  最后输出的就不是A




19.C语言不可以函数嵌套定义


20.如果实参表列包括多个实参,对实参求值的顺序并不是确定的,有的系统按自左至右顺序求实参
的值,有的系统则按自右至左顺序。例如:
  printf(“%d, %d”,i, ++i);
若i的原值为3,在 VC++ 6.0环境下运行的结果不是“3,4”,而为“4,4”。因为按自右而左顺序,求
++i得4,再向左进行,此时的i已是4了。


21.函数的“定义”和“声明”不是一回事
函数的定义是指对函数功能的确立,包括指定函数名,函数值类型、形参及其类型、函数体等,
它是一个完整的、独立的函数单位。函数的声明的作用则是把函数的名字、函数类型以及形参的类型、
个数和顺序通知编译系统,以便在调用该函数时系统按此进行对照检查。它不包含函数体。 


22.全局变量:
在函数之外定义的变量是外部变量
有效范围为从定义变量的位置开始到本源文件结束。
声明时默认初始值为0;
在各个函数执行时都可能改变全局变量的值


23.所谓静态存储方式是指在程序运行期间由系统分配固定的存储空间的方式。
动态存储方式则是在程序运行期间根据需要进行动态的分配存储空间的方式。
这个存储空间可以分为三部分:
   1.程序区 2.静态存储区 3.动态存储区
在C语言中每一个变量和函数有两个属性:数据类型和数据的存储类别。




24.代码区:存放程序代码
静态区:存放全局变量/数据和静态变量/数据
堆区:取放动态数据
栈区:存放局部变量/数据


25.自动存储变量存放在栈区
auto
自动存储变量存放在栈区
 进入声明的块时生成,在结束块时删除 
 函数的参数和局部变量都是自动存储类 
 自动存储是变量的默认状态


26.静态变量:static
1. 静态局部变量属于静态存储类别,在静态存储区内分配存储单元。
在程序整个运行期间都不释放。而自动变量(即动态局部变量)属于动态存储类别,
占动态存储区空间而不占静态存储区空间,函数调用结束后即释放。
2. 对静态局部变量是在编译时赋初值的,即只赋初值一次,在程序运行时它已有初值。
以后每次调用函数时不再重新赋初值而只是保留上次函数调用结束时的值。
3.如在定义局部变量时不赋初值的话,则对静态局部变量来说,
编译时自动赋初值0(对数值型变量)或空字符(对字符变量)。而对自动变量来说,
如果不赋初值则它的值是一个不确定的值。
4. 虽然静态局部变量在函数调用结束后仍然存在,但其他函数不能引用它。


27.寄存器变量(register):
变量的值是存放在内存中的。当程序中用到哪一个变量的值时,
由控制器发出指令将内存中该变量的值送到运算器中。 经过运算器进行运算,如果需要存数,
再从运算器将数据送到内存存放。 


28.自动变量存储在动态存储区;静态局部变量存储在静态存储区;寄存器存储在CPU中的寄存器中。


29.extern 关键字:
在一个文件内扩展外部变量的作用域
#include <stdio.h>
int max(int,int);                //函数声明
void main( )
 {     extern int a,b;            //对全局变量a,b作提前引用声明
       printf(“%d\n”,max(a,b));
 }
int a=15,b=-7;                  //定义全局变量a,b
int max(int x,int y)
 {int z;
  z=x>y?x:y;
  return z;
 }
运行结果如下:
15
在main后面定义了全局变量a,b,但由于全局变量定义的位置在函数main之后,因此如果没有程序的第5行,
在main函数中是不能引用全局变量a和b的。现在我们在main函数第2行用extern对a和b作了提前引用声明,
表示a和b是将在后面定义的变量。这样在main函数中就可以合法地使用全局变量a和b了。如果不作extern声明,
编译时会出错,系统认为a和b未经定义。一般都把全局变量的定义放在引用它的所有函数之前,
这样可以避免在函数中多加一个extern声明




30.用extern将外部变量(全局变量)的作用域扩展到其他文件。


31.将外部变量的作用域扩展到其他文件 
 //Ch7_1.cpp
int num =3;
….
//Ch7_2.cpp
extern int num;
编译系统由此知道num是一个已在别处定义的外部变量,它先在本文件中找有无外部变量num,如果有,
则将其作用域扩展到本行开始。如果本文件中无此外部变量,则在程序连接时从其他文件中找有无外部变量num,
如果有,则把在另一文件中定义的外部变量num的作用域扩展到本文件,在本文件中可以合法地引用该外部变量num。




32.将外部变量的作用域限制在本文件中 
在程序设计中,某些外部变量只限于被本文件引用,而不能被其他文件引用。这时可以在定义外部变量时加
一个static声明。
例如:
file1.c                           file2.c
static int A;                   extern int A; // Error!
void main ( )                  void fun (int n)
{                                      {…
…                                    A=A*n;

//就是说如果一个变量是static(静态的),那么它就不能使用extern引用




33.用static 声明一个变量的作用是:
(1) 对局部变量用static声明,把它分配在静态存储区,该变量在整个程序执行期间不释放,
其所分配的空间始终存在。
(2) 对全局变量用static声明,则该变量的作用域只限于本文件模块(即被声明的文件中)


34.内部函数:
如果一个函数只能被本文件中其他函数所调用,它称为内部函数。在定义内部函数时,
在函数名和函数类型的前面加static。即
static 类型标识符 函数名(形参表)
例如:   static int fun ( int a , int b )


35.外部函数
(1)定义函数时,如果在函数首部的最左端加关键字extern,则表示此函数是外部函数,可供其他文件调用。
例如,函数首部可以写为extern int fun (int a, int b),这样,函数fun就可以为其他文件调用。
如果在定义函数时省略extern,则隐含为外部函数。
(2) 在需要调用此函数的文件中,用extern对函数作声明,表示该函数是在其他文件中定义的外部函数 


36.一个变量除了数据类型以外,还有3种属性: 
(1)作用域:  指程序中可以引用该变量的区域。 
(2)存储类别 : auto,static,register和extern 4种存储类别。
(3) 存储期 : 指变量在内存的存储期限


37.变量小结:
(1) 从作用域角度分
局部变量
静态局部变量(离开函数,值仍保留)
自动变量,即动态局部变量(离开函数,值就消失)
寄存器变量(离开函数,值就消失)
形式参数(可以定义为自动变量或寄存器变量)
全局变量
静态外部变量(只限本文件引用)
外部变量(即非静态的外部变量,允许其他文件引用)




38..在C语言中,函数类型的定义可以是默认类型,此时函数值的默认类型是(int )。


39.下列哪一个存储类别只用于全局变量( D )
A. auto B. static C. register D. extern(只用于全局变量)


40.下列有关extern 关键字的说明错误的是( D )
A. extern 可以改变同一个文件中的全局变量的作用域
B. extern 可以使得一个文件中的函数对其他文件可见
C. extern不能将静态外部变量的作用域扩展到其他文件
D. extern 可以用来定义一个外部变量(错误,不是定义外部变量)


41.//这个地方有个结合性的问题  运算符的优先级
自右向左
*p++: 取p所指向单元的数据作为表达式的值,然后使p指向下一个单元;//这个一定要注意
 (*p)++:取p所指向单元的数据作为表达式的值,然后使该单元的数据值增1;
*++p: 使p指向下一个单元,然后取该单元的数据作为表达式的值;
++*p:将p所指向单元的数据增1并作为表达式的值;


42.int (*p)[4]; ---p是一个指针变量,它指向包含4个整型元素的一维数组


43.char string1[] ="I love China!";
char * string2 ="I love China!";
string1[i]=‘A’; //允许,因为string1[i]有可修改的内存单元
string1=“xyz”; //不允许,因为string1是常量指针
string2[i]=‘A’; //不允许,因为string2指向常量区
string2=“xyz”; //允许,因为string2本身是指针变量
根本原因:存储位置(是否有可修改的内存单元)




44.字符数组和字符指针变量的区别
(1)字符数组由若干元素组成,每个元素中放一个字符,字符指针变量中存放的是地址(字符串第1个字符的地址),
而不是将字符串放到字符指针变量中。
(2) 赋值方式
对字符数组只能对各个元素赋值。
 char  str[20] = “hello”;
str=″I love China!″; // error
字符指针变量  
char*a = 0;      a=″I love China!″;     
(3) 初始化方式
对字符指针变量赋初值:
char *a=″I love China!″;
等价于     char*a = 0;a=″I love China!″;
对数组的初始化:
char  str[]=″I love  China!″;
不能等价于char str[20];str[ ]=″I love China!″;
(4) 内存分配 :定义一个字符数组,在编译时为它分配内存单元,  
它有确定的地址和连续的内存空间。
定义一个字符指针变量,给指针变量分配内存单元,  
在其中可以放一个字符变量的地址。  
(5) 指针变量的值是可以改变的,数组名为指针常量,不能改变!
(6) 字符数组中各元素的值是可以改变的,字符指针变量指向的字符串中的内容是不变的(不能对字符串常量再赋值)。 
char a[]=”House”;
char *b=” House”;
a[0]=’h’;              //r取代u   
b[2]=’r’;              //非法,字符串常量不能改变  


45.不能通过改变形参指针变量的值而使实参指针变量的值改变。


46.指向函数的指针
含义:可以定义一个指向函数的指针变量,用来存放某一函数的起始地址,这就意味着此指针变量指向该函数。
形式:数据类型 (*指针变量名)(函数参数表列)例如: int  (*p)(int, int);
作用:调用一个函数两种方式:通过函数名  通过指向函数的指针变量  指向函数的指针也可以作为函数的参数


47.//多重指针
指向指针型数据的指针变量,简称指向指针的指针   类型名**指针名;




48.全局变量是分配在内存中的静态存储区的,非静态的局部变量(包括形参)是分配在内存中的动态存储区的,
这个存储区是一个称为栈(stack)的区域。
C语言还允许建立内存动态分配区域,以存放一些临时用的数据,这些数据是临时存放在一个的特别的自由存储区,
称为堆(heap)区。
堆是内存空间,堆允许程序在运行时(而非编译时)动态申请某个大小的内存空间,需要时随时开辟,不需要时随时释放。


49.指针指向多维数组是要注意的事项:
int a[3][4]  a是数组的起始地址也是第一列的起始地址  a+1是数组第二列的起始地址  a+i 是i+1列的起始地址
eg;a的值是2000  那么 a + 1 的值应该注意计算 2000 + 2 × 4 = 2008 (每个int占的字节数 × 列数)
int * p = a; p++ 这时p是&a[0][1]的值  因为p是指向int的指针  p++会移动一个int  所以会指到&a[0][1]上
另一种  int (*p)[4]; p = a;
这是一个指向包含四个整型元素的一维数组,因此p++会引动2×4个int 所以p直接指到&a[1][0]上
int (*p)[4] 表示*p有四个元素,每个元素为整型,也就是p所指向的对象是有4个整型元素的数组,即p是指向
一维数组的指针
可以这样理解  int a[3][4] int (*p)[4]  所以p指向a p+1指向a[1]


50.文件指针
在缓冲文件系统中,每个被使用的文件都要在内存中开辟一FILE类型的区,存放文件的有关信息.
查看stdio.h中文件类型声明:typedef struct{…}  FILE; 
文件型指针变量:
FILE  *fp;在标准输入输出库中,系统定义了三个FILE型的指针变量:
1.stdin (标准输入文件指针)
2.stdout (标准输出文件指针)
3.stderr (标准错误文件指针)




51.#define  宏替换只对记号进行,对括在引号中的字符串不起作用
宏定义可以带参数
#define square(x) x * x  int temp = square(z+ 1);  会替换成  z +1 × z + 1 = 2 × z + 1


52.const用于声明可以存放在存储器中的对象,并可能提高优化的可能性
volatile用于强制某个实现屏蔽可能的优化





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章