c语言中取地址符和*有啥区别?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c语言中取地址符和*有啥区别?相关的知识,希望对你有一定的参考价值。

紧急求助:请问c语言中&和*有什么区别,不都是取地址吗?

不都是取地址。

1,符号含义不同:&是取地址运算符,&a为变量a的地址。

2,用法不同:声明中 int x;  x 是整型量。

语句中,&x 是整型量x的地址。不是指针,才有&。

语句中,x 是整型量x的值。

3,指向不同:*是指针运算符,*p为指针变量p所指向的存储单元中的内容。而指针变量p中一般只存放地址。* 表示指针,例如: int *p; -- p 是指针,指向整型量。

语句中,*p 表示指针指向的整型量的值。

语句中,p 表示指针指向的地址。

语句中,没有 &p 形式,如果p是指针。

扩展资料

*空指针,*野指针

在函数内部对指针进行赋值操作后,在函数执行完毕后,该指针就成了一个空指针(变量从栈中弹出)。但是通过动态地址分配(堆空间)的指针不会有上述问题。

free(p)后释放内存的指针为野指针。

指针(pointer)是对数据对象或函数的一种引用。指针有多种用途,例如定义“传址调用”函数,它还可以实现动态数据结构,例如链表和树。

通常,管理大量数据的有效方法不是直接处理数据本身,而是使用指向数据的指针。例如,如果需要对大量的大型记录进行排序,对指向该记录的指针列表进行排序效率要比直接对记录排序高得多,因为这样无需在内存中移动数据。

类似地,如果需要把大型记录传入函数,传递指向该记录的指针会比直接传递记录本身更经济,即使函数不需要修改该记录。

指针代表了一个对象或函数的地址和类型。如果一个对象或函数具有 T 类型,那么指向它的指针就具有一个衍生出的指向 T 的指针类型(pointer to T)。

例如,如果 var 是一个 float 变量,那么表达式 &var(其值是该 float 变量的地址)属于指向 float 的指针类型,按照 C 语言表达,就是 float* 类型。

指向任何 T 类型的指针也被简称为 T 指针(T point)。因此,&var 中地址运算符会生成一个 float 指针。

因为 var 没有在内存中移动位置,所以表达式 &var 是一个常量指针。然而,C 也允仵使用指针类型来定义变量。指针变量存储的是另一个对象或函数的地址。

我们后面会进一步讨论指向数组和函数的指针。首先,看看如何声明指向非数组对象的指针,语法如下:

类型 * [类型限定符列表] 名称 [= 初始化器];

在声明中,星号(*)表示“指向的指针”。标识符“名称”被声明为一个对象,其对象类型为“类型”,也就是“指向‘类型’的指针”。类型限定符为可选择项,可能包含 const、volatile 和 restrict 的任意组合。

参考资料

百度百科——指针

参考技术A

c语言中取地址符和*有两点区别:

一、p指令:

声明中: * 表示指针,例如: int *p,p是指针,指向整型量。*p表示指针指向的整型量的值。

语句中,p表示指针指向的地址。如果p是指针,没有 &p 形式。

二、 x指令:

声明中:x是整型量。&x是整型量x的地址,不是指针。

语句中:x是整型量x的值。&另一用途是按位运算符,按位* 是乘号。

扩展资料:

C语言中常见符号的作用:

1、 ? x:y,类似于if语句,例如: x>9?50:100;   意思是x是否大于9 ,是的话就输出50,不是的话就输出100。

2、c语言中,!的作用是逻辑非,例如:!a 凡是a不等于0,那么输出都是0,只有当a等于0时,输出的才是0。!=意思是不等于,一般应用与判断 if(a!=b)。

3、c语言中,&&表示逻辑且(交集) ,||表示逻辑或(并集)。实际上两者也是用来输出正确与错误,也就是输出0或1,判断的意思。

参考技术B

区别如下:

(1)两者根本意义不同。*是指针的意思,而&是去地址的意思,这两个相辅相成。

(2)用法不同。高级的c语言都是动态开辟内存,是使用malloc和free,这时就不用&了,因为取引用都是对于栈上的数据,在数据结构中,都是在堆上开辟数据容量。

(3)语言规则不同,变量类型加*就是一个指向该变量类型的指针,通俗点说,指针就是可以通过地址修改和获取该变量的值,而&符号只是获取该变量的地址!

指针中的“取地址符”

扩展资料:

引用的声明符放置在变量名的前面,和*操作符的用法一样。

引用声明完毕后,相当于目标变量名有两个名称,即该目标原名称和引用名,且不能再把该引用名作为其他变量名的别名。 ra=1; 等价于 a=1;

声明一个引用,不是新定义了一个变量,它只表示该引用名是目标变量名的一个别名,它本身不是一种数据类型,因此引用本身不占存储单元,系统也不给引用分配存储单元。

故:对引用求地址,就是对目标变量求地址。&ra与&a相等。

#include<iostream> using namespace std; int main() 

int m[10]=1,2,3,4,5,6,7,8,9,10; int (&n)[10]=m; for(int i=0;i<10;i++) cout<<m[i]<<' ' ;

cout<<endl; for( i=0;i<10;i++) cout<<n[i]<<' ' ; cout<<endl; return 0;

例如:

int*pointer;//建立一个指针

int*&p1=pointer;/*

正确,编译系统把"int*"看成一体,把"&p1"看成一体,即建立指针pointer的引用,就是给指针pointer起别名p1。

int&*p2=pointer;//错误,这就变成了引用的指针。

参考资料:&(C的位运算符)_百度百科

       

参考技术C

c语言中取地址符&和指针*的区别:

1、功能不同

&是一元运算符,取变量地址。

*作为标识符,定义变量为指针。

2、含义不同

&是一个引用,这个引用声明时不开辟新空间,它在内存分配表加入新的一行,该行内存地址等于和调用时传入的对应参数内存地址。

*是一个无符号整数,这个整数指向某个内存地址,一次访问sizeof(type)长度。

3、指向不同

&p指向变量a的地址。

*p为指针变量p所指向的存储单元中的内容。

4、用法不同

&声明中 int x;  x 是整型量,&x 是整型量x的地址。不是指针,才可以使用&。

*x 声明时指示后面的变量是指针变量,且其基类型是前面的类型,使用时把地址转向所指向的变量。

参考资料来源:百度百科——指针

百度百科——地址计算

参考技术D

两者区别在于操作对象。

操作对象的不同:取地址运算符&,对任意变量都可以进行取地址操作;*是取指针目标运算符,其后跟随的必须是指针类变量。

扩展资料

指针变量可以进行加减运算,例如p++、p+i、p-=i。指针变量的加减运算并不是简单的加上或减去一个整数,而是跟指针指向的数据类型有关。

给指针变量赋值时,要将一份数据的地址赋给它,不能直接赋给一个整数,例如int *p = 1000;是没有意义的,使用过程中一般会导致程序崩溃。

使用指针变量之前一定要初始化,否则就不能确定指针指向哪里,如果它指向的内存没有使用权限,程序就崩溃了。对于暂时没有指向的指针,建议赋值NULL。

两个指针变量可以相减。如果两个指针变量指向同一个数组中的某个元素,那么相减的结果就是两个指针之间相差的元素个数。

数组也是有类型的,数组名的本意是表示一组类型相同的数据。在定义数组时,或者和 sizeof、& 运算符一起使用时数组名才表示整个数组,表达式中的数组名会被转换为一个指向数组的指针。

参考资料:百度百科-指针:*和&

typescript 访问修饰符和 javascript 访问修饰符有啥区别?在使用打字稿时我应该更喜欢哪一个?

【中文标题】typescript 访问修饰符和 javascript 访问修饰符有啥区别?在使用打字稿时我应该更喜欢哪一个?【英文标题】:What are the differences between typescript access modifiers and javascript ones? And which one should I prefer while using typescript?typescript 访问修饰符和 javascript 访问修饰符有什么区别?在使用打字稿时我应该更喜欢哪一个? 【发布时间】:2021-09-18 02:14:20 【问题描述】:

Typescript 提供了 public,protectedprivate 关键字来定义成员的可见性或在它们旁边声明的方法,但是,我知道由于 ES6 Javascript 允许使用前缀“#”到类成员或方法以达到相同的结果。

为了更好地了解幕后的工作原理,我在 Typescript 中编写了一个玩具类,只是为了看看它是如何在 javascript 中编译的:

class aClass

    #jsPrivate: number;
    get jsPrivate()
         return this.#jsPrivate;

    private tsPrivate: number;
    protected tsProtected: number;
    public tsPublic: number;

    constructor( a: number, b: number, c: number, d: number)
    
        this.#jsPrivate = a;
        this.tsPrivate = b;
        this.tsProtected = c;
        this.tsPublic = d;
    


console.log(new aClass(1,2,3,4));

使用 tsc --target es6 和 Typescript 版本 4.3.5 编译的内容变为:

var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) 
    if (kind === "m") throw new TypeError("Private method is not writable");
    if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
    if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
    return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
;
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) 
    if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
    if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
    return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
;
var _aClass_jsPrivate;
class aClass 
    constructor(a, b, c, d) 
        _aClass_jsPrivate.set(this, void 0);
        __classPrivateFieldSet(this, _aClass_jsPrivate, a, "f");
        this.tsPrivate = b;
        this.tsProtected = c;
        this.tsPublic = d;
    
    get jsPrivate()  return __classPrivateFieldGet(this, _aClass_jsPrivate, "f"); 
    ;

_aClass_jsPrivate = new WeakMap();
console.log(new aClass(1, 2, 3, 4));

我不确定我做的是否正确,但我注意到 js 样式的私有成员现在在全局范围内,而且使用 typescript 修饰符声明的成员现在都是公共的,尽管理论上任何访问在编译为 javascript 时应该捕获私有成员,我不确定这是否是代码安全的最佳选择。

对于修改成员可见性的最佳方法,您有什么建议吗?

您能否也向我解释一下为什么会有这些差异?

【问题讨论】:

看起来 TS 编译器没有使用 JS private 功能。无论哪种方式,使用你喜欢使用的东西。如果您在 TS 中编程,这并没有什么不同,因为编译器会处理可见性/访问问题。 "因为 ES6 Javascript 允许对类成员或方法使用前缀“#”以达到相同的结果。" 1. 不是 ES6,这个是一个最近的变化,还没有正式发布。 2. 仅供private访问,没有“受保护”访问级别。 【参考方案1】:

JavaScript 私有字段语法#

支持

这还不是官方的。语法包含在the latest upcoming draft of the specifications 中。但是,ES2021 specification (ES12) 没有它。所以现在它正处于成为官方的过渡状态。

与此同时,并非所有浏览器都支持私有字段。最值得注意的是 Firefox 版本 89(在撰写本文时,浏览器的当前版本)不支持它。即将推出的 90 版将增加对私有字段的支持,但它处于测试阶段。

访问级别

私有字段语法只允许隐藏一个字段。 JavaScript 中没有关于 protected 访问的概念(仅对类的后代可见)。所以对于类之外的任何代码,一个字段要么对任何人可见,要么不可见。两者之间没有任何关系。

此外,JavaScript 中的私有字段完全隐藏。没有官方机制可以从外部以编程方式提取它们并与之交互。只有声明它的类才能使用它们。

class Foo 
  #id;
  constructor(num)    this.#id = num; 
  viewPrivate(other)  return other.#id; 


class Bar 
  #id;
  constructor(num)  this.#id = num; 


const foo1 = new Foo(1);
const foo2 = new Foo(2);

console.log(foo1.viewPrivate(foo1)); //1
console.log(foo1.viewPrivate(foo2)); //2

const bar = new Bar(3);
console.log(foo1.viewPrivate(bar)); //Error 
                                    // cannot access #x from different class

TypeScript 访问修饰符

支持

TypeScript 访问修饰符在任何地方都得到技术支持。那是因为 TypeScript 代码被转换为纯 JavaScript。可以配置编译器应该针对哪个 ECMAScript 版本。

与类型系统的其他部分一样,访问修饰符将在编译时被剥离。如果您尝试访问不应访问的字段,则会出现编译错误。

访问级别

最大的不同是支持protected访问级别,以允许从子类访问字段:


class Foo 
    public    a = 1;
    protected b = 2;
    private   c = 3;


class Bar extends Foo 
    doStuff(): number 
        return this.a + //OK - it's public
               this.b + //OK - it's protected and Bar extends Foo
               this.c;  //Error - it's private
    

Playground Link


与纯 JavaScript 相比的另一个大区别是 TypeScript 访问修饰符可以在子类中更改以减少限制:

class A 
    protected x = "hello";


class B extends A 
    public x = "world";


console.log(new A().x); // Compilation error
console.log(new B().x); // OK

Playground Link


最后,我必须加倍说明 JavaScript 的私有字段与 TypeScript 的 private 访问修饰符有何不同。 TypeScript 不会“隐藏”字段。它会阻止您引用它们。这些字段仍然存在,并且可以通过代码正常访问。甚至可以防止编译错误:

class Foo 
    private secret = "top secret";


const foo = new Foo();

console.log(JSON.stringify(foo)); //""secret":"top secret"" 
console.log((foo as any).secret); //"top secret" 

Playground Link

JavaScript 中的私有字段语法不会发生这种情况。同样,私有字段对外部完全隐藏。

使用哪个

这取决于选择。如果编写专注于 OOP 的 TypeScript 代码,您可能只想坚持使用 privateprotectedpublic 关键字。他们更好地处理类层次结构。

话虽如此,如果您想要更强的封装且不会泄漏,那么 JavaScript 中的私有字段语法 # 会非常强大。

您也可以混合使用这两种封装。

归根结底,这将是每个案例的基础。

【讨论】:

描述得很好。 谢谢!你涵盖的非常好,而且你在每个例子中都非常清楚!【参考方案2】:

前缀“#”的使用是相当新的,尚未正式使用。如果您使用它,浏览器兼容性也可能是一个问题。所以我建议你现在使用 typescript 的类型,因为它是稳定的,并且可以自己处理跨浏览器支持。 另外,到目前为止,您在 JS 中还没有受保护的访问修饰符。

【讨论】:

根据MDN page,看起来只有在三星互联网浏览器上用于移动领域的问题以及用于移动和桌面方法的Safari时才会出现问题,其余浏览器似乎可以很好地处理它好吧,那么当然对于受保护的人来说,唯一的选择就是打字稿方式。 是的,但有时您还需要查看行业标准。到目前为止,我还没有看到很多开源项目使用它。 @MicheleNuzzi current version of Firefox is 89 和 doesn't support private fields。即将推出的 90 版最终将支持它们。所以,现在它甚至不适用于普通的 FF 用户。 FF ESR 用户可能暂时无法使用它。我不会说这处理得“相当好”

以上是关于c语言中取地址符和*有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

汇编语言 ECALL怎么用 ECALL、LCALL、ACALL有啥区别

在c语言编程中,传值方式和传引用方式之间有啥区别?

C语言中sbit是啥意思,与bit有啥区别?

C语言中取地址跟C++中的引用是一个意思吗?

c语言中啥是类(class),啥是结构。两者有啥区别?详细点。书上不太清楚。。谢谢

c语言与WIN32有啥区别?