c 语言中的数组和指针

这篇具有很好参考价值的文章主要介绍了c 语言中的数组和指针。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1 如何把数组初始化成全 0

声明的局部变量数组,如果没有初始化,那么数组保存在栈上,数组的内容是不确定的。

局部变量不像全局变量,全局变量如果没初始化,那么默认是全 0。

将数组初始化为 0 的方式主要有以下 3 种,本人在开发过程中习惯于使用第一种,即使用 {0} 将数组初始化为全 0。

(1)数组声明的时候使用 {0} 初始化

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

int main() {
  int a[10] = {0};
  int b[10][10] = {0};
  for (int i = 0; i < 10; i++) {
    printf("a[%d] = %d\n", i, a[i]);
  }

  for (int i = 0; i < 10; i++) {
    for (int j = 0; j < 10; j++) {
      printf("b[%d][%d] = %d\n", i, j, b[i][j]);
    }
  }
  return 0;
}

 

 (2)memset()

使用 memset() 将数组设置成 0。

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

int main() {
  int a[10] = {0};
  int b[10][10] = {0};
  for (int i = 0; i < 10; i++) {
    printf("a[%d] = %d\n", i, a[i]);
  }

  for (int i = 0; i < 10; i++) {
    for (int j = 0; j < 10; j++) {
      printf("b[%d][%d] = %d\n", i, j, b[i][j]);
    }
  }
  return 0;
}

 

(3)使用 for 循环将数组元组逐个设置为 0

2 指针加减运算

指针的加减运算移动的单位是指针指向的数据的大小。

而不是把指针看做一个整型数,在这个数的基础上加减。

 

 2.1 一级指针

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

struct test {
  int a;
  char name[10];
  long data;
};

int main() {
  char c;
  char *pc = &c;

  int a = 0;
  int *pa = &a;

  struct test t;
  struct test *pt = &t;

  printf("pc: %p, pc + 1: %p\n", pc, pc + 1);
  printf("pa: %p, pa + 1: %p\n", pa, pa + 1);
  printf("pt: %p, pt + 1: %p\n", pt, pt + 1);
  printf("sizeof(struct test): %d\n", sizeof(struct test));
  printf("&t: %p, &t.a: %p, &t.name: %p, &t.data: %p\n", &t, &t.a, &t.name, &t.data);
  return 0;
}

pc 指向的数据类型是 char 类型,所以 pc + 1,地址移动 1 个字节。

pa 指向的数据类型是 int 类型,所以 pa + 1,地址移动了 4 个字节。

pt 指向的数据类型是 struct test 类型,所以 pt + 1,地址移动了 24 个字节。

c 语言中的数组和指针,c语言,算法,java

 

结构体的大小并不是所有结构体成员大小的和,因为结构体中的成员需要对齐。

怎么才算对齐 ? 成员地址 % 成员大小 等于 0

从上边的打印可以看出来,成员 a 的地址是 0x7ffd20d18350 对 4 可以整除;

成员 name 是一个数组,不是以数组为整体进行对齐,而是以数组中的元素进行对齐;

name 最后一个元素的地址是 0x7ffd20d1835e,但是 data 却不能保存到 0x7ffd20d1835f 处,因为这个地址对 data 的长度不能整除,所以 data 保存在了 0x7ffd20d18360 处。

指针的减法,得到的是两个指针之间相隔的元素的个数。

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


int main() {
  int a[10] = {0};
  int *pa = a;
  int *pa5 = a +5;
  printf("pa5 - pa: %d\n", pa5 - pa);
  return 0;
}

c 语言中的数组和指针,c语言,算法,java

 

2.2 二级指针

二级指针指向的数据类型是一级指针,所以二级指针加减运算的时候移动的单位是一个一级指针的大小。

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

struct test {
  int a;
  char name[17];
  long data;
};

int main() {
  char c;
  char *pc = &c;
  char **ppc = &pc;

  int a = 0;
  int *pa = &a;
  int **ppa = &pa;

  struct test t;
  struct test *pt = &t;
  struct test **ppt = &pt;

  printf("ppc: %p, ppc + 1: %p\n", ppc, ppc + 1);
  printf("ppa: %p, ppa + 1: %p\n", ppa, ppa + 1);
  printf("ppt: %p, ppt + 1: %p\n", ppt, ppt + 1);
  printf("sizeof(struct test): %d\n", sizeof(struct test));
  printf("&t: %p, &t.a: %p, &t.name: %p, &t.data: %p\n", &t, &t.a, &t.name, &t.data);
  return 0;
}

c 语言中的数组和指针,c语言,算法,java

3 数组加减运算

3.1 数组 sizeof()

数组名其实是一个指针,一维数组的数组名是一个一级指针 int *,二维数组的数组名是一个二级指针 int **。但是在使用 sizeof() 计算数组的大小的时候,并不是返回的一个指针的大小,而是返回的数组占用的空间。

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

int main() {
  int a[10] = {0};
  int b[10][10] = {0};

  int *pa = a;
  int **pb = b;
  printf("sizeof(a): %d, sizeof(&a): %d, sizeof(pa): %d\n", sizeof(a), sizeof(&a), sizeof(pa));
  printf("sizeof(b): %d, sizeof(&b): %d, sizeof(pb): %d\n", sizeof(b), sizeof(&b), sizeof(pb));
  return 0;
}

c 语言中的数组和指针,c语言,算法,java 

3.2 一维数组加减运算

一维数组的数组名是一级指针 int *,使用数组名做加减运算,移动的单位是数组元素的长度。

一维数组的数组名取地址,然后做加减运算,移动的单位是整个数组的大小。

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

int main() {
  int a[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

  printf("a: %p, a + 1: %p\n", a, a + 1);
  printf("&a: %p, &a + 1: %p\n", &a, &a + 1);
  printf("*a: %d\n", *a);
  return 0;
}

使用数组名做运算,a 和 a + 1 相差 4 个字节,即一个数组元素的长度。

使用数组名取地址做运算, &a 和 &a + 1相差整个数组的大小,4 * 10 = 40,即 0x28。

c 语言中的数组和指针,c语言,算法,java

数组的加减运算有自己的特殊之处,并不能完全按照指针的加减运算来使用。

如果按照指针的加减运算,那么 &a + 1 偏移的长度应该是一个 int * 的长度,在 64 为机器上是 8。

3.3 二维数组加减运算

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

int main() {
  int a[4][4] = {{1, 2, 3, 4}, {11, 12, 13, 14}, {21, 22, 23, 24}, {31, 32, 33, 34}};

  printf("a: %p, a + 1: %p\n", a, a + 1);
  printf("*a: %p, *a + 1: %p\n", *a, *a + 1);
  printf("&a: %p, &a + 1: %p\n", &a, &a + 1);
  return 0;
}

二维数组的数组名是一个二级指针 int **, 加减运算移动的单位是一行的大小,这个例子中行和列都是 4,所以移动单位是 16。

二维数组名使用 * 取值之后就是一级指针,指向某一行,而指向某一行的指针和一维数组的数组名是类似的,移动的单位是一个元素的长度。

二维数组的数组名取地址再做加减运算,和一维数组是类似的,移动的单位是整个数组的大小。

c 语言中的数组和指针,c语言,算法,java

 

4 字符数组

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

int main() {
  char *a = "hello";
  char b[] = "hello";

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

  printf("\n");
  printf("a: %p, a + 1: %p\n", a, a + 1);
  printf("b: %p, b + 1: %p\n", b, b + 1);
  return 0;
}

a 是一个 char * 指针,b 是一个 char 数组的数组名,两者还是有区别的。

sizeof(a) 是一个指针的大小,在 64 位系统中,长度是 8。

sizeof(b) 是一个数组的大小,长度是 6,包括字符串最后的结束符 '\0'。

strlen(a) 和 strlen(b) 是相同的,均是字符串的长度。使用 strlen() 获得的字符串的长度是不包括最后的字符串结束符 '\0' 的。

 c 语言中的数组和指针,c语言,算法,java

 

5 指针数组,数组指针

指针数组只的是一个数组,数组中的元素都是指针。

数组指针,可以叫数组的指针,是指一个指针,指向一个数组。

如下代码中,pa 是一个指针数组,数组长度是 2,可以保存两个指针。

ap 是数组指针,指向了数组 b。

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

int main() {
  int a[4] = {1, 2, 3, 4};
  int b[5] = {5, 6, 7, 8, 9};

  int *pa[2] = {a, b};
  int *ap = b;

  for (int i = 0; i < sizeof(a) / sizeof(a[0]); i++) {
    printf("a[%d] = %d\n", i, pa[0][i]);
  }

  for (int i = 0; i < sizeof(b) / sizeof(b[0]); i++) {
    printf("b[%d] = %d\n", i, ap[i]);
  }

  return 0;
}

如下代码需要深入理解指针数组与数组指针的概念,记录如下。

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

int main() {
  char *str[] = {"Welcome", "to", "Fortemedia", "Nanjing"};
  for (int i = 0; i < sizeof(str) / sizeof(str[0]); i++) {
    printf("str[%d] = %p\n", i, str[i]);
  }

  char **p = str + 1;
  printf("1111, *p: %s\n", *p); // to

  p++; // p 指向 Fortemedia
  printf("2222, *p: %s\n", *p);
  p--; // p 指向 to

  str[0] = (*p++) + 2; // p++ --> p 指向 Fortemedia, + 2 --> 超出数组范围
  printf("3333, *p: %s\n", *p);

  str[1] = *(p + 1); // p + 1 --> p + 1 指向 Nanjing,p 不变
  printf("4444, *p: %s\n", *p);

  str[2] = p[1] + 3; // p[1] --> Nanjing + 3 --> jing,因为 *p 的值也保存在 str[2] 这个位置,所以 p 也改变了
  printf("p[0]: %s, *p: %s, str[2]: %s, str[1]: %s\n", p[0], *p, str[2], str[1]);

  str[3] = p[0] + (str[2] - str[1]); // p[0] --> Fortemedia, str[2] jing, str[1] Nanjing,str[2] - str[1] = 3,p[0] + 3 指向 Nanjing 的最后一个字符 g

  printf("%s\n", str[0]);
  printf("%s\n", str[1]);
  printf("%s\n", str[2]);
  printf("%s\n", str[3]);
  return 0;
}

c 语言中的数组和指针,c语言,算法,java文章来源地址https://www.toymoban.com/news/detail-831180.html

到了这里,关于c 语言中的数组和指针的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C语言 ——指针数组与数组指针

    目录 一、二维数组 二、指针数组 (1)概念  (2)书写方式 (3)指针数组模拟二维数组 三、数组指针 (1)概念 (2)使用数组指针打印一维数组  (3)模拟二维数组的传参 首先,我们要理解一下二维数组和指针变量之间的一些相关概念。 二维数组 : int arr [ 3 ][ 5 ]  

    2024年02月13日
    浏览(50)
  • C语言--指针详解(下)--字符指针、数组指针、指针数组、函数指针、函数指针数组(转移表)

    在C语言中有一种指针类型为字符指针 char*,常用其来表示字符,使用如下: 除了上述用法之外,还可以有以下的用法: 在上面的代码中,字符 \\\" hello word \\\"是常量字符串,将\\\"hello word\\\"放入 pstr 指针的实质是将第一个字符 “ h \\\" 的地址传递给了 pstr ,通过首字符 ” h \\\" 就可以访问

    2024年02月03日
    浏览(51)
  • 【go语言基础】指针数组和数组指针

    (1)指针数组: 存储指针的数组,也叫存储地址的数组,简单说就是存储地址的。 首先它是一个数组,数组中的元素都是指针(地址)。 (2)数组指针: 首先它是一个指针,存储的是指向数组的指针。 (1)指针数组 定义: 注意:首先是一个数组,将数组中的元素定义为

    2024年02月13日
    浏览(52)
  • 【C语言】指针的基本知识详细讲解(指针数组、数组指针、函数指针....

    接着上次的函数的基本知识,今天我们来讲一讲🔍指针 目录 一、指针的概念 二、指针变量 三、野指针 四、字符指针 五、指针与数组 六、指针数组 七、数组指针  八、指针与函数 总结 一、指针的概念 1.1、变量和地址 所谓指针,也就是内存的地址;所谓指针变量,也就是

    2023年04月08日
    浏览(41)
  • C语言:指针和数组(看完拿捏指针和数组)

    目录 数组名的理解: 一维数组:  解析:  字符数组:  解析:   解析: 字符串数组:  解析:   解析:  一级指针:   解析:   解析:  二维数组:  解析:  指针笔试题: 题一:一维数组 题二: 结构体指针 题三: 一维数组 题四: 二维数组 题五: 二维数组 题

    2024年02月11日
    浏览(43)
  • 【C语言基础入门】二级指针、一维数组与指针、二维数组与指针

    在学习C语言的过程中,理解指针的概念是非常重要的。指针提供了一种直接访问内存地址的方式,使得我们可以更加灵活地管理数据和内存。在本文中,我们将介绍C语言中的二级指针、一维数组与指针,并通过通俗易懂的语言和示例代码来帮助读者理解这些概念。 二级指针

    2024年02月05日
    浏览(57)
  • 【C语言】指针进阶:字符指针&&数组指针&&函数指针

    ✨作者:@平凡的人1 ✨专栏:《C语言从0到1》 ✨一句话:凡是过往,皆为序章 ✨说明: 过去无可挽回, 未来可以改变 🌹 感谢您的点赞与关注,同时欢迎各位有空来访我的 🍁平凡舍 回想之前,我们学了 指针 的一些基础👉 指针与结构体 我们知道了指针的概念: 指针就是

    2023年04月08日
    浏览(43)
  • C语言:指向数组的指针和指向数组首元素的指针

    相关阅读 C语言 https://blog.csdn.net/weixin_45791458/category_12423166.html?spm=1001.2014.3001.5482         指向数组的指针和指向数组首元素的指针常常被混淆,或者笼统地被称为数组指针,但它们之间是有差别的,本文就将对此进行讨论。         下面的代码首先创建了一个数组,然后创

    2024年02月02日
    浏览(52)
  • C语言的函数指针、指针函数, 函数数组

    是指向函数的指针,它允许您在程序运行时动态选择要调用的函数。函数指针可以像普通变量一样传递、存储和使用,这使得它们在许多编程场景中非常有用,如回调函数、函数表、插件架构等。 以下是一个简单的例子来说明函数指针的概念: 函数数组是一个数组,其中的

    2024年02月09日
    浏览(46)
  • 【C语言】——指针七:数组和指针试题解析

         在前面的学习中,我们已经对C语言指针的知识有一个较为全面的了解,那么接下来我们做一些练习吧,即是检验我们的学习成果,也是对之前的知识的巩固。       1.1、 s i z e o f sizeof s i zeo f      因为后面的习题大量涉及 s i z e o f sizeof s i zeo f 与 s t r l

    2024年04月15日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包