移动 前端 Python Android JavaC/C++ 专题知识每天进步一点点

C 语言常用小点

2021-04-14  本文已影响0人  zcwfeng

c 语言函数官网文档

1. 数组与指针

数组使用

二维数组
int ** arr;
三维数组
int *** arr;

void * 可以任意转换成int * ..... 任意指针

遍历和指针

 int arr[] = {1,2,3};
    int i=0;
    for (i = 0; i < sizeof(arr) / sizeof(int); ++i) {
        printf("%d\n",*(arr+i));
    }

正常情况下
c语言常量不能修改,但是可以通过指针修改
const int num = 100;
int *pnum = #
*pnum = 10000;

2. 函数和指针

指针函数

void add (int num1,int num2){
    printf("num1+num2=%d ",num1+num2);
}
void mins(int num1,int num2){
    printf("num1-num2=%d ",num1-num2);
}

void operate(*method(int,int),int num1,num2){
    method(num1,num2);
}

函数回调

void callBackMethod(char * file_name,int current,int progress){
    printf("%s的图片压缩进度%d/%d\n",file_name,current,progress);
}

void compress(char * filename,void(* callBackP)(char *,int,int)){
    callBackP(filename,50,100);
}

调用

void (* call)(char *,int,int);
    call =  callBackMethod;
    compress("david.png",call);

3. 内存模式

全局区,

全局&静态&常量:全局(global)变量,静态(static)变量,各种常量(字符串字面量,const修饰的量)

代码区,

你写的代码,各种函数(包括类成员函数)

栈,

局部变量&函数参数:在函数内声明的变量(包括main函数)

堆,

使用new,malloc,colloc等关键字手动开辟的内存

磁盘,寄存器

4. 申请内存函数区别

栈区

局部变量&函数参数:在函数内声明的变量(包括main函数)

int arr[(int) (1.5 * 1024 * 1024)];

注意栈区大小有限制比较小,根据系统不同不同

堆区

使用new,malloc,colloc等关键字手动开辟的内存

windows 给编译器空间比较大,80% 大概,看实际情况

malloc:
堆中申请内存,一般情况,配合memset 对内存初始化

alloca:
栈中申请内存,不需要师范

realloc
扩容,重置指针指向内存大小,堆

calloc
malloc + memset,堆

静态分配

void foo(){
int arr[5];
...
}

main函数进栈,调用foo,foo函数进栈,foo执行完毕弹出栈,释放arr[5] 的20 空间

动态分配

char * str = malloc(100)... free(str)


void malloctest(){
    int * arr = malloc(10);
    printf("arr 栈%p,堆,%p\n",&arr,arr);
    free(arr);
    arr = NULL;
    printf("2222arr 栈%p,堆,%p\n",&arr,arr);
}

5. inline的用法和解释

参见C++ 常用小点

6. 友元函数

参见C++ 常用小点

7. 频率比较高的函数

C语言速查
srand 随机数

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

int main(void) 
{ 
   int i; 
   time_t t;

   srand((unsigned) time(&t)); 
   printf("Ten random numbers from 0 to 99\n\n"); 
   for(i=0; i<10; i++) 
       printf("%d\n", rand() % 100); 
   return 0; 
} 
  

strcpy 拷贝函数

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

int main(void) 
 { 
    char string[10]; 
    char *str1 = "abcdefghi";

    strcpy(string, str1); 
    printf("%s\n", string); 
    return 0; 
 } 

sleep

#include <dos.h> 
#include <stdio.h>

int main(void) 
{ 
   int i;

   for (i=1; i<5; i++) 
   { 
      printf("Sleeping for %d seconds\n", i); 
      sleep(i); 
   } 
   return 0; 
} 
  

sticmp

strcmpi

strstr

atoi

查看c文档,小白级别

8. 字符串

char * str = "David";
char str[] = {'D','a','v','i','d','\0'}

注意‘\0’结尾

str[2] = 'z' 只能修改str[] 他是栈区

C语言 字符串截取的几个思路

void substr(char *result, char *str, int start, int end) {
    char *temp = str;
    int count = 0;
    while (*temp) {
        temp++;
        count++;
        if (count >= start && count <= end) {
            *result = *temp;
            result++;
        }
    }
}


void substr2(char *result, char *str, int start, int end) {
    char *temp = str;
    // 截取字符串,截取多少用多少
    char resultArr[end - start];
    int count = 0;
    int i;
    for (i = start; i < end; ++i) {
        resultArr[count] = *(temp + i);
        count++;
    }
//    *result = resultArr;//x 错误一级指针指向容器,因为容器结束方法会栈回收
    strcpy(result, resultArr);//1. copy字符串
}

void substr2_2(char **result, char *str, int start, int end) {
    char *temp = str;
    // 截取字符串,截取多少用多少
    char resultArr[end - start];
    int count = 0;
    int i;
    for (i = start; i < end; ++i) {
        resultArr[count] = *(temp + i);
        count++;
    }
    strcpy(*result, resultArr);//1. copy字符串
}

void substr3(char **result, char *str, int start, int end) {
    char *temp = str;
    // 截取字符串,截取多少用多少
    char *resultArr = malloc(end - start);
    int count = 0;
    int i;
    for (i = start; i < end; ++i) {
        resultArr[count] = *(temp + i);
        count++;
    }
    *result = resultArr;
}

void substr4(char *result, char *str, int start, int end) {
    int i;
    for (i = start; i < end; ++i) {
        *(result++) = *(str + i);
    }
}

void substr5(char **result, char *str, int start, int end) {
    strncpy(*result, str+start, end-start);
}

int main() {
   char *str = "David is good is better man ! Alex eat shit!";
    char *result;
//    substr(result,str,2,5);
//    substr2(result, str, 2, 5);
//    substr3(&result, str, 2, 5);
//    free(result);
//    substr2_2(&result, str, 2, 5);
//    substr4(result, str, 2, 5);

    substr5(&result, str, 2,5);
    printf("result === %s", result);


}

9. 用指针获取长度,有的时候传递数组sizeof不灵

int getLen(char * str){
    int count=0;
    while(*str){
        str++;
        count++;
    }
    return count;
}
int getLen2(int intarr[]){
    int len = sizeof(intarr) / sizeof(int);
    printf("getLen2 len:%d\n",len);
}

int getLen3(int * intarr){
    int len = sizeof(intarr) / sizeof(int);
    printf("getLen2 len:%d\n",len);
}

int getLen4(int * intarr){
    int count=0;
    while(*intarr){
        intarr++;
        count++;
    }
    printf("getLen2 len:%d\n",count);

    return count;
}

int main(){
    char str[] = {'A','B','C','\0'};
    int len = getLen(str);
    printf("length str:%d\n" ,len);
    int arr[]={1,2,3,4,5,6,7};
    getLen2(arr);
    getLen3(arr);
    getLen4(arr);

}

10 结构体

struct Dog {
    char name[10];
    int age;
    char sex;
};

struct Person {
    char *name;
    int age;
    char sex;
} ppp = {"David", 33, 'M'};

struct Study {
    char *studyContent;
};
struct Student {
    char *name;
    int age;
    char sex;
    struct Study study;
    struct Wan {
        char *wanContent;
    } wan;

};

struct Cat{
    char name[10];
    int age;
};


int main() {
    struct Dog dog;
    strcpy(dog.name, "xiao miao");
    dog.sex = 'w';
    printf("name %s,%c\n", dog.name, dog.sex);

    printf("name %s,%c,%d\n", ppp.name, ppp.sex, ppp.age);

    struct Student student = {
            "David", 'M', 33,
            {
                    "C++"
            }, {
                    "王者荣耀"
            }
    };
    Struct Student *student1 = &student;
    student1->age = 3;

    struct Cat * cat = malloc(sizeof(struct Cat));
    strcpy(cat->name,"Cat Cat");

    free(cat);
    cat = NULL;

    return 0;
}

struct 兼容

struct Worker_{
    char name[10];
    int age;
    char sex;
};

typedef struct Worker_ Worker_;
typedef struct Worker_ * Worker;
//=======

typdef struct Worker_{
    char name[10];
    int age;
    char sex;
} worker;

`枚举`类似enum的兼容

typedef enum CommenType{
    TEXT = 10,
    TEXT_IMAGE,
    IMAGE
}CommenType;

int main() {
    

    Worker worker;

    return 0;
}

很多源码,大量使用typedef 别名,原因是为了平台的兼容问题。


结构体定义与使用

    struct Book1{
        char title[10];
        char author[10];
        int id;
    
    } book = {.title="c lang",.author="av",.id=1};

    struct Book book1;
    strcpy(book1.title,"c++ lang");
    strcpy(book1.author,"david");
    book1.id = 2;
    -> 指针使用
    struct  Book *p;
    p = &book1;

    printf("book id:%d\n",p->id);
    printf("book title:%s\n",p->title);
    printf("book author:%s\n",p->author);

    printf("book id:%d\n",(*p).id);
    printf("book title:%s\n",(*p).title);
    printf("book author:%s\n",(*p).author);

Union 类似Struct

union Data{
        int i;
        float f;
        char str[20];
    } data ={.i=1,.f=1.0,.str="ddd"};

    -> 占用内存方式有区别
    printf("%lu",sizeof(book1));
    printf("%lu",sizeof(data));

11. 文件操作读写,加解密

int main15() {
//FILE  *fopen(const char * __restrict __filename, const char * __restrict __mode) __DARWIN_ALIAS_STARTING(__MAC_10_6, __IPHONE_2_0, __DARWIN_ALIAS(fopen));
//r,w,rb,rw

    char *filename = "/Users/zcw/dev/c_workspace/TempC/src/cpp/DavidFile.txt";
    FILE * file = fopen(filename, "r");
    if(!file){
        printf("文件打开失败,请检%s文件查路径",filename);
        exit(0);
    }
    char buffer[10];
    while(fgets(buffer,10,file)){
        printf("%s",buffer);
    }
    //close
    fclose(file);
    return 0;
}

int main17() {
//FILE  *fopen(const char * __restrict __filename, const char * __restrict __mode) __DARWIN_ALIAS_STARTING(__MAC_10_6, __IPHONE_2_0, __DARWIN_ALIAS(fopen));
//r,w,rb

    char *filename = "/Users/zcw/dev/c_workspace/TempC/src/cpp/DavidFileW.txt";
    FILE * file = fopen(filename, "w");
    if(!file){
        printf("文件打开失败,请检%s文件查路径",filename);
        exit(0);
    }

    fputs("David Success",file);

    //close
    fclose(file);
    return 0;
}

int main18() {
//FILE  *fopen(const char * __restrict __filename, const char * __restrict __mode) __DARWIN_ALIAS_STARTING(__MAC_10_6, __IPHONE_2_0, __DARWIN_ALIAS(fopen));
//r,w,rb

    char *filename = "/Users/zcw/dev/c_workspace/TempC/src/cpp/DavidFile.txt";
    char *filenameCopy = "/Users/zcw/dev/c_workspace/TempC/src/cpp/DavidFileCopy.txt";
    //读取二进制
    FILE * file = fopen(filename, "rb");
    FILE * fileW = fopen(filenameCopy,"wb");
    if(!file || !fileW){
        printf("文件打开失败,请检%s文件查路径",filename);
        exit(0);
    }
    int buf[512];
    int len;//每次读取长度
    while((len = fread(buf, sizeof(int),
            sizeof(buf)/ sizeof(int),file)) !=0){
        fwrite(buf, sizeof(int), len, fileW);
        fflush(fileW);
    }
    //close
    fclose(file);
    fclose(fileW);
    return 0;
}

int main19(){
//FILE  *fopen(const char * __restrict __filename, const char * __restrict __mode) __DARWIN_ALIAS_STARTING(__MAC_10_6, __IPHONE_2_0, __DARWIN_ALIAS(fopen));
//r,w,rb

    char *filename = "/Users/zcw/dev/c_workspace/TempC/src/cpp/DavidFile.txt";
    //读取二进制
    FILE * file = fopen(filename, "rb");
    if(!file){
        printf("文件打开失败,请检%s文件查路径",filename);
        exit(0);
    }
    // 指针挪动读取大小,SEEK_SET,SEEK_CUR,SEEK_END
    fseek(file,0,SEEK_END);    //file 有了更丰富的值
    long file_size = ftell(file);    //file 赋值记录信息
    printf("%s文件的大小是%ld\n",filename,file_size);

    //close
    fclose(file);
    return 0;
}

int main20(){
    char *filename = "/Users/zcw/dev/c_workspace/TempC/src/cpp/DavidFile.txt";
    char *filenameEncode = "/Users/zcw/dev/c_workspace/TempC/src/cpp/DavidFileEncode.txt";

    //读取二进制
    FILE * file = fopen(filename, "rb");//文件已经有了
    FILE * fileEncode = fopen(filenameEncode, "wb");//创建0kb文件

    if(!file || !fileEncode){
        printf("文件打开失败,请检%s文件查路径",filename);
        exit(0);
    }

    //TODO
    //加密,破坏文件,解密,还原之前的样子
    // 每个字节都拿出来,对每一个字节处理
    // 部分加密一部分拿出来处理
    // while 循环遍历取出来的10
    // 10 异或 5 变成 1111
    //TODO
    // 解密 1111 异或 5 还原10

    int c;//接受读取值,fget 返回EOF=end of file
    while((c = fgetc(file)) != EOF ){
        fputc(c ^ 5,fileEncode);
    }

    //close
    fclose(file);
    fclose(fileEncode);
    return 0;
}

int main21(){
    char *filename = "/Users/zcw/dev/c_workspace/TempC/src/cpp/DavidFileEncode.txt";
    char *filenameDecode = "/Users/zcw/dev/c_workspace/TempC/src/cpp/DavidFileDecode.txt";

    //读取二进制
    FILE * file = fopen(filename, "rb");//文件已经有了
    FILE * fileDecode = fopen(filenameDecode, "wb");//创建0kb文件

    if(!file || !fileDecode){
        printf("文件打开失败,请检%s文件查路径",filename);
        exit(0);
    }



    int c;//接受读取值,fget 返回EOF=end of file
    while((c = fgetc(file)) != EOF ){
        fputc(c ^ 5,fileDecode);
    }

    //close
    fclose(file);
    fclose(fileDecode);
    return 0;
}

int main(){
//    char *filename = "/Users/zcw/dev/c_workspace/TempC/src/cpp/DavidFile.txt";
//    char *filenameDecode = "/Users/zcw/dev/c_workspace/TempC/src/cpp/DavidFileEncode2.txt";
    char *filename = "/Users/zcw/dev/c_workspace/TempC/src/cpp/DavidFileEncode2.txt";
    char *filenameDecode = "/Users/zcw/dev/c_workspace/TempC/src/cpp/DavidFileDecode2.txt";

    char * password = "123456";
    //读取二进制
    FILE * file = fopen(filename, "rb");//文件已经有了
    FILE * fileDecode = fopen(filenameDecode, "wb");//创建0kb文件

    if(!file || !fileDecode){
        printf("文件打开失败,请检%s文件查路径",filename);
        exit(0);
    }



    int c;//接受读取值,fget 返回EOF=end of file
    int index = 0;
    int pass_len = strlen(password);
    while((c = fgetc(file)) != EOF ){
        char item = password[index % pass_len];
        index++;
        //1 2 3 4 5 1 2 3 4 5
        printf("%c\n",item);
        fputc(c ^ item,fileDecode);
    }

    //close
    fclose(file);
    fclose(fileDecode);
    return 0;
}
上一篇 下一篇

猜你喜欢

热点阅读