C语言指针、数组、位运算符、类型转换、#include 、内存

一、C语言中的指针

1.基本概念

        C语言中指针(pointer)是一个变量,用来存储内存地址。通过指针,程序可以直接访问内存中的数据,包括变量、数组、结构体等等。指针在C语言中十分重要,因为它允许程序员直接操作内存,这在一些应用中非常有用。在C语言中,每个变量都有一个地址,可以通过取地址运算符(&)获取。例如以下指针语法:

int x = 5; 
int *x_addr = &x;      //int *x_addr指向整型变量x的地址; 例如值为0x7ffd2766a948 
*x_addr = 6;           //可以使用*运算符访问基础值 
int x_value = *x_addr; //解引用,这将得到6 
int arr1[10];          //数组隐含了指针! 
int *arr2[20];         //指针数组,使arr2成为指向指针的指针 
void *myPtr;

2.指针运算

假设char *c的值为0x100002,则

c++;    // 0x100003
c += 4; // 0x100007

假设int *i的值为0x100002,则

i++;    //0x100006
i += 4; //0x100016

原因:指针以基本数据类型的长度(以字节为单位)进行加减。

        需要注意的是,指针可以指向任何位置,包括未分配的内存和其他程序的内存。这可能导致程序崩溃或者产生安全漏洞,因此需要谨慎使用指针。

二、C语言数组

        C数组是存储特定数据类型的连续内存块。变量实际就是数组起始位置的指针。

char myString[40];                 // myString的类型是char* 
char *myArrayOfStrings[20];        // myArrayOfStrings的类型是char** 
int counting[5] = {1, 2, 3, 4, 5}; // counting类型为int*

 假设我们定义了int arr[4] = {5, 6, 7, 8},那么下面这些是等价的

arr[2] = 7; 
*(arr + 2) = 7; // 记住指针的算术运算! 

 三、C语言的位运算符

& (and/与): 10001 & 10000 -> 10000
| (or/或): 10001 | 10000 -> 10001
^ (xor/异或): 10001 ^ 10000 -> 00001
~ (complement/取反): ~10000 -> 01111
<< (left shift/左移): 1 << 4 -> 10000 (binary) -> 16 (decimal) 
>> (right shfit/右移): 10101 >> 3 -> 10 (binary)

 四、C语言类型转换

1.隐式类型转换

        这种类型转换是在表达式求值过程中自动发生的,无需显式地进行类型转换。例如,将一个整数赋值给一个浮点数变量时,整数会自动转换为浮点数。

2.显式类型转换

        这种类型转换需要使用显式的类型转换符来指定要转换的数据类型。例如,可以使用强制类型转换将一个整数转换为浮点数。在C语言中进行类型转换的语法是:(newType)variable。例如:

(char*)myVoidPtr;//将void*转换为char*
(uint64)(2 + 3);//从表达式转换为uint64

五、C语言的#include 

.h文件包含声明(构成)

.c文件包含定义(实现)

include卫兵是指这样的结构

#ifndef XXXX_H

#define XXXX_H

...

#endif

六、C语言的内存

下面程序有什么错误?

char *makeABC() { 
    char y[3] = {'a', 'b', 'c'}; 
    return y; 
}

        上述函数创建了一个包含 3 个元素的字符数组 y,并将字符 'a'、'b' 和 'c' 赋值给它。然后它试图返回指向数组 y 的第一个元素的指针。但存在的问题是,一旦函数退出,变量 y 所占用的内存就会被释放,这意味着返回指向 y 的指针将指向一段无效的内存地址。因此,返回指向局部变量的指针是不安全的,可能会导致未定义的行为,如访问已释放的内存,从而导致程序崩溃或出现其他意外行为。

        我们可以怎样解决呢?可以通过以下两种方法之一来修复代码:要么使用 malloc() 动态分配内存,要么将一个数组作为参数传递给函数。

//方法一:使用malloc()动态分配内存,注意不需要分配的内存时使用 free() 释放,否则可能会导致内存泄漏
char* makeABC() {
    char* y = malloc(3 * sizeof(char));
    y[0] = 'a';
    y[1] = 'b';
    y[2] = 'c';
    return y;
}
//方法二:将数组作为参数传递给函数
//由于传递的是指向数组的指针,所以对数组所做的更改会保留在调用函数的作用域中
void makeABC(char* y) {
    y[0] = 'a';
    y[1] = 'b';
    y[2] = 'c';
}


int main() {
    char arr[3];//必须在调用函数之前创建一个字符数组
    makeABC(arr);//并将其传递给函数,现在,arr 包含字符 'a'、'b' 和 'c'
    return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值