C语言01 - 基本数据类型 sacnf数组指针

Posted 李樟清

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言01 - 基本数据类型 sacnf数组指针相关的知识,希望对你有一定的参考价值。

1. Hello JNI

#include "stdafx.h"
#include <Windows.h>

int main()
    printf("hello jni, zeking les01 \\n");
    system("pause");    

2. 基本数据类型

// 1. 基础数据类型
// int short long float double char bool
// short %d
// long %ld
// float %f
// double %lf
// char %c
int main()

    int i = 1;
    printf("%d\\n", i);  // 输出 1 

    float f = 23.3;    
    printf("%f\\n", f); //  输出 23.299999

    long l = 200000;
    printf("%ld, sizeof: %d\\n", l, sizeof(l)); //  输出 20000,sizeof:4

    system("pause");

3. scanf 介绍

// scanf运行出错 ,系统警告
// 错误   1   error C4996: 'scanf': This function or variable may be unsafe. Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.    d:\\nodes\\jni\\les01\\jni_01_vs\\jni_01_vs\\jni_01_vs.cpp    40  1   JNI_01_VS
// 解决方法 右键项目名 JNI_01_VS --> 属性  --> C/C++ --> 预处理器 --> 预处理器定义 --> 添加 _CRT_SECURE_NO_WARNINGS
// 查看内存, 在打断点的情况下,点击调试 --> 窗口 --> 内存 -- > 内存1
// 4字节的整数,带符号显示,列数1
int main()
    int n;
    printf("请输入一个int 数据:");
    printf("地址: %#x ", &n);   //  查看内存
    scanf("%d", &n);

    printf("%d\\n", n);
    system("pause");

4. 数组

int main()

    // ===================================================================================

    // java 的用法
    // int[10] intAarry;                    
    // intAarry = new int[20];
    // int[] arr; 
    // C 语言的数组,在申明的时候就必须确定大小和基本类型。
    int intArry[10]; //C
    float fArray[10];

    // ===================================================================================

    // 知识点说明一: 很明显下面的 int a_array[n]; 中的n报错了,为什么?
    // 因为C 语言的数组,在申明的时候就必须确定大小和基本类型
    // 因为在程序运行的时候动态申请的数组,n的值是动态的,在预编译阶段,是不知道n的大小的
    // 只有在运行时才能知道n的大小,既然n是一个变量,而且是一个运行时才知道的变量 ,他就是不确定的,编译的时候就通不过

    int n ;
    scanf("%d",&n);
    int a_array[n];

    // ===================================================================================

    // 知识说明二:
    // 因为n这个值是在运行的时候才知道他是10,而编译期间还是不知道。
    // 而申请数组的时候,必须在编译期间,就确定数组的大小,因为要分配内存空间

    int n = 10;   // 我这边给n复制了,为什么 int a_array[n]; 中的n还是报错了?
    scanf("%d", &n);
    int a_array[n];

    // ===================================================================================

    // 知识说明三:
    // const 关键字 相当于我们java里面的 static int n = 10;
    // 他会在静态内存区域里面存储起来,

    const int n = 10;  // 当加上 const的时候 ,就可以了,不报错了,为什么?
    scanf("%d", &n);
    int a_array[n];


    // ===================================================================================

    int a_array[10];
    int i;
    printf("地址: %#x",&a_array);

    for (i = 0; i < 10; i++)
        a_array[i] = i;
    

    // 查看内存 
    //0x0111FCF8 + 0  ....
    //0x0111FCFC + 1  ....
    //0x0111FD00 + 2  ....
    //0x0111FD04 + 3  ....
    //0x0111FD08 + 4  ....
    //0x0111FD0C + 5  ....
    //0x0111FD10 + 6  ....
    //0x0111FD14 + 7  ....
    //0x0111FD18 + 8  ....
    //0x0111FD1C + 9  ....
    // 为什么 他们的 地址  都相差4个字节?
    // 因为 int 型的数组,每一个数组里面存的都是int型的数据,每个int型的数据占用的字节就是4个字节

    // 总结:C 语言的数组,在申明的时候就必须确定大小?
    // 在C语言里面定义数组的时候 ,他必须把这个数组存储在一块连续的空间上
    // 既然是一块连续的空间,就要去计算这个空间的大小,编译期间就要提前记录下来
    // 在预编译阶段,就算出了数组要多大的空间,只有明确了大小之后,
    // 才能在内存中找到一块能够存储数据的空间

    // ===================================================================================

    // 定义一个40M
    // 报错 :0x00C31577 处有未经处理的异常(在 JNI_01_VS.exe 中):  0xC00000FD: Stack overflow (参数:  0x00000000, 0x00112000)。
    // Stack overflow: 栈溢出 
    // 整个C语言的程序空间,都不能够分配这么大的栈
    // 也就是说这一个数组,是存储在stack中的,stack的大小是有限制的,stack的大小大概是2M 左右吧,不确定反正不大,跟平台相关
    // 这个大小是由系统定义的,所以我们不能开辟静态的大的数组
    // 如果要开辟这么大的数组,我们必须去动态的开辟

    // 为什么这个是40M,不是10M么,1024 * 1024 * 10是10M ,它存储的是int型的数组,每一个int型的数组占4个字节,所以就是40M
    // 40M :4byte * 1024 *1024 * 10 = 40M
    int a_array[1024 * 1024 * 10];
    int i;
    printf("地址: %#x",&a_array);

    for (i = 0; i < 10; i++)
        a_array[i] = i;
    

    // ===================================================================================

    // 动态申请数组,不在stack 中,而是在堆里面
    // 在statck申请的系统会帮我们释放,而在堆里面申请的系统是不会帮我们释放的,我们要手动释放
    int * a_array;
    // 在任务管理器中查看 是 40.4M 
    a_array = (int *)malloc(sizeof(int) * 1024 * 1024 *10);

    system("pause");
    // 释放
    delete(a_array); // C语言的释放用delete
    //free(a_array);

5. siseof

// siseof: 关键字不是一个函数,,计算基本数据类型所占用的空间的大小(字节)
int main()

    int i = 1;
    printf("int 值: %d, int 类型数据内存大小:%d \\n", i, sizeof(int)); // java system.out.println(i);

    float f = 23.3;
    printf("%f\\n", f);

    long l = 200000;
    printf("%ld, sizeof: %d\\n", l, sizeof(l));

    //  int 值: 1, int 类型数据内存大小:4
    //  23.299999
    //  200000, sizeof: 4 
    //  不同的系统环境,占用的字节 可能不一样
    system("pause");

    return 0;

6. 控制流程

// for
// if
// switch
// while
// break
// continue
// 和java一样

7. 指针

// & 取地址操作符。运用在内存中的对象上面,即变量与数组元素
// * 间接寻址或者引用运算符。
// 都是单目运算符
// i++ 单目
// 1+2 双目
// 3 > 2 ? true : false   三目

// 指针: 指针变量存储的是变量类型的对应的变量的地址
int main()
    int i = 10;
    int *p;    // 存储的是int型的 变量地址
    p = &i;  

    printf("i value: %d\\n", i);
    printf("p 的地址:%#x \\n", &p);
    printf("i 的地址:%#x \\n", &i);
    printf("修改i ");  // 这边打断点,手动修改i的值,然后看下面 *p的值也改变了

    printf("*p : %d\\n",*p);  // *p : 10

    printf("===========================================================\\n"); 
    // ===========================================================================

    double f = 23.99f;
    double * fp;
    fp = &f;
    printf("f 的内存:%d \\n", sizeof(f)); // f 的内存:8
    printf("sizeof(fp): %d\\n",sizeof(fp)); // sizeof(fp): 4
    // 为什么 f 的内存:8 而 sizeof(p): 4
    // f 是一个变量,指向double 类型的数据的变量
    // fp 是存储的 地址,地址是占用4个字节的。32 位 4 * 8
    // 比如,f是房子,fp是钥匙,不管房子多大,钥匙就是那么大
    printf("f 的地址:%#x \\n", &f);
    printf("fpi 的地址:%#x \\n", &fp);


    printf("===========================================================\\n");
    // ===========================================================================

    int z = 9;
    int *zp;
    zp = &z;
    printf("z value: %d \\n",z);
    printf("zp 的地址:%#x \\n", &zp);
    printf("z 的地址:%#x \\n", &z);
    printf("z value: %d \\n", z); // 打断点修改z的值

    *zp = 100;
    printf("z value: %d \\n", z);
    system("pause");
    return 0;

8. 外挂

int main() 
    int i = 1000;
    printf("i 的地址:%#x \\n", &i);
    while (i > 0) 
        printf("计数器的值: %d\\n", i);
        i--;
        Sleep(2000);
    
    char * p2;
    double * p3;

    return 0;

新建一个 dll 工程 就是外挂

// 右键项目名 -> 属性 -> 配置属性 -> 常规 -> 配置类型 改为 .dll 
_declspec(dllexport) go()
    int * p;
    p = (int *)0x54fbd4; // 这边放要修改的地址
    *p = 100000;

最后使用 DllInject.exe 工具进行 注入

以上是关于C语言01 - 基本数据类型 sacnf数组指针的主要内容,如果未能解决你的问题,请参考以下文章

c语言的基本类型数据有哪几种

C语言提高内容目录

C语言数组是“引用类型”么?

学习C语言第一天

C语言指针进阶第三站,数组指针!

漫谈C语言指针