第六章 指针
本章内容:1.指针的声明和使用 2.指针作为函数参数 3.数组与指针 4.动态内存分配 5.字符串与指针 6.指针数组 7.数组指针 8.指向指针的指针
1. 指针的声明和使用
指针声明通用的格式:数据类型 *指针变量名称;
指针的使用:
int i = 10;
int *p;
p = &i;
也可以如此:
int i = 10;
int *p = &i;
PS:注意这里,假如第一种赋值写成这样 *p = &i;这样是错误的。原因:*号也成为取值,*号的优先级大于=号,所以首先会进行*p运算,而*p运算是求出p指针指向的内存的值,而p内没有数据,所以*p找不到元素。
还可以这样赋值: int *p = 200; 或者写成 int *p; *p = 10;
指针的运算:(*p)++ 执行完毕后p的指向仍然是i 。*p++ 执行完毕后p指向下一个地址,p的指向发生了改变。
2. 指针作为函数参数
//指针作为函数参数传值
void changxToY(int *arr,int count)
{
int *satrt=arr,*end=&arr[count-1];
for (int i=0; i<count/2; i++,satrt++,end--) {
int temp = *satrt;
*satrt = *end;
*end = temp;
}
}
3. 数组与指针
3.1 一维数组与指针:
初始化:
int array[5];
int *p;
p = &array[0];
p = &array[4];
p = array;
通过指针元素访问数组:
int array[] = {1,2,3,4,5};
int *p;
p = array;
printf("下标法输出开奖结果:\n");
for(int i=0 ; i<5; i++)
{
printf("%d\n",array[i]);
}
printf("使用数组名法输出开奖结果:\n");
for(int i=0 ; i<5; i++)
{
printf("%d\n",*(array+i));
}
printf("指针法输出开奖结果:\n");
for( ; p<array + 5; p++)
{
printf("%d\n",*p);
}
3.2 二维数组与指针
初始化:
int *p;
int a[2][4];
p = a[0];
p = &a[0][0];
通过指针访问数组:
int arr[3][4] = {1,2,3,4,11,22,33,44,111,222,333,444};
int *p;
p = arr[0]; //或者 p = &arr[0][0]
for(int i=0; i<3*4; i++,p++)
{
if(i % 4 == 0)
printf("\n");
printf("%d\t",*p);
}
//结果为: 1 2 3 4
11 22 33 44
111 222 333 444
4. 动态内存分配
malloc()函数,free()函数,calloc()函数
//输入几个数,然后将这些数字翻转过来然后输出
int *p,*start ,*end,temp;
int count;
printf("请输入要输入的数字个数:\n");
scanf("%d",&count);
p = (int *)malloc(count * sizeof(int));
if(p == (int *)NULL)
{
printf("分配内存出错\n");
exit(0);
}else{
printf("请输入%d个数",count);
for(int i=0;i<count;i++)
{
scanf("%d",p+i);
}
start = p;
end = p+count-1;
for(int i=0;i<count/2;i++,start ++,end --)
{
temp = *start;
*start = *end;
*end = temp;
}
printf("翻转后的结果\n");
for(int i=0;i<count;i++)
{
printf("%d",*(p+i));
}
free(p); //释放内存
}
calloc()函数和malloc()函数功能是一样的,唯一的区别在于:malloc()函数申请到得内存区域内并不初始化为0,而calloc()函数申请到得内存区域初始化为0。
5. 字符串与指针
初始化:
char str[] = "hello word";
char *p;
p = str;
或者
char *p = "hello word";
printf("%s",p);
二维字符数组和指针:
char string[3][20] = {"hello word","hello coder","hello youths"};
char *p;
p = string[0];
for(int i=0; i<3; i++)
{
printf("%s\n",p+i*20);
}
6. 指针作为函数返回值
//指针作为函数返回值
int *getArrays()
{
static int arrays[]={1,2,3,4,5,6,7,8,9,10};
for (int i=0; i<10; i++) {
arrays[i] = arrays[i] * 10;
}
return arrays;
}
7. 指针数组
指针数组代表数组中得每一个元素都是一个指针,而这些指针可以指向其他地址。
初始化:
int i=10,j=20,k=30;
int *p[] = {&i,&j,&k};
使用:
char *boosName[5]={"C Primer","Objective-C","Visual","Learn Objective-C"};
sortBookName(boosName, 5);
for (int i=0; i<5; i++) {
printf("%s\n",boosName[i]);
}
//字符 指针数组排序
void sortBookName(char *booksName[],int num)
{
char *temp;
for (int i=1; i<num; i++) {
for (int j=0; j<num-i; j++) {
if (strcmp(booksName[j], booksName[j+1])>0) {
temp = booksName[j];
booksName[j] = booksName[j+1];
booksName[j+1] = temp;
}
}
}
}
8. 数组指针
数组指针是值向一个数组的指针变量,就是说我们定义的指针变量中存放的地址必须是一个数组才行,指针数组是一个数组,初始化需要多个数据初始化,而数组指针只需要一个地址数据就可以初始化。
//数组指针
void aaaa()
{
int a[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
int (*p)[4];
p=a;
for (int i=0; i<3; i++,p++) {
for (int j=0; j<4; j++) {
printf("%d ",* (*p+j) );
}
printf("\n");
}
}
9. 指向指针的指针
//指向指针的指针
void bbbb()
{
int **p;
int i=10,*p1;
p1 = &i;
p = &p1;
printf("%d\n",**p);
char *names[]={"basic","c plus pluse","c sharp","objective-c"};
char **p2;
for (int i=0; i<4; i++) {
p2 = names+i;
printf("%s\n",*p2);
}
}
下面给出一些小例子:
1.用指针实现三个数大小问题
//用指针实现三个数大小问题
void zhiZhenCountMax()
{
int num[3],*p,*max;
for (int i=0; i<3; i++) {
scanf("%d",&num[i]);
}
p=num;
max = p;
for (int i=0; i<3; i++,p++) {
if (*max<*p) {
*max = *p;
}
}
printf("最大值为:%d",*max);
}
2.用指针实现排序问题
//用指针实现排序问题(从小到大)
void zhiZhenScore()
{
int num[100],*p,temp,count;
p = num;
printf("要输入几个数count=");
scanf("%d",&count);
for (int i=0; i<count; i++) {
scanf("%d",p+i);
}
for (int i=1; i<count; i++,p=num) {
for (int j=0; j<count-i; j++,p++) {
if (*p > *(p+1)) {
temp = *p;
*p = *(p+1);
*(p+1) = temp;
}
}
}
for (int i=0; i<count; i++) {
printf("%d ",num[i]);
}
}
3. 从第一个字符串中复制长度为n的字符到第二个字符串中
char str1[]="hello word";
char str2[100]={'\0'};
copyOneToOne(str1, 5, str2);
puts(str2);
//从第一个字符串中复制长度为n的字符到第二个字符串中
void copyOneToOne(char *str1,int n,char *str2)
{
for (int i=0;i<n; str1++,i++,str2++) {
*str2 = *str1;
}
}
4. 从二维数组中找到最大值和最小值
//二维数组中找到最大值和最小值
void searchMaxAndMin()
{
int arrays[3][4]={0},*p,*max,*min;
printf("请输入12个数:\n");
p = arrays[0];
for (int i=0; i<3*4; i++,p++) {
scanf("%d",p);
}
p=arrays[0];
max = p;
min = p+1;
for (int i=0; i<3*4; i++,p++) {
if (*max < *p) {
*max = *p;
}
if (*min > *p) {
*min = *p;
}
}
printf("最大值为max=%d,最小值为:min=%d",*max,*min);
}
5. 将第二个数组复制到第一个数组中
//mian函数内部
int a[]={1,2,3,4,5,6},b[]={11,12,44,55};
int count1 = sizeof(a)/sizeof(a[0]);
int count2 = sizeof(b)/sizeof(b[0]);
arrayprt(a,count1, b,count2);
for (int i=0; i<count1; i++) {
printf("%d\n",a[i]);
}
//数组拷贝函数(将第二个数组复制到第一个数组中)
void arrayprt(int *a,int count1,int *b,int count2)
{
if (count1>=count2) {
for (int i=0; i<count1; i++,a++,b++) {
if (i<count2) {
*a = *b;
}
else
{
for (int i=0; i<count1-count2; i++,a++) {
*a = 0;
}
}
}
}else{
for (int i=0; i<count1; i++,a++,b++) {
*a = *b;
}
}
}