C语言基础

基础

关键字

typeof

int a = 5;
typeof(int *) var = &a;

数据类型变量

char              1
unsigned char     1
signed char       1
int               4
unsigned int      4
short             2
unsigned short    2
long              4/8
unsigned long     4/8
long long         8

float             4
double            8
long double       16

void fuction(void);

void *ptr = malloc(12);


85         /* 十进制 */
0213       /* 八进制 */
0x4b       /* 十六进制 */
30         /* 整数 */
30u        /* 无符号整数 */
30l        /* 长整数 */
30ul       /* 无符号长整数 */

//定义常量
#defined a 100
const int a = 100;

存储类

auto
register
static 
extern
volatile

变量自动auto  函数自动auto

auto int a;  == int a;

register int a;    //每次取值从内存去 编译器不要优化
static int a;      //静态变量 生命周期全局

static void fun();  //限制函数名称作用域再本文件别的文件不能引用 避免命名空间污染

extern int a;      //变量a引用
extern void fun(); //引用别的文件的函数

volatile 防止编译器优化掉操作变量的语句

数组

//一维数组
int array[4] = {1, 2, 3, 4}
int array[] = {1, 2, 3, 4};

int a = array[0]
//二维数组
int array[3][4] = {  
 {0, 1, 2, 3} ,   /*  初始化索引号为 0 的行 */
 {4, 5, 6, 7} ,   /*  初始化索引号为 1 的行 */
 {8, 9, 10, 11}   /*  初始化索引号为 2 的行 */
};
int val = array[2][3];

int people[30] = {[0 ... 29] = 1};

//数组传参
1.
void fun(int *array) 
{   
}
2.
void fun(int array[4])
{
}
3.
void fun(int array[])
{
}
常用1和3
//传递二维数组
int array[4][3] = {0};
void fun(int array[][3])
void fun(int (* p)[3]);  //数组指针  指向数组

fun(array);

数组相同于指针
一维数组
int array[5];
*(array + 1) ==  *(&array[0] + sizeof(array)) //*(&array[0] + 5) 

二维数组
int array[4][5];
*(array + 1) == *(&array[0] + sizeof(array)) //*(&array[0] + 20) 
三维
int array[3][4][5];
*(array + 1) == *(&array[0] + sizeof(array))  //*(&array[0] + 60) 
//指针+1内存增加指针指向数据类型长度


//函数返回数组
int * fun()
{
    static int array[10];
    return array;
}

//指向数组指针
int array[4] = {1, 2, 3, 4}
int *ptr = array;

int array[4][4]
int *ptr = array;
int (*p)[4] = array; 

枚举

enum DAY {
    MON = 1,
    TUE
};

enum season {spring, summer=3, autumn, winter};
没有指定值的枚举元素,其值为前一元素加 1。也就说 spring 的值为 0,summer 的值为 3,autumn 的值为 4,winter 的值为 5

enum DAY
{
      MON=1, TUE, WED, THU, FRI, SAT, SUN
};
enum DAY day;

enum DAY
{
      MON=1, TUE, WED, THU, FRI, SAT, SUN
} day;

指针

int *p;    //一级指针
int **p;   //二级指针

int (*p)[4]; //数组指针  就是 指针指向数组  数组存储大小是4个单元
int *p[4];   //指针数组  4个指向int的指针    int a = 10; p[0] = &a;

int (*p)(int, int);   //函数指针 指向函数

int fun(int a, int b);
p = fun;

p(1, 2);//执行

typedef int (*fun_ptr)(int, int);

fun_ptr p = fun;  //别名定义




字符串

数组最后一个字节存储  '\0'
char greeting[6] = {'H', 'e', 'l', 'l', 'o', '\0'};

char str[] = "hello"  //自动添加 '\0'

结构体

//定义
1.
struct Books {
    char title[10];
    char author[10];
} book;
2.
struct Books book;
3.
typedef struct {
    char title[10];
    char author[10];
} Books;

Books book;
//初始化

Books book = {"c", "my"};
Books book = {.title = "c", .author = "my"};  //C风格
Books book = {title : "c", author : "my"};   //C++风格


结构体大小
1,每个结构体成员的起始地址为该成员大小的整数倍,即int型成员的其实地址只能为0、4、8等
2,结构体的大小为其中最大成员大小的整数倍

共用体

共用体是一种特殊的数据类型,允许您在相同的内存位置存储不同的数据类型。您可以定义一个带有多成员的共用体,但是任何时候只能有一个成员带有值。共用体提供了一种使用相同的内存位置的有效方式

union Data
{
   int i;
   float f;
   char  str[20];
};
 
int main( )
{
   union Data data;        
 
   printf( "Memory size occupied by data : %d\n", sizeof(data));
 
   return 0;
}
//20
//大小为最大成员大小
big-endian和little-endian格式。在小端模式中,低位字节放在低地址,高位字节放在高地址;在大端模式中,低位字节放在高地址,高位字节放在低地址。

//大小端测试
#include<stdio.h>
union var{
        char c;
        int i;
};
int main(){
    union var data;
    data.c = 0x04;
    printf("%x\n",data.i);
    if(data.i == 0x04) {
        printf("小端");
    } else {
         printf("大端");
    }
}

REVERSED
#if defined(REVERSED)
    std::cout<< ("大端");
#else
    std::cout<<("小端");
#endif
    





变参数函数

double average(int num,...)
{
 
    va_list valist;
    double sum = 0.0;
    int i;
 
    /* 为 num 个参数初始化 valist */
    va_start(valist, num);
 
    /* 访问所有赋给 valist 的参数 */
    for (i = 0; i < num; i++)
    {
       sum += va_arg(valist, int);
    }
    /* 清理为 valist 保留的内存 */
    va_end(valist);
 
    return sum/num;
}
 
int main()
{
   printf("Average of 2, 3, 4, 5 = %f\n", average(4, 2,3,4,5));
   printf("Average of 5, 10, 15 = %f\n", average(3, 5,10,15));
}

预处理器

字符串常量化运算符(#)和标记粘贴运算符(##)

#define Conn(x, y) x##y   //连接字符
#define ToString(x) #x    //转化为字符串
#define  message_for(a, b)  \
    printf(#a " and " #b ": We love you!\n")

int main(void)
{
   message_for(Carole, Debra);
   return 0;
}

参数宏  #define square(x) ((x) * (x))

#define eprintf(format, ...) fprintf(stderr, format, ##__VA_ARGS__)

#ifdef DEF     ==  #if define(DEF)

#else

#endif


#ifndef DEF

#endif

指令	描述
#define	定义宏
#include	包含一个源代码文件
#undef	取消已定义的宏
#ifdef	如果宏已经定义,则返回真
#ifndef	如果宏没有定义,则返回真
#if 	如果给定条件为真,则编译下面代码
#else	#if 的替代方案
#elif	如果前面的 #if 给定条件不为真,当前条件为真,则编译下面代码
#endif	结束一个 #if……#else 条件编译块
#error	当遇到标准错误时,输出错误消息
#pragma	使用标准化方法,向编译器发布特殊的命令到编译器中

内存管理

void *calloc(int num, int size);  //分配并初始化为 size

void free(void * address);        //释放内存
void *malloc(int num)             //分配内存

void *realloc(void *address, int newsize); //扩展大小

位域

struct bs
{
    unsigned a:4;
    unsigned :0;
    unsigned b:4;
    unsigned c:4;
}

0填充对其

整个结构体的总大小为最宽基本类型成员大小的整数倍

位域变量类型:int unsigned int signed int

字节对齐方式

#pragma pack(1)//单字节对齐
typedef struct{
    uint32 ID;
    uint32 Num;
    uint32 Type;
    uint32 lat;
    uint32 lng;
    uint32 alt;
    uint32 speed;
}Waypoint;//Payload_Data
 
#pragma pack(pop)

大小端

//方法1
int a = 1;
if(*(char *)(&a) == 1) {
    //小端
} else {
    //大端
}

//方法2
union Endian 
{
    int a;
    char b;
}

Endian endian;
endian.a = 1;
if(endian.b == 1) {
    //小端
} else {
    //大段
}

extern C 

#ifdef __cplusplus             //告诉编译器,这部分代码按C语言的格式进行编译,而不是C++的
extern "C"{
#endif
 
/*…*/
 
#ifdef __cplusplus
}
 
#endif

库函数

stdio.h

int printf(const char *format, ...)


%d      有符号10进制  正数不带符号位
%o      无符号8进制
%x,X    无符号16进制
%u      无符号十进制
%f      浮点数
%e,E    指数形式浮点数
%c      单个字符
%s      字符串
%p      指针
%lu     32位无符号
%llu    64位无符号

%+d     显示+/-
%-d     左对齐 
%02X    填充 0 宽度2  默认填充空格
%-05X   左对齐

%#x    显示0x
%#f    显示一个小数

%*s, len, str   参数指定长度
%.2f   两位小数
%lf    双精度浮点数
%hd    短整型 short

类似:
int fprintf(FILE *stream, const char *format, ...)  //则返回写入的字符总数
int sprintf(char *str, const char *format, ...)

int scanf(const char *format, ...)
int sscanf(const char *str, const char *format, ...)


math.h

double exp(double x)    e的x次幂
double ceil(double x)   大于等于x最小整数
double fabs(double x)   x绝对值
double floor(double x)  小于等于x最大整数

signal.h

void sighandler(int);

signal(SIGINT, sighandler); //注册信号
ret = raise(SIGINT);        //发射信号

stdlib.h

double atof(const char *str)   
int atoi(const char *str)

long int atol(const char *str)
double strtod(const char *str, char **endptr)
str -- 要转换为双精度浮点数的字符串。
endptr -- 对类型为 char* 的对象的引用,其值由函数设置为 str 中数值后的下一个字符。

long int strtol(const char *str, char **endptr, int base)
unsigned long int strtoul(const char *str, char **endptr, int base)

int system(const char *string)

//二分查找
void *bsearch(const void *key, const void *base, size_t nitems, size_t size, int (*compar)(const void *, const void *))

//排序
void qsort(void *base, size_t nitems, size_t size, int (*compar)(const void *, const void*))

int abs(int x)

int rand(void)   0 - RAND_MAX 之间随机数

string.h

int memcmp(const void *str1, const void *str2, size_t n)
void *memcpy(void *dest, const void *src, size_t n)
void *memset(void *str, int c, size_t n)

char *strcat(char *dest, const char *src)
int strcmp(const char *str1, const char *str2)
char *strcpy(char *dest, const char *src)
size_t strlen(const char *str)

char *strrchr(const char *str, int c)
在参数 str 所指向的字符串中搜索最后一次出现字符 c(一个无符号字符)的位置。

char *strstr(const char *haystack, const char *needle)

time.h

time_t time(time_t *timer)
计算当前日历时间,并把它编码成 time_t 格式。

char *ctime(const time_t *timer)
返回一个表示当地时间的字符串,当地时间是基于参数 timer。

struct tm *localtime(const time_t *timer)
timer 的值被分解为 tm 结构,并用本地时区表示。

size_t strftime(char *str, size_t maxsize, const char *format, const struct tm *timeptr)
根据 format 中定义的格式化规则,格式化结构 timeptr 表示的时间,并把它存储在 str 中。


   time_t rawtime;
   struct tm *info;
   char buffer[80];

   time( &rawtime );

   info = localtime( &rawtime );

   strftime(buffer, 80, "%Y-%m-%d %H:%M:%S", info);
   printf("格式化的日期 & 时间 : |%s|\n", buffer );

数据结构和算法

数据结构

算法

冒泡排序

void bubble_sort(int array[], int len)
{
    len = len - 1;    //len - 1次排序就够了 
    for(int i = 0; i < len; i++) {
        for(int j = 0; j < len - i; j++) {   //最大的值冒泡到最后
            if(array[j] > array[j + 1]) {
                array[i] = array[i] ^ array[j];
                array[j] = array[i] ^ array[j];
                array[i] = array[i] ^ array[j];
            }
        }
    }
}
static void bubble_sort(int arr[], int len)
{
    while(len-- > 0) {
        for(int j = 0; j < len; j++) {
            if(arr[j] > arr[j + 1]) {
                arr[j] = arr[j] ^ arr[j + 1];
                arr[j + 1] = arr[j] ^ arr[j + 1];
                arr[j] = arr[j] ^ arr[j + 1];
            }
        }
    }
}

int main()
{
    int array[] = {22, 45, 56, 12, 35, 45, 7, 90};
    int len = sizeof(array) / sizeof(int);
    bubble_sort(array, len);

    for(int i = 0; i < len; i++) {
        printf("%d ", array[i]);
    }
    return 0;
}

选择排序

static void selectSort(register int arr[], int len)
{
    for(int i = 0; i < len - 1; i++) {
        for(int j = i; j < len; j++) {  //找出最小值
            if(arr[j] < arr[i]) {
                arr[i] = arr[i] ^ arr[j];
                arr[j] = arr[i] ^ arr[j];
                arr[i] = arr[i] ^ arr[j];
            }
        }
    }
}
int main() {

    int arrTest[] = {3, 1, 4, 2, 7, 1, 3, 5, 3, 2, 7, 3};
    selectSort(arrTest, sizeof(arrTest) / 4);

    for(int i = 0; i < sizeof(arrTest) / 4; i++) {
        printf("%d ", arrTest[i]);
    }
    return 0;
}

插入排序

static void insertSort(int arr[], int len)
{
    for(int i = 1; i < len; i++) {
        int temp = arr[i], j = i;
        //查找比 arr[i] 小的 跳出循环  或者没有找到说明最小  插入到最前面
        for(j = i; j > 0 && arr[j - 1] > temp; j--) {
            arr[j] = arr[j - 1];
        }

        arr[j] = temp;
    }
}
int main() {

    int arrTest[] = {3, 1, 4, 2, 7, 1, 3, 5, 3, 2, 7, 3};
    insertSort(arrTest, sizeof(arrTest) / 4);

    for(int i = 0; i < sizeof(arrTest) / 4; i++) {
        printf("%d ", arrTest[i]);
    }
    return 0;
}

归并排序

void merge_sort_recursive(int arr[], int reg[], int start, int end) {
    if (start >= end)
        return;
    int len = end - start, mid = (len >> 1) + start;

    int start1 = start, end1 = mid;
    int start2 = mid + 1, end2 = end;

    merge_sort_recursive(arr, reg, start1, end1);
    merge_sort_recursive(arr, reg, start2, end2);

    int k = start;
    //从小到大复制两个 排序数组, 每个数组已经从小到大排序完成了
    while (start1 <= end1 && start2 <= end2)
        reg[k++] = arr[start1] < arr[start2] ? arr[start1++] : arr[start2++];

    while (start1 <= end1)
        reg[k++] = arr[start1++];

    while (start2 <= end2)
        reg[k++] = arr[start2++];
    //全部复制
    for (k = start; k <= end; k++)
        arr[k] = reg[k];
}
void mergeSort(int arr[], const int len) {
    int reg[len];
    merge_sort_recursive(arr, reg, 0, len - 1);
}

int main() {

    int arrTest[] = {3, 1, 4, 2, 7, 8, 9, 2, 1, 23, 11, 3, 5, 3, 2, 7, 3};
    mergeSort(arrTest, (sizeof(arrTest) / 4));

    for(int i = 0; i < sizeof(arrTest) / 4; i++) {
        printf("%d ", arrTest[i]);
    }
    return 0;
}

快速排序

//快速排序
void quick_sort_recursive(int arr[], int start, int end) {
    if (start >= end)
        return;
    int mid = arr[start];
    int left = start, right = end;
    while (left < right) {
        // 从右向左找第一个小于mid的数
        while (arr[right] >= mid && left < right)
            right--;

        if(left < right) {
            arr[left++] = arr[right];
        }
        // 从左向右找第一个大于等于mid的数
        while (arr[left] < mid && left < right)
            left++;

        if(left < right) {
            arr[right--] = arr[left];
        }
    }
    arr[left] = mid;

    quick_sort_recursive(arr, start, left - 1);
    quick_sort_recursive(arr, left + 1, end);
}
void quick_sort(int arr[], int len) {
    quick_sort_recursive(arr, 0, len - 1);
}

int main() {

    int arrTest[] = {3, 1, 4, 2, 7, 8, 9, 2, 1, 23, 11, 3, 5, 3, 2, 7, 3};
    quick_sort(arrTest, 0, (sizeof(arrTest) / 4) - 1);

    for(int i = 0; i < sizeof(arrTest) / 4; i++) {
        printf("%d ", arrTest[i]);
    }
    return 0;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值