C语言基础一

一、基本数据类型

#include 
// <> 寻找系统的资源
// “” 寻找我们自己写的资源
// .h .hpp(声明文件 头文件)
// .c  .cpp (实现文件)

// 代码结构
int main1() {  // 函数的主入口
    //getchar(); // 阻塞程序
    // 基本数据类型
    int i = 100;
    double d = 200;
    float f = 200;
    long l = 100;
    short s = 100;
    char c = 'd';
    // 字符串
    char * str = "lzr";

    // 不是随便打印的,需要占位
    printf("i的值是:%d\n", i); // d == 整形 100
    printf("d的值是:%lf\n", d); // lf == long float  200.000000
    printf("f的值是:%f\n", f); // f == float  200.000000
    printf("l的值是:%d\n", l); // d == 整形  100
    printf("s的值是:%d\n", s); // s == short  100
    printf("c的值是:%c\n", c); // c == char  d
    printf("字符串:%s\n", str); // s == String   lzr

    printf("char 数据类型所占的字节数:%d\n", sizeof(char));// 1
    printf("short 数据类型所占的字节数:%d\n", sizeof(short));// 2
    printf("long 数据类型所占的字节数:%d\n", sizeof(long));// 4
    printf("float 数据类型所占的字节数:%d\n", sizeof(float));// 4
    printf("int 数据类型所占的字节数:%d\n", sizeof(int));// 4
    printf("double 数据类型所占的字节数:%d\n", sizeof(double));// 8
    return 0;
}

二、指针

1、基本

#include 

// 地址概念
// Java 万物皆对象
// C C++(对象) 万物皆指针(地址)
// Linux 万物皆文件
int main(){
    // %p 地址输出占位符
    // & == 取出地址
    int num = 1000;
    printf("num的地址是%p",&num); //0022FE4C

    int number_int = 100;
    double number_double = 200;
    printf("number_int的值是:%d\n", number_int);
    printf("number_double的值是:%lf\n", number_double);

    // * == 取出number_int地址所对应的值 == 100
    // 指针取出值
    // 既然任何变量都是地址,可以使用都在获取值
    printf("number_int的值是:%d\n", *(&number_int));
    printf("number_double的值是:%lf\n", *(&number_double));

    int * intP = &number_int;
    double * doubleP = &number_double;
    printf("number_int的值是:%d\n", *intP);
    printf("number_double的值是:%lf\n", *doubleP);

    /**
       理解:  大道至简 (化繁为简)
       内存地址 == 指针
        int *,  double *      (int类型的指针)
        指针别名,指针变量 == 就是一个变量而已,只不过 是指针的 变量 而已 :intP,  doubleP
     */
    return 0;
}
指针01.png

2、修改值

#include 
// 通过  指针(地址) 修改值
int main() {
    int i = 100;
    // p:我只接收地址,你给我一个100,不规范
    // int * p = i;
    int * p = &i;
    i= 200;
    printf("i的值是:%d\n", i);
    *p = 300;
    printf("i的值是:%d\n", i);//300
    return 0;
}
4.png
//先声明
void change(int* i);
int main() {
    int i = 100;
    change(&i);
    printf("i的值%d:",i); //666
 // * i 和 *i 有什么区别呢  没区别 写法而已
    /*
        int * i;  定义指针
        *i = 888;  取出内存地址所对应的值修改成 888
    */
    return 0;
}
// 函数不能写在 main的下面,会报错,除非先声明,后实现
void change(int * i){
    *i =666;
}
6.png

4、交换

#include 
void changeAction(int *a,int *b){
    printf("地址:%p,%p\n", a, b);//a:61FE1C   b:61FE18
    //changeAction(a的地址,b地址)
    //*a取出61FE1C内存地址对应的值100
    //*b取出61FE18内存地址对应的值200
    int temp = *a; //temp =100 取出61FE1C内存地址对应的值100赋值给temp
    *a = *b;//将61FE1C内存地址对应的值100修改为61FE18内存地址对应的值200
    *b = temp;//将61FE18内存地址对应的值200修改为100

}
int main(){
    int a = 100;
    int b= 200;
    changeAction(&a,&b);
    printf("交换完成后的效果:%d,%d\n", a, b);
    return 0;
}

5、多级指针

//多级指针
int main() {
    int num = 999;
    int * num_p = # //取出num的内存地址给num_p(一级指针)
    int ** num_p_p = &num_p;//取出num_p的内存地址给num_p_p(二级指针) 指针也有自己的内存地址
    printf("num_p的值是%p,num_p_p的值是:%p\n",num_p,num_p_p);
    printf("输出值:%d",**num_p_p);//999
    return 0;
}
多级指针.png

三、数组和数组指针

1、基础

int main(){
    //定义数组
    //int []arr={1,2,3,4};//错误
    int arr[] = {1,2,3,4};
    //遍历数组

    int i;//先定义
    for (i = 0; i <4; ++i) {
        printf("%d\n",arr[i]);
    }

    //数组和数组指针
    // 数组的内存地址 == 第一个元素的内存地址  == &arr
    printf("arr = %p\n",arr); //22FE30
    printf("&arr = %p\n",&arr); //22FE30
    printf("&arr[0] = %p\n",&arr[0]);//22FE30

    //数组是一个内存地址
    int * arr_p = arr;
    printf("%d\n",*arr_p);//取出元素一内存地址的值 1
    arr_p++; //指针移动 元素二内存地址
    printf("%d\n",*arr_p); //2
    arr_p += 2;
    printf("%d\n",*arr_p); //4

    arr_p -= 3; // 挪动指针指向到 元素一
    printf("%d\n", *arr_p); //1
    arr_p += 2000; //不会越界,相当于在一块内存只占用了1234,其他都是系统使用
    printf("%d\n", *arr_p); // 系统值 572662306

   //指针遍历数组
    int * arr2 = arr;
    int j;//先定义
    for (j = 0; j <4; ++j) {
        printf("位置%d的值是%d\n",j,*(arr2 +j));
        //数组是连续的内存空间(没有断层,有规律) 数组  每次挪动数组类型的大小的字节
        printf("位置%d的内存地址是%p\n",j,arr2 +j);//22FE20,22FE24,22FE28,22FE2C
    }
    return 0;
}

数组指针,指的是数组名的指针,即数组首元素地址的指针。即是指向数组的指针。例:int (*p)[5]; p即为指向数组的指针,又称数组指针。其本质为指针。
指针数组是数组元素为指针的数组(例如 int *p[3],定义了p[0],p[1],p[2]三个指针),其本质为数组。

数组指针.png

2、循环时给数组赋值。

int main() {
    // 定义数组
    // int [] arr = {1,2,3,4}; 错误的写法
    int arr[4];
    int * arrP = arr;
    // sizeof arr == sizeof(arr)
    // 循环赋值操作
    int j = 0;
    for (j = 0; j < 4; ++j) {
        // 1.拿到 元素一 元素二 元素三 元素四 的内存地址   (arrP + j)
        // 2.取出 元素一 元素二 元素三 元素四 的内存地址 所对应的值 * (arrP + j)
        * (arrP + j) = (j + 10001);
    }
    // 变量 刚刚赋值的数组
    for (int i = 0; i <  sizeof arr / sizeof(int); ++i) {
        printf("位置%d的值是:%d\n", i, * (arrP + i));
    }
    return 0;
}

四、函数指针

1、第一种写法

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

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

// 操作 回调到  add  reduce
// void(*method)(int,int)  声明好 函数指针
// void 返回值
// (*method) 函数名
// (int,int) 两个参数
void operator(void(*method)(int,int),int num1,int num2){
    method(num1,num2);
    printf("opreate函数的 method指针是多少:%p\n", method);
}
//函数指针,类似java的接口回调
int main() {
    //直接使用函数指针
    operator(add,10,10);
    operator(reduce,100,20);
    printf("main函数的 add指针是多少:%p\n", add);//00401740
    printf("main函数的 reduce指针是多少:%p\n", reduce);//0040176B

 // &add和add是一样的值吗
    printf("%p, %p\n", add, &add); //  004018CE, 004018CE  一样的
    return 0;
}
函数指针.png

2、第二种

void callBackMethod(char *fileName, int current, int total) {
    printf("当前%s图片压缩的进度是%d/%d", fileName, current, total);
}

//定义函数指针
void compress(char *fileName, void(*callP)(char *, int, int)) {
    callP(fileName,10,100);
}

int main() {
    //第二种先定义,在使用
    void(*call)(char * ,int ,int);
    call = callBackMethod;
    compress("hh.png",call);
    return 0;
}

你可能感兴趣的:(C语言基础一)