目录
while(scanf("%d",&n) != EOF)重复输入,牛客IO题。
一、swap的理解
C语言指针值传递和地址传递_c语言地址传递-CSDN博客https://blog.csdn.net/lanhuazui10/article/details/107144276交换两个数:
发现这样并没有交换a和b的值,只是交换了x和y的值,这是因为:
//当实参传递给形参的时候,形参是实参的一份临时拷贝
//对形参的修改不能改变实参
实参与形参是什么?
实参:真是传递给函数的参数,在进行函数调用时,必须有确切的值;形参:指的是函数名括号中的变量,因为形参只在函数调用的时候才实例化(分配内存单元)。形参在函数调用完成之后就自动销毁(局部变量),因此形参只在函数中才有效。形参实例化之后相当于实参的一份临时拷贝。
那如何交换a和b?
交换方法:
//形参 - 形式参数
//当实参传递给形参的时候,形参是实参的一份临时拷贝
//对形参的修改不能改变实参
void Swap(int* x, int* y)
{
int z = 0;
z = *x;
*x = *y;
*y = z;
}
int main()
{
int a = 0;
int b = 0;
scanf("%d%d", &a, &b);
printf("交换前:a = %d b = %d\n", a, b);
Swap(&a, &b);//实参
printf("交换后:a = %d b = %d\n", a, b);
return 0;
}
注意:int*接收int,int**接收int*
但是为什么下面这种不用传地址?见调试图:,ret会临时拷贝到寄存器中,再返回,所以对于内存是否销毁释放无关。
扩展:printf函数:
注意:printf函数的返回值是:
返回值
如果成功,则返回写入的字符总数,否则返回一个负数。
int main()
{
printf("%d\n", 43);//43
printf("%d", printf("%d", printf("%d", 43)));
/*当执行最外层的printf的时候,其打印内容是printf("%d",43)的返回值,
而在最外层printf函数得到printf("%d",43)的返回值之前,会先执行printf("%d",43)
也就是会先打印 43
43共2个字符,所以printf("%d",43)返回整型2*/
//printf函数返回值返回的是打印的字符的个数
return 0;
}
特别注意的是:printf函数处理方式 从右至左
二、函数递归
求5的阶乘
/*利用递归函数实现5!*/
/*
5! = 5*4*3*2*1
5! = 5*4!
4! = 4*3!
3! = 3*2!
2! = 2*1!
*/
int fac(int num)//fac(4)//fac(3)//fac(2)//fac(1)
{
if (num == 0 || num == 1)
{
return num;//return 1//即fac(1)的结果是1,递归完开始返回//
}
else
{
return num * fac(num - 1);//5*fac(4)
//4*fac(3)
//3*fac(2)
//2*fac(1)
//之前没走完的函数接着走,返回2*1 = 2
//返回3*2
//返回4*3*2
//返回5*4*3*2
}
}//当fac(1)返回值后到了这里,fac(1) == 1
int main()
{
int ret = fac(5);
printf("%d\n", ret);
return 0;
}
三、数组赋值注意事项
去除数组中的重复数字:(必须使用qsort)直接结合的力扣的题
#include<stdio.h>
#include<assert.h>
int removeDuplicates(int* nums, int numsSize)
{
assert(nums);
if (numsSize == 0)
{
return 0;
}
int slow = 0;
for (int fast = 0; fast < numsSize - 1; fast++)
{
if (nums[fast] != nums[fast + 1])
{
slow++;
nums[slow] = nums[fast + 1];
}
}
return slow + 1;
}
int cmp(const void* a, const void* b)
{
return *(int*)a - *(int*)b;
}
int main(int argc,const char* argv[])
{
int arr[] = { 1,1,2,2,2,3,3,4,4,5,5,5,2,5,6,1,3,2 };
int sz = sizeof(arr) / sizeof(arr[0]);
qsort(arr, sz, sizeof(int), cmp);
int ret = removeDuplicates(arr, sz);
int i = 0;
for (i = 0; i < ret; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
通过赋初值的方式给一维字符数组赋字符串
1、用给一般数组赋初值的相同方式给一维字符组赋初值
char str[10]={‘s’,‘t’,‘r’,‘i’,‘i’,‘n’,‘j’,’\0’}
字符数组str共有10个元素,但str作为字符串,其长度为7,虽然最后一个字符是‘\0’,但它并不是结束标识因为系统会自动的给其分配一个结束标识。
2、在赋值时直接赋字符串常量
char str[10]={“string”};
习惯上省略花括号
char str[10]=“string!”(这种方式会自动给字符串的末尾添加结束标识,但需要注意的是字符串数组的长度一定要比赋值的长度多一个)
注意:长度是存在区别的
用一维字符数组存放字符串-CSDN博客https://blog.csdn.net/m0_46170663/article/details/104295429
注意下图情况的数组分布:所以数组中必须确定的是列数
扩展:数组名的注意事项
数组名表示首元素的地址,但是有两个例外:
1.sizeof(数组名),这个数组名表示整个数组
2.&数组名,这个数组名也表示整个数组,取出的是整个数组的地址