1.while(true) while(false)
/*===============================================
* 文件名称:1_while.c
* 创 建 者:
* 创建日期:2022年04月11日
* 描 述:
================================================*/
#include <stdio.h>
int main(int argc, char *argv[])
{
int t=0;
while(printf("*"))
{
t++;
if(t<3)
break;
}
printf("%d\n",t);
return 0;
}
root@ubuntu:/C# ./a.out
*1
//打印 * 号,成功执行循环体内语句,失败不执行
/*===============================================
* 文件名称:1_while.c
* 创 建 者:
* 创建日期:2022年04月11日
* 描 述:
================================================*/
#include <stdio.h>
int main(int argc, char *argv[])
{
int t = 'E';
int m = 'A';
while(!t) // while(!E)
{
t++;
}
printf("%d\n",t);
printf("%d\n",m);
return 0;
}
root@ubuntu:/C# ./a.out
69
65
//字符为小整数 while(!E); 等价于 while(!1);
/*===============================================
* 文件名称:1_while.c
* 创 建 者:
* 创建日期:2022年04月11日
* 描 述:
================================================*/
#include <stdio.h>
int main(int argc, char *argv[])
{
int a=1,b=2,c=2;
while(a<b<c) //多次循环
{
int t=a;
a=b;
b=t;
c--;
}
printf("%d,%d,%d\n",a,b,c);
return 0;
}
root@ubuntu:/C# ./a.out
1,2,0
// a<b<c 先比较a<b,true,为1,然后比较 1<c,true,a、b交换,然后继续比较第二轮。
2.若已有定义:float x;,则下列对指针变量p进行定义且赋初值的语句中,正确的是( D )。
A) float *p=1024;
B) int *p=(float)x;
C) float p=&x;
D) float *p=&x;
3.以下叙述中正确的是(C)
A)如果p是指针变量,则&p;是不合法的表达式
B)如果p是指针变量,则*p表示变量p的地址值
C)在对指针进行加、减算术运算时,需要考虑指针所指的类型才能确定具体偏移量
D)如果p是指针变量,则*p+1和*(p+1)的效果是一样的
注意:这是对单个指针操作,两个指针相减是没有意义的
4.设有定义:char p[]={’1’,’2’,’3’},*q=p; ,以下不能计算出一个char型数据所占字节数的表
达式是( A )
A)sizeof(p) B)sizeof(char) C) sizeof(*q) D)sizeof(p[0])
sizeof(a)/sizeof(a[0]) sizeof(a[0])/sizeof(int) sizeof(a)/sizeof(int)二维
注意:这是计算char型数据所占字节数,不是求char型数据所占元素个数
* 和 [] 都是一维的,某些时候可以相互替换 ,这里sizeof(*q)等价sizeof(p[0])等价sizeof(char)
5.若有定义语句:int a[2][3],*p[3]; ,则以下语句中正确的是(C )
A)p=a; B)p[0]=a; C) p[0]=&a[1][2]; D)p[1]=&a;
维度:p,a二维 二维数组、指针数组(数组存放指针)
p:数组名,常量
6.以下叙述中正确的是( D )
A)预处理命令行必须位于源文件的开头
B)在源文件的一行上可以有多条预处理命令
C)宏名必须用大写字母表示 (推荐)
D)宏替换不占用程序的运行时间 宏替换是在预处理的时候占用的是编译的时间,不占用运行时间。
①预处理指令是指在程序正式编译前就由编译器进行的操作,可放在程序中任何位置。 预处理是C语言的一个重要功能,它由预处理程序负责完成。 当对一个源文件进行编译时,系统将自动引用预处理程序对源程序中的预处理部分作处理,处理完毕自动进入对源程序的编译
②预处理:展开头文件、宏替换、去掉注释、条件编译
③编译:检查语法,生成汇编 -S
④汇编:汇编代码转换成机器码 -C
⑤链接:链接在一起生成可执行文件a.out(动态、静态链接库)
编译阶段的四步:预处理、编译、汇编、链接
7.C语言规定,程序中各函数之间 【 A 】
A) 既允许直接递归调用也允许间接递归调用
B) 不允许直接递归调用也不允许间接递归调用
C) 允许直接递归调用不允许间接递归调用
D) 不允许直接递归调用允许间接递归调用
8.sizeof(float)是【 C 】
A) 一种函数调用 B) 一个不合法的表示形式
C) 一个整型表达式 D) 一个浮点表达式
9. 对于基类型相同的两个指针变量之间,不能进行的运算是 【C 】
A) < B) = C) + D) -
10.已有定义int k=2;int *ptr1,*ptr2;且ptr1和ptr2均已指向变量k,下面不能正确执行的赋值语句是【 B 】 。
A)k=*ptr1+*ptr2 B)ptr2=k C)ptr1=ptr2 D)k=*ptr1*(*ptr2)
11. 注意字符串常量区
void fun(char* str1, char* str2)
{
static char buffer[21];
strncpy(buffer, str1, 10);
strncat(buffer, str2, 10);
*str1 = *str2;
str1 = buffer;}
main()
{
char *str1="ABC\n";
char *str2="BCD\n";
fun(str1, str2);
printf(str1);
printf(str2);
}
程序运行结果是 Segmentation fault (core dumped)
12. 强转过后求字节
main()
{
short *p, *q;
short ar[10]={0};
p = q = ar;
p++;
printf("%5d", p-q);
printf("%5d", (char*)p - (char*)q);
printf("%5d", sizeof(ar)/sizeof(*ar)); 20/2
}
假设sizeof(short)==2
程序运行结果是 1 2 10
13. 注意逗号表达式 函数指针变量
int sub(int a, int b)
{
return a-b;
}
main()
{
typedef int (*SUB)(int, int);
SUB psub=sub;
/* psub++; */
printf("%d", psub(10,(10,5)));
}运行结果 5
如果将中间注释掉的语句加上, 编译为什么会报错?
因为 typedef int (*SUB)(int,int)是将SUB这个指针指向这个函数,push是用来指向函数的入口地址,而函数是独立不连续的,因此不能用psub++来指向下一个函数的入口地址,也找不到下一个函数的入口地址。push++ 移动八个字节
14. 注意指针指向
main()
{
char* pstrar[3];
int i;
for(i=1; i<3; i++)
{
pstrar[i]=" "; //指向同一片空间
}
strcpy(pstrar[1], "你好");
/* strcpy(pstrar[0], "世界"); */
printf(pstrar[2]);
}
假设编译器设置字符串常量为可读写,则程序结果是__你好__正常情况下Segmentation fault (core dumped)
为什么说注释掉的程序语句是不正确的?
因为pstrar[0]这个指针没有指向,是一个野指针,等价于 *p = 15;
15. 注意变量范围
main()
{
char *p1,*p2;
{
char* pchar;
char charar[] = "你好,世界";
pchar = "Hello,World!";
}p1 = pchar;
p2 = charar;
printf(p1);
printf(p2);
}
说出此程序的错误之处?最里面那个括号是局部变量,生命周期仅在那括号内,不能在拿在外面使用,static除外
16. putchar() : 放入一个字符 指针数组:存放首地址
main()
{
int i;
char **p;
int msg[16]={0x40, 0x41, -1, 0x00, 0x01, -1, 0x12, -1, 0x20, 0x27, 0x41, 0x35, -1, 0x51, 0x12, 0x04};
char* strar[]={"bejing", "shanghai", "guangzhou", "guangdong", "Tokyo", "American"};
char* (*pstrar)[6]; //指针数组指针,一个二级指针
//一个指针指向一个指向数组的指针
pstrar = &strar;
p = strar;
for(i=0; i<16; i++)
{
if(msg[i] == -1){
putchar(' ');
continue;
}else if(msg[i]&0xF0 == 0x40){
putchar(p[msg[i]>>4][msg[i]&0x0F]);
continue;
}else if(msg[i]&0xF0 == 0x30){
putchar(*(strar[msg[i]>>4]+(msg[i]&0x0F)));
continue;
}else{
putchar(*(*(*pstrar+((msg[i]&0xF0)>>4)+(msg[i]&0x0F)));
}
}
}
此题有故弄玄虚之处,但如理解指针,不难解出.
请问此题的运行结果是__To be a good man__________
17.通过代码使程序跳转到0x10000地址去执行
typedef void (*P)(void);
P p = (P)0x10000;
p();
=====================================================================
在绝对地址0xbfda87a8上写入字符'a'的语句是______.
char *ptr;
ptr = (char *)0xbfda87a8;
*ptr = 'a';
亦或者
*(char *)0xbfda87a8 = 'a';
写上整数100则是:*(int *)0xbfda87a8 = 100;
18. int a[5] = {1,2,3,4,5};
printf("%d\n", *(int *)((a+1)-1));
printf("%d\n", *((int *)(&a+1)-1));
运行结果是 1 5
19. 下面函数的功能是( A)。
int fun (char*x)
{
char *y=x;
while(*y++);
return(y-x-1);
}
[A] 求字符串的长度
[B] 比较两个字符串的大小
[C] 将字符串x复制到字符串y
[D] 将字符串x连接到字符串y后面
20. 执行下面语句后的输出结果为( D)。 if无花括号的范围
int i = -1;
if (i < =0)
printf(“****\n”);
i = 2;
else
printf(“%%%%\n”);
[A] **** [B] %% [C] %%%% [D] 有语法错误。不能正确执行
21. 下述程序的输出结果是( C)。
int main(void)
{
int Y=100;
while(Y--);
printf(“Y=%d”,Y);
}
7 #include <stdio.h> 8 9 int main(int argc, char *argv[]) 10 { 11 int Y=100; 12 while(Y--); 13 14 // while(Y){ 15 // Y--; 16 // }这里Y=0,侧面可以说明while(Y--);在Y=0过后, 还减了一次 17 printf("Y=%d\n",Y); 18 return 0; 19 } root@ubuntu:/mnt/U_share/caogao# gcc while_.c root@ubuntu:/mnt/U_share/caogao# ./a.out Y=-1 7 #include <stdio.h> 8 9 int main(int argc, char *argv[]) 10 { 11 int Y=100; 12 // while(Y--); 13 14 while(Y){ 15 Y--; 16 } 17 //这里Y=0,侧面可以说明while(Y--);在Y=0过后,还减> 了一次 18 printf("Y=%d\n",Y); 19 return 0; 20 } root@ubuntu:/mnt/U_share/caogao# gcc while_.c root@ubuntu:/mnt/U_share/caogao# ./a.out Y=0
[A] Y=0 [B] Y=1 [C] Y=-1 [D] Y=随机数
22.下述程序第二次的输出结果为( B )
int main(void)
{
extern int a;
int b=0;
static int c;
a+=3;
other();
b+=3;other();
}
int a=5;other()
{
int b=3;
static int c=2;
a+=5; b+=5; c+=5;printf("%d,%d,%d\n",a,b,c);
c=b;
}[A] 13,0,13 [B] 18,8,13 [C] 13,8,13 [D] 18,8,0
注意考虑销毁,亦或者变量存储区域
简述static 和 extern的区别
static全局变量:生命周期为本文件,存放在全局变量(BSS、data)区,初始化默认为0,不能被extern引入
static局部变量:生命周期为本文件,且初始化为静态变量,只是作用域为函数内部
extern:可以引用其他文件的变量,不过要事先声明
23. 下述程序输出结果为 ( D )
int main (int argc, char *argv[])
{
int a[ ][2] = {(1,2),(3,4),(5,6)}; 2 4 6 0
int *p = a[0];
printf("%d\n",p[0]); 2
printf("%d\n", p[1]); 4
printf("%d\n", sizeof(a)); 4*4=16
return 0;
}
[A] 1,2,12 [B] 1,2,24
[C] 1,3,24 [D] 2,4,16
逗号运算符
24. Shell是一个命令编译器,将用户命令编译成二进制程序,交给操作系统执行。( 错 )
Shell是一个命令行解释器,没有编译,直接运行
25.在默认情况下,所定义的Shell变量的作用域是局部有效。( 错 )
Shell变量的作用域可以分为三种:
有的变量可以在当前Shell会话中使用,这叫做全局变量(globalvariable);
有的变量只能在函数内部使用,这叫做局部变量(localvariable);需要用 function 改变
而有的变量还可以在其它 Shell 中使用,这叫做环境变量(environmentvariable)。
linux shell变量作用域,Shell变量的作用域:Shell全局变量、环境变量和局部变量_Yuki酱酱的博客-CSDN博客
26. 网络ip地址,分为主机号+网络号两部分。( 错 )反过来才行
27.若有以下定义和语句, 时刻注意指针的指向
则*p[0]引用的是a数组元素中的( a[0] ),
*(p[1]+1)引用的是a数组元素中的( a[3] ). int *(p[1]+1)指p[1]偏移4个字节《=》p[1][1]
int *p[3], a[6], i;
for( i = 0; i < 3; i++)
p[i] = &a[2*i]; ==>p[0]=a[0],p[1]=a[2],p[2]=a[4]
28.下述程序运行的结果为( ). 0x100w或者0x200w 0x01000000 0x02000000
int main(int argc, char *argv[]) 整型地址+1=》移2位(16进制)
{
int buff[] = {1, 2};
int *p = buff;
printf("%x\n", *(int *)((int)p + 1)); 地址p先强转位int整数,后+1,再强转成指针,最后*求值
return 0;
} //十六进制的地址=》整数值=》十六进制的地址 //0x112233 高位:11 低位:33
本题考查的是大小端存储
大端存储:高位存低地址
小端存储:高位存高地址
小端(用16进制):(高位)00 00 00 02(低) (高)00 00 00 01(低位) p指向01,p+1:向前移动一个格子(两个十六进制位),即 02 00 00 00,也就是0x200w
数组低位开始,也就是先存1,再存2,依次类推
大端(用16进制):(高位)20 00 00 00 10 00 00 00(低位) p指向20,p+1:向后移动一个格子,即 00 00 00 10,这时候请注意,要从右向左看,也就是0x100w
为什么移动一个格子呢?
因为 0000 0001 等价 0x01,也就是四个字节一个十六进制位
=====================================================================
int main() //258: 0000 0000 0000 0000 0000 0001 0000 0010 { int x=258; char *p = (char *)&x; printf("%d ",*p); printf("%d ",*(++p)); } //程序结果:2,1或者0,0 大小端
29.int (*s[10])(int) 表示的是什么 int型的函数指针数组
30. 给定结构struct A
{
char t:4; 位域运算符 32位机 占四个二进制位
char k:4;
unsigned short i:8;
unsigned long m; 总共6个字节,字节对齐
}; 问sizeof(A) = 8
31. void func(char buf[100]){ ...... },请问 sizeof(func) = 4或者8 错误 ,正确显示为1
函数名的所占字节数,是一个地址,但是函数体内无语句,也就没有开辟空间,导致结果
运行显示为1,因为只是函数名,结构体内为空,也就是没开辟空间,输出1表示占位符,实际上是0
struct a{}; sizeof(a) = 0; 结构体不一样,编译器会认为结构体里面没有东西,所以是直接显示为0
32.下面程序段的运行结果是 C //机器人思想,一步一步跟着走,切记非熟跳过
7 #include <stdio.h> 8 9 int main(int argc, char *argv[]) 10 { 11 int n=2; 12 while(n++<=2); 13 printf("%d\n",n); 14 return 0; 15 }
A) 2 B)3 C)4 D)语法错误
33. 下面程序的功能是在输入一批正整数中求出最大者,输入0结束循环,请选择填空
7 #include <stdio.h> 8 9 int main(int argc, char *argv[]) 10 { 11 int a,max=0; 12 scanf("%d",&a); 13 while(____){ // a 14 if(max<a) 15 max=a; 16 scanf("%d",&a); 17 } 18 printf("max:%d\n",max); 19 return 0; 20 }
A) a==0 B) a C) a==1 D) !a
虽然while循环条件是true和false,但是在比较的时候,不是随便一个非零字符都代表着1,比如说:while(a == c),其结果为false,而while(a),其结果有代表着true.
34.对for(表达式1;;表达式3) 可理解为_____. B,为空则表示所有皆可
A) for(表达式1;0;表达式3) B) for(表达式1;1;表达式3)
C) for(表达式1;null;表达式3) C) 缺少一个表达式
35.以下不是无限循环的语句为____. C 溢出
A)int i=100; while(1){ i = i%100+1; if(i>100) break; } B)for(;;); C)int k=0; do{ ++k; }while(k>=0); D)int s=36; while(s); --s;
36. 区别 for(int i=1;i++<4;)与for(int i=1;i<4;i++)
注意:if(!((i-3)%7))...
break statement not within loop or switch:break只能在循环和switch语句中使用
37.
char *a[3]={"hello","world","china"};
请问a的类型( char **(二级指针) ),以及&a的类型( char * (*) [3](指针数组指针))
int a[10];
请问&a的类型( int (*)[10](数组指针))
a)一个整型数(An integer)
b)一个指向整型数的指针( A pointer to an integer)
c)一个指向指针的的指针,它指向的指针是指向一个整型数( A pointer to a pointer to an intege)
d)一个有10个整型数的数组( An array of 10 integers)
e)一个有10个指针的数组,该指针是指向一个整型数的。(An array of 10 pointers to integers);
f)一个指向有10个整型数数组的指针( A pointer to an array of 10 integers)
g)一个指向函数的指针,该函数有一个整型参数并返回一个整型数(A pointer to a function that takes an integer as an argument and returns an integer)
h)一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型数( An array of ten pointers to functions that take an integer argument and return an integer )
a) int a;
b) int *a;
c) int **a;
d) int a[10];
e) int *a[10];
f) int (*a)[10];
g) int (*a)(int);
h) int (*a[10])(int);
38.
int a[5][5];
int (*p)[4];
p = a;
求: &p[4][2] - &a[4][2]?
思路:
首先需要理解 a[1][1] == *(*(p+1)+1),拓展可得 a[i][j] == *(*(p+i)+j).
其次需要理解 int (*p)[4] 是该表达式表示行指针为 *p ,列数有4列
=====================================================================
a[5][5]:
p[0][0] p[0][1] p[0][2] p[0][3] p[1][0]
p[1][1] p[1][2] p[1][3] p[2][0] p[2][1]
p[2][2] p[2][3] p[3][0] p[3][1] p[3][2]
p[3][3] p[4][0] p[4][1] p[4][2] p[4][3]
p[5][0] p[5][1] p[5][2] p[5][3] p[6][0]
其中:
a[0][0] == *(*(p+0)+0)
a[0][1] == *(*(p+0)+1)
a[0][4] == *(*(p+1)+0)
也可以这样理解:00===================这代表内存中的物理存储空间,其中a和p都指向第一个0,也就是相对对齐,然后各自向后移动,移动完后面的距离便是结果,小减大为负
那么:&p[4][2] == &a[3][3],这样便能转化成 &a[3][3] - &a[4][2] == -4.
规律:
(4 * 4 +3)- (4 * 5 + 3) == 19 - 23 == -4.
亦或者 (4 * 5 -1) - (5 * 5 -2) == -4.
扩展问题:
int a[12][12];
int (*p)[3] = a;
&p[5][1] - &a[3][8]的结果? -28
=====================================================================
39. 32位小端字节序的机器上,如下代码:
void main (void)
{
char array[12]={0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08};
short *pshort=(short *)array;
int *pint=(int *)array;
int64 *pint64=(int64 *)array;
printf("0x%x, 0x%x, 0x%x, 0x%x\n", *pshort, *(pshort+2), *pint64, *(pint+2));
}
输出?
答:0x201, 0x605, 0x4030201, 不确定,如果是*(pint+1)=0x08070605