一.C基础
1.static
static | |
修饰及作用域 | 全局和函数(本文件)局变(本含数) |
生命周期 | 变量 ( 全局) |
存放位置 | 变量(静态区) |
初始化 | 变量(无则0),初始化只能一次 |
2.const
const(常量化) | |
修饰 | 变量,指针 |
作用 | 常量化,位置不同,指针指向不同 |
3.typedef和define
typedef(关键字) | define(预处理指令) | |
定义位置及作用 | 全局 函数 别名 | 全局 宏定义 |
时间 | 编译阶段 | 预处理阶段 |
作用域 | 作用域内有效 | 全局 |
定义格式 | ~ old new | ~ replace old |
类型安全 | 别名安全 | 文本替换 |
场景 | 复杂类型 | 常量或函数宏 |
4.枚举(enum)
多个宏定义的集合,成员系统会自动赋初值,0~N。
5.volatile和Extern
volatile:关键字,用于在 C 和 C++ 中修饰变量,编译器该变量的值可能在程序执行期间发生变化,从而禁止编译器对该变量进行优化。
Extern:引用其他文件中的全局变量或函数。
6.数组和链表
数组 | 链表 | |
定义 | 相同类型的数据集合 | 有相同数据类型的有序集合 |
访问 | 索引随机访问 | 不允许随机访问,指针访问 |
存储 | 内存连续 | 内存不连续 |
内存分配 | 静态分配(编译器) | 动态分配(运行期) |
大小 | 初始化和声明指定 | 随元素的插入或删除动态变化 |
7.指针的理解
指针就是地址
指针数组:本质是数组,存放指针
数组指针:本质是指针,指向数组
8.结构体和共用体
结构体:实现C语言面向对象,成元注意字节对齐
在32位系统下,最大字节对齐数为4,计算出结构体所占空间成员最大值,然后与最大对齐数比较。按照小的字节数对齐。
结构体成员进行字节对齐是遵循最大对齐数的对齐规则,如果成员中存在double数据类型成员,按照4个字节倍数进行对齐。
共用体:联合体,所有成员共享内存空间,大小为成员中占内存最大的那个。
9.堆和栈的区别
栈区 | 堆区 | |
管理方式 | 编译器自动分配 | 程序员手动 开辟 释放 |
空间大小 | 低地址扩展,连续 | 高地址扩展,不连续 |
是否产生碎片 | 不会 | 会 |
增长方向 | 向下 | 向上 |
10.全局变量和局部变量
全局变量 | 局部变量 | |
定义位置 | 函数体外部 | 函数体内部 |
存储位置 | 全局区 | 栈区 |
生命周期 | 整个程序 | 函数结束 |
作用域 | 全局 | 函数体内部 |
11.memcpy和strcpy的区别
memcpy | strcpy | |
拷贝内容 | 指定任意数据大小字符串,不检测‘\0’ | 拷贝第一个‘\0’结束的字符串 |
参数 | 目标,源,拷贝字节数 | 目标,源 |
安全性 | 目标不够,溢出 | 目标不够,溢出,自动添加‘\0’ |
性能 | 拷贝大数据高效 | 拷贝长字符串性能差 |
12.段错误,怎么解决
段错误:空指针访问,数组越界,非法内存访问,访问只读内存写操作
解决:检查空指针,检查数组越界,动态内存管理,避免只读内存写操作,使用工具检查。
13.什么是内存泄露
开辟内内存使用后没有及时释放,导致内存堆积,系统崩溃。
野指针
编程题:
1.define比较两个值的大小
#define MAX(a,b) ((a)>(b)?(a):(b))
#define MIN(a,b) ((a)<(b)?(a):(b))
2.字符串逆序打印
#include <stdio.h>
#include<string.h>
void Exchangestr(char *str)
{
int n=strlen(str);
char *p=str;
char *q=str+n-1;
while(p<q)
{
char temp=*p;
*p=*q;
*q=temp;
*p++;
*q--;
}
}
int main(int argc, char const *argv[])
{
char buf[]="hello world";
printf("原来=%s\n",buf);
Exchangestr(buf);
printf("后来=%s\n",buf);
return 0;
}
3.冒泡排序
#include <stdio.h>
#include<string.h>
int main(int argc, char const *argv[])
{
int buf[]={2,1,4,6,7,9,5,3,8};
int n=sizeof(buf)/sizeof(int);
for(int i=0;i<n-1;i++)
{
for(int j=0;j<n-i-1;j++)
{
if(buf[j]<buf[j+1])
{
int t=buf[j+1];
buf[j+1]=buf[j];
buf[j]=t;
}
}
}
for(int i=0;i<n;i++)
printf("%d ",buf[i]);
printf("\n");
return 0;
}
4.实现 strlen,strcpy,strcat,strcmp
#include <stdio.h>
#include<string.h>
size_t my_strlen(const char *str)
{
size_t len=0;
while(*str)
{
len++;
*str++;
}
return len;
}
int main(int argc, char const *argv[])
{
char buf[]="hello world";
size_t len=my_strlen(buf);
printf("长度=%d\n",len);
return 0;
}
#include <stdio.h>
char *my_strcpy(char *dest,const char *scr)
{
while(*scr)
{
*dest=*scr;
dest++;
scr++;
}
*dest='\0';
return dest;
}
int main(int argc, char const *argv[])
{
char buf[]="hello world";
char dest[20]="";
my_strcpy(dest,buf);
printf("buf=%s\n",buf);
printf("bm=%s\n",dest);
return 0;
}
#include <stdio.h>
char *my_strcat(char *dest,const char *scr)
{
while(*dest)
{
dest++;
}
while(*scr)
{
*dest=*scr;
dest++;
scr++;
}
*dest='\0';
return dest;
}
int main(int argc, char const *argv[])
{
char buf[10]="yes";
char dest[20]="hello world";
my_strcat(dest,buf);
printf("%s\n",dest);
return 0;
}
#include <stdio.h>
int my_strcmp(const char *dest,const char *scr)
{
while(*dest&&&*scr)
{
if(*dest!=*scr)
{
return *dest-*scr;
}
dest++;
scr++;
}
}
int main(int argc, char const *argv[])
{
char buf[10]="abc、";
char dest[20]="def";
int result= my_strcmp(dest,buf);
if(result<0)
{
printf(" 其中dest小于buf >>> %s %s\n",dest,buf);
}
else if(result==0)
{
printf("其中dest等于buf>>> %s %s\n",dest,buf);
}
else
printf("其中dest大于buf>>> %s %s\n",dest,buf);
return 0;
}
5.打印杨辉三角前十行
#include <stdio.h>
int main(int argc, char const *argv[])
{
const int rows=10;
int yangbuf[rows][rows];
for(int i=0;i<rows;i++)
{
yangbuf[i][0]=1;
yangbuf[i][i]=1;
}
for(int i=2;i<rows;i++)
{
for(int j=1;j<i;j++)
{
yangbuf[i][j]=yangbuf[i-1][j]+yangbuf[i-1][j-1];
}
}
for(int i=0;i<rows;i++)
{
for(int j=0;j<=i;j++)
{
printf("%d ",yangbuf[i][j]);
}
printf("\n");
}
return 0;
}
6.atoi函数自定义
#include <stdio.h>
int my_atoi(const char *str)
{
int result=0;
int flag=1;
while (*str==' ')
{
str++;
}
while(*str=='-'||*str=='+')
{
flag=(*str=='-')?-1:1;
str++;
}
while (*str>='0'&&*str<='9')
{
result=result*10+(*str-'0');
str++;
}
return result*flag;
}
int main(int argc, char const *argv[])
{
char *str=" -1234a";
int n=my_atoi(str);
printf("%d\n",n);
return 0;
}