![](https://img-blog.csdnimg.cn/20201014180756918.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
C语言
菠萝菠萝菠萝葡萄
这个作者很懒,什么都没留下…
展开
-
内存泄漏举例
原创 2021-05-27 15:22:22 · 136 阅读 · 0 评论 -
scanf之后这个49是怎么来的?
已解决:a读进来是字符1,对应ascii表是49原创 2021-05-04 20:48:19 · 79 阅读 · 0 评论 -
动态申请堆区空间
正确void test(int n){ malloc(n);}错误void test2(int n){ new int[n][n];}```正确void test2(int n){new int[n][5];}也就是说必须指定列数原创 2021-04-12 12:25:51 · 110 阅读 · 0 评论 -
内存分区
程序运行前为什么还占用内存?这个一般针对于编译型语言,理论上不占内存,但是程序在被CPU调度执行起来前有个临界状,是需要占用内存,提高程序运行效率原创 2021-03-11 09:42:02 · 49 阅读 · 0 评论 -
野指针产生的原因
野指针产生原因:1.指针变量未初始化任何指针变量刚被创建时不会自动成为NULL指针,它的缺省值是随机的,它会乱指一气。所以,指针变量在创建的同时应当被初始化,要么将指针设置为NULL,要么让它指向合法的内存。2.指针释放后之后未置空有时指针在free或delete后未赋值 NULL,便会使人以为是合法的。别看free和delete的名字(尤其是delete),它们只是把指针所指的内存给释放掉,但并没有把指针本身干掉。此时指针指向的就是“垃圾”内存。释放后的指针应立即将指针置为NULL,防止产生“野指原创 2021-03-11 09:40:10 · 378 阅读 · 0 评论 -
位运算举例
1、将data的第2、3位置1,第5、6为清0,其他位保持不变第一步:将data的第2、3位置1data = data|0000 1100 == data | (0000 1000 | 0000 0100)==data | (0000 0001<| 0000 0001<<2)== data | (0x01<<3 | 0x01<<2)第二步:将data的第5、6为清0data = data & 1001 1111== data & ~(0原创 2021-03-11 09:35:28 · 127 阅读 · 0 评论 -
volatile
用 volatile 定义的变量,是易改变的,即告诉 cpu 每次用 volatile 变量的时候,重新去内存中取 保证用的是最新的值,而不是寄存器中的备份。 volatile 关键字现在较少适用 volatile int a=10;用途:曾用在多线程中突然改变a的值,此时由于太快,while检测不到,会出错,故a在定义时要加volatilewhile(1){ if(a>0) { break; }}...原创 2021-03-11 09:15:33 · 35 阅读 · 0 评论 -
宏编译
参考:https://www.cnblogs.com/the-tops/p/7839803.html原创 2021-03-08 20:46:41 · 2245 阅读 · 0 评论 -
描述一下普通局部变量,普通全局变量,静态局部变量,静态全局变量的区别
项目ValueValueValueValue普通局部变量存在栈区不初始化内容随机只在定义的复合语句中有效复合语句结束变量空间释放普通全局变量存在全局区不初始化内容为0整个进程结束空间释放能被当前源文件或其他源文件使用,其他源文件使用时要加extern静态局部变量存在全局区不初始化内容为0整个进程结束空间释放只能在定义所在的复合语句中有效静态全局变量存在全局区不初始化内容为0整个进程结束空间释放只能在当前源文件中使用...原创 2021-03-08 19:25:57 · 2770 阅读 · 0 评论 -
一维数组冒泡排序及优化
#include <stdio.h>//数组的冒泡排序void my_pop_sort(int* arr,int n){ int i = 0; int j = 0; for(i = 0;i<n-1;i++) { for(j = 0;j<n-i-1;j++) { if(arr[j]>arr[j+1]) { arr[j] ^=原创 2021-03-07 21:02:27 · 117 阅读 · 0 评论 -
一维数组的选择排序及优化
#include <stdio.h>//数组的选择排序void my_select_sort(int* arr ,int n){ int i = 0; int j = 0; for(i = 0;i<n-1;i++) { for(j = i+1;j<n;j++) { if(arr[j]<arr[i]) { arr[j] ^= a原创 2021-03-07 20:47:59 · 293 阅读 · 0 评论 -
const
1.const在*前const char * a : a内容不可修改,指向可修改char const * a:a内容不可修改,指向可修改2.const在 * 后char* const a: a指向不可修改,内容可修改原创 2021-03-02 21:26:27 · 41 阅读 · 1 评论 -
不用sizeof求任意数据类型大小
核心:利用了指针+1即跳过数据类型宏函数不检查参数类型注意:数组名代表数组第一个元素的地址,数组名取地址才代表数组的地址#include <iostream>#define mysizeof(var) (char*)(&var+1)-(char*)&varint mysize(char* a){ return (char*)(a + 1) - (char*)a;}int main(int argc, char* argv[]){原创 2021-03-01 21:49:15 · 489 阅读 · 0 评论 -
递归实现数组求和
#include <iostream>using namespace std;int sum(int ht[], int n){ if (n>0) { return sum(ht, n-1)+ht[n-1]; } else { return 0; }}int main(int argc, char* argv[]){ int arr[4] = { 1,2,4,6 }; int原创 2021-03-01 21:15:02 · 548 阅读 · 0 评论 -
结构体的大小
结构体的对齐规则第一步:确定分配单位(每行开辟多少字节)结构体中最大的基本类型的长度 为分配单位。【#pragma pack (value)时的指定对齐值valuemin(value,最大的基本类型的长度) 为分配单位。】第二步:确定成员的偏移位置。偏移位置:成员自身类型的整数倍(0~n倍)(如果是结构体嵌套结构体,那么结构体成员的偏移位置为结构体成员的最大基本类型的整数倍)第三步:收尾工作:结构体的总大小必须是分配单位的整数倍。参考:https://www.cnblogs.com/原创 2021-02-25 12:16:08 · 92 阅读 · 0 评论 -
用递归判断数组是否递增
参考:https://www.cnblogs.com/cysolo/p/3584059.html注意:该方法巧妙的利用了,数组的长度。递归传参时缩小数组的长度即改变了下标#include<stdio.h>void Judge(int *a, int n){ if (n == 1){ printf("递增"); } if (n != 1) { if (a[n-1] >= a[n - 2]){ Judge(a, n - 1); }原创 2021-02-25 12:00:17 · 263 阅读 · 0 评论 -
逆序字符串
综述:本文提供两种方法,分别为递归,非递归#include <stdio.h>//逆置输出字符串//非递归逆置void reverse_str2(char* p){ char* p1 = p; char* p2 = p; while (*p2) p2++; p2--; while (p1<p2) { //无参交换 *p1 ^= *p2; *p2 ^= *p1; *原创 2021-02-24 19:04:52 · 148 阅读 · 0 评论 -
a++是否改变a的值
#include <stdio.h>#include<stdlib.h>int main() { int a, b, c, d; a = 10; b = a++; c = ++a; d = 10 * a++; printf("b,c,d:%d,%d,%d", b, c, d); return 0;}总结:1.a++在等号右侧会改变a的值2.注意没问最后a=多少,不要马虎...原创 2021-02-24 17:04:44 · 1161 阅读 · 0 评论 -
传递指针实现变量值交换
#include <stdio.h>#include<stdlib.h>void swap1(int* a, int* b){ int* c = a; a = b, b = c;}void swap2(int* a, int* b){ int c = *a; *a = *b, * b = c;}int main() { int a = 10, b = 15; swap1(&a, &b); printf("%d,%d\n", a, b)原创 2021-02-24 16:59:13 · 107 阅读 · 0 评论 -
static在c/c++中的使用
staticValueValueValueValueC修饰全局变量,使之只在当前.c有效。在程序运行中一直存在。默认值为0修饰局部变量:在第一次调用局部变量所在的函数时赋值,函数结束不释放,再次调用不开辟空间不赋值static放在函数返回值前,表示函数为内部函数,仅在当前.c有效-----C++static静态成员:1.静态成员类中声明类外定义2.静态成员不属于对象,在为对象分配空间时不包括静态成员所占空间3.静态成员可以通过类名/对象名来调用static静态成员...原创 2021-02-24 11:33:19 · 103 阅读 · 0 评论 -
const在c和c++中
CONST在c/c++中异同C(待补充,暂认为相同)C++1.修饰普通变量,并以常量初始化时,变量会存放在符号常量表里(属于代码段,不可取地址)2.如果对其取地址,会再为它开辟空间3.以变量初始化则不会放在符号常量表#include <stdio.h>#include<stdlib.h>int main(int argc, char* argv[]){ const int a = 10; printf("a=%d\n",...原创 2021-02-23 09:55:50 · 44 阅读 · 0 评论 -
求n行m列的数组的每行最大值(优化)
要点:1.利用二维数组在物理上是一维的特性,将二维数组使用一级指针传递2.二维数组名是个二级指针思路:每循环m次,跳到max数组下一个元素,再不断更新这个元素。#include <stdio.h>#include<stdlib.h>int* find_max(int* arr, int n, int m){ int i = 0; int j = 0; int* max = (int*)malloc(sizeof(int) * n);原创 2021-02-22 22:09:50 · 941 阅读 · 0 评论 -
求n行m列数组的每行的最大值
求n行m列数组的每行的最大值问题:如何传递行列都不确定的二维数组?int main(int argc, char *argv[]){ int p[3][4]= {1,3,5,7, 2,4,6,8, 8,2,4,6 }; int n = 3; int m = 4; int* max = (int*)malloc(sizeof(int)*n);原创 2021-02-22 17:04:45 · 927 阅读 · 0 评论 -
strcpy自实现
注意:下述未考虑地址重复未考虑NULL要避免可以使用assert#include <stdio.h>char* my_strcpy(char* dest,char* src){ char* tmp = dest; while (*src!=0) *tmp++ = *src++; *tmp=0; return dest;}int main(int argc, char *argv[]){ char arr[100]="hu原创 2021-02-22 16:05:56 · 115 阅读 · 0 评论 -
自实现strcat
注意:下代码未考虑1. 地址重叠2. 指针未NULL#include <stdio.h>char* my_strcat(char* dest,char* src){ //把源字符串追加到目的字符串后 //注意:目的指针所指向的空间要够长 //1.指向目的字符串\0位置 char* tmp = dest; while (*tmp!=0) tmp++; //2.拷贝,直到src到\0 while (*src!原创 2021-02-22 12:01:49 · 117 阅读 · 0 评论 -
(a++) += a错在哪里
1.什么是左值?lvalue 现“l”可解释为 location ,也可理解为一个变量,首先常量肯定不能作为左值那么a++为什么也不能作为左值?简单的回答是:C/C++语言本身规定如此。如果再追问为什么这样规定,可以解释如下:对一个合法的赋值语句(例如a=0),编译程序总是先求出等号右边的值,然后再求出左值的地址并立即把计算出的值赋给该地址。但对于(a++)=0,如果a++可以作为左值,则编译程序求出左值的地址后就不能立即对其进行赋值操作,而是要插入一个加一操作。这就破坏了编译程序在编译不同赋值语原创 2021-02-22 11:12:51 · 708 阅读 · 1 评论 -
有序数组合并优化
#include <stdio.h>void merge_arry(int* arr1,int n1,int* arr2,int n2,int* arr3,int n3){ int i = 0; int j = 0; int k = 0; while (i!=n1 && j!=n2) { if(arr1[i]<arr2[j]) arr3[k++]=arr1[i++]; else原创 2021-02-20 13:44:43 · 91 阅读 · 0 评论 -
合并两个数组使之有序
思路:设两个分别指向两数组的指针,只需比较这两个指针指向得数据,若从小到大排序:小数据的指针+1,并将其放到第三个数组中问题:一个数组到结尾怎么办?将另一个数组按顺序全部放入第三个数组#include <stdio.h>//合并两个有序数组,使之有序void merge_arry(int* arr1,int n1,int* arr2,int n2,int* arr3,int n3)//传递三个数组,前两个为待合并,第三个为合并后{ //思路: //设两个分别指原创 2021-02-20 11:40:41 · 153 阅读 · 0 评论 -
一重循环找数组的次最值
注意事项:数组元素全部相同核心思想:在找出一个更大的值后保存它的当前值#include <stdio.h>//一重循环找数组中第二大的数//注意://1. 数组元素全部相同int find_sec(int* arr,int n){ int i = 1; int max = arr[0]; int sec = 0; int flag = 0; for(i = 1;i<n;i++) { if(max<原创 2021-02-20 11:25:48 · 259 阅读 · 3 评论 -
memcopy手写实现
void my_memcopy(void* dst,void* src,int size){ //考虑几个方面? //1. 可能出现错误不应在这里边判断,出现错误就是段错误 //不过可能出现:访问非法内存,(其实就是源或目的地址越界(非法)) //跟strcpy的区别就是需要一个强转 //2. 地址重叠,目的地址在前没问题,目的地址在后会损失重叠部分的内容 //解决方法:从后向前拷贝 char* pdst; char* psrc;原创 2021-02-19 15:29:16 · 207 阅读 · 0 评论 -
C语言实现简易音乐播放器
注:在显示音乐播放器的图形界面时,根据的是页面的坐标来显示,故在运行时终端的大小应为Xshell全屏时终端的大小。(否则页面会显示的混乱)具体运行效果:原创 2021-02-07 09:54:02 · 7869 阅读 · 0 评论