指针详解
arr[i] = *(arr+i) = *(p+i) = p[i]
字符指针
char p*
int main()
{
char ch = 'w';
char* pc = &ch;
return 0;
}
int main()
{
char arr[] = "abcdefg";
char* pc = arr;
printf("%s\n",arr);
printf("%s\n",pc);
return 0;
}
//%s输出字符串形式,遇到字符指针会自动解引用,打印,直到遇到\0才结束打印
int mian()
{
char* p = "abcde";//将字符串首字符的地址放到p里去了
printf("%c\n",*p);//结果为a
printf("%s\n",p);//结果为abcde;
return 0;
}
错误操作
int mian()
{
char* p = "abcdef";//"abcdef"为常量字符串,后续无法对其进行更改
*p = 'W';//不合规的操作,会造成段错误
return 0;
}
int main()
{
char arr1[] = "abcdef";
char arr2[] = "abcdef";
char* p1 = "abcdef";//常量字符串无法被修改
char* p2 = "abcdef"//指针p2所指向的空间的内容为abcdef,即p1指针和p2指针一样
if(arr1 == arr2)//此处比较的时两个数组的首元素的地址
{
printf("hehe\n");
}
else
printf("haha\n");
//结果打印haha
if(p1 == p2)
{
printf("hehe");
}
else
printf("haha");
//此处打印hehe
return 0;
}
注意!易错点:
char* p = "abc";
printf("%s\n",p);//打印的是p指针指向的地址之后的一串字符,遇到\0停止打印,所以结果为abc;
printf("%p\n",p);//打印的是p指针指向的内容的地址,即字符串abc的地址;
printf("%p\n",&p);//打印的是指针p本身自己的地址
指针数组
其实是数组
int arr[10] = {0};//整型数组
char ch[5] = { 0 };//字符数组
同理,指针数组是用来存放指针的
int* parr[4];//存放整型指针的数组,简称指针数组
char* pch[5];//存放字符指针的数组,也是指针数组
int main()
{
int a = 10;
int b = 20;
int c = 30;
int d = 40;
int* arr[4] = {&a,&b,&c,&d};
int i = 0;
for(i=0;i<4;i++)
{
printf("%d ",*(arr[i]) );
}
return 0;
}
#include <stdio.h>
int main()
{
int arr1[] = {1,2,3,4,5};
int arr2[] = {2,3,4,5,6};
int arr3[] = {3,4,5,6,7};
int* parr[] = {arr1,arr2,arr3};//分别存储各数组的首元素的地址
int i = 0;
for(i=0;i<3;i++)
{
int j = 0;
for(j=0;j<5;j++)
{
printf("%d ",*(parr[i]+j));//以prr[i]地址为起点,移动j个字节,每一组有5个字节,即每个arr[i]中间间隔五个字节
}
printf("\n");
}
//注意 整型指针数组打印采用循环嵌套,区别于之前字符指针%s会自动解引用
return 0;
}
↑
arr[0]:指第一行数字1的地址
arr[1]:指第二行数字2的地址
arr[2]:指第三行数字3的地址
数组指针
是指向数组的指针,可以存放数组的地址(指代表整个数组的地址,即&arr)
int arr[10] = {0};
int(*p)[10] = &arr;//先看*p,(原本[ ]的优先级高于*)即p是指针,再指向int [10],即指向一个数组。即此处的p是一个数组指针
//如果写成 int* p[10] = &arr,则此处p还是一个数组,而不是一个指针
int main()
{
char* arr[5] = {0};
char* (*pa)[5] = &arr;//数组中每一个指针元素的类型是char*
return 0;
}
使用
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
int (*pa)[10] = &arr;
int i = 0;
for(i=0;i<10;i++)
{
printf("%d ",(*pa)[i]);//(*pa) = arr
}
return 0;
}
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
int (*pa)[10] = &arr;
int i = 0;
for(i=0;i<10;i++)
{
printf("%d ",*(*pa+i);// pa = &arr,*pa = arr
}
return 0;
}
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
int* p = arr;
int i = 0;
for(i=0;i<10;i++)
{
printf("%d ",*(p+i);// *pa = arr
}
return 0;
}
正式使用
#include<stdio.h>
void print2(int(*p)[5],int x,int y)
{
int i = 0;
int j = 0;
for(i=0;i<x;i++)
{
for(j=0;j<y;j++)
{
printf("%d ",*(*(p+i)+j));//*(p+i)其实是第i行数组的数组名,代表该行首元素的地址(此时的首元素真的就是单个元素,而不再是一整个数组,因为此时第i行数组是一维数组)
//printf("%d ",*(p[i]+j));
//printf("%d ",p[i][j]);
}
printf("\n");
}
}
int main()
{
int arr[3][5] = {{1,2,3,4,5},{2,3,4,5,6},{3,4,5,6,7}};
print2(arr,3,5);//二维数组时arr代表首元素地址,即代表第一行的地址
return 0;
}
数组指针解引用后得到的是数组名,即为该数组的首元素的地址!
数组参数、指针参数
一维数组传参
void test(int arr[])
{}
void test(int arr[10])
{}
void test(int* arr)//整型->指针
{}
-----------------------------------------------------------------------------------------------------------
void test2(int* arr2[])
{}
void test2(int* arr2[20])
void test2(int* *arr2)//指针->指针
----------------------------------------------------------------------------------------------------------
int main()
{
int arr[10] = {0};
int* arr2[20] = {0};//指针数组
return 0;
}
二维数组传参
void test(int arr[3][5])
{}
void test(int arr[][5])//必须写列数,不可省略
{}
---------------------------------------------------------------------------------------------------------
void test3(int(*arr)[5])
int main()
{
int arr[3][5] = {0};
test(arr);//二维数组传参
test3(arr);
return 0;
}
一级指针传参
void test(int* p)
{}
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
int* p = arr;
test(p);
return 0;
}
void test1(int* p)
{}
//test1能接收什么类型的变量?
//一:test1(&a);
//二:int* pa=&a;test1(pa);
二级指针传参
void test(int** ptr)
{}
int main()
{
int n = 10;
int* p = &n;
int* *pp = &p;
test(pp);
test(&p);
}
void test(int** p)
{}
//test能接受什么类型的变量?
//int* ptr;test(&ptr);
//int** ptr;test(ptr);
//int* arr[10];test(arr);//arr是指针数组,arr代表首元素地址,首元素本身就是指针,所以arr是二级指针
函数指针
是存放函数地址的一个指针
int Add(int a,int b)
{
int z = 0;
z = a+b;
return z;
}
int main()
{
int x = 10;
int y = 20;
//printf("%d\n",Add(x,y));
printf("%p\n",&Add);//注意此处没有括号!
printf("%p\n",Add);
//Add与&Add是一模一样的,都是函数的地址
int(*pa)(int,int) = Add;//pa是指针,参数类型是int,int,函数的返回类型是int
printf("%d\n",(*pa)(2,3));//对pa解引用,传入参数2,3,得到函数的运行结果
return 0;
}
void Print(char* str)
{
printf("%s\n",str);
}
int main()
{
void(*p)(char*) = Print;//p即为函数指针//*p代表p为指针,()代表p指向函数,char*代表函数的参数类型,void代表函数的返回值类型
(*p)("hello!");
return 0;
}
注意:
以上代码中Print函数接受类型为char*是为了接收整个字符串的地址,这样后续才可以直接打印整个字符串。
因为char类型只能接收一个单个字符:
#include <stdio.h>
void Print(char str)
{
printf("%c\n", str);
}
int main()
{
void (*p)(char) = Print; // p即为函数指针
(*p)('a'); // 传递字符 'h' 给函数指针
return 0;
}
标签:10,arr,int,void,C语言,char,详解,指针
From: https://www.cnblogs.com/arongsec/p/17615030.html