NDK
基本数据类型
int short long float double char
int %d
short %d
long %ld
float %f
double %lf
char %c
%x 十六进制
%o 八进制
%s 字符串
void main(){
//基本数据类型所占的字节数
printf("int 占 %d 字节\n", sizeof(int)); //4字节
printf("char 占 %d 字节\n", sizeof(char)); //1字节
printf("float 占 %d 字节\n", sizeof(float));//4字节
system("pause");
}
输入输出函数
void main(){
int i;
printf("请输入一个整数:");
//赋值
scanf("%d", &i); //控制台输入,&取地址符
//打印
printf("i的值为:%d\n", i);
system("pause");
}
指针
指针存储的是变量的内存地址
内存地址,系统给数据分配的编号
void main(){
int i = 60;
//指针变量,创建一个int类型的指针
int* p = &i;//p的值就是i这个变量的内存地址
printf("%#x\n", p);
float f = 89.5f;
//创建一个float类型的指针
float* fp = &f;
printf("%#x\n", fp);
system("pause");
}
变量名,对内存空间上的一段数据的抽象
void main(){
int i = 60;
//创建一个int类型的指针
int* p = &i;
//输出地址,两个地址是一样的
//p指向i的地址
printf("p的地址:%#x\n", p);
printf("i的地址:%#x\n", &i);
//通过指针修改i的值
*p = 66;
printf("i的值为:%d\n", i);
system("pause");
}
指针为什么要有类型?
- 指针有类型,地址没有类型
- 地址只是开始的位置,类型读取到什么位置结束
void main(){
int i = 89;
//int 类型的指针
int *p = &i;
double j = 78.9;
//赋值为double类型变量的地址
p = &j;
printf("double size:%d\n", sizeof(double));
printf("%#x,%lf\n",p,*p); //想通过4字节读取8字节变量的值,是不行的
getchar();
}
NULL空指针
void main(){
int i = 9;
int *p = NULL;
//p = &i;
//空指针的默认值为0
printf("%#x\n",p);
//访问内存地址0x000000操作系统不允许
//p = 100; //操作系统不允许访问
printf("%d\n",*p);
getchar();
}
多级指针(二级指针)
指针保存的是变量的地址,保存的这个变量还可以是一个指针变量
void main(){
int a = 50;
//p1上保存的a的地址
int* p1 = &a;
//p2上保存的p1的地址
int** p2 = &p1;
//int*** p3 = &p2;
printf("p1:%#x,p2:%#x\n",p1,p2);
**p2 = 90;
printf("%d\n",a);
getchar();
}
指针的运算
指针的运算,一般在数组遍历时才有意义,基于数组在内存中线性排列的方式
void main(){
//数组在内存中连续存储
int ids[] = { 78, 90, 23, 65, 19 };
//数组变量名:ids就是数组的首地址
printf("%#x\n",ids);
printf("%#x\n",&ids);
printf("%#x\n",&ids[0]);
//指针变量
int *p = ids;
printf("%d\n",*p);
//指针的加法
p++; //p++向前移动sizeof(数据类型)个字节
printf("p的值:%#x\n", p);
//p--;
printf("%d\n", *p);
getchar();
}
通过指针给数组赋值
void main(){
int uids[5];
//高级写法
//int i = 0;
//for (; i < 5; i++){
// uids[i] = i;
//}
//早些版本的写法
int* p = uids;
printf("%#x\n",p);
int i = 0; //i是数组元素的值
for (; p < uids + 5; p++){
*p = i;
i++;
}
getchar();
}
函数指针
int msg(char* msg,char* title){
MessageBox(0,msg,title,0);
return 0;
}
void main(){
//msg();
printf("%#x\n",msg);
printf("%#x\n",&msg);
//函数指针
//函数返回值类型,函数指针的名称,函数的参数列表
int(*fun_p)(char* msg, char* title) = msg;
fun_p("消息内容","标题");
getchar();
}
int add(int a,int b){
return a + b;
}
int minus(int a,int b){
return a - b;
}
//msg函数需要传递一个函数指针参数
//类似于我们Java中的回调函数
void msg(int(*func_p)(int a, int b), int m, int n){
printf("执行一段代码...\n");
printf("执行回调函数...\n");
int r = func_p(m, n);
printf("执行结果:%d\n",r);
}
void main(){
//加法
//int(*func_p)(int a, int b) = add;
msg(div, 10, 20);
//减法
//msg(minus,50,10);
getchar();
}
//案例:用随机数生成一个数组,写一个函数查找最小的值,并返回最小数的地址,在主函数中打印出来
int* getMinPointer(int ids[], int len){
int i = 0;
int* p = &ids[0];
for (; i < len; i++){
if (ids[i] < *p){
p = &ids[i];
}
}
return p;
}
void main(){
int ids[10];
int i = 0;
//初始化随机数发生器,设置种子,种子不一样,随机数才不一样
//当前时间作为种子 有符号 int -xx - > +xx
srand((unsigned)time(NULL));
for (; i < 10; i++){
//100范围内
ids[i] = rand() % 100;
printf("%d\n", ids[i]);
}
int* p = getMinPointer(ids, sizeof(ids) / sizeof(int));
printf("%#x,%d\n",p,*p);
getchar();
}
指针与数组的几种写法
void main(){
int a[] = { 78, 34, 73, 25, 80, 90 };
int i = 0;
for (; i < 6; i++){
printf("%d,%#x ", a[i], &a[i]);
//a首地址
//a 等价于 &a[0] ,a+1 等价于&a[1]
//结论: a+i 等价于 &a[i]
//*a等价于 a[0],*(a+1)等价于a[1]
//结论: *(a+i)等价于a[i]
printf("%d,%#x ", *(a + i), a + i);
printf("\n");
}
//总结:
//a+i 等价于 &a[i],*(a+i)等价于a[i],后者只是简写方式,在最古老的C语言里是没有中括号的
//另外一种写法
printf("\n\n");
int* p = a;
//p变量指针,a常量指针
//p = &i;
//a = &i; 不行
i = 0;
for (; i < 6; i++){
//a[i]表达式:首地址[i]
printf("%d,%#x ", p[i], &p[i]);
printf("%d,%#x ", *(p + i), p + i);
printf("\n");
}
getchar();
}
//指针引用二维数组(行指针,列指针)
void main(){
int a[2][3] = {95,82,56,17,29,30};
//遍历输出
//外层循环控制行,内层循环控制列
int i = 0;
for (; i < 2; i++){
int j = 0;
for (; j < 3; j++){
printf("%d,%#x ", a[i][j], &a[i][j]);
}
printf("\n");
}
//
//printf("%#x,%#x,%#x\n",a,&a,*a);
//printf("%d,%d,%d\n", sizeof(*a), sizeof(*&a), sizeof(**a));
//a是一个行指针,指向一个有三个元素的数组,12
//&a是一个指向二维数组的指针,当前二维 数组6个元素,24
//*a 是一个指向int类型数据的指针(a[0][0]),4
//printf("%d\n", **a);
//a是一个行指针,是数组第一行的指针,a+1第二行的指针,以此类推
printf("%#x,%#x\n",a,a+1);
//*a是数组的第一行第一个元素的指针,*a+1是数组第一行第二个元素的指针
printf("%#x,%#x\n",*a,*a+1);
//*(a+1)是数组的第二(1)行第一(0)个元素的指针
//注意:不一定是正常逻辑
printf("%#x,%#x\n",*(a+1),*(a+1)+1);
//取数组的第1(二)行,第2(三)个元素
printf("%d\n",a[1][2]);
printf("%d\n",*(*(a+1)+2));
//总结:
//a[i][j] 等价于 *(*(a+i)+j)
//&a[i][j] 等价于 (*(a+i)+j)
getchar();
}