栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C语言基础:010 C进阶语法 - 指针详解

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C语言基础:010 C进阶语法 - 指针详解

指针的概念 1. 指针 就是个 变量 ,用来 存放地址 ,地址 唯一 标识一块 内存空间 。 2. 指针的 大小 是固定的 4/8个字节 (32位平台/64位平台)。 3. 指针是有 类型 ,指针的类型决定了 指针 的  +- 整数的步长,指针 解引用 操作的时候的权限。 4. 指针的 运算 。
  1. 字符指针
    1. C/C++会把常量字符串存储到单独的一个内存区域,当几个指针指向同一个字符串的时候,他们实际会指向同一块内存。
    2. 用相同的常量字符串去初始化不同的数组的时候就会开辟出不同的内存块。
    3. 代码  const char* pstr = "hellobit";//本质是把字符串 hellobit 首字符的地址放到了pstr中。
    4. code示例
      #include 
      
      int main()
      {
      	char ch = 'w';
      	char* pc = &ch;
      	*pc = 'd';
      	printf("%c %pn", *pc, pc); // d 000000DB503BFA84 
      
      	const char* pstr = "hellobit";//本质是把字符串 hello bit. 首字符的地址放到了pstr中。
      	printf("%s %c %d %pn", pstr, *pstr, strlen(pstr), &pstr);       // hellobit h 8 000000E4813BFAE8
      	
      	char str1[] = "hello bit.";
      	char str2[] = "hello bit.";
      	const char* str3 = "hello bit.";
      	const char* str4 = "hello bit.";
      
      	// 用相同的常量字符串去初始化不同的数组的时候就会开辟出不同的内存块。
      	// 所以str1和str2不同,str3和str4不同。
      	if (str1 == str2) printf("str1 == str2n");
      	else printf("str1 != str2n");              // str1 != str2
      
      	// str3和str4指向的是一个同一个常量字符串
      	// C/C++会把常量字符串存储到单独的一个内存区域,
      	// 当几个指针指向同一个字符串的时候,他们实际会指向同一块内存。
      	if (str3 == str4) printf("str3 == str4n"); // str3 == str4
      	else printf("str3 != str4n");
      
      	return 0;
      }
  2. 指针数组
    1. code示例
      #include 
      
      int main()
      {
      	int* arr1[10]; //整形指针的数组
      	char* arr2[4]; //一级字符指针的数组
      	char** arr3[5];//二级字符指针的数组
      
      	return 0;
      }
  3. 数组指针
    1. 数组指针的定义
      1. 数组指针 是 指针 ,不是数组
      2. 数组指针:指向数组的指针
        1. 整形指针 : int * pint ; 指向 整形数据 的 指针 。
        2. 浮点型指针: float * pf; 指向 浮点型数据的指针。
      3. code示例
        #include 
        
        int main()
        {
        	int* p1[10]; //整形的指针数组
        	int(*p2)[5];
        	// 解释:p2先和*结合,说明p2是一个指针变量,然后指着指向的是一个大小为5个整型的数组。
        	// 所以p是一个,指向一个数组,叫数组指针。
        	// 同时:[]的优先级要高于*号的,所以必须加上()来保证p先和*结合。
        	return 0;
        }
    2. &数组名  VS 数组名
      1. 其实&arr和arr,值是一样的,但是意义应该不一样的。
        实际上: &arr 表示的是数组的地址,而不是数组首元素的地址。(细细体会一下); arr 是数组名,数组名arr表示数组首元素的地址。
        1. 下例中 &arr 的类型是: int(*)[10] ,是一种数组指针类型。数组的地址+1,跳过整个数组的大小,所以 &arr+1 相对于 &arr的差值是40。
      2. code示例
        #include 
        
        int main()
        {
        	int arr[10] = { 0 };
        	// &arr和arr,值是一样的,但是意义应该不一样的。
        	//   &arr 表示的是数组的地址,而不是数组首元素的地址
        	//   arr 是数组名,数组名表示数组首元素的地址
        	printf("%pn", arr);  // 000000B27340F5D8
        	printf("%pn", &arr); // 000000B27340F5D8
        
        	printf("arr+1 = %pn", arr + 1);  // arr+1 = 000000B27340F5DC
        	printf("&arr+1= %pn", &arr + 1); // &arr+1= 000000B27340F600
        
        	return 0;
        }
    3. 数组指针的使用
      1. 数组指针指向的是数组,数组指针中存放的应该是数组的地址。
      2. code示例
        #include 
        
        void print_arr1(int arr[3][5], int row, int col) {
        	int i = 0;
        	for (i = 0; i < row; i++)
        	{
        		for (int j = 0; j < col; j++)
        		{
        			printf("arr1[%d][%d] = %d ",i, j, arr[i][j]);
        		}
        		printf("n");
           }
        }
        
        void print_arr2(int(*arr)[5], int row, int col) {
        	int i = 0;
        	for (i = 0; i < row; i++)
        	{
        		for (int j = 0; j < col; j++)
        		{
        			printf("arr2[%d][%d] = %d ", i, j, arr[i][j]);
        		}
        		printf("n");
        	}
        }
        
        
        int main()
        {
        	int arr[3][5] = { 1,2,3,4,5,6,7,8,9,10 };
        	print_arr1(arr, 3, 5);
        	//数组名arr,表示首元素的地址
        	//但是二维数组的首元素是二维数组的第一行
        	//所以这里传递的arr,其实相当于第一行的地址,是一维数组的地址
        	//可以数组指针来接收
        	print_arr2(arr, 3, 5);
        	return 0;
        }
  4. 数组参数、指针参数
    1. 一维数组传参
      1. code示例
        #include 
        void test_a(int arr[])//ok
        {}
        void test_b(int arr[10])//ok
        {}
        void test_c(int* arr)//ok
        {}
        void test2_a(int* arr[20])//ok
        {}
        void test2_b(int** arr)//ok
        {}
        int main()
        {
        	int arr[10] = { 0 };
        	int* arr2[20] = { 0 };
        	test_a(arr);
        	test_b(arr);
        	test_c(arr);
        	test2_a(arr2);
        	test2_b(arr2);
        }
    2. 二维数组传参
      1. 二维数组传参,函数形参的设计只能省略第一个[]的数字。
        //因为对一个二维数组,可以不知道有多少行,但是必须知道一行多少元素。
        //这样才方便运算。
      2. code示例
        #include 
        
        void test_a(int arr[3][5])//ok
        {}
        //void test_b(int arr[][])//语法有误
        //{}
        void test_c(int arr[][5])//ok
        {}
        //总结:二维数组传参,函数形参的设计只能省略第一个[]的数字。
        //因为对一个二维数组,可以不知道有多少行,但是必须知道一行多少元素。
        //这样才方便运算。
        void test_d(int* arr)//ok
        {}
        void test_e(int* arr[5])//ok
        {}
        void test_f(int(*arr)[5])//ok
        {}
        void test_g(int** arr)//ok
        {}
        int main()
        {
        	int arr[3][5] = { 0 };
        	test_a(arr);
        	// test_b(arr);
        	test_c(arr);
        	test_d(arr);
        	test_e(arr);
        	test_f(arr);
        	test_g(arr);
        }
    3. 一维指针传参
      1. 当一个函数的参数部分为一级指针的时候,函数能接收什么参数?数组
      2. code示例
        #include 
        void print(int* p, int sz) {
        	int i = 0;
        	for (i = 0; i < sz; i++)
        	{
        		printf("p[%d] = %dn",i, *(p + i));
        	}
        	
        }
        int main()
        {
        	int arr[10] = { 1,2,3,4,5,6,7,8,9 };
        	int* p = arr;
        	int sz = sizeof(arr) / sizeof(arr[0]);
        	//一级指针p,传给函数
        	print(p, sz);
        	return 0;
        }
    4. 二维指针传参
      1. 二级指针:接受二级地址作为参数
      2. code示例
        #include 
        
        void test(int** ptr) {
        	printf("num = %dn", **ptr);
        }
        int main()
        {
        	int n = 10;
        	int* p = &n;
        	int** pp = &p;
        	test(pp); // num = 10
        	test(&p); // num = 10
        
        	char* arr[10];
        	test(arr);// 出错
        
        	return 0;
        }
  5. 函数指针
    1. 调用函数输出两个地址,这两个地址是 test 函数的地址。
      1. 如何保存数组的地址? 首先,能给存储地址,就要求pfun1或者pfun2是指针,那哪个是指针?
        答案是:
        pfun1可以存放。pfun1先和*结合,说明pfun1是指针,指针指向的是一个函数,指向的函数无参数,返回值类型为void。
      2. code示例
        #include 
        void test()
        {
        	printf("hehen");
        }
        
        //下面pfun1和pfun2哪个有能力存放test函数的地址?
        void (*pfun1)();
        void* pfun2();
        
        int main()
        {
        	printf("%pn", test);  // 00007FF7B97A146A
        	printf("%pn", &test); // 00007FF7B97A146A
        	return 0;
        }
  6. 函数指针数组
    1. 数组 是一个存放 相同类型数据 的存储空间
    2. 把 函数的地址 存到一个 数组 中,那这个数组就叫 函数指针数组
    3. 函数指针数组 如何 定义 :int (*parr1[10])();
      1. 解析: parr1 先和 [] 结合,说明 parr1是数组 ,数组的 内容 是 int (*)() 类型的 函数指针 。
        函数指针数组的用途: 转移表
    4. code示例
      #include 
      
      int add(int a, int b) {
      	return a + b;
      }
      int sub(int a, int b) {
      	return a - b;
      }
      int mul(int a, int b) {
      	return a * b;
      }
      int div(int a, int b) {
      	return a / b;
      }
      int main()
      {
      	int x, y;
      	int input = 1;
      	int ret = 0;
      	int(*p[5])(int x, int y) = { 0, add, sub, mul, div }; //转移表
      	while (input)
      	{
      		printf("*************************n");
      		printf(" 1:add             2:sub n");
      		printf(" 3:mul             4:div n");
      		printf("*************************n");
      		printf("请选择:");
      		scanf("%d", &input);
      		if ((input <= 4 && input >= 1))
      		{
      			printf("输入操作数:");
      			scanf("%d %d", &x, &y);
      			ret = (*p[input])(x, y); // 函数指针数组
      		}
      		else
      			printf("输入有误n");
      		printf("ret = %dn", ret);
      	}
      	return 0;
      }
  7. 指向函数指针数组的指针
    1. 指向函数指针数组的指针是一个 指针;
    2. 指针指向一个 数组 ,数组的元素都是函数指针。
    3. code示例
      #include 
      
      void test(const char* str) {
      	printf("%sn", str);
      }
      int main()
      {
      	//函数指针pfun
      	void (*pfun)(const char*) = test;
      	//函数指针的数组pfunArr
      	void (*pfunArr[5])(const char* str);
      
      	pfunArr[0] = test;
      	//指向函数指针数组pfunArr的指针ppfunArr
      	void (*(*ppfunArr)[5])(const char*) = &pfunArr;
      	return 0;
      }
  8. 回调函数
    1. 回调函数就是一个通过函数指针调用的函数。
      1. 如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。
    2. code示例
      // 代码示例1
      //#include 
      //
      qosrt函数的使用者得实现一个比较函数
      //int int_cmp(const void* p1, const void* p2) {
      //	return (*(int*)p1 - *(int*)p2);
      //}
      //
      //int main()
      //{
      //	int arr[] = { 1, 3, 5, 7, 9, 2, 4, 6, 8, 0 };
      //	int i = 0;
      //
      //	qsort(arr, sizeof(arr) / sizeof(arr[0]), sizeof(int), int_cmp); // 从小到大排列
      //
      //	for (i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
      //	{
      //		printf("%d ", arr[i]);
      //	}
      //	printf("n");
      //	return 0;
      //}
      
      
      // 代码示例2
      // bubble() 模拟 实现qsort()
      #include 
      int int_cmp(const void* p1, const void* p2) {
      	return (*(int*)p1 - *(int*)p2);
      }
      
      void _swap(void* p1, void* p2, int size) {
      	int i = 0;
      	for (i = 0; i < size; i++)
      	{
      		char tmp = *((char*)p1 + i);
      		*((char*)p1 + i) = *((char*)p2 + i);
      		*((char*)p2 + i) = tmp;
      	}
      }
      void bubble(void* base, int count, int size, int(*cmp)(void*, void*))
      {
      	int i = 0;
      	int j = 0;
      	for (i = 0; i < count - 1; i++)
      	{
      		for (j = 0; j < count - i - 1; j++)
      		{
      			if (cmp((char*)base + j * size, (char*)base + (j + 1) * size) > 0)
      			{
      				_swap((char*)base + j * size, (char*)base + (j + 1) * size, size);
      			}
      		}
      	}
      }
      int main()
      {
      	int arr[] = { 1, 3, 5, 7, 9, 2, 4, 6, 8, 0 };
      	//char *arr[] = {"aaaa","dddd","cccc","bbbb"};
      	int i = 0;
      	bubble(arr, sizeof(arr) / sizeof(arr[0]), sizeof(int), int_cmp); // 冒泡排序
      	for (i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
      	{
      		printf("%d ", arr[i]);
      	}
      	printf("n");
      	return 0;
      }
  9. 指针和数组题目解析
    1. code示例
      #define _CRT_SECURE_NO_WARNINGS 1 
      
      #include
      
      int main()
      {
      	// &arr 表示的是数组的地址,而不是数组首元素的地址。
      	// arr 是数组名,数组名arr表示数组首元素的地址。
      	
      	//一维数组
      	printf("一维数组 int a[] = { 1,2,3,4 }; n");
      	int a[] = { 1,2,3,4 };
      
      	printf("数组的地址 = %pn", &a);               // 0092FDD4   &arr 表示的是数组的地址
      	printf("数组的大小 = %dn", sizeof(&a));       // 4
      	printf("数组地址的strlen = %dn", strlen(&a)); // 1
      
      	printf("数组的地址 = %pn", *&a);               // 0092FDD4
      	printf("数组所占字节数 = %dn", sizeof(*&a));   // 16
      	printf("数组地址的strlen = %dn", strlen(*&a)); // 1
      
      	printf("第一个元素地址 = %pn", a);                  // 0092FDD4   数组a首元素的地址
      	printf("数组所占字节数 = %dn", sizeof(a));          // 16   4个元素 * 4个字节 = 16
      	printf("第一个元素地址的strlen = %dn", strlen(a));  // 1
      	
      	printf("第一个元素地址 = %pn", (a + 0));               // 0092FDD4   数组首元素的地址
      	printf("第一个元素地址的大小 = %dn", sizeof(a + 0));   // 4
      	printf("第一个元素地址的strlen = %dn", strlen(a + 0)); // 1
      
      	printf("下标访问:第一个元素地址 = %pn", &a[0]);                 // 0092FDD4
      	printf("下标访问:第一个元素地址的大小 = %dn", sizeof(&a[0]));   // 4
      	printf("下标访问:第一个元素地址的strlen = %dn", strlen(&a[0])); // 1
      
      	printf("第一个元素值 = %dn", *a);                 // 1   解引用:解析出数组首元素地址中,存放的值
      	printf("第一个元素值的大小 = %dn", sizeof(*a));   // 4
      	// printf("第一个元素值的strlen = %dn", strlen(*a)); // 异常
      
      	printf("数组所有4个元素之后的地址 = %pn", (&a + 1));   // 0092FDE4
      	printf("此地址的大小 = %dn", sizeof(&a + 1));          // 4
      	printf("此地址的strlen = %dn", strlen(&a + 1));        // 11
      
      	printf("第二个元素地址 = %pn", (a + 1));               // 0092FDD8   数组第二个元素的地址
      	printf("第二个元素地址的大小 = %dn", sizeof(a + 1));   // 4
      	printf("第二个元素地址的strlen = %dn", strlen(a + 1)); // 1
      
      	printf("下标访问:第二个元素地址 = %pn", &a[0] + 1);                 // 0092FDD8 
      	printf("下标访问:第二个元素地址的大小 = %dn", sizeof(&a[0] + 1));   // 4
      	printf("下标访问:第二个元素地址的strlen = %dn", strlen(&a[0] + 1)); // 1
      
      	printf("第二个元素值 = %dn", a[1]);                    // 2
      	printf("第二个元素大小 = %dn", sizeof(a[1]));          // 4
      	// printf("第二个元素值的strlen = %dn", strlen(a[1])); // 发生异常
      	
      	//字符数组
      	printf("字符数组 char arr1[] = { 'a','b','c','d','e','f' }; n");
      	char arr1[] = { 'a','b','c','d','e','f' };
      
      	printf("数组的地址 = %pn", &arr1);               // 0057F77C   &arr 表示的是数组的地址
      	printf("数组的大小 = %dn", sizeof(&arr1));       // 4
      	printf("数组地址的strlen = %dn", strlen(&arr1)); // 19
      
      	printf("数组的地址 = %pn", *&arr1);               // 0057F77C
      	printf("数组所占字节数 = %dn", sizeof(*&arr1));   // 6
      	printf("数组地址的strlen = %dn", strlen(*&arr1)); // 19
      
      	printf("第一个元素地址 = %pn", arr1);                  // 0057F77C   数组arr1首元素的地址
      	printf("数组所占字节数 = %dn", sizeof(arr1));          // 6   6个元素 * 1个字节 = 6
      	printf("第一个元素地址的strlen = %dn", strlen(arr1));  // 19
      	
      	printf("第一个元素地址 = %pn", (arr1 + 0));               // 0057F77C   数组首元素的地址
      	printf("第一个元素地址的大小 = %dn", sizeof(arr1 + 0));   // 4
      	printf("第一个元素地址的strlen = %dn", strlen(arr1 + 0)); // 19
      
      	printf("下标访问:第一个元素地址 = %pn", &arr1[0]);                 // 0057F77C
      	printf("下标访问:第一个元素地址的大小 = %dn", sizeof(&arr1[0]));   // 4
      	printf("下标访问:第一个元素地址的strlen = %dn", strlen(&arr1[0])); // 19
      
      	printf("第一个元素值 = %cn", *arr1);                 // a   解引用:解析出数组首元素地址中,存放的值
      	printf("第一个元素值的大小 = %dn", sizeof(*arr1));   // 1
      	// printf("第一个元素值的strlen = %dn", strlen(*arr1)); // 异常
      
      	printf("数组所有4个元素之后的地址 = %pn", (&arr1 + 1));   // 0057F782
      	printf("此地址的大小 = %dn", sizeof(&arr1 + 1));          // 4
      	printf("此地址的strlen = %dn", strlen(&arr1 + 1));        // 13
      
      	printf("第二个元素地址 = %pn", (arr1 + 1));               // 0057F77D   数组第二个元素的地址
      	printf("第二个元素地址的大小 = %dn", sizeof(arr1 + 1));   // 4
      	printf("第二个元素地址的strlen = %dn", strlen(arr1 + 1)); // 18
      
      	printf("下标访问:第二个元素地址 = %pn", &arr1[0] + 1);                 // 0057F77D 
      	printf("下标访问:第二个元素地址的大小 = %dn", sizeof(&arr1[0] + 1));   // 4
      	printf("下标访问:第二个元素地址的strlen = %dn", strlen(&arr1[0] + 1)); // 18
      
      	printf("第二个元素值 = %cn", arr1[1]);                    // b
      	printf("第二个元素大小 = %dn", sizeof(arr1[1]));          // 1
      	// printf("第二个元素值的strlen = %dn", strlen(arr1[1])); // 发生异常
      	
      
      	//字符数组
      	printf("字符数组 char arr2[] = "abcdef"; n");
      	char arr2[] = "abcdef";
      
      	printf("数组的地址 = %pn", &arr2);               // 0107F79C   &arr 表示的是数组的地址
      	printf("数组的大小 = %dn", sizeof(&arr2));       // 4
      	printf("数组地址的strlen = %dn", strlen(&arr2)); // 6
      
      	printf("数组的地址 = %pn", *&arr2);               // 0107F79C
      	printf("数组所占字节数 = %dn", sizeof(*&arr2));   // 7
      	printf("数组地址的strlen = %dn", strlen(*&arr2)); // 6
      
      	printf("第一个元素地址 = %pn", arr2);                  // 0107F79C   数组arr2首元素的地址
      	printf("数组所占字节数 = %dn", sizeof(arr2));          // 7   6个元素 * 1个字节 + '' = 7  
      	printf("第一个元素地址的strlen = %dn", strlen(arr2));  // 6
      	
      	printf("第一个元素地址 = %pn", (arr2 + 0));               // 0107F79C   数组首元素的地址
      	printf("第一个元素地址的大小 = %dn", sizeof(arr2 + 0));   // 4
      	printf("第一个元素地址的strlen = %dn", strlen(arr2 + 0)); // 6
      
      	printf("下标访问:第一个元素地址 = %pn", &arr2[0]);                 // 0107F79C
      	printf("下标访问:第一个元素地址的大小 = %dn", sizeof(&arr2[0]));   // 4
      	printf("下标访问:第一个元素地址的strlen = %dn", strlen(&arr2[0])); // 6
      
      	printf("第一个元素值 = %cn", *arr2);                 // a   解引用:解析出数组首元素地址中,存放的值
      	printf("第一个元素值的大小 = %dn", sizeof(*arr2));   // 1
      	// printf("第一个元素值的strlen = %dn", strlen(*arr2)); // 异常
      
      	printf("数组所有4个元素之后的地址 = %pn", (&arr2 + 1));   // 0107F7A3
      	printf("此地址的大小 = %dn", sizeof(&arr2 + 1));          // 4
      	printf("此地址的strlen = %dn", strlen(&arr2 + 1));        // 12
      
      	printf("第二个元素地址 = %pn", (arr2 + 1));               // 0107F79D   数组第二个元素的地址
      	printf("第二个元素地址的大小 = %dn", sizeof(arr2 + 1));   // 4
      	printf("第二个元素地址的strlen = %dn", strlen(arr2 + 1)); // 5
      
      	printf("下标访问:第二个元素地址 = %pn", &arr2[0] + 1);                 // 0107F79D 
      	printf("下标访问:第二个元素地址的大小 = %dn", sizeof(&arr2[0] + 1));   // 4
      	printf("下标访问:第二个元素地址的strlen = %dn", strlen(&arr2[0] + 1)); // 5
      
      	printf("第二个元素值 = %cn", arr2[1]);                    // b
      	printf("第二个元素大小 = %dn", sizeof(arr2[1]));          // 1
      	// printf("第二个元素值的strlen = %dn", strlen(arr2[1])); // 发生异常
      	
          // 字符数组
      	//字符数组
      	printf("字符数组 char *p = "abcdef"; n");
      	char* p = "abcdef";
      
      	printf("数组的地址 = %pn", &p);               // 0108F968   &arr 表示的是数组的地址
      	printf("数组的大小 = %dn", sizeof(&p));       // 4
      	printf("数组地址的strlen = %dn", strlen(&p)); // 3 (每次的值都不固定)
      
      	printf("数组的地址 = %pn", *&p);               // 00A67B58
      	printf("数组所占字节数 = %dn", sizeof(*&p));   // 4
      	printf("数组地址的strlen = %dn", strlen(*&p)); // 6
      
      	printf("第一个元素地址 = %pn", p);                  // 00A67B58   数组p首元素的地址
      	printf("数组所占字节数 = %dn", sizeof(p));          // 4   ? 
      	printf("第一个元素地址的strlen = %dn", strlen(p));  // 6
      	
      	printf("第一个元素地址 = %pn", (p + 0));               // 00A67B58   数组首元素的地址
      	printf("第一个元素地址的大小 = %dn", sizeof(p + 0));   // 4
      	printf("第一个元素地址的strlen = %dn", strlen(p + 0)); // 6
      
      	printf("下标访问:第一个元素地址 = %pn", &p[0]);               // 00A67B58
      	printf("下标访问:第一个元素地址的大小 = %dn", sizeof(&p[0])); // 4
      	printf("下标访问:第一个元素地址的strlen = %dn", strlen(&p[0]));  // 6
      
      	printf("第一个元素值 = %cn", *p);                    // a   解引用:解析出数组首元素地址中,存放的值
      	printf("第一个元素值的大小 = %dn", sizeof(*p));      // 1
      	// printf("第一个元素值的strlen = %dn", strlen(*p)); // 异常
      
      	printf("数组所有4个元素之后的地址 = %pn", (&p + 1));   // 0108F96C
      	printf("此地址的大小 = %dn", sizeof(&p + 1));          // 4
      	printf("此地址的strlen = %dn", strlen(&p + 1));        // 8 (每次的值都不固定)
      
      	printf("第二个元素地址 = %pn", (p + 1));               // 00A67B59   数组第二个元素的地址
      	printf("第二个元素地址的大小 = %dn", sizeof(p + 1));   // 4
      	printf("第二个元素地址的strlen = %dn", strlen(p + 1)); // 5
      
      	printf("下标访问:第二个元素地址 = %pn", &p[0] + 1);                 // 00A67B59 
      	printf("下标访问:第二个元素地址的大小 = %dn", sizeof(&p[0] + 1));   // 4
      	printf("下标访问:第二个元素地址的strlen = %dn", strlen(&p[0] + 1)); // 5
      
      	printf("第二个元素值 = %cn", p[1]);                    // b
      	printf("第二个元素大小 = %dn", sizeof(p[1]));          // 1
      	// printf("第二个元素值的strlen = %dn", strlen(p[1])); // 发生异常
      	
      	//二维数组
      	printf("二维数组 int as[3][4] = { {1,2,3,4},{5,6,7,8},{9,10,11,12} }; n");
      	int as[3][4] = { {1,2,3,4},{5,6,7,8},{9,10,11,12} };
      	printf("%dn", sizeof(as)); // 48   as:数组as首元素的地址
      	printf("%dn", sizeof(as[0][0]));//4
      	printf("%dn", sizeof(as[0])); //16
      	printf("%dn", sizeof(as[0] + 1));//4
      	printf("%dn", sizeof(*(as[0] + 1))); //4
      	printf("%dn", sizeof(as + 1)); // 4
      	printf("%dn", sizeof(*(as + 1))); //16
      	printf("%dn", sizeof(&as[0] + 1));// 4
      	printf("%dn", sizeof(*(&as[0] + 1)));// 16
      	printf("%dn", sizeof(*as)); // 16
      	printf("%dn", sizeof(as[3]));// 16
      
      	return 0;
      }

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/953804.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号