C语言复习
发布日期:2021-05-06 18:58:19 浏览次数:22 分类:技术文章

本文共 5763 字,大约阅读时间需要 19 分钟。

之前复习C时候整理的一些word笔记,刚清理磁盘发现的,感觉扔了又可惜,以后还可以看看就整理成博客

1. 二维数组维数声明错误

int a[]; //错误不知长度	int a[] = {
14}; //正确,元素个数为1 int b[][3] ={
0,0} ; //正确,元素个数为1,每个元素长为3 int c[][] = {
{
1},{
2,1}}; //错误

总结:定义数组时,数组个数可以省,数组长度不能

(只能省最高维)

2. 显示出 ”My salary was increased by 15%!” (有引号) printf(“\”My salary was increased by 15%%!\”\n”);

理由:因为%是代表输出的格式,所以要输出百分号必须用%%		“”输出要转		\”  为 “		%% 为 %		! 为 !(不需要转)		\”  为 “

总结:要输出时用转义序列,反斜杠”\”后面的一个字符原样输出

> 	例:输出  ‘hello;  (注意有个单引号)> 			cout<<"\'hello";> 			printf("\'hello"); 		输出’hello’> 			cout<<”\’hello\’”<

3. 3||5 结果问题

int a(3);	int b(5);	a || b 结果为1   (√)	cout << (3 || 5) << endl;  //结果为1	cout << sizeof((3 || 5)) << endl;   //结果为1	cout << ((5 || 1) == 1 ? "equal 1" : "not equal 1") << 	endl;  //结果为equal 1

4. C语言的基本功能模块为函数,c语言一切皆函数

5. 有以下定义:char x[ ]=“abcdefg”; char y[ ]={‘a’,‘b’,‘c’,‘d’,‘e’,‘f’,‘g’};则数组x的长度大于数组y的长度。

(这题为计算字符长度,但第二个数组里面并不是字符串,而strlen为求字符串的长度,这里不能用strlen,要用sizeof比较)Strlen大小不算\0char x[5] = "abcd";  //定义char x[4] = “abcd”会报错,因为末尾要\0;strlen(x)  // 结果为4sizeof(x);  //结果为5char y[4] = {
'a','b','c','d' };例char a[100] = "abcd"; cout << sizeof(a) << endl; //结果为100 cout << strlen(a) << endl; //结果为4

6. 标准规定其他函数不能调用main()函数

7. ++p比p++更好(通过反汇编可以知道++p两步p++三步)

8. 下列不属于未定义的行为是©

A. int i=0;i=(i++);
B. char *p=”hello”;p[1]=’E’
C. char *p=”hello”;char ch=*p++
D. int i=0;printf(“%d%d\n”,i++,i–)

未定义行为(Undefined

Behavior)是指C语言标准未做规定的行为。同时,标准也从没要求编译器判断未定义行为,所以这些行为有编译器自行处理,在不同的编译器可能会产生不同的结果,又或者如果程序调用未定义的行为,可能会成功编译,甚至一开始运行时没有错误,只会在另一个系统上,甚至是在另一个日期运行失败。当一个未定义行为的实例发生时,正如语言标准所说,“什么事情都可能发生”,也许什么都没有发生。一句话,未定义行为就是运行结果不确定

1.变量即是左边结果,又是右边的操作数,如a+=a++,a %= b ^= a ^= b ^= a

2.使用越界数组也是C的一个“未定义行为”
3.允许一个随便指的指针的读写。
4.使用未初始化的变量 A选项,不知道编译器会怎么选择自增和赋值的顺序,所以这是由编译器决定的,属于未定义行为。 首先,未定义是说最后i到底等于多少? i=i++;
我们知道,i++是先返回i的值,然后再+1。未定义就出现在i返回以后(此时返回0),=和++到底编译器先执行哪个。
如果先执行=,那么执行完=后i为0,再执行++,i为1。
如果先执行++,那么执行完++后i为1,再执行=,注意这里上面返回的是0,因此i赋值为0。=运算符只可能把0赋给i,不可能把1赋给i,这是重点,i=++i才是把1赋给i B选项,”hello“这个字符串属于一个字符串常量了,指针p指向了这个字符串常量,通过这个指针来直接修改常量第二个字符,这也属于未定义行为。
C选项,只是通过指针找到第二个字符并将它赋值给一个字符变量,并没有改变这个字符串常量,所以不属于未定义行为。
D选项,在printf语句中,i++和i–谁先执行由编译器决定,这是未定义行为。 int i = 0; i = (i++); cout
<< i << endl; //在dev运行结果为0在vs2015为1 int j = 0; printf("%d%d",
j++,j–); //在vs和dev是-10

9. 后置++的本质:

两条理论

(b = a++)  int a = 0; 			  int b = a++;    //b的结果为0,a的结果为1

(1): c = a ; a += 1; b = c; (gcc)

(严格按照优先级顺序先++再赋值(赋a++之前的值), 然后把a++之前的值给b)
(2): b = a ;a += 1;(国内教程说法) (vs)
违背优先级顺序先赋值再++,

例子 int a = 2; int c = a++ + a++; //改为int c = (a++) + (a++)效果一样

(1)对于vs,先赋值再自增,结果为c = 2 + 2 等赋值结束a再自增变为4 (++对于表达式计算不产生影响)
(2)对于gcc, 先自增,再把之前的结果给c,因此c = 2 + 3 a还是4 造成啦二义性 例子 int a = 1; a =(a++); 对于gcc: 最终a为1; //先自增,再把之前的值给a 对于vs 结果为2
//先赋值,然后再自增让a变为2

例:int a = 2; int b = a++ + a++ + 3*4 //vs结果为16 gcc为17

10. 若变量已经正确赋值,下列表达式不符合c语言的语法的是(CD)

A. a = a + 2;
B. a = 7 + b + c,a++;
C. int(12.3%4);
D. a =a + 7 = c + b;

解析:对于C来说,取余只能在整数上面来操作 也就是说下面代码是行不通的

int a = 12.3%2; 对于D来说赋值运算是典型的右结合,但是在辅助操作运算符左边,要求必须是变量,在本题中7为常量 也就是说下面这个代码是行不通的 int a = 1; int b = 0; b + 1 = a + 2;

11. 指针变量可以由整形变量直接赋值,不能用浮点变量直接赋值。

int* p = (int*)1235445; //直接用整数,因为地址本来就是十六进制整数, 所

以用前面加(int*)会把它转化为十六进制的整数并加上0x 而float要转为int int* q =
(int*)(int)123456.6; 例: int* p = (int*)1235445;
printf("%x\n",1235445); //结果为12d9f5 cout<<p<<endl; //结果为0x12d9f5

12. 以下字符中不是转义字符的是(C)

A. ‘\a’;
B. ‘\b’
C. ‘\c’
D. ‘\’
解析:常见转义字符表

13. 逗号表达式(优先级最低,左结合)

逗号表达式,又称为“顺序求值运算符”。逗号表达式的一般形式为
表达式1,表达式2

3+5,6+8逗号表达式的求解过程是:先求解表达式1,再求解表达式2。整个逗号表达式的值是表达式2的值。例如,上面的逗号表达式“3+5,6+8”的值为14。又如,逗号表达式  a=  3*5,a*4      (假设a初始值为3)易错想法:先计算逗号表达式(3*5,a*4)  结果为12再赋值给a(错误,,没有想优先级)易错想法:先计算a = 3*5 = 15;再计算a = a *4 得60正确做法:先计算 a = 3*5得15,此时a已经是15啦,原来的逗号表达式变为15,a*4             整个表达式结果为60但a还是15a = (3 * 5, a * 4)  //a的值等于逗号表达式值12例:(x=4*5, x*5), x+25 最后表达式结果为45

14. 输出的结果为:

#define MIN (x,y) (x)<(y) ? (x):(y)
void main()
{
int i=10,j=15,k;
k=10*MIN(i,j);
printf ("%d\n",k);
}
宏替代完全替代: k = 10 * (10) < (15) ? (10):(15);
结果为15

15. malloc函数进行内存分配是在什么阶段(D)

A. 编译阶段
B. 链接阶段
C. 装载阶段
D. 执行阶段

解析:程序占用三种类型的内存:静态内存、栈内存、堆内存; 静态内存: 用来保存局部static对象、类static数据成员以及定义在任何函数之外的变量(全局变量) 第一次调用时分配内存并作初始化栈内存:用来保存定义在函数内的非static对象。分配在静态内存或栈内存中的对象由编译器自动创建和销毁。对于栈对象,仅在其定义的程序块运行时才存在;static对象在使用之前分配,在程序结束时销毁。堆内存:在程序运行时分配。动态对象的生存周期由程序(用户)来控制。各个内存最大?

16. 宏替代不占用程序运行时间

17. 关于c++/java类中static成员和对象说法正确的是(C)

A. static 成员变量在对象构造时生成
B. static 成员函数在对象成员函数中无法调用
C. 虚成员函数不可能是static 成员函数
D. static 成员函数不能访问static 成员变量

解析:static成员变量是在类加载时候生成的,static成员函数既可以通过类名直接调用,也可以通过对象名进行调用,虚函数是c++中的,虚函数不可能是static的,static成员函数可以访问static变量,类的static成员属于类不属于对象,静态与非静态唯一区别就是有无this指针

static的学习

1、静态全局变量:全局变量加上static关键字

特点: 1、在全局数据区分配内存 2、未出初始化的会被自动初始化为0 3、整个文件可见,不会被其它文件所访问

、静态局部变量:全局变量加上static关键字

特点: 1、在全局数据区分配内存 2、在程序执行到该对象的声明处被首次初始化,    之后的函数调用也不会再进行初始化 3、始终驻留在全局数据区,直到程序运行结束    但其作用域为局部作用域,当定义它的函数或语句块结束时,    其作用域随之结束。

3、面向对象(类中的static关键字)

3.1 静态数据成员:数据成员加上static

特点:

1、静态数据成员只分配一次,供所有对象共用
2、static数据成员在全局数据区分配内存,
所以没有产生类对象时其作用域就可见,
即不产生类的实例时可以操作
3、static成员变量是在类加载的时候生成的

3.2 静态成员函数:static + 成员函数        特点:     1、无法访问类对象的非静态数据成员和非静态成员函数     2、可以访问静态的成员和函数     3、非静态的成员函数可以访问static的    4、static成员函数不可以声明为const和virtua

18. 有如下程序,输入数据:12345M678<cR>后(表示回车),x的值是() 。

#include<stdio.h>
main()
{
int x;
float y;
scanf("%3d%f",&x,&y);
}

解析:scanf("%3d%f",&x,&y); int

x,说明x是整形数据!%3d意思就是取3个整形数据,y是浮点数!输入的M后面的识别不了自动忽略!只有12345能被识别!&x就是%3d对应的数据,对应123这三个整数!所以x是123。
%f对应y,故y应该是45。

19. 下列属于合法的字符常量是(B)

A. ’\087’
B. ‘\x43’
C. ‘abc’
D. 68

解析A:表示八进制,八进制每个数取值0 – 7 B.表示十六进制67,对应字符C C.只能一个字符 D.只能引号

`

20. 静态局部生命期全局,作用域受限于本函数

#include
using namespace std;void fun();int main(){
for(int i = 1;i<=4;i++) fun(); //结果依次为2 3 4 5, 全局变量的初始化代码,只执行1次作用域受限于函数内部,但可以拐弯用指针来访问。(类中私有成员也是可通过指针) return 0;}void fun(){
static int m = 1; m++; cout<
<
using namespace std;int *fun();int main(){
int *p = fun(); (*p)++; //m也发生了改变 fun(); return 0;}int *fun(){
static int m = 1; cout<
<
上一篇:eclipse中server location灰色解决
下一篇:java中获取程序运行时间

发表评论

最新留言

路过按个爪印,很不错,赞一个!
[***.219.124.196]2025年03月22日 20时52分25秒