char str1[] = "hello world."; char str2[] = "hello world."; constchar* str3 = "hello world."; constchar* str4 = "hello world."; if (str1 == str2) printf("str1 and str2 are same\n"); else printf("str1 and str2 are not same\n"); if (str3 == str4) printf("str3 and str4 are same\n"); else printf("str3 and str4 are not same\n");
这里 str1 和 str2 是在内存中开辟了两块不同的内存空间。所以不等。
而 str3 和 str4 指向的是同一个常量字符串,C语言中没必要开辟两块内存空间用
于存放同一个常量字符串。
数组指针变量
指向一个数组的指针变量称为数组指针变量,存放的是一个数组的地址
1
type (*p)[];// 语法格式
在定义时需要用()将 * 和 p 结合起来,表明 p 是一个指针变量。
2.1 数组指针变量的初始化
使用 & 取地址符
二维数组传参的本质
可以看到,二维数组的数组名是首元素即该数组第一行的地址
下面仅需一个二维数组传参的示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14
voidtest(int arr[3][5], int r, int c) { for (int i = 0;i < r;i++) { for (int j = 0;j < c;j++) { printf("%d ", arr[i][j]); } printf("\n"); } }
int arr[3][5] = { {1,2,3,4,5},{6,7,8,9,10},{11,12,13,14,15} }; test(arr, 3, 5);
可以看到二维数组本质上也是传递了地址,传递的是第一行这个一维数组的地址
这就意味着二维数组传参也可以写成指针形式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
voidtest(int (*p)[5], int r, int c) { for (int i = 0;i < r;i++) { for (int j = 0;j < c;j++) { printf("%d ", *(*(p + i) + j)); // p 存放的是 arr 首行的地址 p + i 是 arr 第 i 行的地址 // *(p + i) 可以拿到第 i 行的数组 // *(p + i) + j 可以拿到第 i 行第 j 个元素的地址 } printf("\n"); } }
int arr[3][5] = { {1,2,3,4,5},{6,7,8,9,10},{11,12,13,14,15} }; int (*p)[5] = &arr; test(p, 3, 5);
而对于一个数组名来说
1
*(arr + i) 与 arr[i] 等价
所以可以这样写
1 2 3 4 5 6 7 8 9 10 11 12 13 14
voidtest(int (*p)[5], int r, int c) { for (int i = 0;i < r;i++) { for (int j = 0;j < c;j++) { printf("%d ", p[i][j]); } printf("\n"); } } int arr[3][5] = { {1,2,3,4,5},{6,7,8,9,10},{11,12,13,14,15} }; int (*p)[5] = &arr; test(p, 3, 5);