C 语言解 常见编程题(下)

简介: C 语言解 常见编程题

C 语言解 常见编程题(上):https://developer.aliyun.com/article/1489149


10 回文数

/* 判断 n 是否为回文数 */
#include <stdio.h>
/* 思路: 倒置数值,判断倒置后是否相等 */
int isPalindromes(int n){
    // m倒置后的, nn复制一份n用于操作, div 倒置所需乘数
    int m = 0, nn = n, div = 1;   
    while (n / div) div *= 10;
    do
    {
        div /= 10;
        m += nn % 10 * div;
    } while (nn /= 10);
    printf("%d----倒置后:%d\n",n,m);
    if (m == n) return 1;
    else return 0;
}
int main(){
    printf("%d", isPalindromes(1234321));
    return 0;
}

测试数据1: 1234321

1234321----倒置后:1234321

1

测试数据1: 12345

12345----倒置后:54321

0

/* 判断 n 是否为回文数 */
#include <stdio.h>
/* 思路: 挨个比较 每个位上的 数字 */
int isPalindromes(int n){
    int div1 = 1,div2 = 1;   //div1 左第一位所需的除数, div2 右第一位所需的除数
    int m1,m2;  //m1 左第一位的值, m2 右第一位的值
    while(n/div1/10) div1 *= 10;;
    while(div1 > div2){    //对比过 中间一个,停止对比
        m1 = n/div1%10;
        m2 = n/div2%10;
        printf("%d----%d\n",m1,m2);   
        if(m1!=m2) return 0;
        div2*=10;
        div1/=10;
    }
    return 1;
}
int main(){
    printf("%d", isPalindromes(1234321)); 
    return 0;
}

测试数据1: 1234321

1----1

2----2

3----3

1

测试数据2: 12354321

1----1

2----2

3----3

5----4

0

测试数据3: 1234

1----4

0


11 进制转换


① N进制转10进制


  • 由于16进制包括有abc等字符, 需使用字符串形式输入
  • 原理:权值相加 , 比如8进制转10进制,如下

/* n进制转10进制 */
#include <stdio.h>
//将字符转为所表示的数值, 比如 'a'或'A' 返回 10
int charToint(char c){
    if(c>='a') return c-87;
    else if(c>='A') return c-55;
    else return c-'0';
}
// n进制数num 转为 10进制数值
int numTodec(char *num, int n){
    int i,dec=0,k=1;   // k 权值
    for(i=0; num[i+1];i++);  //下标指向末位,从最后位开始
    for(;i>=0;i--,k*=n)
        dec+= k*charToint(num[i]);
    return dec;
}
int main(){
    char num[20];   //使用字符串形式,兼容16进制
    gets(num);   
    printf("%d",numTodec(num,8));
    return 0;
}
/* 
  n进制转10进制 -- 排除16进制(不考虑字符情况) 
*/
#include <stdio.h>
// n进制数num 转为 10进制数值
int numTodec(int num, int n){
    int dec=0,k=1;   // k 权值
    for(;num;k*=n,num/=10) dec+=num%10*k;   
    return dec;
}
int main(){
    int num;   
    scanf("%d",&num);
    printf("%d",numTodec( num , 8 ));
    return 0;
}

② 10进制转N进制


  • 原理: 除N取余, 至0为止
  • 比如二进制:

/* 递归 -- 10进制转N进制 */
#include <stdio.h>
//输出 10进制数num 的 n进制形式,只输出,不返回值
void decToany(int num,int n){
    if(num){
        decToany(num/n,n);
        printf("%c", num%n + (num%n>9?55:'0') );  //兼容16进制,以字符形式输出
    }
}

int main(){
    decToany(89,2);
    return 0;
}

12 数组排序


通用函数 – 交换:

//将数组p中的下标分别为a,b的两个数交换
void swap(int a,int b,int p[]){
    int temp = p[a];
    p[a] = p[b];
    p[b] = temp;
}

① 冒泡排序

#include<stdio.h>
int main(){
  int a[10]={3,2,5,8,1,9,7,4,0,6};
  // 外层循环代表循环次数(n-1)
  for (int i = 0; i < 10-1; i++){
    // 内层循环代表第j个与第i个比
    for (int j = i+1; j <= 10; j++){
      if(a[i]>a[j]){
        int t=a[i];
        a[i]=a[j];
        a[j]=t;
      }
    }
 }
// 打印结果
  for (int i = 0; i <= 9; i++) printf("%d",a[i]);
  return 0;
}

/* 
  冒泡排序法
  将长度为len的数组arr, 以升序排序
*/
void bubbling(int *arr,int len){
    // 外层循环代表循环次数(n-1)
    for(int i=0;i<len-1;i++){
        int var = 1;  //交换标记变量
         // 内层循环代表个数(n-1-i)
        for(int j = 0; j< len - i - 1; j++)
            if(arr[j]>arr[j+1]) { 
                swap(j,j+1,arr); 
                var = 0;
            }
        //print_arr(arr,len);   //查看排序过程
        if(var) break;   //本回合未产生排序,即已排序完成,跳出循环,提高效率(非必须)
    }
}

② 选择排序

#include<stdio.h>
int main(){
  int a[10]={3,2,5,8,1,9,7,4,0,6};
  // 外层循环代表循环次数(n-1)
  for (int i = 0; i < 10-1; i++){
    // 内层循环代表第j个与第i个比
    for (int j = i+1; j <= 10; j++){
      if(a[i]>a[j]){
        int t=a[i];
        a[i]=a[j];
        a[j]=t;
      }
    }
 }
// 打印结果
  for (int i = 0; i <= 9; i++) printf("%d",a[i]);
  return 0;
}

/* 
  选择排序法 升序
  最多产生 len(数组长度) 次交换
*/
void elect_sort(int *arr,int len){
    int i,j,k;
    for(i=0;i<len;i++){
        k=i;  //假设当前下标为最小值
        for(j = i + 1; j < len; j++)  //找最小值下标
            if(arr[j]<arr[k]) k = j;
        if(k!=i) swap(i,k,arr);  //将最小值交换到i的位置
    }
}
//选择排序法1,交换次数较多,但更简洁
void elect_sort_1(int *arr,int len){
    for(int i = 0; i < len; i++)
      for(int j = i + 1; j < len; j++)
            if(arr[i]>arr[j]) swap(i,j,arr);
}

③ 插入排序

//一般插入排序
#include<stdio.h>
int main(){
  int a[10]={3,2,5,8,1,9,7,4,0,6};
  // 循环数组a
  for (int i = 0; i < 10; i++){
    // 循环前面的被插入数组
    for (int j = i; j > 0; j--){
      if (a[j] < a[j - 1])
      {
        int t = a[j];
        a[j] = a[j - 1];
        a[j - 1] = t;
      }
    }
  }
// 打印结果
  for (int i = 0; i <= 9; i++) printf("%d",a[i]);
  return 0;
}

/*
  插入排序法 升序
*/
void insertt_sort(int *r, int len){
    int i, j, k;
    for (i = 1; i < len; i++){
        if (r[i] < r[i - 1]){
            k = r[i];  //存入当前待插入的值,否则定位后移 会覆盖
            for (j = i - 1; r[j] > k && j>=0; j--)  //后移,寻找合适的插入位置
                r[j + 1] = r[j];  
            r[j + 1] = k;  //插入
        }
    }
}

13 数组反转

// 交换a,b所指向的值
void swap(int *a,int *b){
    int temp = *a;
    *a = *b;
    *b = temp;
}
/* 
  数组反转
  传入数组首地址head与长度len
*/
void reverse(int *head,int len){
    int *tail = head+len-1;  //tail 尾指针,指向最后一个元素
    while(head<tail)
        swap(head++,tail--);
}

14 查找


① 折半查找


  • 要求已按 升序 排序好的数组
/* 
  循环 -- 折半查找
  在arr数组 [0,len]之间, 查询num的下标 
  存在 返回其下标,不存在返回 -1
*/
int Halfsearch(int *arr,int len,int num){
    int mid,low = 0, high = len - 1;
    do{
        mid = (low + high)/2;
        printf("\n%d---%d",low,high);
        if(arr[mid]>num) high = mid - 1;
        else if(arr[mid]<num) low = mid + 1;
        else return mid;
    }while(low <= high);
    return -1;
}
/*
  递归 -- 折半查找
  在arr数组的下标为 [low,high] 之间查找 num
  存在 返回其下标,不存在返回 -1
*/
int Halfsearch(int *arr,int low,int high,int num){
    if(low>high) return -1;
    int mid = (low+high)/2;
    if(arr[mid]>num) 
        return Halfsearch(arr,low,mid-1,num);
    else if(arr[mid]<num) 
        return Halfsearch(arr,mid+1,high,num);
    else return mid;
} 

② 顺序查找


  • 对数组无要求 , 不排序也行
  • 效率极低
/* 顺序查找 */
int sequential(int *arr,int len,int num){
  for(int i = 0; i < len; i++)
        if(arr[i]==num) return i;
     return -1;
}
  • 要求已按 升序 排序好的数组
/* 顺序查找 */
int sequential(int *arr,int len,int num){
  for(int i = 0; i < len; i++)
        if(arr[i]==num) return i;
      else if(arr[i]>num) break;   //找不着
     return -1;
}

15 字符串函数


① 字符串连接

#include <stdio.h>
//将s2连接到s1后面, s2不改变
void strconcat(char *s1,char *s2){
    int i,j;
    for(i = 0;s1[i];i++);  //定位到 s1字符串 中的'\0' 位置
    for(j = 0;s2[j];i++,j++)
        s1[i] = s2[j];
    s1[i] = '\0';       //结束!!!超级重要!!!超级容易忘!!!
}
int main(){
    char a[100],b[100];
    gets(a);
    gets(b);
    strconcat(a,b);
    puts(a);
    return 0;
}

② 比较字符串

#include <stdio.h>
//比较字符串s1,s2 , 相等返回0, 正数s1大,反之.
int strcomp(char *s1,char *s2){
    for(int i=0;s1[i] || s2[i];i++)
        if(s1[i]!=s2[i]) return s1[i]-s2[i];
    return 0;
}

int main(){
    char a[100],b[100];
    gets(a);
    gets(b);
    printf("%d",strcomp(a,b));
    return 0;
}

③ 复制字符串

#include <stdio.h>
//s2字符串 复制 到s1中
void strcopy(char *s1,char *s2){
    int i,j;
    for(i=0;s2[i];i++)
        s1[i] = s2[i];
    s1[i] = '\0';        //结束!!!超级重要!!!超级容易忘!!!
}

int main(){
    char s1[100],s2[100];
    gets(s2);
    strcopy(s1,s2);
    puts(s1);
}

16 链表


① 动态链表创建

#define LEN sizeof(Player)
//类型声明
typedef struct Node{
    int num;
    struct Node *next;
} Player;
//动态链表创建
Player *creat(){
    int temp;  //暂存量--判断是否继续输入
    Player *head, *p1, *p2;
    head = p1 = p2 = (Player *)malloc(LEN);
    printf("请输入你的编号 宝儿:");
    scanf("%d", &temp);
    if (!temp) return NULL;  //第一次输入0,返回空表
    p2->num = temp;  //存入
    do
    {
        scanf("%d", &temp);  // 下一个节点的数据!!!
        if (!temp) break;    //输入0结束输入,不想继续输入=>不用再创建新节点     
        p1 = (Player *)malloc(LEN);  //创建新节点
        p1->num = temp;
        p2->next = p1;    //上个节点next指向新的节点
        p2 = p1;          //p2 也指向新节点
    } while (1);
    p2->next = NULL;    //将本节点的next指向NULL,如改为指向head,形成一个圈,循环链表
    return head;
}

② 链表打印+返回长度

//链表打印+长度
int printLinked(Player *head){
    int len = 0;
    if (!head)
        printf("这个是空表哦 亲");
    else {
        Player *p = head;
      while (p){
          printf("%d ", p->num);
          p = p->next;
            len++;
            if(p==head) break;  //如果是首尾相连的链表
      }
     }
    return len;
}

③ 链表删除节点

//链式链表 删除节点
void del_linked(Player *head,Player *del){
    Player *p = head;
    while(p->next!=del){   //找到待删除节点的上一个节点
        p = p->next;
      if(!p){
            printf("\n找不到你要删除的节点呢 亲");
            return;
        }
    }
    p->next = del->next;  //将其指向下一个节点
}
//循环链表 删除节点
void del_linked(Player *del){
    Player *p = del;
    while(p->next!=del)   //找到待删除节点的上一个节点
        p = p->next;
    p->next = del->next;  //将其指向下一个节点
}
//删除头结点可在主函数中使用以下语句
head = head -> next;

④ 链表插入

//将add插入到head链表的第n个位置之后, n>=1     链式链表
void insert(Player* head,Player *add,int n){
    if(n<1) {printf("非法操作!");return;}  
    if(n>linklegth(head)) n = linklegth(head);  //大于最大长度,插入在最后
    Player * p = head;
  while(--n)
        p=p->next;
    add->next = p->next;
    p->next = add;    
}

17 求方程近似解


① 二分法

#include <stdio.h>
#include <math.h>
double func(double n){
    return 2 * pow(n, 3) - 4 * pow(n, 2) + 3 * n - 6;   //待求解函数
}

double Solution(double low, double high){
    double mid, fm;
    mid = (low + high) / 2;
    fm = func(mid);      
    //printf("%f--%f   -->  %f\n", low, high, mid);   //二分过程
    if (fm == 0 || (high - low) < 1e-5)//两种情况停止,一是fm刚好等于0(应该不可能),二是精度小于1e-5时,直接返回mid为近似解
        return mid;
    else if (fm < 0)
        return Solution(mid, high);
    else if (fm > 0)
        return Solution(low, mid);
}
int main(){
    printf("%.2f", Solution(-10, 10));
    return 0;
}

② 牛顿迭代法

#include<stdio.h>
#include<math.h>
double func(double x){ //举例函数
    return 2*x*x*x-4*x*x+3*x-6.0;
}
double func1(double x){ //导函数
    return 6*x*x-8*x+3;
}
int Newton(double *x,double precision,int maxcyc){      //maxcyc 迭代次数
    double x1,x0;
    int k;
    x0=*x;
    for(k=0;k<maxcyc;k++){
        if(func1(x0)==0.0){//若通过初值,函数返回值为0
            printf("迭代过程中导数为0!\n");
            return 0;
        }
        x1=x0-func(x0)/func1(x0);//进行牛顿迭代计算
        if(fabs(x1-x0)<precision || fabs(func(x1))<precision){//达到结束条件
            *x=x1; //返回结果
            printf("该值附近的根为:%lf\n",*x);
            return 1;
        }
        else //未达到结束条件
            x0=x1; //准备下一次迭代
    }
    printf("迭代次数超过预期!\n"); //迭代次数达到,仍没有达到精度
    return 0;
}
 
int main(){
    double x,precision;
    int maxcyc;
    printf("输入初始迭代值x0:");
    scanf("%lf",&x);
    printf("输入最大迭代次数:");
    scanf("%d",&maxcyc);
    printf("迭代要求的精度:");
    scanf("%lf",&precision);
    if(Newton(&x,precision,maxcyc)==1) //若函数返回值为1
    ;
    else //若函数返回值为0
        printf("迭代失败!\n");
    return 0;
}

18 求最大值


① 输入三个数abc,输出其中最大值

#include <stdio.h>
int main()
{
  int a, b, c;
  scanf("%d,%d,%d", &a, &b, &c);
  if (a >= b && a >= c)
    printf("max=%d", a);
  else if (b >= a && b >= c)
    printf("max=%d", b);
  else if (c >= a && c >= b)
    printf("max=%d", c);
  return 0;
}

②求出n个数字的最大值

#include<stdio.h>
 
int main()
{
  int x,max,n;
  scanf("%d",&n);
  scanf("%d",&x);
  max=x;
  for(int i=0;i<n-1;i++)
  {
    scanf("%d",&x);
    if(max<x)
      max=x;
  }
  printf("%d",max); 
  return 0; 
} 

19 打印图形


①打印菱形

#include<stdio.h>
 
int main()
{
  int m=3,n=1;
  for (int i = 0; i < 7; i++)
  {
    for (int i = 0; i < m; i++)
    {
      printf(" ");//前面空格数
    }
    i<3?m--:m++;
    for (int j = 0; j < n; j++)
    {
      printf("%c",'*');
    }
    n=i<3?n+2:n-2; 
    printf("\n"); 
  }
  return 0; 
} 


测试相关函数


/* 循环 */
#include <stdio.h>
int main(){
    
    return 0;
}

随机生成数组

#include <time.h>
//函数声明: 防止编译系统警告
void srand(unsigned seed);
int rand(void);
//随机数组 a数组首地址,l数组长度
void getArr(int *a,int l){
    int i=0;
    srand(time(NULL));  //以当前系统时间作为种子
    printf("\n你生成的数组为:");
    while (i < l) printf("%d,",a[i++] = rand()%(2*l+1));  //限制范围[0,2*l]
}

打印数组

void print_arr(int *a,int len){
    printf("\n数组为:");
    while(len--)  printf("%d,",*a++);
}

折半查找 测试案例

/*折半查找 */
#include <stdio.h>
#include <time.h>
//函数声明: 防止编译系统警告
void srand(unsigned seed);
int rand(void);
//随机数组 a数组首地址,l数组长度
void getArr(int *a,int l){
    int i=0;
    srand(time(NULL));  //以当前系统时间作为种子
    printf("你生成的数组为:");
    while (i < l) printf("%d,",a[i++] = rand()%(2*l+1));  //限制范围[0,2*l]
}
//将数组p中的下标分别为a,b的两个数交换
void swap(int a,int b,int p[]){
    int temp = p[a];
    p[a] = p[b];
    p[b] = temp;
}
/*
  插入排序法 升序
*/
void insertt_sort(int *r, int len){
    int i, j, k;
    for (i = 1; i < len; i++){
        if (r[i] < r[i - 1]){
            k = r[i];  //存入当前待插入的值,否则定位后移 会覆盖
            for (j = i - 1; r[j] > k && j>=0; j--)  //后移,寻找合适的插入位置
                r[j + 1] = r[j];  
            r[j + 1] = k;  //插入
        }
    }
}
/* 
  在长度为len的arr数组中, 查询num的下标 
  存在 返回其下标,不存在返回 -1
*/
int Halfsearch(int *arr,int len,int num){
    int mid,low = 0, high = len - 1;
    do{
        mid = (low + high)/2;
        printf("\n%d---%d",low,high);
        if(arr[mid]>num) high = mid - 1;
        else if(arr[mid]<num) low = mid + 1;
        else return mid;
    }while(low <= high);
    return -1;
}
void print(int *a,int len){
    printf("\n数组为:");
    while(len--)  printf("%4d",*a++);
}
int main(){
    int arr[10];
    getArr(arr,10);
    insertt_sort(arr,10);
    print(arr,10);
    printf("\n%d",Halfsearch(arr,10,8));
    return 0;
}

数组反转 测试

#include <stdio.h>
#include <time.h>
//函数声明: 防止编译系统警告
void srand(unsigned seed);
int rand(void);
//随机数组 a数组首地址,l数组长度
void getArr(int *a,int l){
    int i=0;
    srand(time(NULL));  //以当前系统时间作为种子
    printf("\n你生成的数组为:");
    while (i < l) printf("%d,",a[i++] = rand()%(2*l+1));  //限制范围[0,2*l]
}
// 交换a,b所指向的值
void swap(int *a,int *b){
    int temp = *a;
    *a = *b;
    *b = temp;
}
/* 数组反转 */
void reverse(int *head,int len){
    int *tail = head+len-1;
    while(head<tail)
        swap(head++,tail--);
}
//打印
void print_arr(int *a,int len){
    printf("\n数组为:");
    while(len--)  printf("%d,",*a++);
}
int main(){
    int arr[10];
    getArr(arr,10);
    reverse(arr,10);
    print_arr(arr,10);
    return 0;
}

你生成的数组为:18,12,0,7,1,19,11,3,13,0,

数组为:0,13,3,11,19,1,7,0,12,18,

相关文章
|
19天前
|
存储 编译器 C语言
【C语言】数据类型全解析:编程效率提升的秘诀
在C语言中,合理选择和使用数据类型是编程的关键。通过深入理解基本数据类型和派生数据类型,掌握类型限定符和扩展技巧,可以编写出高效、稳定、可维护的代码。无论是在普通应用还是嵌入式系统中,数据类型的合理使用都能显著提升程序的性能和可靠性。
40 8
|
23天前
|
C语言
C语言编程中,错误处理至关重要,能提升程序的健壮性和可靠性
C语言编程中,错误处理至关重要,能提升程序的健壮性和可靠性。本文探讨了C语言中的错误类型(如语法错误、运行时错误)、基本处理方法(如返回值、全局变量、自定义异常处理)、常见策略(如检查返回值、设置标志位、记录错误信息)及错误处理函数(如perror、strerror)。强调了不忽略错误、保持处理一致性及避免过度处理的重要性,并通过文件操作和网络编程实例展示了错误处理的应用。
56 4
|
2月前
|
NoSQL C语言 索引
十二个C语言新手编程时常犯的错误及解决方式
C语言初学者常遇错误包括语法错误、未初始化变量、数组越界、指针错误、函数声明与定义不匹配、忘记包含头文件、格式化字符串错误、忘记返回值、内存泄漏、逻辑错误、字符串未正确终止及递归无退出条件。解决方法涉及仔细检查代码、初始化变量、确保索引有效、正确使用指针与格式化字符串、包含必要头文件、使用调试工具跟踪逻辑、避免内存泄漏及确保递归有基准情况。利用调试器、编写注释及查阅资料也有助于提高编程效率。避免这些错误可使代码更稳定、高效。
433 12
|
3月前
|
存储 算法 Linux
C语言 多进程编程(一)进程创建
本文详细介绍了Linux系统中的进程管理。首先,文章解释了进程的概念及其特点,强调了进程作为操作系统中独立可调度实体的重要性。文章还深入讲解了Linux下的进程管理,包括如何获取进程ID、进程地址空间、虚拟地址与物理地址的区别,以及进程状态管理和优先级设置等内容。此外,还介绍了常用进程管理命令如`ps`、`top`、`pstree`和`kill`的使用方法。最后,文章讨论了进程的创建、退出和等待机制,并展示了如何通过`fork()`、`exec`家族函数以及`wait()`和`waitpid()`函数来管理和控制进程。此外,还介绍了守护进程的创建方法。
C语言 多进程编程(一)进程创建
|
3月前
|
Linux C语言
C语言 多进程编程(三)信号处理方式和自定义处理函数
本文详细介绍了Linux系统中进程间通信的关键机制——信号。首先解释了信号作为一种异步通知机制的特点及其主要来源,接着列举了常见的信号类型及其定义。文章进一步探讨了信号的处理流程和Linux中处理信号的方式,包括忽略信号、捕捉信号以及执行默认操作。此外,通过具体示例演示了如何创建子进程并通过信号进行控制。最后,讲解了如何通过`signal`函数自定义信号处理函数,并提供了完整的示例代码,展示了父子进程之间通过信号进行通信的过程。
|
3月前
|
Linux C语言
C语言 多进程编程(四)定时器信号和子进程退出信号
本文详细介绍了Linux系统中的定时器信号及其相关函数。首先,文章解释了`SIGALRM`信号的作用及应用场景,包括计时器、超时重试和定时任务等。接着介绍了`alarm()`函数,展示了如何设置定时器以及其局限性。随后探讨了`setitimer()`函数,比较了它与`alarm()`的不同之处,包括定时器类型、精度和支持的定时器数量等方面。最后,文章讲解了子进程退出时如何利用`SIGCHLD`信号,提供了示例代码展示如何处理子进程退出信号,避免僵尸进程问题。
|
3月前
|
消息中间件 Unix Linux
C语言 多进程编程(五)消息队列
本文介绍了Linux系统中多进程通信之消息队列的使用方法。首先通过`ftok()`函数生成消息队列的唯一ID,然后使用`msgget()`创建消息队列,并通过`msgctl()`进行操作,如删除队列。接着,通过`msgsnd()`函数发送消息到消息队列,使用`msgrcv()`函数从队列中接收消息。文章提供了详细的函数原型、参数说明及示例代码,帮助读者理解和应用消息队列进行进程间通信。
|
3月前
|
缓存 Linux C语言
C语言 多进程编程(六)共享内存
本文介绍了Linux系统下的多进程通信机制——共享内存的使用方法。首先详细讲解了如何通过`shmget()`函数创建共享内存,并提供了示例代码。接着介绍了如何利用`shmctl()`函数删除共享内存。随后,文章解释了共享内存映射的概念及其实现方法,包括使用`shmat()`函数进行映射以及使用`shmdt()`函数解除映射,并给出了相应的示例代码。最后,展示了如何在共享内存中读写数据的具体操作流程。
|
3月前
|
消息中间件 Unix Linux
C语言 多进程编程(二)管道
本文详细介绍了Linux下的进程间通信(IPC),重点讨论了管道通信机制。首先,文章概述了进程间通信的基本概念及重要性,并列举了几种常见的IPC方式。接着深入探讨了管道通信,包括无名管道(匿名管道)和有名管道(命名管道)。无名管道主要用于父子进程间的单向通信,有名管道则可用于任意进程间的通信。文中提供了丰富的示例代码,展示了如何使用`pipe()`和`mkfifo()`函数创建管道,并通过实例演示了如何利用管道进行进程间的消息传递。此外,还分析了管道的特点、优缺点以及如何通过`errno`判断管道是否存在,帮助读者更好地理解和应用管道通信技术。
|
3月前
|
存储 Ubuntu Linux
C语言 多线程编程(1) 初识线程和条件变量
本文档详细介绍了多线程的概念、相关命令及线程的操作方法。首先解释了线程的定义及其与进程的关系,接着对比了线程与进程的区别。随后介绍了如何在 Linux 系统中使用 `pidstat`、`top` 和 `ps` 命令查看线程信息。文档还探讨了多进程和多线程模式各自的优缺点及适用场景,并详细讲解了如何使用 POSIX 线程库创建、退出、等待和取消线程。此外,还介绍了线程分离的概念和方法,并提供了多个示例代码帮助理解。最后,深入探讨了线程间的通讯机制、互斥锁和条件变量的使用,通过具体示例展示了如何实现生产者与消费者的同步模型。
下一篇
DataWorks