Linux编程笔记2-控制&数组&指针&函数&动态内存&构造类型&Makefile

控制流程

If-else只与附近的if相匹配

如:

cpp 复制代码
if(a==b)

If(b==c)

Printf("a==b==c\n");

Else

Printf("a!=b\n");

输出a!=b

用位运算来进行进制转换:十进制转二进制------245转11110101???

cpp 复制代码
unsigned char n = 245;
for (int i = 7; i >= 0; i--) {
    putchar(((n >> i) & 1) + '0');
}

Char str[N]="abc";此可以改其数据吗?那种指向"abc"的地址的是什么样的?

答:char *str_ptr = "abc"; 字符串存储在程序的只读数据段里

数组:

部分元素赋值,其他元素自动默认赋为0值

数组名:是表示地址的常量,起始地址------数组[i]本身就是一个指针的操作a[i]=&(a+i),所以实际上是指针的操作,编译器不会报错(一般的,现在的会主动报错)。

排序

冒泡排序:

最多n-1,

cpp 复制代码
#include<stdio.h>
#include<stdlib.h>
int main(void) {
    int arr[] = { 2,5,1,3,7,4 };
    int len = sizeof(arr) / sizeof(arr[0]);
    int i, j, temp;
    for (i = 0; i < len - 1; i++) {
        for (j = 0; j < len - i - 1; j++) {
            if (arr[j] > arr[j + 1]) {
                temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
        }
    }
    for (int i = 0; i < len; i++) {
        printf("[%s]:%d\n", __FUNCTION__, arr[i]);
    }
    return 0;
}

选择排序:

确定一个最小值/最大值,依次遍历,最多n-1的排序

cpp 复制代码
#include<stdio.h>
#include<stdlib.h>
int main(void) {
    int arr[] = { 2,5,1,3,7,4 };
    int len = sizeof(arr) / sizeof(arr[0]);
    int i, j, temp, obj;
    for (i = 0; i < len - 1; i++) {
        obj = i;
        for (j = i + 1; j < len; j++) {
            if (arr[j] < arr[obj]) {
				obj = j;
            }
        }
        if (i != obj) {
			temp = arr[i];
			arr[i] = arr[obj];
			arr[obj] = temp;
        }
    }
    for (int i = 0; i < len; i++) {
        printf("[%s]:%d\n", __FUNCTION__, arr[i]);
    }
    return 0;
}

快速排序:

我们以数组 [5, 2, 8, 3, 1, 6, 4] 为例,目标是排成升序 [1, 2, 3, 4, 5, 6, 8]。

第一步:选择基准和分区

选择最右边元素 4 作为基准pivot。

初始数组: [5, 2, 8, 3, 1, 6, 4] (pivot=4)

分区过程:

j=0: 5 > 4,不移动,i不动

j=1: 2 <= 4,i++ (i=0),交换 arr[0]和arr[1] → [2, 5, 8, 3, 1, 6, 4]

j=2: 8 > 4,不移动

j=3: 3 <= 4,i++ (i=1),交换 arr[1]和arr[3] → [2, 3, 8, 5, 1, 6, 4]

j=4: 1 <= 4,i++ (i=2),交换 arr[2]和arr[4] → [2, 3, 1, 5, 8, 6, 4]

j=5: 6 > 4,不移动

分区完成后,交换基准到正确位置:

交换 arr[i+1] (arr[3]=5) 和 arr[high] (arr[6]=4) → [2, 3, 1, 4, 8, 6, 5]

此时基准4已经在最终正确位置

第二步:递归排序左右子数组

现在递归排序左边 [2, 3, 1] 和右边 [8, 6, 5]

排序左边 [2, 3, 1] (pivot=1):

分区后:所有元素都>=1,i保持-1

交换后:[1, 3, 2] → 基准1已在正确位置

继续排序 [3, 2]...

排序右边 [8, 6, 5] (pivot=5):

分区后:[5, 6, 8] → 基准5已在正确位置

继续排序 [6, 8]...

最终整个数组变为:[1, 2, 3, 4, 5, 6, 8]

cpp 复制代码
#include<stdio.h>
#include<stdlib.h>

// 分区函数-确保基准找到正确位置
int partion(int arr[], int low, int high) {
    int pivot = arr[high];
    int i = low - 1;
    for (int j = low; j <= high - 1; j++) {
        if (arr[j] <= pivot) {
            i++;
            int temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }
    }
    // 把基准放到正确位置
    int temp = arr[i + 1];
    arr[i + 1] = arr[high];
    arr[high] = temp;
    return i + 1;
}

// 快速排序主函数
void quicksort(int arr[], int low, int high) {
    if (low < high) {
        int p = partion(arr, low, high); // 确定基准的最终位置
        quicksort(arr, low, p - 1);      // 递归排序小于基准元素
        quicksort(arr, p + 1, high);     // 递归排序大于基准元素
    }
}

int main(void) {
    int arr[] = { 2,5,1,3,7,4 };
    int len = sizeof(arr) / sizeof(arr[0]);
    quicksort(arr, 0, len - 1);
    for (int i = 0; i < len; i++) {
        printf("[%s]:%d\n", __FUNCTION__, arr[i]);
    }
    return 0;
}

二维数组:

只有行可以省略arr[][M]=0;

A[0]表示:a[0][1]、a[0][2]、a[0][3]

字符数组:

Char str[N]={'a','b',''c};

Char str[N]="abc";

存在结束标识符'\0'

Scanf(遇到分隔符会直接截断)------gets------fgets:输入字符串函数

Strlen&sizeof


Strlen不会包含'\0',以'\0'为结束标志位,返回值为int

Sizeof会包含


Strcpy&Strncpy:拷贝时也要把'\0'拷贝走

Strcpy(目标,源);

Strncpy(目标,源,拷贝数量);


Strcat&Strncat:连接

Strcat(目标,追加的源字符串);

Strncat(目标,追加的源字符串,最多从源字符串 src 中追加的字符数);


Strcmp&Strncmp:比较:比较ASCII码,返回值是int:如果 A>B:则返回1,相等返回0;反之则为负值

Strcmp(目标,源);

Strncmp(目标,源,比较字母的数量);


1.#if #else #endif------与注释有什么区别?

答:注释本来是对代码进行说明的,#if是对代码进行预处理的;一个是增强代码可读性,做描述或临时屏蔽代码部分(不要依赖);另一个是根据不同环境、平台、配置选择编译不同代码,面向开发与调试需求。

2.段错误是什么?

答:是计算机程序运行时常见的错误,通常发生在程序试图访问未被允许访问的内存区域,或者以不允许的方式访问内存时。

3.qsort函数使用???

答:

void qsort(void *base, size_t nitems, size_t size, int (*compar)(const void *, const void*));

  1. base:指向要排序的数组的首地址(void* 类型,可接受任意类型数组)。
  2. nitems:数组中元素的数量。
  3. size:每个元素的字节大小(例如 int 是 sizeof(int))。
  4. compar:比较函数的指针,用于定义排序规则,返回值:

负数:第一个参数应排在第二个参数前面------正序

0:两个参数相等

正数:第二个参数应排在第一个参数前面

cpp 复制代码
#include<stdio.h>
#include<stdlib.h>

int compare_int(const void* a, const void* b) {
    return (*(int*)a - *(int*)b);
}

int main(void) {
    int arr[] = { 2,5,1,3,7,4 };
    int n = sizeof(arr) / sizeof(arr[0]);
    //升序排序
    qsort(arr, n, sizeof(int), compare_int);
    for (int i = 0; i < n; i++) {
		printf("%d ", arr[i]);
    }
    return 0;
}

指针

变量与地址

指针与指针变量 +多级指针

cpp 复制代码
        Int i=1;

        Int *p=&i;

        Int **q=&p;

I------》1

&i------》0x2000

P------》&i

&p------》0x3000

*p------》*(0x2000)------》1

*q------》*(&p)------》p------》&i

**q------》*(*q)------》*(&i)------》1

指针在解引用时会根据自身的类型进行读取数据,int为4B,若用char *ch;来读取则会截断2B的数据,导致失真;

指针与数组的关系:

二维数组:

*(a+i)+j,*(*(a+i)+j)

P=&a[0][0];------一般的这种p指针只能在列移动

所以 for(ini i=0;i<6;i++,p++){

Printf[("%d",*p);

}

数组指针

Int (*q)[3]=a ==int a[2][3]

字符数组

Char str[]="hello";

Char *str="hello";

Const与指针

Const修饰:const int a;和int const a; ------变量一直保持常量值

Const int *p; 和int const *p; Int *const p;

常量指针和指针常量:

常量指针:指针的指向可以发生变化,但指针指向的值不能发生变化

指针常量:反之

Const int *const p;

指针数组和数组指针

Int (*q)[3];------》type name------》int[3] *p

int *arr[3];------》name type------》int *[3] arr

函数

函数与数组:

二维数组:

Myprintf(&a[0][0],M*N)------将二维数组变为一个大数组来处理

Myprintf(*a,M*N)------转列解引用

Myprintf(a,M*N)------数组指针------》Myprintf(int(*p)[N],int m,int n)

p[num][i] ≡ *(p[num] + i) ≡ *(*(p + num) + i)

函数与指针:

指针函数:int *fun(int);------return *(int);需要返回值为地址

函数指针:(*指针名)(形参):int (*p)(int)------指针指向函数:int(*funcp)(int,int)

函数指针数组:int(*arr[N])(int);------int(*funcp[2])(int,int)

构造函数:

结构体

类型声明是不占空间的

Struct name{

Type 成员1;

......

};

单独设置成员struct stu S={S.math=59};

存储存在偏移量:attribute(packed)使用此宏让其不偏移

函数传参:一般都使用指针来进行传参;

结构体成员之间可以直接用等于代替

共用体

Union 共用体名{

数据类型 成员名1;

.......

};

多个成员共用一个空间,按类型最大的进行确定大小;其应用的方式与结构体相同;

位域:

char a:1;

char b:2;

char c:1;

数值存入会被以补码形式来看待,所以需要对其进行格式处理

动态内存管理

原则:谁申请谁释放

malloc

calloc

raelloc

Free

1.Typedefine和define的区别???

答:

cpp 复制代码
// 使用 typedef
typedef int INTEGER;
typedef char* STRING;

// 使用 define
#define INT int
#define CHAR_PTR char*
  1. #ifndef __Sqlist_H #define Sqlist_H 和#ifndef Sqlist_H #define Sqlist_H

的区别???

答:

__Sqlist_H

根据C标准:

  • 双下划线开头 的标识符是实现保留

  • 编译器或标准库可能使用类似名称,可能产生冲突

  • 示例:__FILE__, __LINE__, __DATE__ 等都是编译器预定义的

Sqlist_H_(推荐)

  • 使用单下划线结尾,避免与保留标识符冲突

  • 更清晰易读:Sqlist_H_ 明显表示"Sqlist头文件的保护宏"

  • 符合现代编程规范

3,fprintf的用法

答:

cpp 复制代码
int fprintf(FILE *stream, const char *format, ...);
  • stream:文件指针,指定要写入的文件

  • format:格式化字符串,与 printf 类似

  • ...:可变参数,根据格式化字符串提供数据

返回值:成功返回写入的字符数,失败返回负值(printf同理)

4.预定义宏( LINE

答:

宏名称 说明 示例值
__LINE__ 当前行号(整数) 25
__FILE__ 当前文件名(字符串) "main.c"
__DATE__ 编译日期(字符串) "Sep 25 2024"
__TIME__ 编译时间(字符串) "14:30:25"
__func__ 当前函数名(C99) "main"
__FUNCTION__ 当前函数名(GCC扩展) "main"
__cplusplus C++版本号(C++中) 199711L
__STDC__ 标准C编译器标识 1

Makefile:

进行分析在文件工程中的依赖和被依赖的关系,形成这样的脚本

解释:

Main.c

cpp 复制代码
#include<stdio.h>

#include"tool1.h"

#include"tool2.h"

int main(void){

       mytool1();

       mytool2();

       return 0;

}

a.out依赖于main.o tool1.o tool2,o

Main.o依赖于main.c tool1.c tool2.c

Tool1.o依赖于tool1.c

Tool2.o依赖于tool2.c

bash 复制代码
Makefile:

OBJS=main.o tool1.o tool2.o

CC=gcc

CFLAGS+=-c -Wall -g



mytool:$(OBJS)

        //$(CC) $(OBJS) -o mytool



$(CC) $^ -o $@

main.o:main.c

        //$(CC) main.c $(CFALGS) -o main.o

$(CC) $^ $(CFALGS) -o $@

tool1.o:tool1.c

        //$(CC) tool1.c $(CFALGS)-o tool1.o

$(CC) $^ $(CFALGS)-o $@

tool2.o:tool2.c

        //$(CC) tool2.c $(CFALGS) -o tool2.o

$(CC) $^ $(CFALGS) -o $@

clean:

        rm *.o mytool -rf

=

相关推荐
PKNLP2 小时前
逻辑回归(Logistic Regression)
算法·机器学习·逻辑回归
可触的未来,发芽的智生3 小时前
新奇特:神经网络的自洁之道,学会出淤泥而不染
人工智能·python·神经网络·算法·架构
放羊郎3 小时前
SLAM算法分类对比
人工智能·算法·分类·数据挖掘·slam·视觉·激光
Juan_20124 小时前
P1447题解
c++·数学·算法·题解
ai智能获客_狐狐4 小时前
智能外呼产品架构组成
人工智能·算法·自然语言处理·架构·语音识别
高山上有一只小老虎4 小时前
输出单向链表中倒数第k个结点
java·数据结构·链表
Algo-hx5 小时前
数据结构入门 (五):约束即是力量 —— 深入理解栈
数据结构·算法
我要用代码向我喜欢的女孩表白5 小时前
数据结构13003考前急救
数据结构
芒果量化5 小时前
ML4T - 第7章第5节 用线性回归预测股票回报Prediction stock returns with linear regression
算法·回归·线性回归