前言:关于指针的一些概念
1. 指针就是个变量,用来存放地址,地址唯一标识一块内存空间。
2. 指针的大小是固定的4/8个字节(32位平台/64位平台)。
3.指针是有类型,指针的类型决定了指针的±整数的步长,指针解引用操作的时候的权限。
4. 指针的运算。
提示:以下是本篇文章正文内容,下面案例可供参考
一、字符指针
在指针的类型中我们知道有一种指针类型为字符指针char*
1. 一般使用
#include<stdio.h>
int main()
{
char ch = 'w';
char* pc = &ch;
*pc = 'a';
printf("%c", ch);
return 0;
}
上述代码使用,char *指针把这个字符变量的地址放到这个char *指针中,然后通过对 *pc解引用,找到字符ch ,然后改变其中的值为a,我们来看一下打印的结果。这就是我们的一般用法.
2. 另一种方法使用
我们来看一个简单的代码
#include<stdio.h>
int main()
{
char* p = "abcdef";
}
这段代码的意思是什么呢?这里是把字符串"abcdef"放到这个char*p的指针变量中了吗?呢我们就需要去想它能放的下吗?现在是在32位环境下,p指针变量是4个字节而"abcdef"是6个字节,在加上/0是7个字节,所以答案是存不下。所以这个代码的意思绝对不是把"abcdef"放到指针变量p中。其实这个代码的意思是把这个常量字符串"abcdef"首字符a的地址存放到指针变量p中。 下面画图来说明(假设首字符地址是0x0012ff40)
如果你还是不敢相信,呢么我们可以使用 *p解引用访问这个字符串,其实访问的就是字符a 我们可以打印看看是不是.结果和我们想的一样
在有些初学者,不正确理解上述代码,就会出现下列问题。下面这个程序崩了,这是为什么呢?这是因为,这个字符串是一个常量字符串,常量字符串是不允许被修改的。
其实我们对这个代码,稍做优化可以防止出现这个错误。 这里就提示你编译错误。
#include<stdio.h>
int main()
{
const char* p = "abcdef";
*p = 'w';
}
3. 经典面试题
我们观察下列代码,会输出说明结果呢?
#include <stdio.h>
int main()
{
char str1[] = "hello world.";
char str2[] = "hello world.";
const char* str3 = "hello world.";
const char* 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");
return 0;
}
这里最终输出的是:
这是因为: 这里str3和str4指向的是一个同一个常量字符串。C/C++会把常量字符串存储到单独的一个内存区域,当几个指针。指向同一个字符串的时候,他们实际会指向同一块内存。但是用相同的常量字符串去初始化不同的数组的时候就会 开辟出不同的内存块。所以str1和str2不同,str3和str4不同。
二、指针数组
指针数组是一个存放指针的数组
1. 一种使用
来看下面的一段代码 : 这里是3个变量,我们只需创建3个指针变量就可,但是如果变量10个 20个甚至更多呢?我们也需要创建对应的指针变量吗?呢我们就想到创建一个整型指针的数组,来存放变量的地址。
#include<stdio.h>
int main()
{
//int* arr[10];//存放整型指针的数组
//char* ch[5];//存放字符指针的数组
int a = 10;
int b = 20;
int c = 30;
int* p1 = &a;
int* p2 = &b;
int* p3 = &c;
int* arr[3] = { &a, &b, &c };//arr就是一个指针数组
int i = 0;
for (i = 0; i < 3; i++)
{
printf("%d ", *(arr[i]));//找到变量对应的地址,然后解引用就拿到了对应的元素
}
return 0;
}
2. 第二种使用
来看下面的一段代码 :
#include<stdio.h>
int main()
{
int arr1[5] = { 1,2,3,4,5 };
int arr2[5] = { 2,3,4,5,6 };
int arr3[5] = { 3,4,5,6,7 };
int* parr[3] = { arr1, arr2, arr3 };//parr是一个指针数组
int i = 0;
for (i = 0; i < 3; i++)//找到每一行
{
int j = 0;
for (j = 0; j < 5; j++)找到每一个元素
{
//printf("%d ", parr[i][j]);
printf("%d ", *(parr[i]+j));依次加j,相当于找到每个元素地址,然后在解引用,找到并打印这个元素
}
printf("\n");
}
return 0;
我们画图来解释:
我们分别有三个数组arr1 arr2 arr3,数组名表示首元素地址。然后我们把这三个数组名也就是首元素地址,分别存放到parr数组中,每一个类型都是int*
parr[0]–>arr1、parr[1]–>arr2、parr[2]–>arr3 分别对应。这时我们发现好像模拟出一个二维数组,先使用parr找到每一行,然后又可以找到每一个元素,然后就得出下面的打印结果。
三、&数组名vs数组名
我们知道arr是数组名,数组名表示首元素地址。呢么&arr是什么呢?
来看下面的一段代码 :
#include <stdio.h>
int main()
{
int arr[10] = {0};
printf("%p\n", arr);//%p打印地址
printf("%p\n", &arr);
return 0; }
运行结果如下:
可见数组名和&数组名打印的地址是一样的。难道这个两个意义相同吗?
我们在看下面的一段代码 :
#include <stdio.h>
int main()
{
int arr[10] = { 0 };
printf("arr = %p\n", arr);
printf("&arr= %p\n", &arr);
printf("arr+1 = %p\n", arr + 1);
printf("&arr+1= %p\n", &arr + 1);
return 0;
}
运行结果如下:
在这里arr类型是int* 当我们对其+1时由00B6FC70–>00B6FC74 整型指针+1跳过4个字节。而&arr类型是int(*)[10],是数组指针类型,而数组的地址+1,00B6FC74–>00B6FC98 跳过了40个字节,跳过了整个数组的大小,所以 &arr+1 相对于 &arr 的差值是40.
通常情况下,我们说的数组名都是数组首元素的地址但是有2个例外:
1. sizeof(数组名),这里的数组名表示整个数组,sizeof(数组名)计算的是整个数组的大小
2. &数组名,这里的数组名表示整个数组,&数组名,取出的是整个数组的地址
四、数组指针
既然数组指针指向的是数组,那数组指针中存放的应该是数组的地址。
一个数组指针的使用:
#include <stdio.h>
void print_arr1(int arr[3][5], int row, int col) {
int i = 0;
for(i=0; i<row; i++)
{
for(j=0; j<col; j++)
{
printf("%d ", 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(j=0; j<col; j++)
{
printf("%d ", 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; }
学了指针数组和数组指针我们来一起回顾并看看下面代码的意思:
1 int arr[5]; arr是一个整型数组,有5个元素,每个元素是int类型的。
2 int *parr1[10];parr1是一个数组,数组有10个元素,每个元素的类型是int *;所以parr1是指针数组。
3 int (*parr2)[10];parr2先和 * 结合,说明parr2是一个指针,该指针指向一个数组,数组是10个元素,每个元素是int类型的,parr2是数组指针。
4 int (*parr3[10])[5];parr3和[]结合,说明parr3是一个数组,数组是10个元素,数组的每个元素是什么类型呢?是一种数组指针,类型是int( * )[5],该类型的指针指向的数组有5个int类型的元素。
以上就是指针的一部分内容, 🌟Hello world 我们下期见!