C语言入门之指针,数组和内存杂讲
小标 2018-07-25 来源 : 阅读 1000 评论 0

摘要:本文主要向大家介绍了C语言入门之指针,数组和内存杂讲,通过具体的内容向大家展示,希望对大家学习C语言有所帮助。

本文主要向大家介绍了C语言入门之指针,数组和内存杂讲,通过具体的内容向大家展示,希望对大家学习C语言有所帮助。

大端与小端 sizeof对数组名和普通指针的区别 下标运算符 数组指针和指针数组

C语言允许直接访问物理地址,可以直接对硬件进行操作

因此C既具有高级语言的功能,又具有低级语言的许多功能,能够像汇编语言一样对位、字节和地址进行操作。

我们每个知识点会用具体的例子实现,方便理解。·

 

1.大端与小端

执行下面的代码,看看输出结果是什么(注意:源文件后缀为.c)

#include <stdio.h>

int main(){

    short num = 0x1122;     //short 占两个字节

    char *c;                //char 占一个字节

    c = #

    if(*c == 0x22)

        printf("this is little end\n");

    else

        printf("this is big end\n");

    return 0;

}</stdio.h>

   

 

这表示我们的计算机处于小端模式,那么什么是大端模式和小端模式呢?

大端:数据的低位保存在高地址中,而高位保存在低地址中。 小端: 数据的低位保存在低地址中,高位保存在高地址中。

从上述的例子中,我们先定义一个short型的变量,我们知道short类型占两个字节,把0x1122赋给这个变量,再定义一个指向字符型的指针变量,把short变量的地址赋给它,最终输出显示 这个字符型指针指向的就是short型变量的低位。我们可以用下图来表示这个过程。

0x1122 11是高位,22是低位,我们让short的地址赋给c,其实就是让c指向short的位置,但因为char类型只有一个字节,所以只会输出short类型中的一个字节,如图所示:

 

*c输出结果为22,代表目前低位存在低地址中。所以现在机器是小端模式。

 

2.sizeof的注意项

#include <stdio.h>

int main(){

    int a[3] = {1,2,3};

    int *p = a;

    printf("%d\n", sizeof(a));

    printf("%d\n", sizeof(p));

    return 0;

}</stdio.h>

   

输出结果是这样

 

因为a是数组名,sizeof在这里会自动判断,于是输出这个数组的大小。但虽然指针变量p也指向数组首地址,但sizeof判断接收到的是指针变量而不是数组名时,会输出 当前指针类型的大小。这个数组有三个整形变量,每个变量占四个字节,所以就是大小就是12字节,在64位系统下,指针变量的大小是8字节(32位下是4字节)。

 

3.下标运算符

在学完数组之后,我们都知道[]是放数组下标的地方,但怎么用其他方式表示呢?实际上,a[n] 就等同于 * (a+n)。同样我们可以这样写,n[a],这样写好像是错误但,但实际上它表示 *(n+(a)),其实和上面表示的意思是相同的。

下面是个例子

#include <stdio.h>

 

int main(int argc, char *argv[]){

    int nums[3][3] = {1, 2, 3, 4, 5, 6, 7, 8, 9};

    printf("%d\n", nums[1][-2]);

    printf("%d\n", (-1)[nums][5]);

    printf("%d\n",  -1[nums][5]);

    return 0;

}</stdio.h>

   

nums[1][-2] 表示 : ((nums+1)+(-2)) 其实就是 nums[0][1] 结果是 2。 (-1)[nums][5] 表示:(*(nums+(-1))+5) 先向前移动一个一维元素大小(数组),再向后移动五个二维元素的大小(整形变量),其实就是nums[0][3],结果是3。 -1[nums][5] 表示:-((1+(nums))+5),其实就是-a[2][2],结果是-9。

 

4.数组指针和指针数组

我们先来看两行代码:int * a[5]和 int (* a)[5],它们的意义相同吗?答案是否定的。int *a[5] 表示a是一个数组,里面每个数组元素都是指向整形的指针变量。int ( *a)[5],()的优先级高于[],所以首先a是一个指针类型,其次这个指针指向一个数组。

下面是个例子:

#include <stdio.h>

int main(){

    int array[5] = {1, 2, 3, 4, 5};

    printf("%p %p\n", array, &array[0]);

    printf("%p %p\n", &array + 1, &array[0] + 1);

    int (*pArray)[5] = &array;          //数组指针

    for (int i = 0; i < 5; i++) {

        printf("%d ", *pArray[i]);

    }

    printf("\n");

    int array2[2][5] = {

        {1, 2, 3, 4, 5},

        {6, 7, 8, 9, 10}

    };

    pArray = array2;

    printf("%d %d\n", *(*(array2 + 1) + 1), pArray[1][1]);

    int (*pArray2)[2][5] = &array2;

    for (int i = 0; i < 2; i++) {

        for (int j = 0; j < 5; j++) {

            printf("%d ", (*pArray2)[i][j]);

        }

        printf("\n");

    }

    return 0;

}</stdio.h>

   

注:%p代表该变量的地址。

首先输出 array的地址 和array[0]的地址,这表明,数组名就表示数组的首地址。

接下来定义一个数组指针指向array,此时给这个指针每进行一次下标运算符,在内存中移动的是整个数组的大小,所以除了本身,其他运算后的数值都是不可预测的。

后面的也是相同的道理,只不过是二维数组的东西,理解以上之后会很容易理解这些。

本文由职坐标整理并发布,了解更多内容,请关注职坐标编程语言C/C+频道!

本文由 @小标 发布于职坐标。未经许可,禁止转载。
喜欢 | 1 不喜欢 | 0
看完这篇文章有何感觉?已经有1人表态,100%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程