黑马程序员——C复杂数据类型--数组、字符串、指针

时间:2023-02-19 17:09:32

——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-

数组

数组,从字面上看,就是一组数据的意思,没错,数组就是用来存储一组数据的。但是 只能存放一种类型的数据,比如int类型的数组、float类型的数组;这里面存放的数据称为“元素”。

  1. 格式
    元素类型 数组名[元素个数];
    比如:int ages[5];
  2. 简单使用
    简单初始化:int ages[5] = {19, 19, 20, 21, 25};
    元素有顺序之分,每个元素都有一个唯一的下标(索引),从0开始;
    数组元素的访问:a[i]。
    数组只能在定义数组的同时进行初始化,向下面这个就是错误的写法:
int ages[5];
ages
= {10, 11, 12, 14};

如果想再定义数组的同时进行初始化,数组元素个数必须是常量,或者不写。
数组的内存分配是从高地址到低地址进行的,但数组内部元素又是从低到高进行的。

  • 数组的其他用法

    数组作为函数参数,可以省略元素个数

#include <stdio.h>

void change(int array[])
{
array[0] = 100;
}
//// 值传递:基本数据类型作为函数参数的时候,纯粹是值传递
void change2(int n)
{
n = 100;
}

int main()
{
int ages[6] = {10, 11, 10, 11, 10, 11};

change(ages);

//change2(ages[0]);

printf("%d\n", ages[0]);
return 0;
}

在void change(int array[])中数组作为函数参数,传递是整个数组的地址,修改函数形参数组元素的值,会影响到外面的实参数组。所以调用change函数时结果为:100。基本数据类型作为函数参数的时候,纯粹是值传递,并不会改变实参,所以调用change2时结果为:10。

同时需要注意的是:数组当做函数参数传递时,会当做指针变量来使用,指针变量在64bit编译器环境下,占据8个字节。

二维数组是一个特殊的一维数组:它的元素是一维数组。例如int a[2][3]可以看作由一维数组a[0]和一维数组a[1]组成,这两个一维数组都包含了3个int类型的元素。
黑马程序员——C复杂数据类型--数组、字符串、指针

字符串

首先一个’i’是一个字符,很多个字符组合在一起就是字符串。

  1. 字符串的初始化
    char a[] = “123”;和char a[] = {‘1’,’2’,’3’};都是初始化方式,但是其实”123”是由’1’,’2’,’3’,’\0’组成的。在字符串的输出”%s”中,’\0’是不会输出的。

    \0的作用
    1.字符串结束的标记;
    2.printf(“%s”, name);
    会从name这个地址开始输出字符,直到遇到\0为止。

  2. strlen
    strlen函数是用来计算字符串长度的,但是他计算的是字符数,并不是字数,一个汉字算作3个字符;同时计算的字符不包括\0,是从某个地址开始数字符的个数,直到遇到\0为止。
    strlen函数声明在string.h文件中,所以在使用此函数之前需要声明一下,#include

char names[2][10] = {{'J''a''y''\0'},{'J','i','m','\0'}};
char names2[2][10] = {{"Jay"},{"Jim"}};
char names3[2][10] = {"Jay","Jim"};

指针

指针是C语言中非常重要的数据类型,如果你说C语言中除了指针,其他你都学得很好,那你干脆说没学过C语言。

  1. 指针定义
// 变量类型 变量名;
// 格式:变量类型 *变量名;
// 定义了一个指针变量p
// 指针变量只能存储地址
// 指针就一个作用:能够根据一个地址值,访问对应的存储空间
// 指针变量p前面的int:指针变量p只能指向int类型的数据
int *p;

int a = 90;

// 指针变量p指向了变量a
p = &a;

*p = 10;

清空指针时用:p = 0;或者p =NULL;。

下面我们可以用一个简单的指针例子体会一下:

#include <stdio.h>

//声明函数
int sumAndMinus(int a, int b, int *minus);

int main()
{
//定义变量并初始化
int num1 = 11;
int num2 = 9;
//定义和与差的变量
int he;
int cha;
//函数返回(a+b)即和,同时利用指针在cha的地址处输入了(a-b)即和
he = sumAndMinus(num1, num2,&cha);

printf("和为%d,差为%d\n", he, cha);

return 0;
}
//返回值
int sumAndMinus(int a, int b, int *minus)
{
*minus = a - b;
return a + b;

}

直接通过指针访问地址,简化了很多。指针的目的是存放目标的地址,无论是什么类型的指针都占用8个字节的存储空间,这个是恒定不变的。

  • 指针和数组
    *p = &ages[0];和p = ages;含义是相同的,只是不同的表现形式。
    当指针加1时,相当于加一个类型所占字节,比如如果是double型会加8个字节。
    p —> &ages[0]
    p + 1 —> &ages[1]
    p + 2 —> &ages[2]
    p + i —> &ages[i]

  • 指针和字符串
    定义字符串的2种方式
    1> 利用数组
    char name[] = “itcast”;

  • 特点:字符串里面的字符是可以修改的
  • 使用场合:字符串的内容需要经常修改

    2> 利用指针
    char *name = “itcast”;

  • 特点:字符串其实是一个常量字符串,里面的字符是不能修改
  • 使用场合:字符串的内容不需要修改,而且这个字符串经常使用
// 指针数组(字符串数组)
char *names[5] = {"jack", "rose", "jake"};

// 二维字符数组(字符串数组)
char names2[2][10] = {"jack", "rose"};
  • 返回指针的函数
    指针也是C语言中的一种数据类型,因此一个函数的返回值肯定可以是指针类型的。返回指针的函数的一般形式为:类型名 * 函数名(参数列表)。
#include <stdio.h>

char *test();
int main()
{
char *name = test();

printf("name=%s\n", name);

return 0;
}

char *test()
{
return "rose";
}
  • 返回函数的指针
    函数作为一段程序,在内存中也要占据部分存储空间,它也有一个起始地址,即函数的入口地址。函数有自己的地址,那就好办了,我们的指针变量就是用来存储地址的。因此,可以利用一个指针指向一个函数。其中,函数名就代表着函数的地址。
    定义指向函数的指针
    double (p)(double, char , int);
    p = haha;
    或者
    double (p)(double, char , int) = haha;

使用注意:
这类指针变量存储的是一个函数的入口地址,所以对它们作加减运算(比如p++)是无意义的。

我们可以通过指向函数的指针变量调用函数:
1> p(10.7, “jack”, 10);
2> (*p)(10.7, “jack”, 10);
这样我们就可以将函数作为参数在函数间传递了。

知识点是很多很杂,但是更多的是练习,死记硬背不是学习C语言的方法,只有多用心想,多敲代码,自然就熟练了。

——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-