1.设有定义:char *p;,以下选项中不能正确将字符串赋值给字符型指针p的语句是( )
正确答案: A B D 你的答案: 空
A p=getchar();
B scanf(“%s”,p);
C char s[ ]=”china”;p=s;
D *p=”china”;
A、类型不匹配, getchar() 函数返回值是int,只能赋值给int 或者char类型,此时p为char*类型
B、 p指针在定义的时候没有分配内存, 所以这行代码在运行的时候会报野指针错误
C、指针p指向数组s
D、 *p代表p指向内存的内容, 这里要使用p="china"才正确
字符串常量"china"出现在一个表达式中时,"china"表达式使用的值就是这些字符所存储的地址(在常量区),而不是这些字符本身。
所以,可以把字符串赋值给指向字符的指针p,而不能把字符串赋值给一个字符数组
2.下面哪些运算符不能被重载?
正确答案: A B D 你的答案: 空
A 做用域运算符“::”
B 对象成员运算符“.”
C 指针成员运算符“->”
D 三目运算符“? :”
C++ 里面 . , .* , :: , ?: , siezof 不能重载.
3、给出以下定义,下列哪些操作是合法的?
正确答案: A 你的答案: B
A p1++;
B p1[2] = ‘w’;
C p2[2] = ‘l’;
D p2++;
解析:
口诀:左定值,右定向。
即 const在*的左边不能改变字符串常量的值,故B错;
const在*的右边不能改变指针的指向,故D错;
由于 “world“存储在字符常量区,不能直接修改其值,故C错;
若要修改其值,应该改为char str []= "world";
4、下列说法哪个正确()
正确答案: C
A 不需要定义类,就能创建对象
B 对象中必须有数据域和方法
C 数据域可以是基本类型变量,也可以是一个对象
D 数据域必须是基本类型变量
5、float 类型(即 IEEE754 单精度浮点数格式)能表示的最大整数是( )。
正确答案: D
A 2^126-2^103 B 2^127-2^104 C 2^127-2^103 D 2^128-2^104
6、下面输出结果为:
正确答案:ink
#include<stdio.h>
int main()
{
static char *s[] = {"black", "white", "pink", "violet"};
char **ptr[] = {s+3, s+2, s+1, s}, ***p;
p = ptr;
++p;
printf("%s", **p+1);
return 0;
7、若有语句:int s[3][3],(*p)[3];p=s;则对s数组元素的引用形式正确的是____
正确答案:C
A、p + 1 B、*(p+1) C、p[1][2] D、*(p+1)+2
首先,在这个题目中我们应该明确的是:在二维数组中,二维数组的数组名是代表首元素的地址,而二维数组的首元素是二维数组第一行的内容
所以在p中存储的地址是s第一行一维数组的地址。(在看二维数组时,我们要将其当做一维数组来看)
其次,我们知道,数组名代表的是首元素的地址,我们访问数组中的元素一般用arr[1]的形式;但是从地址的角度来看:*(arr + 1)也能访问到数组中同样的元素;所以我们可以得到:arr[1] 就等价于*(arr + 1)。(实际上在原理上确实是这样的,比较复杂,有兴趣的可以去查一下)
知道了这些知识后,我们再来看C选项:p[1][2] 就可以写为 *(*(p + 1) + 2),即为访问第二行第三个元素。
(而B选项只是访问的二维数组第二行的元素;A和D选项不符合基本的格式)
8、有如下程序段,则对函数 fun 的调用语句正确的是【多选】( )
正确答案:C D
char fun(char *);
int main()
{
char *s = "one", a[5] = {0}, (*f1)(char *) = fun, ch;
return 0;
}
A: *f1(&a); B: f1(*s); C: f1(&ch); D: ch = *f1(s);要改成(*f1)(s)才正确
解析:
指针函数: 是指函数返回值是某一类型的指针,本质是一个函数。
指针函数的定义为: 类型名 函数名(参数表列); 例如: int a(int x, int y);
指针函数是一个函数,只不过这个函数的返回值是一个地址值。函数返回值必须用同类型的指针变量来接受,也就是说,指针函数一定有函数返回值,而且在主调函数中,函数返回值必须赋给同类型的指针变量。
函数指针: 是指向函数的指针变量,即本质是一个指针变量。
函数指针的定义为: 函数类型 (变量名)(函数形参表);例如:int (p)(int, int);
int (*p) (int x); //声明一个函数指针
p = func; //将func函数的首地址赋给指针p
通过指针调用函数的两种形式:
1、ret = (*p)();
2、ret = p();
对函数指针赋值的两种形式:
1、pf = &func;
2、pf = func;
A应改为:(*f1)(a)或f1(a)
B应改为:(*f1)(s)或f1(s)
CD,f1为函数指针
D、要正常使用f1应该使用(*f1)(s),与f1(s)效果相同。
*f1(s)中()的优先级比*高,()先与f1(s)结合,返回结果是char,*f1(s)是对返回结果
验证:
char
s_char =
'a'
;
char
* fun(
char
*){
return
&s_char;
};
int
main()
{
char
*s =
"one"
, a[5] = { 0 }, *(*f1)(
char
*) = fun, ch;
ch = *f1(s);
cout << ch;
return
0;
}
//输出 a
9、下列程序的输出是()
正确答案:D
#include <stdio.h>
int main(void) {
int a[12] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}, *p[4], i;
for (i = 0; i < 4; i++) p[i] = &a[i * 3];
printf("%d\n", p[3][2]);
return 0;
}
A: 上述程序有错误 B: 6 C: 8 D: 12
解析:
int *p[4]: p 是指针数组, 数组内包含 4 个元素, 每个元素都是 int* 类型.
p[3] = &a[9], 即第 3 个元素是指向 a[9] 的
p[3][2] = p[3]+2, p[3] 是 int* 类型, 偏移 2 个单位后指向 a[11]
9、下列程序的输出是()
正确答案:abddcccd
char* f(char *str, char ch) {
char *it1 = str;
char *it2 = str;
while (*it2 != '\0') {
while (*it2 == ch) { it2++; }
*it1++ = *it2++;
}
return str;
}
void main(int argc, char *argv[]) {
char *a = new char[10];
strcpy(a, "abcdcccd");
cout << f(a, 'c');
}
分析:看下面这段代码:
while(*it2 != '\0')
{
while(*it2 == ch) { it2++; }
*it1++ = *it2++;
}
it1的前两个字符为ab没有异议,当it2的指针指向c时执行 it2++,运行后it2指向d,然后其不为c,所以it1的指针内复制为d,即此时it1为abd,
之后遇到3个c,执行 it2++,直到it2指向d时才将d赋值给it1,也就是此时it1=abdd,但是接下来it2已经为空了,也就是“\0”,所以就不执行循环了,但是it1内本身后面还有cccd,前面的四个字母只是it2覆盖成abdd
所以最终的答案是abddcccd
10、关于char*f和c_str的使用
char* func()
{
string s = "1234";
return s.c_str();
}
const char* c_str();
c_str()函数返回一个指向正规C字符串的指针常量, 内容与本string串相同.
这是为了与c语言兼容,在c语言中没有string类型,故必须通过string类对象的成员函数c_str()把string 对象转换成c中的字符串样式。
注意:一定要使用strcpy()函数 等来操作方法c_str()返回的指针比如:最好不要这样:
char* c;
string s="1234";
c = s.c_str(); //c最后指向的内容是垃圾,因为s对象被析构,其内容被处理,同时,编译器也将报错——将一个const char *赋与一个char *。正确使用:
char c[20];
string s="1234";
strcpy(c,s.c_str());
这样才不会出错,c_str()返回的是一个临时指针,不能对其进行操作再举个例子
c_str() 以 char* 形式传回 string 内含字符串
如果一个函数要求char*参数,可以使用c_str()方法:
string s = "Hello World!";
printf("%s", s.c_str()); //输出 "Hello World!"
10、下面正确的是:
正确答案:A
union d
{ int d1; float d2; }d;
A. 变量d与各成员的地址相同 B. d.d1和d.d2具有相同的地址
C. 若给d.d2赋10后,d.d1中的值是10 D. 若给d.d1赋10后,d.d2中的值是10
解析:这题思路应该是:共用体中只能存在一个值,如果给某个值赋值后,另一个值就不存在;共用一个地址;
11、以下有关C语言的说法中,错误的是( )
正确答案:D
A: 内存泄露一般是指程序申请了一块内存,使用完后,没有及时将这块内存释放,从而导致程序占用大量内存,但又不使用不释放
B: 可以通过malloc(size_t)函数调用申请超过该机器物理内存大小的内存块
C: 无法通过内存释放函数free(void*)直接将某块已经使用完的内存直接还给操作系统,free函数只是将动态申请内存的使用权释放
D: 可以通过内存分配函数malloc(size_t)直接申请物理内存
答案解析:
free释放的内存不一定直接还给操作系统,可能要到进程结束才释放。malloc不能直接申请物理内存,它申请的是虚拟内存
12、下面输出结果为:
正确结果: D
char a=101;
int sum=200;
a+=27;sum+=a;
printf("%d\n",sum);
A: 327 B: 99 C: 328 D: 72
char为有符号类型,占1个字节,也就是8位,其中最高位是符号位,取值范围为-128~127;a=101+27=128,128表示为1000 0000,作为补码放在内存中,符号位为1,在与int类型的sum进行加计算时会整型提升,高位补1,再转成原码为-128,sum=200+(-128)=72
13、假设C语言程序里使用 malloc 申请了内存,但是没有 free 掉,那么当该进程被kill之后,操作系统会( )
正确答案:D
A: 内存泄露 B: segmentation fault C: core dump D: 以上都不对
不管用户程序怎么用malloc,在进程结束的时候,用户程序开辟的内存空间都将会被回收
14、下面输出结果为
正确答案:A
#include <stdio.h>
#define a 10
void foo();
int main()
{
printf("%d..", a);
foo();
printf("%d", a);
return 0;
}
void foo()
{
#undef a
#define a 50
}
A: 10..10 B: 10..50 C: Error D: 0
define在预处理阶段就把main中的a全部替换为10了。另外,不管是在某个函数内,还是在函数外,define都是从定义开始直到文件结尾,所以如果把foo函数的定义放到main上面的话,则结果会是50…50
15、下面输出结果为
正确答案: B
#include <stdio.h>
typedef struct List_t
{
struct List_t* next;
struct List_t* prev;
char data[0];
}list_t;
int main()
{
printf("%d",sizeof(list_t));
return 0;
}
A: 4byte B: 8byte C: 5byte D: 9byte
解析:
题目中的char data[0]或写成char data[],即为柔性数组成员;在计算机结构体大小的时候data不占用struct的空间,只是作为一个符号地址存在。因此sizeof的值是两个指针所占字节,即4+4=8字节(默认是在32位下)
16、假设函数原型和变量说明如下,则调用合法的是( )
正确答案:C
void f(int **p);
int a[4]={1,2,3,4};
int b[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};
int *q[3]={b[0],b[1],b[2]};
A: f(a); B: f(b); C: f(q); D: f(&a);
解析:
A选项,f(a)传参时,a会退化成指向其首元素的地址,类型是 int*,不符。
B选项,b是二维数组,传参时会退化成指向其首元素的指针,也就是b[0]的地址,b[0]的类型是int [4],故&b[0]类型是int()[4],不符。
D选项,&a是数组a的地址,其类型是int()[4],不符。
C选项,q是一个指针数组,在初始化时用b[0]、b[1]、b[2], 此时b[0]、b[1]、b[2]会退化成指向各首元素的指针(int* 类型,因此类型符合,可以用它们初始化)。q传参时,退化成指向其首元素的指针,即 int**
17、关于to_string用法:
void test()
{
int cnt;
cin >> cnt;
cout << cnt + '0' << " " << to_string(cnt) << endl;
string s1;
s1+=cnt + '0';
string s2;
s2 += to_string(cnt);
cout << s1 << " " << s2 << endl;
}
当我们输入2的时候
输入10的时候
易知to_string比+'0'更加好,尤其是转化不是单位的数字为字符时
18、下列程序会输出什么()
正确答案:14
#include<stdio.h>
#define Mul(x,y) ++x*++y
int main()
{
int a = 1;
int b = 2;
int c = 3;
printf(“%d”,Mul(a+b,b+c));
return 0;
}
解析:
Mul(a+b,b+c)经过宏替换变成++a+b*++b+c,需要注意宏替换的原则,是不会凭空加括号的。另外++优先级大于*,因此会先++a 和++b,然后a=2,b=3进行a+b*b+c=2+3*3+3=14