C语言程序与设计——指针地址与main函数

指针变量

在C语言中,最重要的就是对于指针和地址的理解,因为C语言是更接近底层的编程语言,所以它可以允许开发者对内存操作,这也是区别于其它编程语言的一个重要特性。
如何对内存进行操作呢。我们知道在编程过程中,在任何语言中,我们在定定义一个变量的过程中,实际上就是向操作系统申请了一块内存,但由于其它编程语言不支持我们对于内存进行操作,所以我们只知道申请了一块内存,但不知道该位置在哪。由于C语言支持我们对于内存的操作,所以我们可以通过在变量前加一个取地址符&,得到该内存的地址,数组的话无需加取地址符。

#include<stdio.h>
int main(){int a[5];int b;printf("&b = %p, sizeof(&b) = %lu\n", &b, sizeof(&b));printf("a[0] = %p\n", a);printf("a[1] = %p\n", a + 1);printf("a[2] = %p\n", a + 2);printf("a[3] = %p\n", a + 3);printf("a[4] = %p\n", a + 4);
}运行结果
>>&b = 0x7fffe87408ec, sizeof(&b) = 8
a[0] = 0x7fffe87408f0
a[1] = 0x7fffe87408f4
a[2] = 0x7fffe87408f8
a[3] = 0x7fffe87408fc
a[4] = 0x7fffe8740900

可以看到整型数组的地址间隔刚好为4,也就是说明整型变量大小是四个字节。而且指针的大小是8个字节。

指针的大小
在我所演示的运行环境是在64位操作系统下运行的,64bit刚好是8字节,也就是说如果在32位操作系统下运行该程序的话sizeof(&b)会是4字节

  • 指针的大小是与系统环境相关的
  • 以int为例,int占用四个字节,在取地址时从相关地址的首地址开始
  • 在一个32bit操作系统中,地址最多为4GB,所以假设插入一个8GB的内存条则会有另外4GB无法使用

变量的地址

指针变量也是变量,也就说,指针变量同样也有地址。由此,我们就可以对数组的各个地址取地址符,这样就构成了二维数组。

#include<stdio.h>int main(){int a;int *p = &a;int arr[3][3];printf(" &a = %p\n p = %p\n &p = %p\n", &a, p, &p);printf(" arr[0][0] = %p, sizeof(arr[0][0]) = %lu\n", arr, sizeof(&arr));printf(" arr[1][0] = %p, sizeof(arr[1][0]) = %lu\n", arr + 3, sizeof(arr + 3));printf(" arr[1][0] = %p, sizeof(arr[2][0]) = %lu\n", &arr + 1, sizeof(arr + 3 + 3 + 1));}运行结果>> &a = 0x7fff350f5c54p = 0x7fff350f5c54&p = 0x7fff350f5c58arr[0][0] = 0x7fff350f5c60, sizeof(arr[0][0]) = 8arr[1][0] = 0x7fff350f5c84, sizeof(arr[1][0]) = 8arr[1][0] = 0x7fff350f5c84, sizeof(arr[2][0]) = 8

理解了双重指针以及二维数组之后,那么就可以尝试高维数组的实现形式。

所以在scanf(“%d”, &n);这行代码中,我们传入的是地址,因为我们要改变的是n所代表的这块内存上的值,所以需要找到内存的所在地址然后存入数据。

函数指针

在之前函数的章节,已经涉及到了函数指针,但只是把函数作为传入参数的形式,下面我们将演示函数指针的声明形式

#include<stdio.h>int add(int a, int b){return a + b;
}
int main(){int (*func)(int, int);func = add;printf("%d", func(1,1));
}
#include<stdio.h>int add(int a, int b){return a + b;
}
int main(){typedef int (*func)(int, int);func f = add;printf("%d", f(1, 1));
}

可以看到我们使用了两种方式定义了函数指针。可以看到以第一种是直接声明的了一个函数指针,而后将指针指向了add()函数,那么第二种的话用到了一个关键字typedef,而后func变成了一个类型的样子,随后定义了f指针指向了add()函数。二者的定义形式的区别就是

声明一个函数指针变量: int (*add)(int, int);
定义一个函数指针类型: typedef int (*add)(int, int);

Main函数

我们知道在C语言中,一个程序运行必须要有main函数,但是我们在使用main函数中,基本都是无参数的形式,但实际上的main函数有三种形式,如下。下面就简单了解一下main函数的其他两种形式

int main();
int main(int argc, char *argv[]);
int main(int argc, char *argv[], char **env);

参数解释:
argc: 命令行参数个数(例如 ls -al al就是参数)
*argv[ ]:命令行内容(注意这是一个二位数组)
**env:环境变量

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

在这里插入图片描述
可以看到示例 ./a.out -a -l -s。其中作为参数全部传入了程序中,值得一提的是./a.out也作为了一个参数传入了,也就是说程序在运行时至少会有一个命令行参数。我们也不难发现空格是参数的分隔符,但是我们可以通过加\转义字符,使其可以把空格传入。

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

在这里插入图片描述
可以看到env参数包含了很多我们的环境变量,包括用户路径语言等等。这些都是操作系统为我们提供的接口允许我们可以做在操作系统中做一些底层的操作。

main()返回值

在我们初学C语言时就接触了main()函数,我们可以不用返回值,但是又会经常见到return 0。那么main的返回值是返回给谁,又有什么作用呢?从函数上来讲,当然是谁调用就返回给谁,该函数是操作系统调用的,所以就是返回给操作系统的。
我们可以通过echo $?的命令查看上一次运行是不是成功运行,如果返回值为0,代表执行失败。如果是1则是成功执行,所以说可能对于我们来讲程序的功能是成功执行的,但是对于操作系统来讲我们的程序没有执行成功。所以我们应尽量在主函数中加入返回值。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/798599.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

题目:学习使用external的用法。

题目&#xff1a;学习使用external的用法。 There is no nutrition in the blog content. After reading it, you will not only suffer from malnutrition, but also impotence. The blog content is all parallel goods. Those who are worried about being cheated should l…

JavaScript之闭包的实现原理和作用详解

闭包是JavaScript中强大而灵活的概念&#xff0c;它不仅可以解决作用域的问题&#xff0c;还能够实现函数式编程的一些特性。本文将详细解释JavaScript闭包的实现原理和作用&#xff0c;包括什么是闭包、闭包的实现原理、闭包的作用以及具体的代码示例。 1. 闭包的定义 闭包是指…

C++面试100问与自动驾驶100问

C的学习和面试其实是非常的不友好的&#xff0c;首先C的学习内容非常的多&#xff0c;其次C的面试不单单面试C的知识点&#xff0c;还有它的“七大姑八大姨”&#xff08;计算机网络、数据结构、算法、计算机组成原理、操作系统、编译、xxx的底层实现 and so on&#xff09;。 …

突破编程_前端_SVG(基础元素介绍)

1 rect 矩形 在 SVG 中&#xff0c;<rect> 元素用于创建圆形。 &#xff08;1&#xff09;基本语法 <rectx"x坐标"y"y坐标"width"宽度"height"高度"rx"可选&#xff1a;圆角x半径"ry"可选&#xff1a;圆角…

用可视化案例讲Rust编程5.用泛型和特性实现自适配绘制和颜色设置

上一节我们讲了用泛型实现返回结果&#xff0c;这一节我们来讲讲在函数签名里面使用泛型来对输入参数进行自适配。 先看UML设计图&#xff1a; 好吧&#xff0c;看起来有点复杂&#xff0c;我们一个个来解释。 首先定义的是一个生成绘图元素需要的参数结构,并且定义个特性&am…

Spring Security——09,解决跨域

解决跨域 一、SpringBoot配置二、配置SpringSecurity三、修改端口四、修改vue项目4.1 拿到token4.2 前端存储token4.3 前端请求头携带token 五、测试5.1 认证测试5.2 授权测试 一键三连有没有捏~~ 浏览器出于安全的考虑&#xff0c;使用 XMLHttpRequest对象发起 HTTP请求时必须…

day 74 js

js脚本 JS的作用&#xff1a; 描述显示的内容&#xff08;HTML&#xff09;修饰 HTML 标签&#xff08;CSS&#xff09;设置 HTML 标签的动作&#xff08;JS&#xff09;JS特点&#xff1a;基于对象的编程语言&#xff0c;通过浏览器解释执行作用&#xff1a;表单验证、改变标签…

使用阿里云服务器可以做什么?太多了

阿里云服务器可以干嘛&#xff1f;能干啥你还不知道么&#xff01;简单来讲可用来搭建网站、个人博客、企业官网、论坛、电子商务、AI、LLM大语言模型、测试环境等&#xff0c;阿里云百科aliyunbaike.com整理阿里云服务器的用途&#xff1a; 阿里云服务器活动 aliyunbaike.com…

LeetCode-热题100:763. 划分字母区间

题目描述 给你一个字符串 s 。我们要把这个字符串划分为尽可能多的片段&#xff0c;同一字母最多出现在一个片段中。 注意&#xff0c;划分结果需要满足&#xff1a;将所有划分结果按顺序连接&#xff0c;得到的字符串仍然是 s 。 返回一个表示每个字符串片段的长度的列表。…

AcWing 4. 多重背包问题 I

解题思路 相关思路 import java.util.Scanner; public class Main {public static void main(String[] args){Scanner scanner new Scanner(System.in);int N scanner.nextInt();int V scanner.nextInt();int v[] new int[N1];int w[] new int[N1];int s[] new int[N1];…

揭秘AI幻觉:GPT-4V存在视觉编码漏洞,清华联合NUS提出LLaVA-UHD

ChatGPT狂飙160天&#xff0c;世界已经不是之前的样子。 新建了免费的人工智能中文站https://ai.weoknow.com 新建了收费的人工智能中文站https://ai.hzytsoft.cn/ 更多资源欢迎关注 GPT-4V 的推出引爆了多模态大模型的研究。GPT-4V 在包括多模态问答、推理、交互在内的多个领…

capter1:GPU 硬件与 CUDA 程序开发工具

GPU 硬件与 CUDA 程序开发工具 参考书籍&#xff1a;CUDA 编程 樊哲勇 代码地址&#xff1a;https://github.com/QINZHAOYU/CudaSteps GPU 硬件 在由 CPU 和 GPU 构成的异构计算平台中&#xff0c;通常将起控制作用的 CPU 称为 主机&#xff08;host&#xff09;&#xff0c;…

二. CUDA编程入门-双线性插值计算

目录 前言0. 简述1. 执行一下我们的第十个CUDA程序2. Bilinear interpolation3. 代码分析总结参考 前言 自动驾驶之心推出的 《CUDA与TensorRT部署实战课程》&#xff0c;链接。记录下个人学习笔记&#xff0c;仅供自己参考 Note&#xff1a;关于 CUDA 加速双线程插值的内容博主…

Linux下I2C设备驱动:i2c_driver 的注册示例代码

一. 简介 前面学习了 Linux下 I2C驱动框架分为&#xff1a;I2C总线驱动与I2C设备驱动两个部分。我们主要重点学习 I2C设备驱动&#xff0c;前一篇文章学习了I2C设备驱动相关的结构体与设备驱动注册与删除。文章如下&#xff1a; Linux下I2C驱动实验&#xff1a;I2C 设备驱动…

对象存储服务MinIO安装使用

对象存储服务MinIO安装使用 MinIO简介 MinIO基于Apache License v2.0开源协议的对象存储服务&#xff0c;可以做为云存储的解决方案用来保存海量的图片&#xff0c;视频&#xff0c;文档。由于采用Golang实现&#xff0c;服务端可以工作在Windows,Linux, OS X和FreeBSD上。配置…

爬虫逆向非对称加密和对称加密案例

注意&#xff01;&#xff01;&#xff01;&#xff01;某XX网站逆向实例仅作为学习案例&#xff0c;禁止其他个人以及团体做谋利用途&#xff01;&#xff01;&#xff01; 案例--aHR0cHM6Ly9jcmVkaXQuaGxqLmdvdi5jbi94eWdzL3l6d2ZzeHF5bWQv 第一步&#xff1a;分析页面、请求…

CTF 之Zhuanxv

拿到题目进行目录遍历发现有一个/list文件 打开/list文件&#xff0c;发现是一个登录界面 尝试过爆破&#xff0c;毫无疑问不可能成功。 刷新页面&#xff0c;抓包&#xff0c;然后放一个包&#xff0c;发现又发了一个请求。 GET /loadimage?fileNameweb_login_bg.jpg HTTP/…

1995-2021年各省分品种能源产量和消费量数据

1995-2021年各省分品种能源产量和消费量数据 1、时间&#xff1a;1995-2021年 2、来源&#xff1a;能源统计年鉴、各省年鉴 3、指标&#xff1a;能源消费总量、煤炭消费量、焦炭消费量、原油消费量、汽油消费量、煤油消费量、柴油消费量、燃料油消费量、天然气消费量、电力消…

不开玩笑,你应该像「搬砖」一样写代码!斯坦福大学研究如是说

由于程序员不可避免要进行很多重复性的工作&#xff0c;并且工作强度很高&#xff0c;导致有一种自嘲的说法出现&#xff1a;程序员们自称自己每天都在搬砖&#xff08;实际上很多职场人都这么自嘲&#xff09;。我相信当我们说工作像「搬砖」的时候&#xff0c;只是在表达一种…

JSX 入门:React 开发者的必备技能指南

JSX 是 React 的一种语法扩展&#xff0c;用于描述 UI 组件的外观。在 React 中&#xff0c;JSX 可以与 JavaScript 一起使用&#xff0c;帮助您在应用程序中创建动态和可重用的组件。以下是 JSX 的语法、使用技巧和注意事项&#xff0c;以及一些示例代码。 JSX 基础语法 JSX…