听翁恺老师mooc笔记(5)--指针与数组

  如果我们通过函数的参数将一个数组传递到参数中去,那么在函数里接收到的是什么东西呢?我们知道如果传递一个普通变量,那么参数接收到的是值,如果传递一个指针变量,参数接收到的也是值,只不过这时的值是地址。那么数组是什么?将数组作为值传给一个函数,在函数的参数里有一个数组变量来接收这个数组,看下到底接收到数组变量的什么东西呢?以minmax作为例子来测试下:

  在minmax函数中能不能计算出数组a的个数?在minmax和main中分别添加printf函数,从结果可以看出,在main里a的大小是68,而在minmax函数中数组a的大小为8,8是什么,在64位机器下,8刚好和一个指针的大小是一样的,和地址的大小是一样的。

 1 #include <stdio.h>
 2 void minmax(int a[],int len,int *max,int *min);
 3
 4 int main(void) {
 5     int a[]={1,2,3,4,5,6,7,8,9,12,13,14,16,17,21,23,55};
 6     int min,max;
 7     printf("main sizeofa[]= %lu\n",sizeof(a));     //sizeof a in main
 8     minmax(a,sizeof(a)/sizeof(a[0]),&min,&max);
 9     printf("min=%d,max=%d\n",min,max);
10     return 0;
11 }
12
13 void minmax(int a[],int len,int *min,int *max){
14     int i;
15     printf("minmax sizeofa[]= %lu\n",sizeof(a));       //sizeof a in minmax
16     *min =*max=a[0];
17     for(i=1;i<len;i++){
18         if(a[i]<*min){
19             *min=a[i];
20         }
21         if(a[i]>*max){
22             *max=a[i];
23         }
24     }
25 }

  然后再看下a在main和minmax中的地址分别是多少,结果地址是一样的,这说明什么,说明在minmax里的这个数组就是main里的这个数组,他们是同一个。再比如在minmax中修改a[0]的值,然后在main中调用完minmax函数后输出a[0]的值,发现确实结果确实改变了。

  minmax参数中int a[]就是指针,那么这个参数为什么必须留一个空的方括号,为什么在方括号里写数字也没用,为什么在minmax中sizeof没有办法得到这个数组元素的个数,原因就在于它其实就是个指针,它只是样子看上去像一个数组,那么既然它实际上是一个指针,我们把它写成像一个指针行不行,a[]写成*a,发现编辑和运行结果都没有变化。所以我们可以说数组和指针存在某种联系:函数参数中的数组实际上是指针,也就是说sizeof(a)= siziof(int*),但是对于这种指针可以使用数组的方括号[]运算符来进行运算。所以说下列四种函数的原型是等价的,不是说他们类型等价,而是说作为函数参数表中出现它们是等价的,作为函数原型他们是等价的。

1 int sum(int *a,int n);
2 int sum(int *,int);
3 int sum(int a[],int n);
4 int sum(int [],int);

  实际上,数组变量是特殊的指针,因为数组变量本身就表达地址,在取地址符&时实验过,直接拿数组的名字就可以得到数组的地址,数组名字本身表达的就是地址,因此int a[10];int *p=a,不需要使用取地址符&,但是数组的每一个元素表达的是单个变量,比如a[0],a[1]就是单个变量,所以对单个的元素取地址是需要用&符号的,a==&a[0]这件事情在取地址时看到过了。

  []这个运算符可以对数组做,也可以对指针做,p[0]相当于*p,做实验测试,在minmax代码的main函数中添加如下代码,输出结果显示*p=p[0]。

1     int *p =&min;
2     printf("*p=%d\n",*p);
3     printf("p[0]=%d\n",p[0]);

  p[0]什么意思,就是我以为p所指的地方是个数组的话,p[0]是数组p的第一个元素。那么实际上我们并没有数组,有的是一个叫做min的变量,min里存放的是2,p指向min,那么*p是所指变量的值,p[0]是把p所指的地方当作是一块数组,现在它不是一个数组只是一个变量,你可以把它当作一个数组看,当作int min[1]来看,作为min[1]来看的话,它有效的数组是什么?min[0].当然对于普通的变量不可以这么写,但是对于指针变量就可以这么写了,也就是它所指的地方的第一个元素取出来作为p[0].

  同样的,*运算符我们知道是对指针做的,是取出指针所指的地方的值,也可以对数组做。如果有数组也可以说*a=25,我们试验下这件事情,结果是*a为1120,可见*a可读可写,总之可以当成指针用。

  数组变量是const指针,在之前讲数组时说到过,如果定义两个数组,int a[],int b[],使b=a是不可以的,数组之间是不能赋值的。那么传递时如果int *q=a,这个是可以的,一个不可以一个可以有什么区别那?实际上我们说的int b[]可以被看作int * const b,const意思是b是常量,不可以改变,它是这个数组就不可以是别的数组了,所以数组是一个常量指针,不可以赋值,不可以代表别的东西了。

时间: 2024-12-15 04:58:36

听翁恺老师mooc笔记(5)--指针与数组的相关文章

听翁恺老师mooc笔记(8)--字符串2

字符串的赋值 字符串的输入与输出 对C语言的基础类型,比如int.double等类型,scanf.printf有专门的格式转换,而对字符串,scanf.printf使用%s格式字符进行输入与输出.当使用scanf进行读一个字符串的时候,读到什么东西,读到什么位置为止是很微妙的,试一下: 1 #include <stdio.h> 2 int main(void){ 3 char word[8]; 4 scanf("%s",word); 5 printf("%s##\

C语言学习笔记(六) 指针和数组

使用C语言就必然会使用到指针和数组.看下面的代码: int main(int argc, char** argv){     int a[4] = {1,3,5,7};     int *p = a;     int i;     for (i=0; i<4;i++){         printf("i=%d, p[i]=%d, *(p+i)=%d, a[i]=%d, *(a+i)=%d\n",                 i, p[i], *(p+i), a[i], *(

《C程序设计语言》笔记 (五) 指针与数组

5.1 指针与地址 指针是一种保存变量地址的变量 ANSI C使用类型void*(指向void的指针)代替char *作为通用指针的类型 一元运算符&可用于取一个对象的地址: p = &c 把C的地址赋值给变量p,我们称p为指向c的指针.地址运算符&只能应用于内存中的对象,即变量与数组元素. 不能作用于表达式 常量或register变量 一元运算符*是间接寻址或间接引用运算符.当它作用于指针时,将访问指针所指向的对象 由于指针也是变量,所以在程序中可以直接使用,而不必通过间接引用的

【黑客免杀攻防】读书笔记12 - 指针与数组

1.指针与数组 C源码 前两组printf()函数是以指针方式访问数组nArray中的数据的,而后两组printf()函数则是使用数组下标的方式访问数组nArray中的数据的. int _tmain(int argc, _TCHAR* argv[]) { // 数组赋值 int nArray[3] = {0x10,0x20,0x300}; // 数组地址赋值给指针 int *pPtr = nArray; // 输出指针中地址 printf("%x %x %x\r\n", pPtr+0,

翁恺老师C语言入门第三周编程题之《数字特征值》

题目内容: 对数字求特征值是常用的编码算法,奇偶特征是一种简单的特征值.对于一个整数,从个位开始对每一位数字编号,个位是1号,十位是2号,以此类推.这个整数在第n位上的数字记作x,如果x和n的奇偶性相同,则记下一个1,否则记下一个0.按照整数的顺序把对应位的表示奇偶性的0和1都记录下来,就形成了一个二进制数字.比如,对于342315,这个二进制数字就是001101. 这里的计算可以用下面的表格来表示: 数字 3 4 2 3 1 5 数位 6 5 4 3 2 1 数字奇偶 奇 偶 偶 奇 奇 奇

翁恺老师零基础学JAVA语言第五周数组--求平均数例题-个人理解

// 用户输入一系列数字,然后求出这些数字的平均数,并输出输入数字中大于平均数的数 Scanner in = new Scanner(System.in); System.out.println("你打算输入多少个数值?请输入:"); // 计算平均数,需要有:1.记录输入的每个数n:输入数的和sum:输入数值的个数cnt: int cnt = in.nextInt(); // 算平均数,定义sum为浮点数 double sum = 0; System.out.println(&quo

翁恺老师零基础学JAVA语言第五周数组--投票程序例题-个人理解

// 输入数量不确定的[0,9]范围内的整数,统计每一种数字出现的次数,输入-1表示结束 // 需要一个int[10]的数组来录入每次输入的数字;需要一个n表示每次输入的数字 // num[] = {0,1,2,3,4,5,6,7,8,9},刚好对应0-9这10个数字 Scanner in = new Scanner(System.in); int[] num = new int[10]; int n = in.nextInt(); if(n >= 0 && n <= 9) {

[JAVA]翁恺老师零基础学java语言第五周素数例题中continue的困惑

第五周求前50个素数的例子中,continue跳出当次循环后的疑问 例题中的这段: ======================================== MAIN_LOOP: for(int x = 3; cnt<50 ;x++) { for (int i=0 ;i<cnt ; i++) { if ( x%primes[i] == 0) { continue MAIN_LOOP; } } } =============================================

初识C语言中的函数(男神翁凯老师MOOC)

什么是函数? 函数是一块代码,接收零个或多个参数,做一件事情,并返回零个或一个值. 可以先想象成数学中的函数: y=f(x) 例如 求begin到end和的函数定义 void sum(int begin, int end) // void 为返回类型(不返回任何东西) sum 为函数名 (int begin, int end)为参数表) { int i; int sum; for(i=0;i<=end;i++){ sum +=i; } printf("%d到%d的和是%d\n",