1.
(1)sizeof(x)表示x所占的字节数,strlen(x)表示x的长度(从第一个字符到第一个结束符之前所占的字节数)
(2)比如”i love linux\0\0\0",sizeof()计算出来是16,strlen()计算出来是12.
2.sizeof(t1) 和sizeof(t2) 虽然排列顺序不同,但是结果都是16.
结构体在为其内部的变量分配内存时,遵循边界对齐原则。边界由结构体中最大数据类型决定。之所以要进行边界对齐,是为了防止有些数据同时占据两个相邻的边界,导致数据总线在访问时要访问两次,提高了工作效率。
3.
void func(int arr[][13])
{
for(int i=0;i<10;i++)
{
for(int j=0;j<13;j++)
printf(" %d ",arr[i][j]);
}
}
4.
(1)传值与传址:函数在调用时只能通过参数传值,这个值可以是常见的想1,2,3一样的数字,当然,也可以是地址。指针之所以能把值传回主函数,正是通过传地址实现的,在这个过程中,地址并不改变,这块地址上存放的数据改变,再次访问这个地址,就可以得到修改后的数据。
(2)局部变量:只存在于声明它的那个函数中,函数调用结束后立即销毁该变量。
静态变量:与局部变量类似,在函数中声明,在函数调用结束之后,该变量不会立即销毁,而是继续存在,但是它只能在声明它的那个函数中被使用。
全局变量:在函数之外声明的变量,作用域为从该变量声明的地方到该程序文件结尾,但是,一旦出现了与其名称相同的本地变量,在该本地变量的作用域内,全局变量的值将被覆盖。
静态全局变量:只能在本文件中被使用的全局变量。
外部全局变量:也可以在其他文件中被引用。
5.sum(n)实现过程为n+(n-1)+......+2+1.
6.对每个变量一步一步分析
short a=-2;
unsigned int b=1;
b+=a;
int c=-1;
unsigned short d=c*250;
c<<=4;
int e=2;
e=-e|5;
d=(d&0xff)+0x2022;
printf("a=0x%hx\tb=0x%x\td=0x%hx\te=0x%x\n",a,b,d,e);
printf("%c=0x%hhx\t\n",(signed char)c);
行数 操作结果(进制)
注:二进制均为补码表示
1 a=-2(10)=1111 1111 1111 1110(2)=fffe(16)
2 b=1(10)
3 b=-1(10) ->1111 1111 1111 1111 1111 1111 1111 1111(2)=ffffffff(16)
4 c=-1(10)
5 d=-250(10) ->1111 1111 0000 0110(2)
6 c=-16(10)=1111 1111 1111 1111 1111 1111 1111 0000(2)=fffffff0(16)
7 e=2(10)
8 e=1111 1111 1111 1111 1111 1111 1111 1111(2)=ffffffff(16)
9 d=0000 0000 0000 0110 + 0010 0000 0010 0010 =0010 0000 0010 1000(2)=2028(16)
所以最后输出a=0xfffe b=0xffffffff d=0x2028 e=0xffffff c=0xf0 (signed char)使c的结果保留1个字节
7.输出结果为10 4 9
8.
(1)func0,func1没有错,func2对指针执行间接访问并企图改变指针指向的对象的值,错误,func3企图将指针指向别处,错误,func4对指针执行间接访问并企图改变指针指向的对象的值,并且企图将指针指向别处,犯了两个错误。
(2)个人认为const int和iint const没有区别
(3)个人认为const int *和iint const *也没有区别
9.大写变小写,小写变大写
char* convert(char*);
int main(void)
{
char *str="XiyouLinux Group 2022";
char *temp=convert(str);
printf("%s",temp);
return 0;
}
char* convert(char* str)
{
int i=0;
char te,aa[100]="\0";
while(te=*(str+i))
{
if(te>='a'&&te<='z')
te-=32;
else if(te>='A'&&te<='Z')
te+=32;
aa[i++]=te;
}
char* p=aa;
return p;
}
10.第一个和第二个swap正确,第三个swap错误。
用宏函数实现的swap更加节省时间,其值在编译时耗费时间,在运行代码时不耗费额外的时间。
do{...}while(0)的作用是只循环一次。
还有其他实现swap的方法,例如
void swap(int* p1,int* p2)
{
int a=*p1;
*p1=*p2;
*p2=a;
}
11,argc表示你在命令行下输入命令的时候,一共有多少个参数。
argv[ ]表示你所输入的参数。
该函数为不用argc输出argv[ ]的方法:
int main(int argc,char *argv[])
{
int i=0;
printf("argc = %d\n",argc);
while(argv[i])
printf("%s\n",argv[i++]);
return 0;
}
12.func3()有错,
静态变量在函数调用结束后不会立即销毁,但其他非全局变量在函数调用结束后会立即销毁。
13.输出为Welcome to xiyou linux group 2021
解释:
每两位16进制数字组成一个Ascil码,表示出一个字符。该计算机存储数据的模式为小端模式,数据的高位存放在高地址上。
14.
(1)预处理阶段。预处理器(cpp)根据字符#开头的命令,修改原始的C程序。
(2)编译阶段。将c语言文件从高级语言转为汇编语言。
(3)汇编阶段。将汇编语言转化为二进制语言。
(4)链接阶段。将使用的头文件与本文件链接起来。
15.栈区内存由编译器自主分配i和释放,堆区内存由程序员手动分配和释放。