一、基本数据类型
#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;
}
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;
}
//先声明
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;
}
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;
}
三、数组和数组指针
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]三个指针),其本质为数组。
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;
}
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;
}