首页 > 代码库 > C基础 - 指针:1.2

C基础 - 指针:1.2

指针和数组

1 - 指针对应的数组元素地址

1 int ages[5]={10,9,8,7,6};
2 int *p = ages;// 等同于:int *p = &ages[0];

第一个元素的地址p    &ages[0];第二个元素的地址p+1    &ages[1];第三个元素的地址p+2    &ages[2]  ......

2 -  示例代码

需求:利用指针,遍历出数组元素

1 int ages[5]={101,19,21,33,22};
2 int *p = ages;
3 for(int i=0;i<5;i++)
4 printf("%d\t",*(p+i));
5 printf("\n");

3 - 数组元素的三种访问形式

  (1) 数组名[下标]

  (2)指针变量名[下标]

  (3) *(指针变量+下标)

  (4)示例代码:

1 char *arr[4]={"ios","iphone","ipod","abc"};
2 printf("%s \n",arr[1]);// 输出:iphone
3 printf("%c \n",*(*(arr+1)+1));// 输出:p
4 printf("%s \n",arr[2]);// 输出:ipod
5 printf("%c \n",*(arr[2]+3));// 输出:d

注:指针变量的+1或-1究竟是加、减多少?这取决于指针的类型:如果是 char 类型的指针就加1个字节;如果是 int 类型的指针则加4个字节

4 - 利用指针来接收一个数组,指针变量指向数组的首元素

1 void change(int array[]);// 等价于:void change(int *array) 

5 - 数组名代表数组的首元地址,它是一个指针常量;指针可以当数组名使?。那么这样两者有什么区别呢 ?当然, 内存中所占字节数不一样

1 int ages[5]={1,2,3,4,5};
2 change(ages);// 输出 3
3 change(&ages[2]);// 输出5     原因:形参array指向的是 ages[2],意味着把ages[2]当做了 array 的首元素
1 int array[3]={1,3,4};
2 int *p = &array[0];// 等价于:int *p = array;
 1 char string[10] = "iphone";
 2 char *p = string;
 3 printf("%p \n", p);// 输出地址:0x7fff5fbff62e
 4 *(p+1)=P;// 操作单个字符串
 5 printf("%s\n",p);// 输出:iPhone
 6 printf("%c\n",*p);// 输出:i
 7 printf("%c\n",*(p+2));// 输出:h
 8 
 9 p++;//向高位偏移
10 printf("%s \n",p);// 输出:Phone
11 printf("%c \n",*(p+1));// 输出:h
12 printf("%s \n",string);// 输出:iPhone
13 printf("%s \n",string+1);// 输出:Phone

指针和字符串

1 - 比较两行代码有什么不同

1 char name[] = "it";
2 char *name2 = "it";
3     
4 name[0]=g;
5 printf("%s\n",name);// 输出:gt
6     
7 *name2= y;// 运行到此句崩溃
8 printf("%s\n",name2);

注:name 是字符串变量,*name2是字符串常量,C语言的数组元素存放于栈,里面的元素可以随便修改,称为字符串变量;而字符串常量存放于常量区,会缓存起来是不可更改的

1 char *name1 = "it";
2 char *name2 = "it";
3 printf("%p\n%p\n",name1,name2);// 地址是一样的,说明 name1 和 name2 指向的是同一个字符串

指针数组

1 - 定义:例如,整型数组:这个数组中存放的都是整型数组,那么,顾名思义,指针数组就是这个数组中存放的都是指针

1 int ages[5] = {0};
2 char *name[10]={"jack","rose","dany"};// 等同于:char name2[3][10] = {"jack","rose","dany"};

2 - 指针数组的重指向

1 char melee[3][20] = {"李小龙","查克·诺里斯","增根泰三"};
2 char *fistfight[3] = {"fist","foot","waist"};
3 fistfight[0] = &melee[0][0];// 重新指向
4 printf("%s\n",*fistfight);// 输出:李小龙

3 -  在控制台中,何输入字符串?(使用数组,为什么?可变嘛)

1 char name[20];
2 printf("请输入姓名:\n");
3 scanf("%s",name);
4 printf("您输入的姓名是:%s\n",name);

返回指针的函数

1 - 示例代码

main.m-------------------------------------------------------------------------------------------

 1 #import <Foundation/Foundation.h>
 2 char *test(){
 3     
 4     return "你愁啥子?老子是指针!";
 5 }
 6 
 7 int main(int argc, const char * argv[]) {
 8 
 9     char *showSome = test();
10     printf("name=%s\n",showSome);
11     
12     return 0;
13 }

注:void change(int array[]); 存储的虽然是数组元素的首地址,但是在传递时就已经变成了指针

指针函数

1 - 定义:正如数组名即数组的地址,那么函数名即函数的地址

2 - 示例代码

main.m-------------------------------------------------------------------------------------------

 1 #import <Foundation/Foundation.h>
 2 void makeTest(int a){
 3     
 4     printf("%d\n",a);
 5     
 6 }
 7 int main(int argc, const char * argv[]) {
 8 
 9     void (*p)(int a);// void指针变量指向的函数没有返回值,()表示p指向的函数没有形参
10     p = makeTest;// 指针p指向函数
11     
12     //调用方式有三种:
13     p(23);// 方式一
14     (*p)(33);// 方式二
15     makeTest(43);// 方式三
16 }

结构体指针

1 - 指向结构体变量的指针

2 - 结构体指针的声明

 1 #import <Foundation/Foundation.h>
 2 typedef struct student{
 3     
 4     char name[20];
 5     char sex;
 6     int age;
 7     float score;
 8 }stu;
 9 
10 typedef struct cpoint{
11 
12     float x;
13     float y;
14 
15 }Cpoint;
16 
17 int main(int argc, const char * argv[]) {
18     
19     stu a = {"fuck",m,23};
20     stu *p = &a;// p就是结构体指针,存放结构体变量第一个成员的地址,它代表整个结构体
21 
22     stu a1 ={"asshole",m,26};
23     *p = a1;// 结构体可以直接赋值
24 }

3 - 访问成员变量

 

C基础 - 指针:1.2