c数组与指针(完)
内容概要
一、通过指针访问数组元素
二、指针数组
三、数组指针
四、数组指针与二维数组
1、通过指针访问数组元素
-数组存储的是数组第一个元素的地址(但是数组绝不等于第一个元素)
#include <stdio.h> int main(void){ int score_a[10]; int i; int *score; for (i=0; i<10; i++){ score_a[i] = i; } score = score_a; // 等价于socre = &score_a[0]; printf("score_a: %p\n",score_a); printf("score: %p\n",score); printf("socre_a[1]: %p\n",&score_a[0]); return 0; }
-通过指针访问数组元素
#include <stdio.h> int main(){ int score_a[10]; int i; int *score; for (i=0; i<10; i++){ score_a[i] = i; } score = score_a; // score指针指向数组第一个元素 printf("score_a[1]: %d\n", *(score+1)); //访问数组第二个元素 printf("socre_a[2]: %d\n", *(score+2)); //访问数组第三个元素 return 0; }
*score是访问score存储的内存地址对应的变量下存储的值
*(score+1)是访问score存储的内存地址对应的下一个地址对对应存储的值
*(score+n)是访问score存储的内存地址对应的下n个地址对应的存储的值
-一个计算字符串长度的小功能
通过指针的方式
#include <stdio.h> int main(){ char str[] = "hello world"; char *pa; int count = 0; for (pa=str; *pa++ != '\0';){ count++; } printf("%d\n",count); return 0; }
不要使用字符指针存储字符串,比如
char *pstr = "hello world";
字符串还是要有真正的存放空间的,如果字符指针改变了,那么这个字符串常量就不可能被访问了,除非你使用const关键字把指针变量不可变
#include <stdio.h> int main(void){ const char * const pstr = "hello world"; const char *pstr1 = "enmmmm...."; char *pstr2 = "hahahah"; // 只有这个会有警告 return 0; }
2、指针数组
指针数组的每个元素的类型都是一种指针类型

#include <stdio.h> int main(){ char *pa[6]; //定义了一个指针数组 char str_array[6] = "hello"; for (int i = 0;i < 6;i++){ pa[i] = &str_array[i]; //给数组中每一个指针元素关联指针 } for (int j = 0;j < 6;j++){ printf("%p\n",pa[j]); //遍历指针数组中的每一个指针 } return 0; }
指针数组通常用于存储字符串的数组(这种数组的类型为char *类型)
#include <stdio.h> int main(){ char *phrase[] = { "hello world", "you can you up no can no bb", "can can can can?", "never give up" }; int i; for (i=0; i<4; i++){ printf("%s\n",phrase[i]); } return 0; }
小练习,使用指向指针的指针copy新的数组(有点绕)
#include <stdio.h> int main(){ char *phrase[] = { "hello world", "you can you up no can no bb", "can can can can?", "never give up" }; char **my_phrase = &phrase[2]; char **other_phrase[3]; other_phrase[0] = &phrase[0]; other_phrase[1] = &phrase[1]; other_phrase[2] = &phrase[3]; return 0; }
***代画图***
3、数组指针
数组指针的定义
#include <stdio.h> int main(){ int (*pa)[4]; return 0; }
4、数组指针与二维数组
指针要得到内存地址,还要知道指向的值的使用方法
-数组指针与二维数组
对于一维数组,可以使用指针的形式访问数组
#include <stdio.h> int main(){int array[3] = {1,2,3}; int *x; x = array; printf("%d\n",*(array+1)); printf("%d\n",*(x+1));return 0; }
注意:array+1和x+1并不是将内存地址简单的加一,而是告诉编译器跳转到下一个元素的内存地址(在这里每个元素之间的内存地址相差为4,因为是整形)
#include <stdio.h> int main(){ int array[2] = {0}; int *x=&array[0], *y=&array[1]; printf("%d\n",y-x); //打印的结果居然不是4,而是1(指的是y的内存地址到x的内存地址相差一个元素的数据长度) return 0; }
验证二维数组的地址是第一个子数组的第一个元素的内存地址
#include <stdio.h> int main(){ int array[3][4] = {0}; printf("array:%p &array[0][0]:%p\n",array,&array[0][0]); //两个地址是一样的 return 0; }
尝试通过*(数组+数字)的方式访问数组
#include <stdio.h> int main(){ int array[3][4] = {0}; printf("array:%p &array[0][0]:%p\n",array,&array[0][0]); printf("array+1:%p &array[1][0]:%p\n",array+1,&array[1][0]); //发现array+1的地址与array[1][0]的地址是一样的,并且array+1内存地址与array的内存地址相差16个字节
return 0; }

-如果像一维数组那样使用指针访问数组元素呢
#include <stdio.h> int main(){ int array[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12}; int *pa = array; // 这里就报错了,因为指针虽然拿到了地址,但是它不知道数据之间的跨度是多少(int 告诉指针每个元素之间是4个字节,其实应该是16个) printf("*p:%d *(p+1):%d *(p+2):%d \n", *pa, *(pa+1), *(p+2)); return 0; }
-此时使用数组指针,将指针指向一个数组
#include <stdio.h> int main(){ int array[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12}; int (*pa)[4] = array; // ()必须加,因为[]的优先级比*高,如果不加(),编译器会将语句识别为指针数组;int [4]告诉编译器pa指向的地址中数据长度为 4*4 = 16字节 printf("*p:%p *(p+1):%p *(p+2):%p \n",*pa,*(pa+1),*(pa+2)); //一次解引用 *pa拿到第一个子数组的地址、*(pa+1)拿到第二个子数组的地址、**(pa+2)拿到第二个子数组的地址 printf("*p:%d *(p+1):%d *(p+2):%d \n",**pa,**(pa+1),**(pa+2)); //第二次解引用拿到子数组的第一个元素 return 0; }
可见,编译器对于数据长度的要求是那么的重要。比如二维数组定义时就初始化时,数组第一个[]号可以不加数字,但是第二个一定需要加入数字(因为只有这样,编译器才能求出每个元素的数据长度)
-自由访问二维数组中每个元素
#include <stdio.h> int main(){ int array[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12}; int (*pa)[4] = array; // printf("(array+1)+2:%d (array+2)+3:%d \n",((array+1)+2),((array+2)+3)); 这是错误的 printf("(array+1)+2:%d (array+2)+3:%d \n",*(*(array+1)+2),*(*(array+2)+3)); printf("*(*(pa+1)+2):%d *(*(pa+2)+3):%d \n",*(*(pa+1)+2), *(*(pa+2)+3)); return 0; }
***完***
本文来自博客园,作者:口乞厂几,转载请注明原文链接:https://www.cnblogs.com/laijianwei/p/14528246.html

浙公网安备 33010602011771号