C语言: 数组与指针知识点

举报
DS小龙哥 发表于 2022/02/27 12:36:11 2022/02/27
【摘要】 1. 数组的名称是数组元素的首地址。(数组的名字就是地址) 2. 数组只能在初始化的时候进行整体赋值。比如: int a[100]={10,20,30}; 3. 数组的下标访问是从0开始的。

一、数组语法

数组特点: 同类型数据的集合。

程序里怎么区分是数组? [ ]   访问连续地址里数据。

数组的注意特点:

1. 数组的名称是数组元素的首地址。(数组的名字就是地址)

2. 数组只能在初始化的时候进行整体赋值。比如:  int a[100]={10,20,30};

3. 数组的下标访问是从0开始的。比如: int a[10];  下标范围: a[0] ~ a[9]

4. 数组名称虽然是地址,但是这个地址是不能偏移、也不能自增自减,也不能改变指向。

   int a[10];   
   int b[10];
   a++、a--;   *//* *错误的*
   a=b;       *//* *错误的*
   a[0]=b[0];  *//* *正确*

5. 如果数组是局部变量,初始化没有赋值的情况下,成员是随机值。

比如: int a[10];  printf("%d\n",a[0]);

初始化的时给数组进行赋值,那么没有赋值的下标是什么值?

比如:  int a[10]={1,2,3}; printf("%d\n",a[6]);  //0

6. 数组定义的时候(C89), 数组的下标里的大小只能填常量。 
    比如:

    int a[];  *//* *错误的,定义数组必须填大小*
    int size=10; int a[size];  *//* *错误的,定义数组只能填常量。*
    int b[100];  *//* *正确*
    #define **SIZE** 100  int a[SIZE];  *//正确*

二、冒泡排序:整数数组

字符串特点:

  1. 字符串本身就是字符数组。比如:char a[10]=“123”;
  2. 常规字符串使用双引号括起来的。 比如:char a[10]=“123”;
  3. 字符串以’\0’ 作为结束符号。
  4. 字符数组一定是字符串? 不一定。 比如: char a[]={12,3,4,5,5};
#include<stdio.h>
int main()
{
    char buff1[10]={'1','2','3','\0','4','5','6','\0','7'};
    
    char buff2[]={'1','2','3','\0'};
    char buff3[]="123";

    printf("%d\n",sizeof(buff2)); //4
    printf("%d\n",sizeof(buff3)); //4
    return 0;
}
    //1. 计算字符串的长度
    //2. 字符串查找函数
    //3. 字符串转整数
    //4. 字符串拼接
    //5. 字符串拷贝
    //6. 字符串比较

#include <stdio.h>
#include <string.h>

int main()
{
    char buff[100];
    int cnt=0;
    printf("请键盘上录入字符串:");
    scanf("%s",buff); // 不可以录入空格

    while(buff[cnt]!='\0')
    {
        cnt++;
    }
    printf("cnt=%d\n",cnt);
    return 0;
}

三、整数数组的练习作业

  1. 从键盘上输入10个整数,删除指定下标的数据
    比如输入数据: 1,2,3,4,5,6,7,8,9,10
    删除第5个下标的数据
    输出的结果:
    1,2,3,4,5,7,8,9,10

  2. 从键盘上输入10个整数,在指定下标增加一个新的数据
    比如输入数据: 1,2,3,4,5,6,7,8,9,10
    从第5个下标增加一个新的数据 888
    输出的结果:
    1,2,3,4,5,888,6,7,8,9,10

四、指针概念

指针:C语言的灵魂。
指针作用:存放地址。

//结构体的内存空间默认对齐方式: 以出现的最大数据类型的倍数申请空间。最大倍数不超过4.
struct stu
{
    int a;
    char c;
};

<数据类型> *<变量名称>;
int *a; //整型指针变量。  占4个字节空间。 存放地址数据。
char *b;//字符类型指针变量。占4个字节空间。  存放地址数据。
float *c; //浮点数类型指针变量。占4个字节空间。  存放地址数据。
struct stu *d;//结构体类型指针变量。 占4个字节空间。  存放地址数据。

指针没有申请有效空间的时候,可以不可以用来存放数据?
可以。 使用地址空间存放数据。 int *a;  a=123;

<数据类型> <变量名称>;
int a; //整型变量   123  占4个字节空间。
char b; //字符类型变量  123和'A'  占1个字节空间。
float c; //浮点数类型变量 123.345 占4个字节空间。
struct stu d; //结构体类型变量。 占个8字节空间。

五、指针例子

5.1 例子1

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main()
{
    char *a;
    int *p=NULL; //指针本身没有数据空间,只能存放地址。  NULL == (void*)0
    p=malloc(4); //申请4个字节空间
    *p=123; //对指针指向的空间进行赋值
    printf("*p=%d\n",*p);  //123
    printf("p1=%d\n",p);   //地址
    free(p);  //释放空间
   
    p=NULL;   //将指针指向NULL
    printf("p2=%d\n",p);   //地址
    if(p!=NULL)
    {
        *p=456;  //给指针指向的空间进行赋值
        printf("*p=%d\n",*p);  //123    取出指针指向空间的数据
    }

    a=(char*)(123456);   //强制转换.  欺骗编译器。
    printf("a=%d\n",a);   //地址
    return 0;
}

5.2 各个指针类型之间相互是否可以直接赋值?会不会溢出?

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main()
{
    char a=0;
    int b=123456;
    a=b;
    printf("a=%d\n",a);
    printf("b=%d\n",b);

    char *p_a;
    int *p_b;
    p_b=malloc(4);
    p_a=(char*)p_b;
    
    printf("p_a=%d\n",p_a);
    printf("p_b=%d\n",p_b);

    return 0;
}

5.3 各类型指针本身最大区别是什么?

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main()
{
    // 指针 本身偏移字节不一样(就是自增/自减)。  
    char c_buff[]="ABCDEF";
    char *c_p=c_buff; //检查等于符号两边类型是否相同。
    printf("%c\n",*(c_p+1)); // 'B'
    printf("%c\n",*c_p++);   // 'A'
    printf("%c\n",*c_p);     // 'B'

    int a_buff[]={1,2,3,5,6,7,8};
    int *a_p=a_buff;
    printf("%d\n",*(a_p+1)); // 2
    printf("%d\n",*a_p++);   // 1
    printf("%d\n",*a_p);     // 2

    //每个类型的指针自增、自减的时候 ,指针偏移量和本身类型有关系
    return 0;
}

5.4 函数的变量作用域

全局变量、局部变量、静态变量、块变量。
全局变量: 在函数之外定义的变量。
局部变量: 在函数里定义的变量。
静态变量: 修饰关键字: static 也称为局部全局变量。
块变量 : 在代码块里定义的变量。

示例1:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int a=100; //全局变量
//static int a; //静态全局变量
void func(void);

int main()
{
    int a=200; //局部变量
    if(123>30)
    {
        int a=300; //块变量
        printf("a=%d\n",a); //300
    }
    printf("a=%d\n",a); //200
    func();
    return 0;
}

void func(void)
{
   int a=400; //局部变量
   // static int a; //静态局部变量
    printf("a=%d\n",a); //400
}

示例2:静态变量

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int a=100; //全局变量
//static int a; //静态全局变量
void func(void);

int main()
{
    int a=200; //局部变量
    if(123>30)
    {
        int a=300; //块变量
        printf("a=%d\n",a); //300
    }
    printf("a=%d\n",a); //200
    func();
    return 0;
}

void func(void)
{
   int a=400; //局部变量
   // static int a; //静态局部变量
    printf("a=%d\n",a); //400
}

5.5 函数传参: 地址问题

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char *func(char *p);
int main()
{
    char a[]="1234567890";
    char *p;
    p=func(a);
    printf("%s\n",p);//4567890
    return 0;
}

//函数的形参是指针类型,返回值是指针类型
char *func(char *p)  //p=a;
{
    printf("%s\n",p); //1234567890
    return p+3; //偏移地址
}

#if 0
/*
数组类型是当做函数的形参,但是不能当做返回值
数组当做形参也有局限性:地址不能自制、自减、访问数据只能使用[ ]    (  *(p+1) )
*/
char p[] func(char p[])
{

}
#endif

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。