C语言进阶-2指针(一)
目录
- 1. 字符指针
- 1.1 一般用法:字符指针指向单字符
- 1.2 第二种用法,字符串首地址给指针变量
- 1.3 习题,下面代码的输出结果是什么?为什么?
- 2. 指针数组
- 2.1实例—— 字符指针数组
- 2.2实例——整形指针数组
- 2.3 例子,识别下下面的的指针数组是什么意思
- 3. 数组指针
- 3.1 数组指针的定义
- 3.2 &一维数组名VS一维数组名
- 3.2.1 实例——&arr和arr分别表示什么
- 3.3 数组指针的使用
- 3.3.1 使用实例1
- 3.3.2 使用实例2
- 3.3.3 练习
1. 字符指针
在指针的类型中我们知道有一种指针类型为字符指针 char* ,指向字符的指针
1.1 一般用法:字符指针指向单字符
#include<stdio.h>
int main()
{
//字符指针
char a = 'm';
char* pc = &a;
pc = 'w';
printf("%c", pc);
return 0;
}
1.2 第二种用法,字符串首地址给指针变量
char *str ="abcdef"的本质意义是把字符串的首字符的地址传给指针变量str了
#include<stdio.h>
int main()
{
//字符指针
char* str = "abcdefgh";
char* ps = str;
printf("%s", ps);
return 0;
}
这里我还写了个错误代码
#include<stdio.h>
int main()
{
//字符指针
//char a = 'm';
//char* pc = &a;
//pc = 'w';
//printf("%c", pc);
char* str = "abcdefgh";
char* ps = &str; //给str取地址了
printf("%s", ps);
return 0;
}
这里传给*ps的地址就不是字符串的首地址了,传的是&str自己的地址,
1.3 习题,下面代码的输出结果是什么?为什么?
#include <stdio.h>
int main()
{
char str1[] = "hello code.";
char str2[] = "hello code.";
const char* str3 = "hello code.";
const char* str4 = "hello code.";
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");
return 0;
}
分析:代码结果第一个是not same 第二个是same
这里str3和str4指向的是一个同一个常量字符串“hello code”。C/C++会把常量字符串存储到单独的一个内存区域,当几个指针(这里是str3和str4)指向同一个字符串的时候,他们实际会指向同一块内存。但是用相同的常量字符串去初始化不同的数组的时候(str1和str2)就会开辟出不同的内存块。所以str1和str2不同,str3和str4不同。
2. 指针数组
指针数组
字符数组,是存放字符的数组
整形数字,是存放整形的数组
所以指针数组是存放指针(地址)的数组
2.1实例—— 字符指针数组
#include<stdio.h>
int main()
{
const char* arr[5] = {"abcd","qw","ertyi","pouggttrr","sky"};//这里最好还是加上const 因为存储的是字符串常量,是不变的值,
//我们不希望被改变,const修饰char*,表示char*指向的值不能被修改
int i = 0;
for (i = 0; i < 5; i++)
{
printf("%s\n", arr[i]);
}
return 0;
}
分析
2.2实例——整形指针数组
#include <stdio.h>
int main()
{
int arr1[5] = { 1,2,3,4,5 };
int arr2[5] = { 5,4,3,2,1 };
int arr3[5] = { 7,8,9,4,5 };
int arr4[5] = { 9,1,2,3,8 };
int* arr[4] = { arr1,arr2,arr3,arr4 };
int i = 0;
for (i = 0; i < 4; i++)
{
int j = 0;
for (j = 0; j < 5; j++)
{
printf("%d ", arr[i][j]); //arr[i]是找到我们的arr1/2/3/4,然后再[j]就是进入arri(i= 1,2,3,4)找到其中的每一个元素
// printf("%d ",*( arr[i]+j) ); 这样打印也可以
}
printf("\n");
}
return 0;
}
分析
2.3 例子,识别下下面的的指针数组是什么意思
int* arr1[10]; //整形指针的数组,存放的是整形指针的数组
char *arr2[4]; //一级字符指针的数组,存放的是一级字符型指针的数组
char **arr3[5];//二级字符指针的数组,存放的是二级字符型指针的数组
3. 数组指针
3.1 数组指针的定义
数组指针是指针?还是数组?——是指针
字符指针——存放字符地址的指针—指向字符的指针char *
整型指针——存放整型地址的指针—指向整型的指针 int *
浮点型的指针——存放浮点型地址的指针—指向浮点型的指针 float* double*
数组指针——存放数组地址的指针——指向数组的指针
如何表示:
int (*p)[10];
分析:p先和*结合,说明p是一个指针变量,然后指着指向的是一个大小为10个整型的数组。所以p是一个指针,指向一个数组,叫数组指针
注意:[ ]的优先级要高于 * 号的,所以必须加上( )来保证p先和 * 结合
3.2 &一维数组名VS一维数组名
int arr[10];
arr 和 &arr 分别是啥?
我们已经知道arr是数组名,数组名表示数组首元素的地址。
那&arr数组名表示的是什么?
3.2.1 实例——&arr和arr分别表示什么
#include <stdio.h>
int main()
{
int arr[10] = { 0 };
printf("%p\n", arr);
printf("%p\n", &arr[0]);
printf("%p\n", &arr);
return 0;
}
- 我们给每个指针+1
#include <stdio.h>
int main()
{
int arr[10] = { 0 };
printf("%p\n", arr);
printf("%p\n", arr+1);
printf("%p\n", &arr[0]);
printf("%p\n", &arr[0]+1);
printf("%p\n", &arr);
printf("%p\n", &arr+1);
return 0;
}
分析
其实&arr和arr,虽然值是一样的,但是意义不一样。
实际上: arr表示的首元素的地址,arr+1跳过的是第一个元素,所以是4个字节
&arr 表示的是数组的地址,而不是数组首元素的地址。
数组的地址+1,跳过的是整个数组的大小,所以 &arr+1 相对于 &arr 的差值是40
3.3 数组指针的使用
既然数组指针指向的是数组,那数组指针中存放的应该是数组的地址。
3.3.1 使用实例1
#include<stdio.h>
int main()
{
int arr[9] = { 1,2,3,4,5,6,7,8,9 };
int(*p)[9] = &arr;;//把数组arr的地址赋值给数组指针变量p
//但是我们一般很少这样写代码
return 0;
}
3.3.2 使用实例2
一维数组名arr,表示首元素的地址
二维数组的首元素是二维数组的第一行
#include <stdio.h>
void print1(int arr[3][4], int r, int c)
{
int i = 0;
for (i = 0; i < r; i++)
{
int j = 0;
for (j = 0; j < c; j++)
{
printf("%d ", arr[i][j]);
}
printf("\n");
}
}
void print2(int(*p)[4], int r, int c)
{
int i = 0;
for (i = 0; i < r; i++)
{
int j = 0;
for (j = 0; j < c; j++)
{
//printf("%d ", (*(p + i))[j]);
printf("%d ", p[i][j]);
}
printf("\n");
}
}
int main()
{
int arr[3][4] = { {1,2,3,4}, {2,3,4,5} , {3,4,5,6} };
//数组名arr,表示首元素的地址
//但是二维数组的首元素是二维数组的第一行
//所以这里传递的arr,其实相当于第一行的地址,是一维数组的地址
//可以数组指针来接收
//print1(arr, 3, 4);
print2(arr, 3, 4);
return 0;
}
3.3.3 练习
int arr[5]; //整形数组,有5个整形元素的 整形数组arr
int *parr1[10]; //指针数组,有10个整形指针元素的 整形指针数组parr1
int (*parr2)[10];//数组指针 ,指向int型的[10]个元素的数组 的数组指针parr2
int (*parr3[10])[5];//parr3是数组,数字有10个元素,数组的每个元素类型是:int(*)[5]的数组指针类型。
int (*parr3[10])[5];分析