C语言算法
Posted jienow
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言算法相关的知识,希望对你有一定的参考价值。
错题详解
int main()
{
int i = 0;
int arr[10] = { 0,1,2,3,4,5,6,7,8,9 };
for (i = 0;i <= 12;i++)
{
arr[i] = 0;
printf("hehe\\n");
}
return 0;
}
错误原因:数组地址指向了数组的外面
无限循环的原因:i创建在了arr的高位,arr往高位读取,将i里面的数字修改成了0,重新开始
数据存放在内存中时,是先放在高地址中,在往低地址中存放
然而数据读取,是从低地址往高地址中读取
vs2019在这个数组和变量的地址中间隔了2隔空地址
自己写一个strcpy(究极简化版)
#include<assert.h>
char my_strcpy(char* arr1,const char* arr2)
{
assert(arr1 != NULL);//断言
assert(arr2 != NULL);//判断如果括号里面的是真,就执行下面,不然会报错,直接打印到界面里面
int* ret = arr1;
while (*arr1++ = *arr2++)//当传过去/0的时候while判断括号里面都是假所以跳出
{
;
}
return ret;
}
int main()
{
char arr1[20] = "*********";
char arr2[] = "hello";
my_strcpy(arr1, arr2);
printf("%s\\n", arr1);
return 0;
}
const的使用
语法使用
int main()
{
const int m = 10;//这里相当于把门封上了,但是靠地址可以空降到地方进行处理
int n = 100;
//int* p = &m;
//const int* p = &m;//这里是将*p即内容锁死,是内容无法更改
//也可以写成int const* p = &m
//p = &n;
//*p = 0;//err
//int * const p = &m;//这里是将p即地址锁死,使地址无法更改无法更改
//p = &n;//err
//*p = 0;
//int const* const p = &m;//这样也可以写,两个都没法改
printf("%d\\n", m);
return 0;
}
自己的理解
int main()
{
int m = 10;
int n = 100;
const int* p = &m;
p = &n;//这里还是被改了只想的地方被改,内容会被改,但是直接更改内容还是不行
printf("%d\\n", *p);
return 0;
}
实现strlen
#include<assert.h>
unsigned int my_strlen(const char* a)
{
assert(a != NULL);//断言的是空指针,而不是指针的内容
unsigned int count = 0;
while (*a++ != \\0)
{
count++;
}
return count;
}
int main()
{
char a[20] = "123";
int i=my_strlen(a);
printf("%d\\n", i);
return 0;
}
实现assert
void my_assert(char* input)
{
if (0==input)
{
printf("此条件不成立\\n");
}
}
int main()
{
int a = 0, b = 0;
int* i = a + b;
my_assert(i);
return 0;
}
奇怪的题
1、++和括号的优先级
int main()
{
int a = 0, b = 1, c = 0;
b = (++c,c++,++a, a++);//b=1,a=2;把括号去掉的话,会把c也加上
printf("%d %d\\n", a, b);//这里输出2 1
return 0;
}
int main()
{
int a = 0, b = 1, c = 0;
b = ++c,c++,++a, a++;//b=1,a=2;把括号去掉的话,会把c也加上
printf("%d %d\\n", a, b);//这里输出2 3
return 0;
}
2、+=和+的优先级
int main()
{
int i = 10;
int j = 30;
int k = 3;
k *= i + j;//+优先级大于*=
//等于k *= (i + j);
printf("%d\\n", k);
return 0;
}
3、特殊语法和类型提升
int main()
{
/*int x = 123;
if (x = 0)//这里判定为假
{
printf("123");
}*/
//int year = 2021, * p = &year;
////等同于
//int year = 2021;
//int* p = &year;
char a;int b;float c;double d;
a* b + c - d;
//这里的结果类型是double
//a会先整型提升为int,a*b的类型会提升为double,再减去float,最后的结果还会是double
return 0;
}
用按位与来求,二进制有多少个1
int number1(int n)
{
int count = 0;
while (n)
{
n = n & (n - 1);
count++;
}
return count;
}
int main()
{
int n = 15;
int ret = number1(n);
printf("%d\\n", ret);
return 0;
}
解释
m 1111
m-1 1110
m 1110
m-1 1101
m 1100
m-1 1011
m 1000
m-1 0111
m 0000
这个算法会让m的二进制最右面的1消掉
看m和n中二进制各个位不一样的有多少
思路:1、先按位异或 2、在看结果有多少1
int number2(int n, int m)
{
int i = n ^ m;
int count = 0;
while (i)
{
i = i & (i - 1);
count++;
}
return count;
}
int main()
{
int m = 1;
int n = 0;
int ret = number2(n, m);
printf("%d\\n", ret);
return 0;
}
思路:用%2/2的方式
int number3(int n)
{
int count = 0;
while (n)
{
if (1 == n % 2)
{
count++;
}
n = n / 2;
}
return count;
}
int main()
{
int m = 15;
int ret = number3(m);
printf("%d\\n", ret);
return 0;
}
输入一个数,将他的二进制的奇数位和偶数位分别打印
int main()
{
int n = 15;
int i = 0;
//scanf_s("%d", &n);
//00000000 00000000 00000000 00001111
// 0000000 00000000 00000000 00001111
//从右向左的判别是否是偶数
//偶数
for (i = 31;i >= 1;i -= 2)
{
printf("%d ", (n >> i) & 1);
//在最后向右移动1位就是最开始从右向左的第二位,即第一个偶数位
}
printf("\\n");
for (i =30;i >= 0;i -= 2)
{
printf("%d ", (n >> i) & 1);
}
return 0;
}
全局变量与局部变量遵从金字塔逻辑
即同级与同级之间没有联系,某一级只和他的上一级和下一级有联系
int a = 1;
void text()
{
int a = 2;
a += 1;
}
int main()
{
text();
printf("%d\\n", a);
return 0;
}
以上是关于C语言算法的主要内容,如果未能解决你的问题,请参考以下文章
我的C语言学习进阶之旅解决 Visual Studio 2019 报错:错误 C4996 ‘fscanf‘: This function or variable may be unsafe.(代码片段
我的C语言学习进阶之旅解决 Visual Studio 2019 报错:错误 C4996 ‘fscanf‘: This function or variable may be unsafe.(代码片段