一. 指针(pointer)简介
-
指针是一个值为内存地址的变量
int *ptr_yaer; ptr_year = &year; //将year值存放地址给ptr_year
-
基本用法:
type * name; //数据类型 * 指针变量名 int *ptr_name char *ptr_name float *ptr_name double *Ptr_name int *ptr_name = NULL; //指针的初始值为空,表示指针不指向任何地址
要点
指针同样是一个变量,只不过该变量中存储的是另一个对象的内存的地址
如果一个变量存储另一个对象的地址,则称该变量指向这个对象
指针变量可以赋值,指针的指向在程序执行中可以改变
#include <stdio.h>
void fun(char *c, int d)
{
*c = *c + 1; //使字符c的ASCII码值加1
d = d + 1;
printf("%c,%c,", *c, d);
}
int main()
{
char b = 'a', a = 'A';
fun(&b, a);
printf("%c,%c\n", b, a);
}
程序输出结果:b,B,b,A
二.指针与数组
-
数组:
存储在一块连续的内存空间中 数组名就是这块连续内存空间的首地址
-
指针的算术运算:
指针的递增和递减(++, --) 指针加上或减去某个整数值
-
demon
#include <stdio.h> int main() { //指针加上或减去某个整数值 int i; double score[5] = {98, 87, 65, 43, 76}; double *ptr_score; ptr_score = &score[1]; ptr_score += 2; //指针+2 printf("%.2lf\n", *ptr_score); ptr_score -= 3; //指针-3 printf("%.2lf\n", *ptr_score); return 0; }
要点
1.int num[50]; //num是数组名,也是数组的首地址
2.num = &num[0];
3.i + 1个元素表示:
地址:&num[i]; 或 num + i;
元素值:num[i]; 或 *(num + i);
4.指针赋值:
int ptr_num = num;
int ptr_num = &num[0];
5.指针变量指向数组元素
int *ptr_num = &num[4];
int *ptr_num = num + 4;
-
demon
#include <stdio.h> void main() { int array[] = {15, 20, 25, 30, 35}; int i;//循环变量 int *ptr_array = array; //用指针访问数组元素 printf("****************************************************************\n"); for(i = 0; i < 5; i++) //方式1 { printf("第%d个元素的值为%d\t地址为:%p\n", i + 1, ptr_array[i], &ptr_array[i]); } printf("****************************************************************\n"); for(i = 0; i < 5; i++) //方式2 { printf("第%d个元素的值为%d\t地址为:%p\n", i + 1, *(ptr_array + i), ptr_array + i); } printf("*****************************************************************\n"); for(i = 0; i < 5; i++) //方式3 { printf("第%d个元素的值为%d\t地址为:%p\n", i + 1, *ptr_array, ptr_array); *ptr_array++; //每次循环都会移动指针的指向,要注意重置 //该循环执行之后不能再遍历数组 } }
使用数组逆序排列
#include <stdio.h>
#define N 5
int main()
{
int array[N] = {15, 20, 25, 30, 35};
//实现数组的逆序--原理就是数组的首尾元素进行交换
int temp; //临时变量
int i;
for(i = 0; i < N / 2; i++)
{
//第i个值和第i-1个值相交换
temp = array[i];
array[i] = array[N - i - 1];
array[N - i - 1] = temp;
}
printf("打印数组:\n");
for(i = 0; i < N; i++)
{
printf("第%d个元素的值是:%d\n", i + 1, *(array + i));
}
return 0;
}
使用指针逆序排列
#include <stdio.h>
#define N 5
int main()
{
int array[N] = {15, 20, 25, 30, 35};
int temp; //临时变量
int i;
int *ptr_array_start = array; //指向数组首元素的指针
int *ptr_array_end = array + N -1; //指向数组末元素的指针
while(ptr_array_start != ptr_array_end)
{
//首尾交换,指针分别进行更新
temp = *ptr_array_start;
*ptr_array_start = *ptr_array_end;
*ptr_array_end = temp;
//首元素指针要向后移动
ptr_array_start++;
ptr_array_end--;
}
printf("数组元素:\n");
for(i = 0; i < N; i++)
{
printf("%d\t", *(array + i));
}
}
三.指针与二维数组
首地址:
&names[0][0];
使用指针访问二维数组:
*(a[1] + 2);
*(*(a + 1) + 2); //先访问行再访问列
- demon:
#include <stdio.h>
int main()
{
//数组名就是数组的首地址(数组首元素地址)
//二维数组的理解:是由个1维数组所组成
double score[5][3] = {{55, 66, 77}, {52, 62, 72}, {15, 26, 37},{54, 65, 76},{55, 66, 77}};
double (*ptr_score)[3] = score; //二维数组赋给指针时需要确定横向列数
int i, j;
printf("***********************************************\n");
printf("打印数组:\n");
//普通方式遍历
for(i = 0; i < 5; i++)
{
for(j = 0; j < 3; j++)
{
printf("%.2lf\t", score[i][j]);
}
printf("\n");
}
//指针方式遍历
printf("**************************************************\n");
printf("打印数组:\n");
for(i = 0; i < 5; i++)
{
for(j = 0; j < 3; j++)
{
printf("%.2lf\t", *(*(score + i)+ j));
}
printf("\n");
}
return 0;
}
小结
-
指针是一个变量,存储另一个变量(对象)的内存地址
-
指针的声明由基本类型、星号(*)和变量名组成
-
为指针赋值,赋值运算符右侧必须是地址
如果是普通变量需要在前面加一个取地址运算符 如果是另一个指针变量或者是一个数组,不需要加
-
运算符 * 用于返回指针指向的内存地址中存储的值
-
使用指针访问一维数组和二维数组的元素
指向字符串的指针
-
将指针指向字符串:
-
可以指向常量字符串
-
也可以指向存储字符串的字符数组
-
#include <stdio.h>
int main()
{
char * words = "hello,china!"; //指向常量字符
puts(words); //打印字符串
printf("%p\n", words); //打印指针地址
words += 6; //指针地址加9
puts(words);
printf("%p\n", words);
return 0;
}
-
数组形式和执行形式的不同:
-
初始化字符数组会把静态存储区的字符串拷贝到数组中
-
初始化指针时只把字符串的地址拷贝给指针
-
#include <stdio.h>
int main()
{
//理解字符串和字符指针的区别
char str1[] = "hello, mengzhen!";
char *str2 = "hello, mengzhen!";
printf("字符串常量的地址:%p\n", "hello, mengzhen!");
printf("字符数组的首地址:%p\n", str1);
printf("字符指针的取值:%p\n", str2);
return 0;
}