C语言学习(3)——指针、数组及main函数

一、指针

首先理解一下内存单元:

计算机中内存最小的存储单位——内存单元。大小一个字节。 每一个内存单元都有一个唯一的编号(数)。称这个内存单元的编号为 “地址”。

再来理解一下指针变量:

存放地址的变量。

指针的定义和使用:

int a = 10;

int *p = &a;                int* p;--- windows;    int *p ---Linux       int * p ;

*p = 250;                   指针的 解引用。 间接引用。

p :将p变量的内容取出,当成地址看待,找到该地址对应的内存空间。如果做左值: 存数据到空间中;如果做右值: 取出空间中的内容。

指针的大小:指针的大小与类型 无关。 只与当前使用的平台架构有关。   32位:4字节。     64位: 8字节。

三种指针:

1.野指针:1)没有一个有效的地址空间的指针。           2)p变量有一个值,但该值不是可访问的内存区域。

1)没有一个有效的地址空间的指针。
int *p;
*p = 1000;
由于一开始声明的指针P没有指向一个地址空间,因此无法对p进行解引用。

2)p变量有一个值,但该值不是可访问的内存区域。
int *p = 10;    //0-255的地址留给操作系统
*p = 2000;
不知道是否正确让P指向了一块可用地址

【杜绝野指针】

2.空指针:

int *p = NULL; 

*p 时 p所对应的存储空间一定是一个 无效的访问区域。

3.万能指针/泛型指针(void *):

可以接收任意一种变量地址。但是,在使用【必须】借助“强转”具体化数据类型。

char ch = 'R';
void *p;  // 万能指针、泛型指针
p = &ch;
printf("%c\n", *(char *)p);

const关键字的使用:

修饰变量:

const int a = 20;
int *p = &a;
*p = 650;
printf("%d\n", a);
//输出
650

【注意】用const修饰来定义的变量可用通过非const指针修改。

修饰指针:

1)const int *p;                可以修改 p,不可以修改 *p。

2)int const *p;                同上。

3)int * const p;               可以修改 *p,不可以修改 p。

4)const int *const p;      不可以修改 p,不可以修改 *p。

数据类型对指针的作用:

1)间接引用:

        决定了从指针存储的地址开始,向后读取的字节数。  (与指针本身存储空间无关。)

2)加减运算:

        决定了指针进行 +1/-1 操作向后加过的 字节数。

指针加减运算:

指针 * / % : 错误!!!

指针 +- 整数:

    1) 普通指针变量+-整数

        char *p; 打印 p 、 p+1  偏过 1 字节。

        short*p; 打印 p 、 p+1  偏过 2 字节。

        int  *p; 打印 p 、 p+1  偏过 4 字节。      

    2)在数组中+- 整数

        short arr[] = {1, 3, 5, 8};

        int *p = arr;

        p+3;            // 向右(后)偏过 3 个元素

        p-2;            // 向前(左)偏过 2 个元素

    3)&数组名 + 1

        加过一个 数组的大小(数组元素个数 x sizeof(数组元素类型))

指针 +- 指针:

    指针 + 指针: 错误!!!

    指针 - 指针:

        1) 普通变量来说, 语法允许。无实际意义。

        2) 数组来说:偏移过的元素个数。

多级指针:

int a = 0;

int *p = &a;                   一级指针是 变量的地址。

int **pp = &p;                二级指针是 一级指针的地址。

int ***ppp = &pp;           三级指针是 二级指针的地址。    

int ****pppp = &ppp;     四级指针是 三级指针的地址。

二、数组

【数组名是地址常量】 --- 不可以被赋值。

获取数组中元素的方式:

int arr[] = {1,3, 5, 7, 8};

int *p = arr; 

1)arr[i]

2)*(arr+0)

3)p[0]

4)*(p+0)

指针和数组的区别:

1)指针是变量。数组名为常量。

2)sizeof(指针) ===》 4字节 / 8字节

      sizeof(数组) ===》 数组的实际字节数。

三、main函数

无参main函数:

    int main(void) == int main()

带参数的main函数:

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

    1)参数1:表示给main函数传递的参数的总个数。

    2)参数2:是一个数组!数组的每一个元素都是字符串 char * 

#include <stdio.h>
int main(int argc, char *argv[])
{
    for(int i=0;i<argc;i++)
        printf("argv[%d]=%s\n",i,argv[i]);
}

测试方法1:使用gcc编译生成可执行文件后调用可执行文件,如 test.exe I am a  gcc test !

结果如下:

argv[0]=test.exe

argv[1]=I

argv[2]=am

argv[3]=a

argv[4]=gcc

argv[5]=test

argv[6]=!

测试方法2:在VS中的项目名称上 --》右键--》属性--》调试--》命令行参数 --》将 I am a  vss test ! 写入。

结果如下:

argv[0]=D:\学习资料\C++学习项目\01-C语言\Day01\Debug\Day01.exe        //这里的输出与你项目文件位置和名称相关

argv[1]=I

argv[2]=am

argv[3]=a

argv[4]=vs

argv[5]=test

argv[6]=!

四、函数相关

1)数组做函数参数:

void BubbleSort(int arr[10]) == void BubbleSort(int arr[])  == void BubbleSort(int *arr) 

传递不再是整个数组,而是数组的首地址(一个指针)。所以,当整型数组做函数参数时,我们通常在函数定义中,封装2个参数。一个表数组首地址,一个表元素个数。

2)指针做函数返回值:

int *test_func(int a, int b);

指针做函数返回值,不能返回局部变量的地址值。

3)数组做函数返回值:C语言,不允许!!!!  只能写成指针形式。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值