1.
结果:16 12
sizeof是运算符,计算的是你使用的操作数所占的空间字节大小,包括’\0’,而strlen是函数,计算的是字符串的长度,遇到’\0’就停止不包括’\0’。
2.
结果:16 16
结构体struct
各成员各自拥有自己的内存,遵循内存对齐原则
1.第一个成员在结构体变量偏移量为0的地址处
2.其他成员变量要对齐到对齐数的整数倍的地址处
对齐数=编译器默认的一个对齐数与该成员大小中的较小值。Linux中的默认值为4.
3.结构体总大小为最大对齐数的整数倍。
3.
二维数组传参三种方法
void func(int i,int n,int arr[][13]);
void func(int i,int n,int (*arr)[13]);
void func(int i,int n,int **arr);
4.
传值
是把实参的值赋值给行参,相当于copy。对形参的修改,不会影响实参的值。
传址
是传递的地址,不是普通的赋值,传地址以后,实参和形参都指向同一个对象。对形参的修改会影响到实参。
总而言之,传值不影响实参,传址会影响实参的改变
#include<stdio.h>
int ver=123;
void func1(int ver)
{
ver++;
printf("ver=%d\n",ver);//1026
}
void func2(int*pr)//把ver的地址给指针pr
{
*pr=1234;//在此函数内部修改pr指向地址中的值
printf("*pr=%d\n",*pr);//1234(传址)
pr=5678;//警告:直接把int型常量赋值给了地址
printf("ver=%d\n",ver);//123
}
int main()
{
int a=0;//局部变量
int ver=1025;//局部变量
for(int a=3;a<4;a++)
{
static int a=5;//静态局部变量(仅在此循环中起作用)
printf("a=%d\n",a);//5
a=ver;
printf("a=%d\n",a);//1025
func1(ver);
int ver=7;//仅在此循环中起作用
printf("ver=%d\n",ver);//7
func2(&ver);
}
printf("a=%d\tver=%d\n",a,ver);//0 1025(局部会覆盖全局变量)
return 0;
}
5.
结果:5050
条件运算符 表达式1?表达式2:表达式3 如果表达式1的值为真,则求解表达式2,表达式为假,则求解表达式3
本题利用递归 当n不为0时不停的返回sum(n-1)调用自己完成1~100的求和
6.
结果:
e=~e|6;
优先级:取反>左移>按位与>按位异或>按位或
了解具体参考本人上一篇博客
%hx->short 类型 %hhx->short short 类型
7.
结果:10 4 9
分析:b是一个指向数组的指针;b+1是说指向a的第二行开头地址;b[1] [1] =10那么此时b[1]指的是a的最后一行,是把最后一行的第二个数字值变为10;&a是指向a的整个数组,&a+1就是指向下一个数组。
对于初始C语言的大家来说可能会把a和&a搞不清楚,我来解释下
a指的是数组首元素的地址
a+1是数组下一个元素的地址
&a指的是整个数组的地址
&a+1是下一个数组的首地址
**(a+1):相当于a[1][0],代表的是数组a的第二行的首元素4
*(ptr-1):是对整个数组的下一个数组-1,得到了上一个数组a的最后一个元素9
8.
const int和int const 一样,都代表int类型的变量不能修改
const int*和int const *一样,都代表指针指向的值不能被修改
代码中错误的是(func2,func3,func4)
与2022年的第6题考察点一样
void func2(const int *n)//const在*n前表示不可修改指针n所指向的值
{
*n+=1;//不能向只读形参赋值
n=&a;
}
void func3(int*const n)//在n前表示不可修改指针n指向的地址
{
*n+=1;
n=&a;//不能向只读指针赋值
}
void func4(const int *const n)
{
*n+=1;//不能向只读形参赋值
n=&a;//不能向只读指针赋值
}
9.
char* convert(const char* s)
{
char* pa = (char*)calloc(40, sizeof(char));//在函数中分配一段空间
int l = strlen(s);
for (int i = 0; s[i]; i++)
{
if (s[i] >= 'a' && s[i] <= 'z')
{
pa[i] = toupper(s[i]);
}
else if (s[i] >= 'A' && s[i] <= 'Z')
{
pa[i] = tolower(s[i]);
}
else
{
pa[i] = s[i];
}
}
}
pa[l] = '\0';
return pa;
}
10.
①swap1直接从原函数中传递参数,方便
②swap2是创建了一个变量t,用来交换,占用内存小
③swap3是错误的。它只是改变了变量a,b的值,并没有传地址,仅仅是在函数体内部改变了a,b的值,相当于没有对a,b做任何操作,函数运行后a,b的值不会发生改变。
④do{ , , ,}while(0)让循环只做了一次交换值
⑤实现交换方法
//传地址
void Swap(int* a,int* b)
{
int t=*a;
*a=*b;
*b=t;
}
//定义一个中间变量
int t=0;
t=a;a=b;b=t;
//简单的数学方法
a=a+b;
b=a-b;
a=a-b;
//用异或进行运算,相同为0,不同为1
a^=b;
b^=a;
a^=b;
11.
1.argc是参数的个数,argv为指针数组的首元素
2.当argv指针不为空时会一直遍历
int main(int argc, char*argv[])
{
int i=0;
while(argv[i]!=NULL)
printf("%s\n",argv[i++]);
return 0;
}
12.
#include<stdio.h>
#include<stdlib.h>
int *func1(void)
{
static int n=0;//静态变量的作用时间是从调用它开始到本函数结束
n=1;
return &n;//只能返回指针值也就是n的地址,因为静态变量的值一直保存,且地址一直存在
}
int *func2(void)
{
int*p=(int*)malloc(sizeof(int));
*p=3;
return p;//返回指向新分配内存的首地址
}
//3错误
int *func3(void)
{
int n=4;
return n;//不可返回局部变量的地址(&n),作用完就被释放了,相当于返回一个野指针
}
13.
结果:Welcome to xiyou linux group 2021
参考2022年12 题添加链接描述
14.
C语言文件到可执行文件