少女祈祷中...

C语言

安装vs2022

配置环境

第一个程序

#include <stdio.h>
int main(){
    printf("Hello world");
    return 0;
}

在第一个程序中,stdio.h全称为标准输入输出,在<>内,还可以放置math.h,time.h等其他库。int定义程序的结果是一个整数,main定义程序的主入口名字,不能改变。{}内是代码范围,return 0;表示程序正常结束,非0表示非正常结束,它于int main相对应。

程序执行流程

1.编写

2.编译

3.链接

4.执行

核心语法

注释

//test

/*

test

*/

关键字

关键字为全部小写高亮字符

常量

  • 整数常量
  • 实型常量 (带小数点的常量)
  • 字符常量 (带单引号的单个字母数字符号)
  • 字符串常量

image-20240925163433463

输出常量

#include <stdio.h>
int main(){
	printf("输出最终内容",)
}
格式控制符 说明 单词
%d 整数型 decimal
%f 实型 floating-point
%c 字符型 character
%s 字符串型 string
#include <stdio.h>
int main(){
    printf("魏鑫身高%f,年龄%d,喜欢吃%s",121.1,18,"shi");
    return 0;
}

Tips

image-20240925181647752

#include <stdio.h>
int main() {
    printf("魏鑫的女朋友的姓名是:%s。性别%s。年龄%d。身高%.1f米。体重%d。", "狗", "女", 18, 1.5, 110);
    return 0;
}

变量

格式

int a ; #int:类型,a:变量名

#include <stdio.h>
int main() {
    int a = 10, b = 20,c=a+b;
    printf("c是:%d", c);
    return 0;
}

计算机存储规则

数据类型

整数类型

整数 取值范围 内存
short -32768~32767 2
int -2147483648~2147489647 4
long ……………………………………… 4,8
long long ………………………………………………… 8

sizeof()测量数据类型占用多少字节

#include <stdio.h>
int main() {
    short int a = 10;
    printf("%d\n",a);
    int b = 50;
    printf("%d\n",b);
    long int c = 1000L;
    printf("%ld\n",c);
    long long int d =10000L;
    printf("%lld\n",d);
    //signed:定义有符号整数,正数,复数
    //unsigned:定义无符号整数,正数
    signed int e = -4;
    printf("%d\n",e);
    unsigned int d = 1; //定义一个序号1,甚至你还可以在unsigned后加个short
    printf("%u\n",d)
	return 0;
}
#include <stdio.h>
int main() {
    float a = 3.14F;
    printf("%.2f\n",a);
    //double双精度小数
    double b = 1.78;
    printf("%.lf\n",b);
    // long double高精度小数
    long double c = 3.1415926L;
    printf("%.2lf\n",c)
    //用sizeof测量每个类型占多少字节
    printf("%zu\n",sizeof(float));
    printf("%zu\n",sizeof(a));
    //小数数据无法跟unsigned组合使用
}
//char类型占一个字节
char a = "a",b = "1";
printf("%c\n%c\n",a,b);

算数运算符与逻辑运算符

大致省略

Tips

键盘输出数字,将其拆分成个位,十位,百位(只能输入百位数)

#include <stdio.h>

int main() {
    printf("请输入数字:");
    int num;
    scanf_s("%d", &num);
    int ge;
    ge = num % 10;
    printf("个位:%d\n", ge);
    int shi;
    shi = num / 10 % 10;
    printf("十位:%d\n", shi);
    int bai;
    bai = num / 100 % 10;
    printf("百位:%d\n", bai);
    return 0;
}

隐式转换

  • 在进行不同类型的数据计算时,会把取值范围小的数据类型转换为取值范围大的数据类型
  • short和char在进行运算时会提升为int类型再计算

double > float > long long > long > int > short > char

强制转换

  • 如果把取值范围大的转换为取值范围小的,就要强制转换
int a = 10;
short i = (short)a;
____________________________________________________________________________________________________________
short a = 10;
short b = 20;
shout r = (short)a + b;//shout运算时会转换为int

运算符

字符相加

#include <stdio.h>
int main() {
    //"a" "A" "0"所对应的ascll码
    printf("%d",'a');
    printf("%d",'A');
    printf("%d",'0');
    return 0;
}

自增自减运算符

int a = 10;
a++;//a = 11
a--;//a = 9
++a;//a = 11
--a;//a = 9

win7时前缀优先后缀,其他优先级一样

赋值运算符

关系运算符

逻辑运算符

&& 与 ||具有短路效果

三元运算符

  • 格式:关系表达式? 表达式1: 表达式2;
  • 首先计算关系表达式的值
  • 如果成立,返回表达式1,反之返回表达式2
//求两数最大值
a > b ? a : b;
//求三数最大值
int t = a > b ? a : b;
t > c ? t : c;

逗号运算符

运算符的优先级

image-20241030205752126

流程控制语句

  • 顺序结构
  • 分支结构
  • 循环结构

分支结构

if a<b {
    return 0;
}
else if {
    return 0;
}
else {
    return 0;
}
switch () {
    case 1 :
        break;
    case 2 :
        break;
    default :
        break;
}

循环语句

for (初始;判断;控制;) {
    return 0;
}
//输入两个整数,求它们范围内能被6和8整除的数
#include <stdio.h>
int main() {
    int num1, num2;
    int a = 0;
    printf("请输入两个整数:\n");
    scanf_s("%d\n%d", &num1,&num2);
    for (int i = num1; i < num2; i++) {
        if (i % 6 == 0 && i % 8 == 0) {
            printf("依次为:\n%d\n", i);
            a++;
        }
    }
    printf("一共有%d个", a);
    return 0;
}

image-20241031192210389

image-20241031192812172

//初始化
while (判断){
    循环
    控制
}

image-20241031202646875

#include <stdio.h>
int main() {
    int n = 0;
    printf("请输入数字:");
    scanf_s("%d", &n);
    int i = n;
    //printf("%d", i);
    while (i != 1 && i % 2 == 0) {
        i /= 2;
        //printf("%d\n", i);
    }
    //printf("%d", i);
    if (i == 1) {
        printf("yes");
    }
    else {
        printf("no");
    }
    return 0;
}

image-20241031203727142

#include <stdio.h>
int main() {
    int a = 0;
    double b = 0.1;
    while (b <= 8844430) {
        b = b * 2;
        a++;
    }
    printf("%d", a);
    return 0;
}

image-20241105185952969

#include <stdio.h>
int d = 0;
int a = 0;
int main()
{
    printf("请输入数字");
    scanf("%d", &d);
    while (d != 0)
    {
        int temp = d % 10;
        d/=10;
        a =a * 10 + temp;
    }
    printf("%d", a);
}

image-20241105190422961

#include <stdio.h>
int main()
{
    int a;
    printf("Enter a number: ");
    scanf("%d", &a);
    int b = 0;
    int c = 0;
    while (c < a)
    {
        b++;
        c = b * b;

    }
    printf("The number is: %d", b-1);
}

image-20241105194220168

#include <stdio.h>
int d = 0;
int a = 0;
int main()
{
    printf("请输入数字");
    scanf("%d", &d);
    int c = d;
    while (d != 0)
    {
        int temp = d % 10;
        d/=10;
        a =a * 10 + temp;
    }
    if (a == c)
    {
        printf("true");
    }
    else if(a!=c)
    {
        printf("not");
    }
}

image-20241105203050357

#include <stdio.h>
int main()
{
   int a,b;
   int c = 0;
   printf("Enter a number:");
   scanf("%d",&a);
   printf("Enter another number:");
   scanf("%d",&b);
   while (a>=b)
   {
      a=a-b;
      c++;
   }
   printf("商:%d\n",c);
   printf("余:%d",a);
}

do….while 语句

初始化语句;

do {

​ 循环体语句;

​ 条件控制语句;

}while循环(条件判断语句);

image-20241105204359518

循环语句(高级)

无限循环

for (;;){
    
}
while (1){
    
}
do{
    
}while(1)

跳转控制语句

  • 在循环控制中,跳到其他语句执行
#在100内第一个能被3和5整除的数
#include <stdio.h>
int main()
{
    for (int i = 1;i<100;i++)
    {
        if (i%3==0&&i%5==0)
        {
            printf("%d\n",i);
            break;
        }
    }
}
#continu就是结束本次循环,跳过本次循环,执行下次循环

循环嵌套

#打印三行五列的*
int main()
{
    for (int i = 0;i < 3;i++)
    {
        printf("\n");
        for (int j = 0;j < 5;j++)
            printf("*");
    }
    return 0;
}
#打印正直角三角和倒直角三角
int main()
{
    for (int i = 1;i <= 5;i++)
    {
        printf("\n");
        for (int j = i;j <= 5;j++)
            printf("*");
    }
    return 0;
}
int main()
{
    for (int i = 1;i<=5;i++)
    {
        printf("\n");
        for (int j = 1;j <=i ;j++)
            printf("*");
    }
    return 0;
}
#九九乘法表
int main()
{
    for (int i =1; i<10; i++)
    {
        printf("\n");
        for (int j =1; j<=i; j++)
        {
            printf("%d * %d = %d\t",j,i,j*i);
        }
    }
    return 0;
}
#找质数
int main()
{
    int a = 0;
    int c = 0;
    printf("num");
    scanf("%d",&a);
    for (int i = 2; i <= a; i++)
    {
        int b = 0;
        for (int j = 2; j < i; j++)
        {
            if (i % j == 0)
            {
                b++;
                break;
            }
        }
        if (b == 0)
        {
            printf("yes");
            c++;
        }
        else
        {
            printf("no");
        }
    }

    printf("%d",c);
    return 0;
}
#输出1~1000内个数相加为15的数
int main()
{
    for (int i = 1;i <= 1000;i++)
    {
        int a = i;
        int b =  0 ;
        while (a != 0){
            b = a;
            int temp = a % 10;
            a = a / 10;
            int temp2 = a % 10;
            a = a / 10;
            if (temp + temp2 + a == 15)
            {
                printf("%d\t",b);
            }
        }
    }
        return 0;
}
#### go to 使用
for (i = 0;i < 5;i++){
    for (j = 0;j < 5;j++){
        printf("he");
        goto a;
    }
}
a: printf("llo");

函数

常见函数

image-20241111174912701

c手册:cppreference.com

随机数

线性同余方程

$x$n-1 $ = ax_n + b\,mod\,m$

#include <stdio.h>
#include <stdlib.h>
int main(){
    srand(1);
    for (int i; i < 5; i++){
        int num = rand();
        printf("%d\n",num);
    }
    return 0;
}

弊端:

  • 种子固定,随机数固定
  • 随机数范围(0~32767)
#随机种子
int main(){
    srand(time(NULL));
    int num = rand();
    printf("%d\n",num);
}
#定义随机范围
#1.(7~87),包左不包右,7~88(87+1)
#2.拿右减开头 88 - 7 = 81
int main(){
    srand(time(NULL));
    int num = rand() % 81+ 7;//0~80 7 就是7~87
    printf("%d\n",num);
}
#判读输入的数是否与随机数相同
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main() {
    srand(time(NULL));
    for (int i = 1; i <= 100; i++)		#用while(1)也行
    {
        int num = rand() % 100 + 1;
        printf("随机数为:%d",num);
        printf("Enter:");
        int num1 = 0;
        scanf("%d", &num1);
        if (num == num1)
        {
            printf("%d\n", num);
            break;
        }
        else
        {
            printf("no\n");
        }
    }
}

数组

数据类型 数组名 [长度] ={数据值,数据值……}

变量 = 数组名[索引]

数组遍历

内存地址

32位:2^32^

64位:2^54^

转十六位方便阅读

数组在内存中

image-20241111234019047

a[5] = {1,2,3,4,5};
printf("%p/n",a);

image-20241113105914612

数组的俩问题

  • 数组作为函数的形参,注意什么
    • 实际传递的是数组的首地址
  • 数组的索引越界问题
    • 最小索引:0
    • 最大索引: 长度-1

image-20241113211013978

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void aa();
int main()
{
    int a[] = {1,2,3,4,5};
    int size = sizeof(a) / sizeof(int);
    aa(a,size);
}
void aa(int a[],int size)
{
    for (int i = 0; i < size; i++)
    {
        printf("%d\n",a[i]);
    }
}

image-20241113212125499

#求最大值
int main()
{
    int a [] ={33,5,66,44,55};
    int len = sizeof(a) / sizeof(int);
    int max = 0;
    for (int i = 1; i < len; i++)
    {
        if (a[i] > max)
        {
            max = a[i];
        }
    }
    printf("%d\n", max);
}

image-20241117195822192

int main()
{
    srand(time(NULL));
    int a = 0,sum = 0;
    int b[10] = {0};
    for (int i = 0; i < 10; i++) {
        a = rand() % 100 + 1;
        b[i] = a;
        sum += b[i];
    }
    printf("和:%d",sum);
}

image-20241117195854080

int main()
{
    srand(time(NULL));
    int a= 0,sum = 0,c = 0,d = 0;
    float count = 0;
    int b[10];
    for (int i = 0; i < 10; i++)
    {
        a = rand() % 100 + 1;
        b[i] = a;
        sum += b[i];
        c++;
    }
    count = sum;
   for (int i = 0; i < 10; i++)
   {
       if (b[i] < count/c)
       {
           d++;
       }
   }
    printf("和:%d:\n",sum);
    printf("平均数:%.1f\n",count/c);
    printf("小于平均数的:%d",d);
    return 0;
}

image-20241117211501709

int main()
{
    int a[5]={0};
    for (int i = 0; i < 5; i++)
    {
        printf("Enter Number : ");
        scanf("%d",&a[i]);
    }
    for (int i = 0; i < 5; i++)
    {
        printf("%d ",a[i]);
    }
    printf("\n");
  for (int i = 0,j = 4; i < j; i++,j--)
  {
      int temp = a[i];
      a[i] = a[j];
      a[j] = temp;


  }
    for (int i = 0; i < 5; i++)
    {
        printf("%d ",a[i]);
    }
}

image-20241117211648201

int main()
{
    srand(time(NULL));

    int b[5];
    for (int i = 0; i < 5; i++)
    {
        printf("Enter a number: ");
        scanf("%d", &b[i]);
    }
    for (int i = 0; i < 5; i++)
    {
        int a = rand() % 5;
        int temp = b[i];
        b[i] = b[a];
        b[a] = temp;
    }
    for (int i = 0; i < 5; i++)
    {
        printf("%d ", b[i]);
    }
}

常见算法

  • 基本查找
  • 二分查找
  • 插值查找
  • 分块查找(以下全了解)
  • 哈希查找
  • 树表查找
  • 斐波那契查找

基本查找:

int main()
{
    int b[5] = {1, 2, 3, 4, 5};
    for (int i = 0; i < 5; i++)
    {

        if (b[i]==3)
        {
            printf("Yes");
            break;
        }
        if (i == 4)
        {
            printf("No\n");
        }
    }
}

二分查找

#必须是有顺序的一组数,不论从大到小还是从小到大
int a();
int main()
{
    int arr[8] = {2,12,354,4567,7544,7777,8888,99888};
    int num = 0;
    int len = sizeof(arr) / sizeof(arr[0]);
    printf("Enter");
    scanf("%d",&num);
    int index = a(arr,len,num);
    printf("%d",index);
}

int a(int arr[], int len, int num)
{
    int max = len -1;
    int min = 0;
    while(min <= max)
    {
        int mid = (max+min)/2;
        if(arr[mid] < num)
        {
            min = mid + 1;
        }
        else if (arr[mid] > num)
        {
            max = mid -1;
        }
        else
        {
            return arr[mid];
        }

    }
    return -1;
}

插值查找(二分查找改进)

$mid = min + (key-arr[min]) / (arr[max] - arr[min]) * (max - min)$

$mid = min + \frac{key-arr[min]}{arr[max]-arr[min]}*(max -min)$

#比二分查找更严格的要求,最好每个数均匀点,如果不满足,反而更慢
..............
    你以为我会写
    	那是不可能的

分块查找

  • 原则1:前一块中的最大数据,小于后一块中所有的数据(块内无序,块外有序)
  • 原则2:块数量一般等于数字的个数开根号。比如16个数字一般分为4块左右。
  • 核心思路:先确定要查找的元素在哪一块,然后在块内挨个查找。

其他不管

排序算法

冒泡排序

  • 相邻俩数据比较,小的放前,大的放后(从小到大,可以改)
int main()
{
    int arr[9] = {3,1,5,4,23,53,11,2,12};
    int len = sizeof(arr) / sizeof(int);
    for (int i = 0; i < len-1; i++)
    {
        for (int j = 0; j < len-1-i; j++)
        {
            if (arr[j] > arr[j + 1])
            {
                int temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
            }
        }
    }
    for (int i = 0; i < len ; i++)
    {
        printf("%d ", arr[i]);
    }
    return 0;
}

选择排序

int main()
{
    int arr[9] = {3,1,5,4,23,53,11,2,12};
    int len = sizeof(arr) / sizeof(int);
    for (int i = 0; i < len-1; i++)
    {
        for (int j = i + 1; j < len; j++)
        {
            if (arr[i] > arr[j]){
                int temp = arr[i];
                arr[i] = arr[j];
                arr[j] = temp;
            }
        }
    }
    for (int i = 0; i < len ; i++)
    {
        printf("%d ", arr[i]);
    }
    return 0;
}

指针

格式:数据类型 * 变量名

int main(){
    int a = 10;
    int *p = &a;
    
    double b = 19;
    double * p = &b;
}

作用:

1.操作其他函数中的变量

2.函数返回多个值

3.函数的结果和计算状态分开

4.方便的操作数组和函数

int swap();
int main()
{
    int a = 12;
    int b = 10;
    swap(&a,&b);
    printf("a=%d, b=%d\n",a,b);
    return 0;
}
int swap(int *a,int *b)
{
    int temp = *a;
    *a = *b;
    *b = temp;
    return 0;
}

指针细节

函数中变量的生命周期跟函数相关,函数结束了,变量也会消失

此时在其他函数中,就不发通过指针使用了

如果不想函数中的变量被回收,可以在变量前面加static关键字

int * p(){
    static int a = 10;
    return &a;
}
int main(){
    int *a = p();
    printf("%d",a);
}
#求最大最小值
void px(int *max,int *min,int len,int a[])
{
    *max = a[0];
    *min = a[0];
    for(int i=1;i<len;i++)
    {
        if(a[i]>*max)
        {
            *max = a[i];
        }
        if(a[i]<*min)
        {
            *min = a[i];
        }
    }
    printf("%d\n",*max);
    printf("%d",*min);
}
int main()
{
    int a[10] = {1,0,112231,4,5,6,7,8,9};
    int len = sizeof(a) / sizeof(a[0]);
    int max = 0,min = 0;
    px(&max,&min,len,a);
}
#定义一个函数,将两数相除,取余数
int a1(int *a,int *b,int *res)
{
    if (*b == 0)
    {
        return 1;
    }
    *res = *a % *b;
    return 0;
}
int main()
{
    int a11 = 0;
    int b11 = 0;
    int res = 0;
    int *a12 = &a11;
    int *b12 = &b11;
    printf("enter:");
    scanf("%d",a12);
    printf("enter:");
    scanf("%d",b12);
    int flag = a1(a12,b12,&res);
    if(flag == 1)
    {
        printf("no");
    }
    else
    {
        printf("%d",res);
    }
}

指针高级

指针的计算

image-20241125214710170

  • 有意义的操作:

    指针跟整数进行加减操作(每次移动n个步长)

    指针跟指针进行减操作

  • 无意义的操作:

    指针跟整数进行乘除操作。原因:指针指向不明

    指针和指针进行加,乘除操作。

  • 野指针:指向空间未分配

  • 悬空指针:指向空间已分配,但被释放了

image-20241126192734507

可以用来交换两个变量的数据

你以为我会写?
    想多了。
  • 指向指针的指针叫二级指针(可套娃)

image-20241126202906815

数组指针

int main() {
    int a[2][5] = {{1, 2, 3, 4, 5},{11,22,33,44,55}
    };
    for (int i = 0; i < 2; i++)
    {
        for (int j = 0; j < 5; j++)
        {
            printf("%d ", a[i][j]);
        }
    }
}

image-20241126220501826

image-20241126220534272

函数指针

image-20241126220615756

image-20241126222128174

#include <stdio.h>
int *j (int *a1, int *b1)
{
    printf("%d\n", *a1 + *b1);
}
int *jj (int *a1, int *b1)
{
    printf("%d\n", *a1 - *b1);
}
int *c (int *a1, int *b1)
{
    printf("%d\n", *a1 * *b1);
}
int * cc (int *a1, int *b1)
{
    if (*b1 == 0)
    {
        printf("error");
        return NULL;
    }
    printf("%d\n", *a1 / *b1);
}
int main()
{
    int a = 0;
    int b = 0;
    int c1 = 0;
    int *p = &a;
    int *p1 = &b;
    printf("enter 1");
    scanf("%d", &a);
    printf("enter 2");
    scanf("%d", &b);
    printf("enter 3");
    scanf("%d", &c1);
    switch (c1)
    {
    case 1:
        j(p, p1);
        break;
    case 2:
        jj(p, p1);
        break;
    case 3:
        c(p, p1);
        break;
    case 4:
        cc(p,p1);
        break;
    default:
        printf("error");
    }
}

字符串

sb c语言没有字符串数据类型,可以用两种方式定义字符串

char str[4] = ["abc"]     #eg:char str[4] = ['a','b','c',\0]
char* str = "abc"
  • c语言中字符保存是以数组的形式保存的
#错误示例
#include <stdio.h>
int main()
{
    char a[3] = "abc";
    printf("%s\n", a);
}
  • 指针定义的字符串不能修改,可以复用

image-20241127194613974

int main()
{
    char a[3] = "";
    printf("Enter a string: ");
    scanf("%s", a);
    for (int i = 0; i < 3; i++)
    {
        printf("%c", a[i]);
    }
}
-------------------------------------------------------------------------------------------------------------------
    int main()
{
    char str[100];
    printf("Enter a string: ");
    scanf("%s", str);
    char* p = str;
    while (*p != '\0')
    {
        printf("%c", *p);
        p++;
    }
}

image-20241127202113246

  • 自己去试

image-20241127222337105

#include <stdio.h>
#include <string.h>
int main()
{
    for (int i = 1; i <= 3;i++)
    {
    char user[100] = "admin";
    char password[100] = "admin";
    char new_user[100] = "";
    char new_password[100] = "admin";
    printf("enter username: ");
    scanf("%s", new_user);
    printf("enter password: ");
    scanf("%s", new_password);

    if (!strcmp(user, new_user) && !strcmp (password, new_password))
    {
        printf("you already exists\n");
        return 0;
    }

    {
        if (i == 3)
    {
        printf("you don't exists,bye\n");
        return 0;
    }
        printf("you don't exists,you only %d\n",3-i);
    }
}
}

image-20241128201819979

int main()
{
    char str[100];
    printf("Enter a string: ");
    scanf("%s", str);
    int bigst = 0;
    int smallst = 0;
    int num = 0;
    for (int i = 0; i < strlen(str);i++)
    {
        char c = str[i];
        if (c >= '0' && c <= '9' )
        {
            num++;
        }
        else if (c >= 'A' && c <= 'Z')
        {
            bigst++;
        }
        else if (c >= 'a' && c <= 'z')
        {
            smallst++;
        }
    }
    printf("The bigst is: %d\n", bigst);
    printf("The smallst is: %d\n", smallst);
    printf("The number is: %d", num);
    return 0;
}

结构体

  • 结构体可以理解为自定义的新的数据类型
  • 他是由一批数据组合而成的结构型数据
  • 里面每个数据都是结构体的成员
struct a {
    char aa[100];
    int b;
    double sc;
};

image-20241128202357334

struct a
{
    char name[20];
    int age;
};
int main()
{
    struct a a = {"John", 20};
    struct a b = {"John1", 201};
    struct a c[3] = {a,b};
    for (int i = 0; i < 2; i++)
    {
        printf("%s %d\n", c[i].name,c[i].age);
    }
}

起别名

typedef struct{
    int a;
    char b[1];
}ss;

image-20241128225217447

typedef struct node
{
    char name[100];
    int age;
    int height;
    int weight;
} ss;
int main()
{
    ss a = {"John", 20,12,21};
    ss b = {"Doe", 30,12,3,};
    ss c = {"Doe", 40,23,12};
    ss d[3] = {a,b,c};
    for (int i = 0; i < 3; i++)
    {
        printf("%s %d\n", d[i].name, d[i].age);
    }
}

结构体作为函数的参数

image-20241128225748708

typedef struct student
{
    char name[20];
    int age;
}s;
void met(s* aa)
{
    printf("%s\t%d\n",aa->name,aa->age);
    printf("enter:");
    scanf("%s",aa->name);
    printf("enter:");
    scanf("%d",&(aa->age));
    printf("%s\t%d\n",aa->name,aa->age);
}
int main()
{
    s stu;
    strcpy(stu.name,"John");
    stu.age = 18;
    printf("student name:%s\n",stu.name);
    met(&stu);
    printf("student age and name:%d %s\n",stu.age,stu.name);
}

结构体嵌套

image-20241128231055858

struct Message
{
    char mail[200];
    char phone[100];
};
struct student
{
    char name[20];
    int age;
    char gender;
    double height;
    struct  Message ms;
};

int main()
{
    struct student s;
    strcpy(s.name,"zhang");
    s.age=20;
    s.gender='m';
    s.height=1.33;
    strcpy(s.ms.phone,"1145134");
    strcpy(s.ms.mail,"sadkfjklas");
    printf("name:%s\n",s.name);
    printf("age:%d\n",s.age);
    printf("gender:%c\n",s.gender);
    printf("height:%f\n",s.height);
    printf("phone:%s\n",s.ms.phone);
    printf("mail:%s\n",s.ms.mail);
}

image-20241129093015171

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

struct node{
    char name[50];
    int count;
};
int main()
{
    struct  node a[4] = {{"A",0},{"B",0},{"C",0},{"D",0}};
    srand(time(NULL));
    for (int i = 0; i < 80; i++)
    {
        int choose = rand() % 4;
        a[choose].count++;
    }
    int max = a[0].count;
    for (int i = 0; i < 4; i++)
    {
        if (a[i].count > max)
        {
            max = a[i].count;
        }
    }
    for (int i = 0; i < 4; i++)
    {
        if (a[i].count == max)
        {
            printf("%s is %d times\n", a[i].name, a[i].count);
        }
    }
    printf("\n");
    for (int i = 0; i < 4; i++)
    {
        struct node t = a[i];
        printf("%s %d\n",t.name,t.count);
    }
}

结构体内存对齐

image-20241203223818938

共同体

  • 一种数据可能又多个数据类型
union Money{
    double mond;
    int mons;
    char mod[100];
}
int main(){
    union Money m;
    m.mod = "100w";
    printf("%s\n",m.mod);
}

共用体的特点

  • 共用体,也叫联合体,共同体
  • 所有的变量都是用同一个内存空间
  • 所占的内存大小 = 最大成员的长度(也受内存影响)
  • 每次只能给一个变量进行赋值,, 因为第二次赋值会覆盖原有数据(也受内存对齐影响)

结构体和共用体的区别

  • 一种事物中包含多个属性

  • 一个数据包含多个类型

    存储方式:

    • 结构体:各存各的
    • 共用体:存一起,多次存会覆盖

    内存占用:

    • 结构体:各变量总和(受内存对齐影响)
    • 共用体:最大类型(受内存对齐影响)

动态内存分配

函数名 作用
malloc 申请连续的空间
calloc 申请连续的空间 + 初始化
realloc 修改空间大小
free 释放空间
#include <stdio.h>
#include <stdlib.h>
int main(){
    int* p = malloc(100 * sizeof(int));
    for (int i = 0;i<100;i++){
        *(p+i) = (i + 1)*10;
        printf("%d\n",*(p+i));
    }
    for (int i = 0;i<100;i++){
        p[i] = (i + 1)*10;
        printf("%d\n",*(p+i));
    }
    free(p);
}

image-20241203231718675

c语言内存结构

image-20241203232051888

  • 函数进栈,变量随之存在,函数退栈,变量随之消失

image-20241203233535491

image-20241203233554556

文件

  • 相对路径
  • 绝对路径

读取文件

  • 打开文件:fopen
  • 读取数据:fgetc fgets fread
  • 关闭文件:fclose
int main()
{
   FILE* file = fopen("D:\\Code_python\\1.txt","r");
   int c ;
   while ((c = fgetc(file))!= EOF)
   {
      printf("%c",c);
   }
   fclose(file);
}

使用fgetc函数从文件流中读取字符时,文件流的内部指针会自动向前移动到下一个字符的位置。这意味着每次调用fgetc时,它都会从当前文件流指针的位置读取字符,并将文件流指针移动到下一个字符。这个过程是自动的,不需要程序员显式地进行指针操作

int main()
{
    FILE* file = fopen("D:\\Code_python\\1.txt","r");
    char c[1024];
    char* str;
    while ((str = fgets(c,1024,file)) != NULL)
    {
        printf("%s",c);
    }
    fclose(file);
}
int main()
{
    FILE* file = fopen("D:\\Code_python\\1.txt","r");
    char c[1024];
    fread(c,sizeof(char),1024,file);
    printf("%s",c);
    fclose(file);
}

写数据

    FILE* file = fopen("D:\\Code_python\\1.txt","w");
    int c = fputc(12,file);
    printf("%d",c);
int main()
{
    FILE* file = fopen("D:\\Code_python\\1.txt","w");
    int d = fputs("hello",file);
    printf("%d",d);
    fclose(file);
}
int main()
{
    FILE* file = fopen("D:\\Code_python\\1.txt","w");
    char a[1024] = {"helloworld"};
    int a1 = fwrite(a,sizeof(a),1,file);
    printf("%d",a1);
    fclose(file);
}

读写模式

模式 描述
r 打开一个已有的文本文件,允许读取文件。
w 打开一个文本文件,允许写入文件。如果文件不存在,则会创建一个新文件。在这里,您的程序会从文件的开头写入内容。如果文件存在,则该会被截断为零长度,重新写入。
a 打开一个文本文件,以追加模式写入文件。如果文件不存在,则会创建一个新文件。在这里,您的程序会在已有的文件内容中追加内容。
r+ 打开一个文本文件,允许读写文件。
w+ 打开一个文本文件,允许读写文件。如果文件已存在,则文件会被截断为零长度,如果文件不存在,则会创建一个新文件。
a+ 打开一个文本文件,允许读写文件。如果文件不存在,则会创建一个新文件。读取会从文件的开头开始,写入则只能是追加模式。
#include <stdio.h>
int main()
{
    FILE* file = fopen("D:\\a\\python杂笔.pdf","rb");
    FILE* file2 = fopen("D:\\a\\python杂笔11.pdf","wb");
    char c[1024];
    int n;
    while((n = fread(c,sizeof(char),1024,file)) != 0)
    {
        fwrite(c,sizeof(char),n,file2);
    }
    fclose(file);
    fclose(file2);
}

本文作者:Iota @ Iotaの小屋

本文发布时间:2024-07-16 11:00:00

本文版权:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

留言