C语言以及C程考题
c语言写 #include<stdio.h>
c语言写using namespace std; 是会编译错误的。
用户标识符就是变量名,只能由数字,下划线,字母构成,区分大小写,数字不能开头
调试就是在程序中查找错误并修改错误的过程。(书上原文)
程序设计语言必须具备数据表达和流程控制的功能。
在C语言中,一行可以书写多个语句。 可以的,试过了。
C语言生成的目标代码质量高,运行效率高。 对的
for(int i=1;i<=n;i++) 会报错,因为好像c不支持在for里定义新的变量。实测 c89 不行(最老的)dev5.11,用 dev 6.3 是可以的,pta 上可以通过。但考试好像用 c89
除了复合语句,C语言中的所有语句都必须以分号结束。
C程序中定义的变量,代表内存中的一个存储单元。
在C语言中,单目运算符需要1个操作数(c++ ),双目 a+b (操作数个数是这个符号需要有几个参数)。
小心 5(a+b) 是错的,中间乘号呢?
printf输出的类型,scanf输入的类型,变量定义的类型,必须一致,否则无效。
scanf("x=%d",&x);是错的,输不进来,除非你输入 "x=" 一个整数,才能让 x = 那个值 ,别 python 学傻了。
{}里的语句合起来叫复合语句。
在C语言中,仅由一个分号(;)构成的语句称为空语句,它什么也不做。
for (fahr = 121 ; fahr <= 125; fahr++) ; 你看到它在跑空循环吗?
为了检查以下if-else语句的两个分支是否正确,至少需要设计3组测试用例,即x的取值至少有三组(小于15的数、15和大于15的数)。
if (x <= 15){
y = 4 * x / 3;
} else{
y = 2.5 * x - 10.5;
}
是对的
自定义函数不用都事先声明。
函数的定义与声明
简而言之,函数的定义就是如
int fact(int n){
xxxxxx
return xx;
}
而函数的声明就是
int fact(int x);
然后函数定义可以写在 main 后面
貌似 int fact(int); 和 int fact(int x); 都可以,但是带 x 的好像更符合书。
这个垃圾代码输出的是0 1
写出执行以下程序段后变量的值。请注意,直接填数字,前后不要加空格等任何其他字符。
int k, flag;
if (k = 0) {
flag = 0;
} else {
flag = 1;
}
原因是赋值的返回值是你赋的那个值,所以返回为 0 ,false ,那么进入 else 分支,flag=1
运算优先级:算术>关系>赋值(=也算运算符)
0x3f 0x后面表示是16进制
'\x61'表示ascll码为16进制下61 的字符,'\61' 则为8进制,'\t'是表示宽度为8的对齐,'%4d' 则可以调宽度。'%x' 表示16进制数,'%h' 为8进制?
合法的字符常量要求单引号,一个字符,包括'\n''\t'这类的也算一个字符,是合法的字符常量。
设计几组数据使来检验程序,需要所有case都进一遍(边界是额外测试的,不包含在对每个case的测试中),测试的原则还要再测下边界。不要问我为什么,问就是规定这样,规定认为这样比较全。
switch 语法
就是,注,case后面跟的就是 a 的可能取的常量值,不能含有变量或表达式。
switch(a){
case 1:
//do something ,但是不能定义变量
break;
case 2:
//do something
break;
default:
//
break;
}
对于 3.1+4.8 ,直接 scanf("%lf%c%lf",&x,&m,&y); 是可以直接一一对应输入进来的。
if-else语句的一般形式如下,其中的语句1、语句2只能是一条语句。
if (表达式) 语句1 else 语句2
对的,因为它没有大括号。
C语言中,大小写字母'A','B','C',…,'Z' ,'a','b','c',…,'z'的ASCII码按升序连续排列。
错的,因为它不连续,不能这么说
执行语句putchar('S');后,在屏幕上显示的输出结果是'S'。
错的,没有引号,它把引号放在代码块内了
设变量已正确定义,执行以下程序段,顺序输入三个字符'Q',则输出Q。
ch = getchar(); putchar(ch);
三个字符指的是' 和 Q和 ',特别注意'放入代码块的情况,那就是一个字符。
/* 程序段A2 */
int grade;
scanf ("%d", &grade);
if(grade < 60)
printf("Fail");
else
printf("Pass");
printf("Bye");
输入59,FailBye;61,PassBye
因为if else没加大括号,Bye都有
double grade;
scanf ("%lf", &grade);
if(grade < 60); {
printf("Fail");
}
printf("?");
不管怎么输都是'Fail?' 因为在if判断后面加了分号,结束了,大括号没有条件就可以执行。
mynumber = 38;
scanf ("%d", &yournumber);
if(yournumber == mynumber){
printf("Right");
}
if(yournumber > mynumber ){
printf("Big");
}else{
printf("Small");
}
输入38 为RightSmall ,因为你就算下面进入了一个分支,但是前面相等还是满足的啊。要输出Right
x ≤ -1或者x ≥ 1:x<=-1||x>=1 别tm写错,真离谱
c语言中or好像不太能用,||是可以的,且比较运算符优先于逻辑运算符。
在嵌套使用if语句时,C语言规定else总是和之前最近且不带else的if配对。
int main(void)
{
int x = 1, a = 0, b = 0;
switch(x)
{
case 0: b++;
case 1: a++;
case 2: a++; b++;
}
printf("a=%d,b=%d\n",a,b);
return 0;
}
a=2,b=1 因为没写break。
int i = 6;
if ( i <= 6 ) printf("hello\n");;
else printf("bye-bye\n");;
不能编译。因为if后;;,导致else报错,找不到前面的if
1-1/3+1/5-1/7+...=pi/4
case内不能出现变量
若变量已正确定义,执行以下while语句将陷入死循环。
i = 1;
while (i <= 10) ;
i++;
相当于while内跑空,i无法改变,这不是死循环是啥?
'0' <= ch <= '9' c语言能编译成功,但是却等价于('0'<=ch)<='9',前面一个是逻辑运算,不管咋样都是0或者1,所以无法判断是否是数字字符。
数组定义后,只能引用单个的数组元素,而不能一次引用整个数组。(注意这是对的,c语言规定,以前*a传的是指针,而不是整个数组)
变量初始化的含义,就是在定义变量时对变量赋值。对的,改成这样理解就行了,意义不大。
字符串常量就是用一对双引号括起来的字符序列,它有一个结束标志 '\0'。对的
将二维数组的行下标和列下标分别作为循环变量,通过二重循环,就可以遍历二维数组,即访问二维数组的所有元素。由于二维数组的元素在内存中按行优先方式存放,将行下标作为外循环的循环变量,列下标作为内循环的循环变量,可以提高程序的执行效率。
寻址连续,对的。
字符'\0'的ASCII码值为0。'\0'就是NULL,也就是static char 的默认值。
直接 int cnt[10];里面元素是啥不确定。
int cnt[10]={1},那么其余项确定为
static int cnt[10];未声明变量默认为
实测感觉有没有static区别不大,就只有默认初值上的不同。
其实还是不同的
include <stdio.h>
int f(int x)
{ static int y=1;
x+=y;
y++;
return x;
}
int main(void)
{ int k;
k=f(3);
printf("%d %d\n",k,f(k)); //%d和%d之间只有1个空格
return 0;
}
答案是4 6
这个static相当于这个函数的全局变量,你在外面虽然不能用,但是这个static的赋值是只能在函数第一次调用时赋值。
while((s[n]=getchar())!='\n') n++;
注意括号不能少,赋值运算是最低的,低于逻辑运算符(!=)
选项( )与以下字符数组定义等价。
static char s[6] = {'H', 'a', 'p', 'p', 'y', '\0'};
A. static char s[6] = {'H', 'a', 'p', 'p', 'y'};
B. static char s[6] ="Happy";
C. static char s[6] ={"Happy"};
D. static char s[6] = {'H', 'a', 'p', 'p', 'y', 0};
答案是全都对,C选项居然也是对的。
#include <stdio.h>
int main()
{
int k, len;
char str[81];
k = 0;
while((str[k]=getchar())!='\0'){
k++;//本来读到\0那个k就是答案,再k++就大一个1了,所以要k--
}
k--;
len = k;
printf("%d\n", len);
return 0;
}
对以下程序段,说法正确的是()。
x = -1; do { x = x * x; } while (x == 0);
程序只执行1次,太tm丢脸了,x==0才一直执行,而不是 x!=0 ,这个看反太离谱了。
定义整形变量 0345,开头为0表示是8进制(只有定义时需要),如果输出一个八进制数,就是%o输出一个变量或一个正常的数,不用加0.
所以不会出现08h,因为8进制中哪来8。
注意for(j=1;j<=n;i++)这种烂题
下面的程序段输出是( )。
short int a; int b = 65536;
a = b; printf("%d\n", a);
输出0
若是65535,输出-1
若是32678,输出-32678
阅读以下程序段,如果从键盘上输入abc<回车>,则程序的运行结果是( )。
char ch;
scanf("%3c",&ch); printf("%c",ch);
输出a,不知道为什么
在C语言程序中,若对函数类型未加显式说明,则函数的隐含类型为(int 型)。
C程中实参和形参
形参在函数调用前不分配内存单元,但调用就会分配,与实参分配的内存单元不同,各自独立
函数定义与函数声明不同,函数声明要分好,定义不用
执行语句int *p = 1000;后,指针变量p指向地址为1000的变量。是对的。
定义的时候int p=(int )1000.定义时候都这样。
~操作:包括符号位全部取反。然后因为符号位变了,如果是变为1,那么按照-补码那套,其余位取反加1
即~2=-3(取反,其余位取反,+1) ~1=-2,~-1=0(-1=11111111,~-1=00000000)
逗号表达式为左结合性,从左到右计算,返回最后一个逗号后面的值
在所有的关系运算符(>=、>、==、!=、<=、<)中,优先级最低的运算符是“==、!=”。这是对的,没问题。
以下选项中,对基本类型相同的指针变量不能进行运算的运算符是 ( )。
-,=,==都是可以的,就+不行
选项 A :“=(赋值)”是对于类型相同的两个指针变量之间常规运算。
选项 B: “==(比较相等)”比较两个指针变量是否相同。
选项 C:“+” 运算是不可以的,因为指针变量是一种特殊的变量,指针变量的值存放的是所指向变量的地址,两个地址相加并不能保证结果为一个有效的地址值,因而在 C 语言中指针变量相加是非法的。
选项 D:“-(减法)”运算两个相同指针变量相减可以获得在之间相隔的同类型元素个数(在某个类型的数组中的应用)。
浙大C程考题
已知字符'A'的ASCII码是65,分别对应八进制数101和十六进制数41,以下( )不能正确表示字符'A'。
'\0x41'='1'不行
'\x41'='A'
'\101'='A'(8进制)
运算符优先级(全)包括[]等乱七八糟运算符
char为一字节,表示大小从-128到+127(2^7-1)
注:按位与的优先级低于左移,优先级高的&是取地址,按位与的优先级低!
t+=1也是赋值。=是右结合性
a=b+c=1
被认作(a=b+c)=1 。但等于号左边只能是变量,不能为表达式,所以不是正确的赋值。
8位二进制中-128的补码表示为10000000(原码,反码无法表示)
-127为负数,原码11111111(负数的原码开头就是1),反码10000000(原码除符号位取反),补码,10000001。
负数原码就是相应正数的原码,将符号位取反就行
负数反码就是将其余位取反,补码就是反码加1
正数补码就是原码。
注意是几个字节表示,如果是两个字节表示,就要写16位,不能只写8位。
指针不可以比较大小
int a[10],*p;
p=a+1;是对的
a=a+1;是错的,因为数组首地址不可以改变。
字符串常量实质上是一个指向该字符串首字符的指针常量。对
字符串常量在内存中的存放位置由系统自动安排。对
字符指针(Character Pointers)是指向字符型数据的指针变量。每个字符串在内存中都占用一段连续的存储空间,并有唯一确定的首地址。因此,只要将字符串的首地址赋值给字符指针,即可让字符指针指向一个字符串。对于字符串字面量而言,字符串字面量本身代表的就是存放它的常量存储区的首地址,是一个地址常量。例如:char ptr = “Hello”;与 char ptr;ptr = “Hello”;//将保存在常量存储区中的“Hello”的首地址赋值给ptr//这两种表达方式时等价的,都表示定义一个字符指针变量ptr,并用字符串字面量“Hello”在常量存储区中的首地址为其初始化,即让ptr指向字符串自字面量“Hello”。注意,这里不能理解为将字符串赋值给ptr。因字符串“Hello”保存在只读的常量存储区中,所以此时可修改指针变量ptr的值(即ptr的指向),但不能对ptr所指向的存储单元进行写操作。例如,此执行如下操作就是非法的:ptr = ‘w’;//不能修改ptr指向的常量存储区中的字符,因为它是只读的但如果字符串“Hello”保存在一个数组中,然后再用一个字符指针指向它,即char str [10] = “Hello”;char ptr = str ;(第二句)那么此时由于数组名代表数组的首地址,因此将str赋值给ptr,就是让ptr指向数组str中存储的字符串“Hello”。其中,上面第二条语句相当于char ptr;ptr = str;因为数组名是一个地址常量,所以str的值是不可修改的,但ptr的值(即ptr的指向)可以被修改,ptr所指向的字符串也可以被修改。例如,若要将ptr所指向的字符串中的第一个字符修改为‘W’,则可使用下面的语句:ptr = ‘W’;//等价于ptr[0] = ‘W’ ; 相当于str[0]=‘W’总之,正确使用字符指针,必须明确字符串被保存到了哪里以及字符指针指向了哪里。
在定义结构类型时,关键字struct和它后面的结构名共同组成一个新的数据类型名。对的。
一个结构类型变量所占的内存空间是其各个成员所占内存空间之和。
在定义嵌套的结构类型时,必须先定义成员的结构类型,再定义主结构类型。
不同类型的结构变量之间也不可以直接赋值。
在对结构变量操作时,.被称为成员或者分量运算符。
结构指针就是指向结构类型变量的指针。
假设结构指针p已定义并正确赋值,其指向的结构变量有一个成员是int型的num,则语句p.num = 100;是错的。((p).num = 100;(因为.的优先级高于*);或者p→num,也可以)
结构体传参是要复制的,数组才是传指针
在使用结构指针时,->被称为指向运算符。
x&&1相当于x!=0
写出以下程序段的运行结果。
char ch = 'w';
int b = 0;
printf("%d\n", ch || (b = 10));
printf("%d\n", b);
如果ch='w',那么已经满足或起来为1,就不会执行b=10,即输出为1\n0\n
如果ch=0,那么会执行b=10,那么就输出1\n10\n
执行语句int *p = 1000;后,指针变量p指向地址为1000的变量。错的
因为你不知道地址为1000的变量是int类型的,所以一旦地址为1000的变量是其他类型的,那么指针变量进行指向就是错的,int 是指不了long long 之类的。
且指针赋值不能赋一个数(c中,因为你不知道变量类型),只能空指针或者取一个变量的地址。
int *p是二级指针,它指向一个int 指针的地址。
c语言中定义结构体struct pp,之后再定义时必须还写struct pp,而不能单独一个pp
而c++中是可以的。
struct person{
char name[10];
int age;
} c[10] = { "John", 17, "Paul", 19, "Mary", 18, "Adam", 16 };
那么一个个分别是{"John",17},{"Paul",19},{"Mary",18}...
struct stu{
char num[10];
float score[3];
};
struct stu s[3] = {{ "20021",90,95,85},{"20022",95,80,75},{"20023",100,95,90}};
scanf("%d",p+i);
用指针本来就不要&了,因为本来就是取地址的。
动态内存分布函数 定义在stdlib.h里
1.动态存储分配函数malloc( ) void malloc (unsigned size) 再内存的动态存储中分配一连续空间,长度为size。申请成功,返回指向所分配内存空间的起始地址的指针;否则返回NULL; //动态分配n个整数类型大小的的空间,调用malloc时,利用sizeof计算存储块大小 if((p= (int )malloc(n*sizeof(int)))==NULL){ printf("Not able to allocate memory, \n"); exit(1); }
2.计数动态存储分配函数calloc( ) void *calloc(unsigned n,unsigned size) 在内存的动态存储区中分配n个连续空间,每一存储空间的而长度为size,并且分配后还把存储块 里全部初始化为0。申请成功,返回指向所分配内存空间的的起始地址的指针;否则返回NULL;
(p = (int ) calloc (n, sizeof(int))) == NULL
void * 返回的也是一个指针,而不是不返回
如这个就是看看空间够不够。单个空间长度大小用sizeof(类型)即可
3.动态存储释放函数free() viod free(void *ptr) 盛放动态存储分配函数申请到的整块内存空间,ptr为指向要释放空间的首地址。 释放后不允许再通过该指针去访问已经释放的块。
4.分配调整函数realloc() void realloc(void ptr,unsigned size) 更改以前的存储分配。ptr必须是以前通过动态存储分配得到的指针。参数size为现在 需要的空间大小。分配失败,返回NULL;分配成功,返回一片能存放大小为siza的区块。
struct pp{...}bt;所占内存的大小为sizeof(bt)
double,long long 都是8个字节的,科学计数法 2^{64} 级别的 。int 是4个字节的
#include<string.h>
这个下面的函数strcmp(a,b)是比较两个字符串a,b,若a>b,则返回正数,a=b,返回0,a<b返回负数。
strcpy(a,b)是将b的字符串的值复制到a的地址上。你也不用管什么时候结束。
#include<stdio.h>
int main(){
int i=1;
for(i=1;i<0;i++) printf("1\n");
return 0;
}
结果是不输出,因为for不是while,他初始条件也要进行判断是否符合循环条件。
宏的本质就是替换,与函数不同,不会人为加括号。
如
#define F(x) x - 2
#define D(x) x*F(x)
int main ( )
{
printf ("%d,%d", D(3), D(D(3))) ;
return 0;
}
D(3) 就是x * x - 2 ,记住千万不要加括号,或改变运算优先级,也不用先代入数字。
因为F(x)就是x-2,这个字符串的替换,所以D(x) 就是x x - 2,而不是x (x-2)
D(D(3)) 也是替换,记住,只是字符上的替换,因为对外层D,它套住的是D(3) ,所以我们要先展开里面的。(注意这个x代表的不是一个未知变量,而是类似于一个字符串替代)
D(D(3)) 变成D(x x -2),然后再展开外面的,就是把外面的'x'替换为'x x -2',变为x x-2 x * x-2,这中间不能有一步提前计算,最后带入x=3
格式文件包含
¨ # include <需包含的文件名> 系统文件夹
¨ # include “需包含的文件名” 作用当前文件夹+系统文件夹
把指定的文件模块内容插入到 #include 所在的
位置,当程序编译连接时,系统会把所有
#include 指定的文件拼接生成可执行代码。
n注意
¨编译预处理命令,以#开头。
¨在程序编译时起作用,不是真正的C语句,行尾
没有分号。
ctype.h 字符处理
math.h 与数学处理函数有关的说明与定义
stdio.h 输入输出函数中使用的有关说明和定义
string.h 字符串函数的有关说明和定义
stddef.h 定义某些常用内容
stdlib.h 杂项说明
time.h 支持系统时间函数
条件编译,就是如果某个条件成立,才执行宏里面的内容 比如 #if FLAG 然后 #define ... 最后 #endif
实参可以是常量、变量、表达式、函数等任意类型,形参只能是变量,在被定义的函数中,必须指定形参的类型。
形式参数(形参):定义函数名和函数体时需要用的参数,目的是用来接收调用该函数时传递的参数。(如int max(int a,int b),里面的a和b,他们是定义在被调函数里的,比不知道他们的值)
实际参数(实参):传递给被调用函数的值。如(调用时max(3,4)中的3和4)
宏名用大写字母表示只是个习惯,大小写都行;
宏替换不占用运行时间,只占编译时间;因为宏替换发生在编译预处理阶段,预处理也是编译工作的一部分。
宏名无类型;
宏替换只是字符替换;
带参数的宏替换和函数不等价;
C语言的编译系统对宏命令的处理( )。 B.在对源程序中其他语句正式编译之前进行的
在“文件包含”预处理语句的使用过程中,当#include后面的文件名用双引号括起来时,寻找被包含文件的方式是( )。 B.先在源程序所在的目录搜索,如没找到,再按系统设定的标准方式搜索
预处理功能主要包括:宏定义、文件包含、条件编译。
while(n--)最后的结果是n=-1,因为n=0时还会进行判断(n--)!=0否,此时比完后n会--.变为-1
return (double)(5/2);返回2.0因为5/2时还是整型,答案为2,强制类型转换前已经是2了。
switch里不能定义变量
设有数组定义:char array [ ]="China"; 则数组 array所占的空间为()。
6个字节。常量字符数组在赋初值的时候或自动加上'\0'结尾,所以占空间6个字节。
有以下定义:char x[ ]="abcdefg"; char y[ ]={'a', 'b', 'c', 'd', 'e', 'f', 'g'}; 则正确的叙述为()。
x[]大,因为常量字符数组长度自己要加1
字符数组可以存放字符串,字符数组中的字符串可以整体输入、输出 这两项是对的。
但是,不可以在赋值语句中通过赋值运算符"="对字符数组整体赋值。因为只有赋初值才可以整体赋值,其他时候都不行,要strcpy
还有c中字符串比较不能用关系符,c连sort都没有。反正你也没见过'ab'>'aa'这种写法。。。
注sizeof会计算到'\0',比strlen大1,strlen是不包括'\0'的。
函数递归调用自身时,每次调用都会得到一个与以前的变量集合不同的新的变量集合。算他对,就当他说的是自动变量。
对于 int 型的二级指针变量,它既可以指向同类型的一级指针变量,也可以指向同类型的普通(非指针)变量。【错误,int **p只能指向一级指针】
空间复杂度考虑的是那些显式额外申请的空间,不考虑栈空间(栈空间可以回收,且在编译时就处理了)
typedef