安卓系统层开发之C++

VIP01-2020.10.22-C语言基础01-地址总线原理

数据类型

在这里插入图片描述

结构类型 struct

sizeof 是测量person堆区分配的大小

#include <stdio.h>
#include <malloc.h>

typedef struct {
   
    int a;
    int b;
} Person1;

int main() {
   
    /* c中创建一个Person1对象,相当于java中Person1 p = new Person1();
     * sizeof是给person1在堆区分配的大小空间,分配了这块大小的内存值给person1
     * 这块内存区有值吗?变量没有值
     * */
    Person1 *person1 = malloc(sizeof(Person1));
    person1->a = 44;
    person1->b = 22;

    printf("a= %d, b= %d", person1->a, person1->b);
    return 0;
}

res:
a= 44, b= 22
指针类型
#include <stdio.h>
#include <malloc.h>
//指针类中
void test01() {
   
	*p 定义的是一个地址变量,存99也只能存地址,所以99是个地址
    int *p;//表示存的是一个地址,在内存中申明一个指针叫p,此时p没有值
    int *p1 = 99;//99是一个内存里的区域
    printf("--- %d", p1);
    printf("------- %d", *p1);//p1地址对应的值*p1获取不到
}

int main() {
   
    test01();
    return 0;
}

res:
--- 99 //此时这个99就是一个地址
-------  没有值,野指针  *p1 指的是p1的地址对应的地址里的值

在这里插入图片描述

#include <stdio.h>
#include <malloc.h>
//指针类中
void test01() {
   
    int *p;//定义一个地址的变量,此时变量是空的,p也有地址
    int a = 10;//定义一个实体的变量
    printf("&a --- %p\n", &a);
    p = &a;//取a变量的地址值放到p的地址位置中去
    //指针
    printf("p --- %p\n", p);
    //指针对应的值
    printf("*p --- %d\n", *p);
    //指针大小是固定8个字节,window 64位是8个字节,32位是4个字节
    printf("sizeof(p) --- %d\n", sizeof(p));
    //指针变量p的地址
    printf("&p --- %p\n", &p);
}

int main() {
   
    test01();
    return 0;
}

res:
&a --- 000000000061FE14
p --- 000000000061FE14
*p --- 10
sizeof(p) --- 8
&p --- 000000000061FE18

指针的大小是固定的 8个字节
windows64 8个字节
windows32 4个字节

    int *p;//等号左边,在内存中申明一个地址变量p,指针变量就相当于容器用来存放地址
    int a = 10;
    p = &a;
    int c = *p;//等号右边,是取出指针变量的地址所指向的值
    printf("--- c: %d\n", c);

res:
--- c: 10

在这里插入图片描述

指针常见错误
1. 指针是有类型的
void test01() {
   
    int *q;
    *q = 100l;
}

res: 返回错误
Process finished with exit code -1073741819 (0xC0000005)
2. 赋值错误
    char *p = NULL;
    strcpy(p, "1234");

res:
Process finished with exit code -1073741819 (0xC0000005)
指针的步长:指针走一步的距离
int a = 0xaabbccdd;
    int *p1 = &a;
    printf("*p1 --- %x\n", *p1);
    char *p2 = &a;
    printf("*p2 --- %x\n", *p2);
    
    //地址,是同一个地址
    printf("p1 --- %p\n", p1);
    printf("p2 --- %p\n", p2);
    //地址最小单位是字节 int 4  char 1
    printf("p1+1 --- %p\n", p1+1);
    printf("p2+1 --- %p\n", p2+1);
    
res:
*p1 --- aabbccdd
*p2 --- ffffffdd
p1 --- 000000000061FDDC
p2 --- 000000000061FDDC
p1+1 --- 000000000061FDE0
p2+1 --- 000000000061FDDD

在这里插入图片描述

数组与数组指针

数组

数组的地址就是数组第一个值的地址

    int c[9] = {
   1,2,3,4,5,6,7,8,9};
    //数组,是一个特殊的指针
    printf("int[] c = %p \n", c);
    //数组中取第一个值
    printf("int[0] c[0] = %d \n", *c);
    //数组中第二个值
    printf("int = %d \n", *(c+1));
res:
int[] c = 000000000061FDC0
int[0] c[0] = 1
int = 2
	int c[9] = {
   1,2,3,4,5,6,7,8,9};
    //数组的总地址
    printf("int[] c = %p \n", c);
    //数组的地址
    printf("&c = %p \n", &c);
    //第一个值的地址
    printf("&c[0] = %p \n", &c[0]);
res:
int[] c = 000000000061FDC0
&c = 000000000061FDC0
&c[0] = 000000000061FDC0

数组的地址和指针变量存的地址相同

    int c[9] = {
   1,2,3,4,5,6,7,8,9};
    printf("c = %p\n", c);
    int *p = c;
    //p指针中存的地址
    printf("p = %p\n", p);
    //p变量的地址
    printf("&p = %p\n", &p);
res:
c = 000000000061FDC0
p = 000000000061FDC0
&p = 000000000061FDB8
int c[9] = {
   1,2,3,4,5,6,7,8,9};
    int *p = c;
    for (int i=0; i<9; i++) {
   
        printf("p[%d] = %d\n", i, p[i]);
    }
res:
p[0] = 1
p[1] = 2
p[2] = 3
p[3] = 4
p[4] = 5
p[5] = 6
p[6] = 7
p[7] = 8
p[8] = 9
int c[9] = {
   1,2,3,4,5,6,7,8,9};
    int *p = c;
    for (int i=0; i<9; i++) {
   
        printf("p[%d] = %d\n", i, p[i]);
        //地址加4个字节
        printf("*(p + %d) = %d\n", i, *(p +i));
        printf("p + %d = %p\n", i, p+i );
    }
res:
p[0] = 1
*(p + 0) = 1
p + 0 = 000000000061FDB0
p[1] = 2
*(p + 1) = 2
p + 1 = 000000000061FDB4
p[2] = 3
*(p + 2) = 3
p + 2 = 000000000061FDB8
p[3] = 4
*(p + 3) = 4
p + 3 = 000000000061FDBC
p[4] = 5
*(p + 4) = 5
p + 4 = 000000000061FDC0
p[5] = 6
*(p + 5) = 6
p + 5 = 000000000061FDC4
p[6] = 7
*(p + 6) = 7
p + 6 = 000000000061FDC8
p[7] = 8
*(p + 7) = 8
p + 7 = 000000000061FDCC
p[8] = 9
*(p + 8) = 9
p + 8 = 000000000061FDD0

c数组是个地址,这个地址是个常量,不能被赋值

    int c[9] = {
   1,2,3,4,5,6,7,8,9};

    printf("%d \n", *c);//取出第一个元素
    printf("%d \n", *(c+1));
    printf("%p \n", c);//数组第一个值的地址
    printf("%p \n", &c[0]);//数组第一个值的地址
    printf("%p \n", &c);
    
res:
1
2
000000000061FDC0
000000000061FDC0
000000000061FDC0


    int c[9] = {
   1,2,3,4,5,6,7,8,9};
    int *p = c;
    char *p1 = c;

    printf("%p \n", c);//c的地址
    printf("%p \n", &p);//p的地址
    printf("%d \n", *p);

    //数组=指针
    for (int i=0; i<8; i++) {
   
        //printf("%d \n", p[i]);
        printf("%d \n", *(p+i));
        printf("%d \n", (p+i));
        printf("%d \n", (p1+i));
    }
    
res:
000000000061FDB0
000000000061FDA8
1
1
6421936
6421936
2
6421940
6421937
3
6421944
6421938
4
6421948
6421939
5
6421952
6421940
6
6421956
6421941
7
6421960
6421942
8
6421964
6421943

数组指针

数组指针,数组里存放的是指针

    int a = 10;
    int b = 20;
    int c = 30;
    int *p1 = &a;
    int *p2 = &b;
    int *p3 = &c;
    printf("&a = %p, &b = %p, &c = %p\n", &a, &b, &c);
    printf("&a = %p, &b = %p, &c = %p\n", p1, p2, p3);
    //整形指针数组
    int *arr[3] = {
   p1, p2, p3};
    printf("*arr[0] = %d\n",*arr[0]);
    //p1的地址
    printf("*arr = %d\n", *arr);
    printf("**arr = %d\n", **arr);
    //指针转换
    char *aa = arr;
    printf("%d\n",*aa);
    printf("%d\n", *((int *)aa));

res:
&a = 000000000061FDD4, &b = 000000000061FDD0, &c = 000000000061FDCC
&a = 000000000061FDD4, &b = 000000000061FDD0, &c = 000000000061FDCC
*arr[0] = 10
*arr = 6421972
**arr = 10
-52
6421964

*arr[0]
在这里插入图片描述

二维数组指针

    int a[] = {
   10};
    int b[] = {
   20};
    int c[] = {
   10};
    int * arr[3] = {
   a, b, c};
    printf("arr = %p\n", arr);
    printf("*arr = %p\n", *arr);
    printf("**arr = %d\n", **arr);
    
	printf("*(*(arr+1)) = %d\n", *(*(arr+1)));

    int * arr1[3] = {
   10, 11, 12};
    printf("arr1 = %p\n", arr1);
    printf("arr1 + 1 = %p\n", arr1+1);
    printf("*arr1 = %d\n", *arr1);
    printf("*(arr1+1) = %d\n", *(arr1+1));
res:
arr = 000000000061FDC0
*arr = 000000000061FDEC
**arr = 10
*(*(arr+1)) = 20

arr1 = 000000000061FDA0
arr1 + 1 = 000000000061FDA8
*arr1 = 10
*(arr1+1) = 11
    int a[] = {
   10,11};
    int b[] = {
   20,21,22};
    int c[] = {
   30};

    int * arr[3] = {
   a, b, c};

    printf("%d \n", *arr);
    printf("%d \n", **arr);

    printf("%d \n", *(*arr+0));
    printf("%d \n", *(*(arr+1)));
    printf("%d \n", **(arr+1));
    printf("%d \n", *(*arr+1));
    printf("------------------ \n");
    int * arr1[3] = {
   100,200,300};
    printf("%p \n", arr1);
    printf("%p \n", arr1+1);
    //printf("%p \n", **arr1);
    printf("%d \n", arr[1][1]);

res:
6421992
10
10
20
20
11
------------------
000000000061FDA0
000000000061FDA8
21

位运算

int a = 10; 二进制

1001 0000 0000 0000 0000 0000 0000 0000

int b = 18; 右移一位

0001 0010 > 1 -> 00001001

VIP02-2020.10.24-C语言基础 指针详解

在这里插入图片描述

	int p;
    int *p1;//整型指针,单个指针变量
    int p2[2];//整型数组
    int *p4[4];//指针数组,先是数组,数组内的元素是指针,指针的类型是int

    int (*p5)[4];//数组指针,数组里的元素是指针,指针的类型是int
    //这个指针自身的类型是什么?指针指的类型是什么?该指针指向了哪里?
    int *p6;//指针类型 int *, 指向的类型 int
    char *p7;//指针类型 char *,指向的类型 char
    int **p8;//int *, 2级指针8个字节
    int (*p9)[3];//数组指针, int()[3]
	int p;
    int *p1;//指针
    int p2[2];//数组
    /* 指针数组
     * p4数组,数组里的元素是指针
     */
    int *p4[4];
    /* 数组指针
     * 一般情况从右向左结合,()优先级大于[],*p5是个指针,指向了后面的数组,数组类型是int
     */
    int (*p5)[4];
    /* 指针自身的类型?指针指向类型?指向哪里?
     * 指针类型 int *, 指向类型 int
     */
    int *p6;
    char *p7;
    /* 二级指针
     *  指针类型 int *
     */
    int **p8;
    /* 数组指针
     * 指针类型 int[]
     */
    int(*p9)[3];
	char ch = 'a';
    char *cp = &ch;

    //作为左值
    printf("cp = %p\n", cp);
    printf("&ch = %p\n", &ch);

    //作为右值
    char *name = &ch;
    printf("*name = %c\n", *name);
    printf("name = %p\n", name);

    char *cp1 = cp;
    printf("cp = %p\n", cp);
    printf("cp1 = %p\n", cp1);

    //作为左值
    //cp = NULL;
    //printf("cp = %p\n", cp);

    //&cp
    printf("&cp = %p\n", &cp);

    //*cp
    printf("*cp = %c\n", *cp);

    //**cp2
    char **cp2 = &cp;
    printf("cp2 = %p\n", cp2);

    //作为左值*cp
    printf("*cp = %c\n", *cp);

    //作为右值
    char name1 = *cp;
    printf("name1 = %c\n", name1);

    //作为右值*cp+1
    char name2 = *cp+1;
    printf("name = %c\n", name2);

    //*(cp+1) 野指针
    printf("*(cp+1) = %p\n", *(cp+1));

res:
cp = 000000000061FE05
&ch = 000000000061FE05
*name = a
name = 000000000061FE05
cp = 000000000061FE05
cp1 = 000000000061FE05
&cp = 000000000061FDF8
*cp = a
cp2 = 000000000061FDF8
*cp = a
name1 = a
name = b
*(cp+1) = 0000000000000062

野指针、悬空指针

	int *p;//指针未初始化,此时p为野指针
    printf("p 0x%x \n", p);
    int *pi = NULL;//指针未初始化,此时p为空指针
    {
   
        int i = 6;
        printf("%p \n", &i);
        pi = &i;//此时pi指向一个正常的地址
        *pi = 8;
        printf("%p \n", pi);
    }
    //i的地址会被销毁
    //由于pi指向的变量i已经销毁,此时pi即成了悬空指针
    int b = *pi;//i=8
    printf("p: %p \n", pi);

res:
p 0x10
000000000061FE08
000000000061FE08
p: 000000000061FE08

malloc和memset

	//申请16个字节
    int *arr = malloc(16);
    for (int i=0; i<4; i++) {
   
        printf("i = %d, value = %d\n", i, *(arr+i));
    }
    
res:
i = 0, value = 10770848
i = 1, value = 0
i = 2, value = 10748240
i = 3, value = 0

//申请16个字节
    int *arr = malloc(16);
    //初始化数组,从0开始,16个字节
    memset(arr, 0, 16);
    for (int i=0; i<4; i++) {
   
        printf("i = %d, value = %d\n", i, *(arr+i));
    }

res:
i = 0, value = 0
i = 1, value = 0
i = 2, value = 0
i = 3, value = 0
#include <stdio.h>
#include <malloc.h>
#include <memory.h>
int main() {
   
    int *p;
    printf("p %p \n", p);
    int *arr = malloc(16);//声明在堆区,16个字节
    memset(arr, 0, 16);
    for (int i=0; i<4; ++i) {
   
        printf("i: %d, value: %d \n", i, *(arr+1));
        printf("i: %d, value: 0x%x \n", i, (arr+1));
    }

    calloc(2,16);

    free(arr);
    arr = NULL;
    return 0;
}

res:
p 0000000000BB13E0
i: 0, value: 0
i: 0, value: 0xbb6a44
i: 1, value: 0
i: 1, value: 0xbb6a44
i: 2, value: 0
i: 2, value: 0xbb6a44
i: 3, value: 0
i: 3, value: 0xbb6a44

malloc、calloc、realloc、free区别

    //申请16个字节
    int *arr1 = malloc(16);
    //申请2*8个字节
    int *arr2 = calloc(2, 8);
    free(arr1);
    free(arr2);
    printf("arr: 0x%x\n", arr1);
    //悬空指针
    if (arr1) {
   
        printf("arr = true\n");
    }
    arr1 = NULL;
    //
    if (arr1) {
   
        printf("arr = false\n");
    }

交换

#include <stdio.h>

//方法在栈区,方法执行完,出栈移除掉了,未交换
int swap(int x, int y) {
   
    printf("swap before x: %d y: %d \n", x, y);
    int tmp = x;
    x = y;
    y = tmp;
    printf("swap after x: %d y: %d \n", x, y);
}

//如需要交换,传指针
int swap1(int *x, int *y) {
   
    printf("swap1 before x: %d y: %d \n", *x, *y);
    int tmp = *x;
    *x = *y;
    *y = tmp;
    printf("swap1 after x: %d y: %d \n", *x, *y);
}

int main() {
   
    int x = 2;
    int y = 4;
    swap(x, y);
    printf("x: %d y: %d \n", x, y);

    swap1(&x, &y);
    return 0;
}

res:
swap before x: 2 y: 4
swap after x: 4 y: 2
x: 2 y: 4
swap1 before x: 2 y: 4
swap1 after x: 4 y: 2
#include <stdio.h>

//C 语言不允许返回一个完整的数组作为函数的参数,必须声明一个返回指针的函数

int * getArr(){
   
//
    static int nums[] = {
   1,2,3,4,5,6};
    return nums;
}

void getArr2(int *start, int *len){
   
    static int nums2[] = {
   1,2,3,4,5,6};

    printf("&nums2[0]=%p\n",&nums2[0]);
    *start = nums2;
    printf("start=%p\n",*start);
    *len = sizeof(nums2)/sizeof(nums2[0]);
}

int main(){
   
//{1,2,3,4,5,6}
	int *arr = getArr();
	
	for(int i=0;i<6;i++){
   
		printf("arr[%d]=%d  %p\n",i,*(arr+i),arr+i);
		// *arr 返回的指针指向数组的第一个元素,相当于下标0,通过增加指针值来访问数组元素
	}

    int *start;//野指针  当变量在用  亅
	int len=0;
//	二级指针
	getArr2(&start,&len);
    printf("----start=%p\n", start);
//	printf("start=%p, *start=%d, len=%d\n",start,*start,len);//!!!此处打印的start保存的数组首元素地址就变了
	
	for(int i=0;i<len;i++){
   
		printf("arr2[%d]=%d  start=%p \n",i,start[i],start+i);
	}
	
}

/*void printArr(int *start,int *len)
{
	for(int i=0;i<*len;i++){
		
	}
}*/

VIP03-2020.10.26-C语言基础03-指针数组与数组指针

区别:
没有括号的是指针数组 int *p[5]
有括号的是数组指针 int (*p)[5]

    int a = 0;
    int *p;//指针类型int *,指针指向类型int
    int **p1;//指针类型int **,指针指向类型int *
    p = &a;
    printf("p: %p \n", p);
    p++;//指针步长,是由指针指向的类型决定(int 4字节)
    printf("p: %p \n", p);
    *p = 10;
    int **temp = &p;//指针类型 int **,指向类型 int *
    printf("int *: %d \n", sizeof(int *));
    printf("temp: %p \n", temp);
    temp++;
    printf("temp: %p \n", temp);
    
res:
p: 000000000061FE14
p: 000000000061FE18
int *: 8
temp: 000000000061FE08 16进制+8,进一位10
temp: 000000000061FE10

指针强转

    int a = 0;
    int *p = &a;
    int **temp = &p;
    char **temp1 = &p;//指针可以强转
    printf("temp1: %p \n", temp1);
    temp1++;
    printf("temp1: %p \n", temp1);

    int *arr[4] = {
   1,2,3,4};//指针类型 int *[4], 指向类型 int [4] = int类型
    int *arr1 = arr;//指向类型int 4个字节
    printf("arr: %p \n", arr1);
    arr1++;
    printf("arr: %p \n", arr1);

res:
temp1: 000000000061FDF8
temp1: 000000000061FE00
arr: 000000000061FDD0
arr: 000000000061FDD4

数组指针:等价于二维数组整个数组

int (ptr)[4] 指针类型 int ()[4],指针指向类型 int()[4]

    char charP[4] = {
   'a', 'b', 'c', 'd'};
    //(*p3)代表单个指针,p3指向1个数组的4个元素作为的整体的新的类型,数组的类型char
    char (*p3)[4] = &charP;//指针类型 char (*)[4],指向类型 char ()[4]
    printf("p3: %p \n", p3);
    p3++;
    printf("p3: %p \n", p3);

res:
p3: 000000000061FDCC
p3: 000000000061FDD0

在这里插入图片描述

指针数组:等价于一维数组首地址

int *arr[4] = {
   1, 2, 3, 4};//指针类型 int *[4], 指向类型 int [4] = int类型
    

在这里插入图片描述
计算步长:

    char charP[5] = {
   'c', 'd', 'e', 'f'};
    char (*p3)[3] = &charP;//指针自身类型 char (*)[3], 指向类型 char ()[3]  
    printf("p3: %p \n", p3);
    p3++;
    printf("p3: %p \n", p3);

res:
p3: 000000000061FE13 //步长 char*3
p3: 000000000061FE16

内存分布

所有java代码都在方法区,C内存分布如下:

在这里插入图片描述

1、变量概念

全局变量
局部变量
静态变量

2、extern关键字

引用同一个文件中的变量;
引用另一个文件中的变量;
引用另一个文件中的函数。

3、代码区

程序被操作系统加载到内存的时候,所有的可执行代码(程序代码指令、常量字符串等)都加载到代码区,这块内存在程序运行期间是不变的。代码区是平行的,里面装的就是一堆指令,在程序运行期
间是不能改变的。函数也是代码的一部分,故函数都被放在代码区,包括main函数。

4、静态区

静态区存放程序中所有的全局变量和静态变量。

5、栈区

栈(stack)是一种先进后出的内存结构,所有的自动变量、函数形参都存储在栈中,这个动作由编译器自动完成,我们写程序时不需要考虑。栈区在程序运行期间是可以随时修改的。当一个自动变量超
出其作用域时,自动从栈中弹出。
每个线程都有自己专属的栈;
栈的最大尺寸固定,超出则引起栈溢出;
变量离开作用域后栈上的内存会自动释放。

#include <stdio.h>
#include <malloc.h>

const int a;//静态区
extern int test() {
   
}

int main() {
   
    int a = 0;//栈区
    char *b = malloc(100);//堆区

    return 0;
}

栈:栈的底部是入口和出口,栈是先进后出

	int a = 10;
    int b = 20;
    int c = 30;
    int d = 40;
    printf("a = %d \n", &a);
    printf("b = %d \n", &b);
    printf("c = %d \n", &c);
    printf("d = %d \n", &d);

    int *arr = malloc(16);
    for (int i = 0; i < 4; ++i) {
   
        printf("arr : %p \n", (arr + i));
    }

res:
a = 6422044
b = 6422040
c = 6422036
d = 6422032
arr : 0000000000B26A40
arr : 0000000000B26A44
arr : 0000000000B26A48
arr : 0000000000B26A4C

在这里插入图片描述
宏定义优先级问题

#include <stdio.h>

//宏定义
#define ADD1(x, y)x+y
#define ADD2(x, y)(x+y)

int main() {
   
    int a = 2;
    int b = 3;
    printf("sum: %d \n", ADD1(a, b));
    printf("sum: %d \n", ADD1(a, b) * 30);//a+b*30=92

    printf("sum: %d \n", ADD2(a, b));
    printf("sum: %d \n", ADD2(a, b) * 30);//(a+b)*30=150
    return 0;
}

res:
sum: 5
sum: 92
sum: 5
sum: 150

一级指针易错点

1. 越界
    char buf[3] = "abc \0";
    printf("buf:%s \n", buf);

res:
buf:abc?
2. 局部变量返回,拿不到(在栈区)
#include <stdio.h>

int *get_str() {
   
    int str[] = {
   10, 20, 30};
    return str;
}

int main() {
   
    int *arr = get_str();
    printf("arr: 0x%x \n", arr);
    printf("arr: %d \n", *arr);
    return 0;
}

res:
arr: 0x0
Process finished with exit code -1073741819 (0xC0000005)

数组指针

*arr[]后面不能加中括号

指针数组

(arr)[] 指针变量,新类型 自身类型int()[],指向类型 int()[3]

#include <stdio.h>

int main() {
   
    int *pi = NULL;
    //代码块不会入栈出栈,在同一栈区
    {
   
        int i = 6;
        pi = &i;//pi指向一个正常的地址
        *pi = 8;
    }
    //由于pi指向的变量i已经销毁,此时pi成了悬空指针
    int b = *pi;
    printf("b: %d \n", b);
    return 0;
}

res:
b: 8

二级指针

#include <stdio.h>
#include <malloc.h>

void print_array(int **arr, int n) {
   
    for (int i = 0; i < n; i++) {
   
        printf("%d \n", *arr[i]);
        printf("%d \n", *(arr[i]));
        printf("%d \n", *(arr + i));
        printf("%d \n", **(arr + i));
    }
}

void test() {
   
    int a1 = 10;
    int a2 = 20;
    int a3 = 30;
    int a4 = 40;
    int a5 = 50;
    int n = 5;
    int **arr = malloc(sizeof(int *) * n);
    arr[0] = &a1;
    arr[1] = &a2;
    arr[2] = &a3;
    arr[3] = &a4;
    arr[4] = &a5;
    print_array(arr, 5);
    free(arr);
}

int main() {
   
    int b = 10;
    int *p1 = &b;
    int **p2 = &p1;//二级指针
    test();
    return 0;
}

res:
10
10
6421948
10
20
20
6421944
20
30
30
6421940
30
40
40
6421936
40
50
50
6421932
50
#include <stdio.h>
#include <malloc.h>

#define David 99//宏变量

void print_array(int **arr, int n) {
   
    for (int i = 0; i < n; ++i) {
   
        printf("%d \n", (*arr)[i]);
    }
}

void allocateSpace(int **p) {
   
    int *temp = malloc(sizeof(int) * 10);
    for (int i = 0; i < 10; ++i) {
   
        temp[i] = 100 + i;
    }
    //一级指针,首地址
    *p = temp;
}

int main() {
   
    //一级指针
    int *p = NULL;
    //二级指针
    allocateSpace(&p);
    print_array(&p, 10);
    return 0;
}

res:
100
101
102
103
104
105
106
107
108
109
#include <stdio.h>
#include <malloc.h>

#define David 99//宏变量

void allocateSpace(int **addr) {
   
    int *temp = malloc(sizeof(int) * 3);
    for (int i = 0; i < 3; ++i) {
   
        temp[i] = 100 + i;
    }
    //一级指针,首地址
    *addr = temp;
}

void freeArray(int *pArray) {
   
    if (*pArray != NULL) {
   
        free(*pArray);
        *pArray = NULL;
    }
}

int main() {
   
    int *p = NULL;
    allocateSpace(&p);
    freeArray(&p);
    return 0;
}
指针数组与数组指针图解

在这里插入图片描述
在这里插入图片描述

VIP04-2020.10.29-C语言基础04-函数指针

数组在C中是没有边界的,必须定义长度

#include <stdio.h>

void test(int array[], int size) {
   
    for (int i = 0; i < size; ++i) {
   
        printf("value: %d \n", array[i]);
    }
}

int main() {
   
    int arr[6] = {
   1, 2, 3, 4, 5, 6};
    test(arr, 6);
    return 0;
}

res:
value: 1
value: 2
value: 3
value: 4
value: 5
value: 6
	//打印指向类型,前面加*
    int arr[6] = {
   1, 2, 3, 4, 5, 6};
    printf("*b: %d \n", sizeof(*arr));
    printf("&arr: %d \n", sizeof(&arr));
    printf("*&arr: %d \n", sizeof(*&arr));

res:
*b: 4
&arr: 8
*&arr: 24
#include <stdio.h>

int main() {
   
    int a1 = 10;
    int a2 = 20;
    int a3 = 30;
    int b[3] = {
   a1, a2, a3};
    printf("b: %p \n", b);
    printf("*b= %d\n", sizeof(*b));
    printf("*&b= %d\n", sizeof(*&b));

    //下标法
    for (int i = 0; i < 3; ++i) {
   
        printf("arr[%d]=%d ", i, b[i]);
    }

    //地址法
    for (int i = 0; i < 3; ++i) {
   
        printf("arr[%d]=%d ", i, *(b+i));
    }

    //指针法
    int *c = b;
    for (int i = 0; i < 3; ++i) {
   
        printf("arr[%d]=%d ", i, *(c+i));
    }
    return 0;
}

res:
b: 000000000061FDF4
*b= 4
*&b= 12
arr[0]=10 arr[1]=20 arr[2]=30 
arr[0]=10 arr[1]=20 arr[2]=30 
arr[0]=10 arr[1]=20 arr[2]=30
    int a[2][5] = {
   1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    printf("a: %p\n", a);
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值