”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > 使用 GNU Emacs 进行 C 语言开发

使用 GNU Emacs 进行 C 语言开发

发布于2024-12-24
浏览:793

C Development with GNU Emacs

Emacs is designed with programming in mind, it supports languages like C, Python, and Lisp natively, offering advanced features such as syntax highlighting, customizable coding styles, and real-time error detection. Its built-in Lisp interpreter makes Emacs highly adaptable, allowing users to shape the editor to fit specific workflows or create entirely new functionalities.

Its rich ecosystem of extensions ensures it remains relevant across diverse fields, from academic writing to system programming, while its customizable interface enables users to optimize their environment for maximum productivity.

It continues to be a reliable choice for those who value control and versatility, proving that a tool designed decades ago can still meet the demands of today’s fast-evolving tech landscape.

Why Choose Emacs?

Emacs is more than just a text editor—it's a powerful, extensible platform for programming, writing, and customization. Unlike modern editors like VS Code or IntelliJ IDEA, Emacs thrives on flexibility and programmability. It allows users to deeply tailor their workflow, turning it into an environment suited for their exact needs. Whether you are coding in C, managing large projects, or even writing novels, Emacs can adapt to your requirements.

For new users, this might seem overwhelming, but once you understand its principles, Emacs becomes a tool that grows with you. This guide aims to help you set up a streamlined Emacs environment, from basic configurations to advanced integrations, ensuring you're productive every step of the way.

C Development with GNU Emacs

Table of Contents

  • Creating init.el
  • Ensuring the init.el Directory is Correct
  • Basic Configuration for Emacs
  • Adding the Linux Kernel Coding Style Patterns
  • Installing and Configuring the MELPA Package Manager
  • Installing the Clang LSP Server
  • Enhancing C Development with Company, Projectile, Treemacs, and Magit
  • Adding GNU Global, GTags, and Helm-Gtags
  • Using YASnippet for Code Templates
  • Configuring Semantic for Context-Aware Navigation
  • Practical Workflow Example for Development
  • Cheat Sheets
  • References for Plugins
  • Additional Learning Resources

Steps:

Creating init.el

  1. Open Emacs on your system.
  2. Use the command C-x C-f (press Ctrl and x, then Ctrl and f), which opens a file for editing.
  3. Type the file path ~/.emacs.d/init.el to create or edit your Emacs configuration file and press Enter.
  4. Add your desired configurations to the buffer. Once done, save the changes with C-x C-s (press Ctrl and x, then Ctrl and s).

Ensuring the init.el Directory is Correct

To ensure that the Emacs configuration always references the correct directory for the init.el file, add the following snippet to the top of your init.el file:

(setq user-emacs-directory "~/.emacs.d/")

This explicitly sets the user-emacs-directory variable to ~/.emacs.d/, ensuring that Emacs uses the specified path for its initialization file and related configurations. This approach avoids potential issues where Emacs might reference a different directory due to environment-specific settings.

Basic Configuration for Emacs

Here’s a simple and practical Emacs setup, explained clearly to help you understand its purpose. This configuration enhances usability, simplifies the interface, and ensures an efficient coding experience.

This line consolidates all backup files into a single directory (~/.saves). It keeps your projects clean and avoids cluttering your workspace.

(setq backup-directory-alist `(("." . "~/.saves")))

To reduce distractions, this removes unnecessary interface elements like the toolbar, scroll bar, tooltips, and menu bar. A cleaner interface helps you focus on coding without visual noise.

(tool-bar-mode -1)
(scroll-bar-mode -1)
(tooltip-mode -1)
(menu-bar-mode -1)

This setup disables the Emacs startup screen, removes the default message in the *scratch* buffer, and silences the system bell. It creates a distraction-free environment right from the start.

(setq inhibit-startup-screen t
      initial-scratch-message nil
      ring-bell-function 'ignore)

The cursor is set to a box style for better visibility, and the blinking effect is disabled. Automatic pairing of parentheses and indentation are enabled, making coding smoother and faster.

(setq cursor-type 'box
      blink-cursor-mode nil
      electric-pair-mode 1
      electric-indent-mode 1)

Line numbers are displayed globally for easier navigation, and the column number is shown in the status bar to keep track of cursor position in each line.

(global-display-line-numbers-mode t)
(column-number-mode t)

This configuration adds a clean and concise time display in the mode line, showing the day, date, and time in 24-hour format. The load average is excluded to keep the interface minimal.

(setq display-time-format "%a %b %d %R"
      display-time-interval 60
      display-time-default-load-average nil)
(display-time-mode 1)

Selections automatically replace highlighted text when typing, and clipboard integration ensures seamless copying and pasting between Emacs and other applications.

(setq select-enable-primary nil
      select-enable-clipboard t)
(delete-selection-mode 1)

All encoding is set to UTF-8, ensuring compatibility with modern text formats and avoiding encoding issues, particularly when working with international text or source code.

(set-terminal-coding-system 'utf-8)
(set-language-environment 'utf-8)
(set-keyboard-coding-system 'utf-8)
(prefer-coding-system 'utf-8)
(setq locale-coding-system 'utf-8)
(set-default-coding-systems 'utf-8)

Syntax highlighting is enabled globally with global-font-lock-mode. Long lines are wrapped naturally with visual-line-mode. Parentheses are highlighted when the cursor is near them, and recently opened files are tracked for quick access.

(global-font-lock-mode t)
(global-visual-line-mode 1)
(show-paren-mode 1)
(recentf-mode 1)

The tangotango theme provides a visually appealing color scheme. The font is set to "Consolas" with bold weight and size 15.2pt for better readability during long coding sessions.

(use-package tangotango-theme
  :ensure t
  :init (load-theme 'tangotango t))
(set-face-attribute 'default nil :family "Consolas" :height 152 :weight 'bold)

Note: Remember, we are using Emacs Lisp (Elisp), a functional programming language, to configure Emacs. This is a huge advantage, as it allows for highly flexible, programmable customization. The ability to write logic in a powerful Lisp dialect makes Emacs not just an editor, but a platform for personalized workflows.


Adding the Linux Kernel Coding Style Patterns

The configuration provided below sets up Emacs to strictly adhere to the Linux kernel coding style, emphasizing 8-character tabs, K&R brace placement, and clear readability. It includes a custom alignment function for argument lists, automatic detection of kernel-related files (e.g., files with Kbuild, Kconfig, or kernel headers), and applies the appropriate style automatically. This ensures consistency and simplifies kernel code editing in Emacs.

The linux-kernel-coding-style/setup function configures Emacs for kernel-specific settings like indent-tabs-mode, tab-width and c-basic-offset to 8, while the linux-kernel-coding-style/c-lineup-arglist-tabs-only function aligns argument lists using tabs, maintaining compliance with kernel guidelines. These hooks automatically apply the style to c-mode when editing Linux kernel files, improving productivity and adherence to coding standards.

(eval-when-compile (require 'cl))
(require 'cc)

(defun linux-kernel-coding-style/c-lineup-arglist-tabs-only (ignored)
  "Line up argument lists by tabs, not spaces"
  (let* ((anchor (c-langelem-pos c-syntactic-element))
         (column (c-langelem-2nd-pos c-syntactic-element))
         (offset (- (1  column) anchor))
         (steps (floor offset c-basic-offset)))
    (* (max steps 1)
       c-basic-offset)))

;; Add Linux kernel style
(add-hook 'c-mode-common-hook
          (lambda ()
            (c-add-style "linux-kernel"
                         '("linux" (c-offsets-alist
                                    (arglist-cont-nonempty
                                     c-lineup-gcc-asm-reg
                                     linux-kernel-coding-style/c-lineup-arglist-tabs-only))))))

(defun linux-kernel-coding-style/setup ()
  (let ((filename (buffer-file-name)))
    ;; Enable kernel mode for the appropriate files
    (when (and filename
               (or (locate-dominating-file filename "Kbuild")
                   (locate-dominating-file filename "Kconfig")
                   (save-excursion (goto-char 0)
                                   (search-forward-regexp "^#include $" nil t))))
      (setq indent-tabs-mode t)
      (setq tab-width 8)
      (setq c-basic-offset 8)
      (c-set-style "linux-kernel")
      (message "Setting up indentation for the Linux kernel"))))

(add-hook 'c-mode-hook 'linux-kernel-coding-style/setup)

(provide 'linux-kernel-coding-style)

Add this configuration to your Emacs initialization file (init.el). Emacs will now automatically detect Linux kernel files and apply the proper coding style, saving you time and ensuring compliance with the kernel's coding standards.


Installing and Configuring the MELPA Package Manager

MELPA makes it easy to install additional packages in Emacs.

Steps:

  • Add MELPA to Emacs:
  ;; Set up package repositories
  (require 'package)
  (setq package-archives
        '(("melpa" . "https://melpa.org/packages/")
          ("gnu" . "https://elpa.gnu.org/packages/")))
  (package-initialize)

  ;; Refresh package list if needed
  (unless package-archive-contents
    (package-refresh-contents))
  • Automatically install packages if they're not present:
  ;; Helper function to install packages
  (defun ensure-package-installed (&rest packages)
    "Ensure that the given PACKAGES are installed."
    (mapcar
     (lambda (package)
       (unless (package-installed-p package)
         (package-install package)))
     packages))

After making changes to your init.el file or adding new configurations, you can refresh Emacs without closing and reopening:

  1. Reload the init.el File:

    • Press M-x (Alt x), type eval-buffer, and press Enter while in your init.el buffer.
    • Alternatively, use the shortcut C-x C-e at the end of the code block to evaluate it.
  2. Manually Evaluate Code:

    • Select the code snippet you want to reload, press M-x, type eval-region, and press Enter.

This allows you to immediately apply changes to your Emacs configuration without restart


Installing the Clang LSP Server

The Language Server Protocol (LSP) provides advanced features like auto-completion and real-time error checking.

Necessary Requirements

Windows

  • LLVM/Clang:
    • Download the LLVM installer from the official website: LLVM Releases
    • During installation, make sure to add LLVM to the system PATH.

Linux

  • Debian/Ubuntu:
  sudo apt-get install clang clangd
  • Fedora:
  sudo dnf install clang clang-tools-extra

FreeBSD

  • Install clangd:
  pkg install clangd

Steps:

  • Install lsp-mode and company-mode:
  ;; Ensure that the packages are installed
  (ensure-package-installed 'lsp-mode 'company)

  ;; Enable lsp-mode for C/C  
  (add-hook 'c-mode-hook #'lsp)
  (add-hook 'c  -mode-hook #'lsp)

  ;; Enable company-mode for auto-completion
  (add-hook 'after-init-hook 'global-company-mode)
  • Configure the path to clangd if necessary:
  ;; Set the path to clangd
  (setq lsp-clients-clangd-executable "clangd")
  • Optional: Set up advanced syntax highlighting with lsp-ui:
  ;; Install lsp-ui
  (ensure-package-installed 'lsp-ui)

  ;; Enable lsp-ui
  (add-hook 'lsp-mode-hook 'lsp-ui-mode)

What is LSP and Why Use It?

The Language Server Protocol (LSP) bridges the gap between editors and programming languages, providing features like auto-completion, error checking, and code navigation. This is particularly useful for C/C development, where managing headers, debugging, and navigating large codebases can be challenging.

By setting up LSP in Emacs, you gain the ability to:

  • View real-time syntax errors as you type.
  • Jump to function or variable definitions instantly.
  • Access intelligent suggestions for completing code.

This makes Emacs competitive with modern IDEs while retaining its lightweight and customizable nature.

Company, Projectile, Treemacs, and Magit

Enhancing your Emacs setup for C development involves integrating Company, Projectile, Treemacs, and Magit. Company provides auto-completion for C programming, enabling real-time suggestions for functions, variables, and keywords, making coding faster and more efficient. By configuring it to use company-clang, you ensure robust support tailored to C development.

Projectile streamlines project management by allowing quick navigation, file discovery, and project compilation. It pairs seamlessly with Treemacs, which provides a visual, tree-based representation of your project structure, helping you locate and manage files intuitively. Finally, Magit is an advanced interface for Git, providing powerful tools for version control directly within Emacs.

With shortcuts like C-x g, you can perform operations such as commits, branching, and merging interactively, enhancing your workflow and productivity. Here’s the complete configuration to set up these tools in your Emacs environment:

;; Ensure required packages are installed
(ensure-package-installed 'company 'projectile 'treemacs 'treemacs-projectile 'magit)

;; Company Setup for Auto-Completion
(add-hook 'after-init-hook 'global-company-mode) ;; Enable globally
(add-hook 'c-mode-hook
          (lambda ()
            (setq-local company-backends '(company-clang company-capf company-files)))) ;; Configure for C
(setq company-minimum-prefix-length 1
      company-idle-delay 0.2) ;; Show suggestions after 0.2 seconds

;; Projectile Setup for Project Management
(projectile-mode  1) ;; Enable globally
(setq projectile-project-search-path '("~/projects/")) ;; Set your project directory
(setq projectile-completion-system 'default) ;; Use default completion system
(global-set-key (kbd "C-c p") 'projectile-command-map) ;; Set a keybinding for Projectile commands

;; Treemacs Setup for Tree-Based File Navigation
(global-set-key (kbd "M-0") 'treemacs) ;; Toggle Treemacs
(global-set-key (kbd "C-x t t") 'treemacs) ;; Alternate keybinding
(with-eval-after-load 'treemacs
  (treemacs-projectile)) ;; Integrate with Projectile
(setq treemacs-width 30 ;; Set tree width
      treemacs-is-never-other-window t) ;; Prevent Treemacs from taking focus

;; Magit Setup for Git Version Control
(global-set-key (kbd "C-x g") 'magit-status) ;; Open Magit status interface

Practical Workflow Example

Let’s see how you can combine these tools in a real-world scenario:

  1. Open a Project:
    • Use C-c p f to quickly find a file within your project directory using Projectile.
  2. Navigate Files Visually:
    • Open Treemacs with M-0, and use the arrow keys to browse your project structure. Double-click a file to open it.
  3. Git Workflow with Magit:
    • Stage changes: Open Magit with C-x g, press s to stage files.
    • Commit: Press c c to commit changes with a message.
    • Push: Use P to push changes to your remote repository.
  4. Code Completion:
    • While editing a .c file, type a function name partially and use company-mode suggestions by pressing TAB.

Enhancements to Add to the Article

  1. GNU Global and GTags Configuration:
    • Add instructions for setting up GNU Global and GTags for code navigation:
   ;; Install and configure ggtags
   (require 'ggtags)
   (add-hook 'c-mode-common-hook
             (lambda ()
               (when (derived-mode-p 'c-mode 'c  -mode 'java-mode 'asm-mode)
                 (ggtags-mode 1))))

   ;; Keybindings for ggtags
   (define-key ggtags-mode-map (kbd "C-c g s") 'ggtags-find-other-symbol)
   (define-key ggtags-mode-map (kbd "C-c g h") 'ggtags-view-tag-history)
   (define-key ggtags-mode-map (kbd "C-c g r") 'ggtags-find-reference)
   (define-key ggtags-mode-map (kbd "C-c g f") 'ggtags-find-file)
   (define-key ggtags-mode-map (kbd "C-c g u") 'ggtags-update-tags)
  1. Helm-Gtags Integration:
    • Include configuration for helm-gtags to enhance project navigation:
   (setq
    helm-gtags-ignore-case t
    helm-gtags-auto-update t
    helm-gtags-use-input-at-cursor t
    helm-gtags-pulse-at-cursor t
    helm-gtags-prefix-key "\C-cg"
    helm-gtags-suggested-key-mapping t)

   (require 'helm-gtags)
   (add-hook 'c-mode-hook 'helm-gtags-mode)
   (add-hook 'c  -mode-hook 'helm-gtags-mode)
  1. Yasnippet Templates:
    • Include YASnippet for code templates:
   (require 'yasnippet)
   (yas-global-mode 1)
   ;; Example snippet for C-mode
   (add-to-list 'yas-snippet-dirs "~/.emacs.d/snippets")
   (yas-reload-all)
   (add-hook 'c-mode-hook #'yas-minor-mode)
  1. Semantic Configuration:
    • Add Semantic for context-aware code completion and parsing:
   (require 'cc-mode)
   (require 'semantic)
   (global-semanticdb-minor-mode 1)
   (global-semantic-idle-scheduler-mode 1)
   (semantic-mode 1)

   ;; Add include paths for Semantic
   (semantic-add-system-include "/usr/include/boost" 'c  -mode)
   (semantic-add-system-include "~/linux/include")
  1. Additional Code Navigation Features:
    • Mention semantic-symref for reference gathering:
   (add-hook 'c-mode-common-hook
             (lambda ()
               (local-set-key (kbd "C-c , g") 'semantic-symref)))

These additions enhance the existing content by providing support for advanced navigation, project management, and automation tools in Emacs, aligning the article with best practices for modern C/C development.


Cheat Sheets

C Development with GNU Emacs

C Development with GNU Emacs


References for Plugins

  • lsp-mode: Language Server Protocol support for auto-completion and error checking. GitHub
  • company-mode: Context-aware autocompletion. GitHub
  • lsp-ui: UI enhancements for lsp-mode. GitHub
  • projectile: Project navigation and management. GitHub
  • treemacs: Tree-based file explorer. GitHub
  • magit: Git interface for Emacs. GitHub
  • ggtags: GNU Global integration for code navigation. GitHub
  • helm-gtags: Navigation with GNU Global and Helm. GitHub
  • yasnippet: Snippet management for reusable code. GitHub
  • semantic: Advanced code parsing and navigation. GNU CEDET

Additional Learning Resources

  • Emacs for Beginners: A beginner-friendly guide to setting up and using Emacs. Link
  • Introduction to Emacs Lisp: Learn how to customize Emacs using Lisp. Link
  • Linux Kernel Coding Style: Official documentation on kernel coding standards. Link
  • Setting Up Emacs for C Development: A practical guide to configure Emacs for C/C programming. Link
版本声明 本文转载于:https://dev.to/scovl/c-development-with-gnu-emacs-j38如有侵犯,请联系[email protected]删除
最新教程 更多>
  • 如何使用不同数量列的联合数据库表?
    如何使用不同数量列的联合数据库表?
    合并列数不同的表 当尝试合并列数不同的数据库表时,可能会遇到挑战。一种直接的方法是在列数较少的表中,为缺失的列追加空值。 例如,考虑两个表,表 A 和表 B,其中表 A 的列数多于表 B。为了合并这些表,同时处理表 B 中缺失的列,请按照以下步骤操作: 确定表 B 中缺失的列,并将它们添加到表的末...
    编程 发布于2025-07-02
  • 为什么不使用CSS`content'属性显示图像?
    为什么不使用CSS`content'属性显示图像?
    在Firefox extemers属性为某些图像很大,&& && && &&华倍华倍[华氏华倍华氏度]很少见,却是某些浏览属性很少,尤其是特定于Firefox的某些浏览器未能在使用内容属性引用时未能显示图像的情况。这可以在提供的CSS类中看到:。googlepic { 内容:url(&#...
    编程 发布于2025-07-02
  • 人脸检测失败原因及解决方案:Error -215
    人脸检测失败原因及解决方案:Error -215
    错误处理:解决“ error:((-215)!empty()in Function Multultiscale中的“ openCV 要解决此问题,必须确保提供给HAAR CASCADE XML文件的路径有效。在提供的代码片段中,级联分类器装有硬编码路径,这可能对您的系统不准确。相反,OPENCV提...
    编程 发布于2025-07-02
  • C++成员函数指针正确传递方法
    C++成员函数指针正确传递方法
    如何将成员函数置于c 的函数时,接受成员函数指针的函数时,必须同时提供对象的指针,并提供指针和指针到函数。需要具有一定签名的功能指针。要通过成员函数,您需要同时提供对象指针(此)和成员函数指针。这可以通过修改Menubutton :: SetButton()(如下所示:[&& && && &&华)...
    编程 发布于2025-07-02
  • 如何在Java中正确显示“ DD/MM/YYYY HH:MM:SS.SS”格式的当前日期和时间?
    如何在Java中正确显示“ DD/MM/YYYY HH:MM:SS.SS”格式的当前日期和时间?
    如何在“ dd/mm/yyyy hh:mm:mm:ss.ss”格式“ gormat 解决方案: args)抛出异常{ 日历cal = calendar.getInstance(); SimpleDateFormat SDF =新的SimpleDateFormat(“...
    编程 发布于2025-07-02
  • 编译器报错“usr/bin/ld: cannot find -l”解决方法
    编译器报错“usr/bin/ld: cannot find -l”解决方法
    错误:“ usr/bin/ld:找不到-l “ 此错误表明链接器在链接您的可执行文件时无法找到指定的库。为了解决此问题,我们将深入研究如何指定库路径并将链接引导到正确位置的详细信息。添加库搜索路径的一个可能的原因是,此错误是您的makefile中缺少库搜索路径。要解决它,您可以在链接器命令中添加...
    编程 发布于2025-07-02
  • 为什么PHP的DateTime :: Modify('+1个月')会产生意外的结果?
    为什么PHP的DateTime :: Modify('+1个月')会产生意外的结果?
    使用php dateTime修改月份:发现预期的行为在使用PHP的DateTime类时,添加或减去几个月可能并不总是会产生预期的结果。正如文档所警告的那样,“当心”这些操作的“不像看起来那样直观。 考虑文档中给出的示例:这是内部发生的事情: 现在在3月3日添加另一个月,因为2月在2001年只有2...
    编程 发布于2025-07-02
  • 如何有效地转换PHP中的时区?
    如何有效地转换PHP中的时区?
    在PHP 利用dateTime对象和functions DateTime对象及其相应的功能别名为时区转换提供方便的方法。例如: //定义用户的时区 date_default_timezone_set('欧洲/伦敦'); //创建DateTime对象 $ dateTime = ne...
    编程 发布于2025-07-02
  • 如何在其容器中为DIV创建平滑的左右CSS动画?
    如何在其容器中为DIV创建平滑的左右CSS动画?
    通用CSS动画,用于左右运动 ,我们将探索创建一个通用的CSS动画,以向左和右移动DIV,从而到达其容器的边缘。该动画可以应用于具有绝对定位的任何div,无论其未知长度如何。问题:使用左直接导致瞬时消失 更加流畅的解决方案:混合转换和左 [并实现平稳的,线性的运动,我们介绍了线性的转换。这...
    编程 发布于2025-07-02
  • 如何在鼠标单击时编程选择DIV中的所有文本?
    如何在鼠标单击时编程选择DIV中的所有文本?
    在鼠标上选择div文本单击带有文本内容,用户如何使用单个鼠标单击单击div中的整个文本?这允许用户轻松拖放所选的文本或直接复制它。 在单个鼠标上单击的div元素中选择文本,您可以使用以下Javascript函数: function selecttext(canduterid){ if(do...
    编程 发布于2025-07-02
  • 左连接为何在右表WHERE子句过滤时像内连接?
    左连接为何在右表WHERE子句过滤时像内连接?
    左JOIN CONUNDRUM:WITCHING小时在数据库Wizard的领域中变成内在的加入很有趣,当将c.foobar条件放置在上面的Where子句中时,据说左联接似乎会转换为内部连接。仅当满足A.Foo和C.Foobar标准时,才会返回结果。为什么要变形?关键在于其中的子句。当左联接的右侧值...
    编程 发布于2025-07-02
  • 如何检查对象是否具有Python中的特定属性?
    如何检查对象是否具有Python中的特定属性?
    方法来确定对象属性存在寻求一种方法来验证对象中特定属性的存在。考虑以下示例,其中尝试访问不确定属性会引起错误: >>> a = someClass() >>> A.property Trackback(最近的最新电话): 文件“ ”,第1行, AttributeError: SomeClass...
    编程 发布于2025-07-02
  • 在程序退出之前,我需要在C ++中明确删除堆的堆分配吗?
    在程序退出之前,我需要在C ++中明确删除堆的堆分配吗?
    在C中的显式删除 在C中的动态内存分配时,开发人员通常会想知道是否有必要在heap-procal extrable exit exit上进行手动调用“ delete”操作员,但开发人员通常会想知道是否需要手动调用“ delete”操作员。本文深入研究了这个主题。 在C主函数中,使用了动态分配变量(H...
    编程 发布于2025-07-02
  • Java字符串非空且非null的有效检查方法
    Java字符串非空且非null的有效检查方法
    检查字符串是否不是null而不是空的 if(str!= null && str.isementy())二手: if(str!= null && str.length()== 0) option 3:trim()。isement(Isement() trim whitespace whitesp...
    编程 发布于2025-07-02
  • Java数组中元素位置查找技巧
    Java数组中元素位置查找技巧
    在Java数组中检索元素的位置 利用Java的反射API将数组转换为列表中,允许您使用indexof方法。 (primitives)(链接到Mishax的解决方案) 用于排序阵列的数组此方法此方法返回元素的索引,如果发现了元素的索引,或一个负值,指示应放置元素的插入点。
    编程 发布于2025-07-02

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3