C语言初阶—操作符

时间:2024-03-07 18:05:35

        逻辑操作符:

        这段代码的结果是什么?

#include <stdio.h>

int main()
{
	int i = 0,a = 0,b = 2,c = 3,d = 4;
	i = a++ && ++b && d++;
	printf("a=%d,b=%d,c=%d,d=%d\n",a,b,c,d);
	return 0;
}

        计算的时候,a++先使用,是0,&&有短路特性,最左边的表达式是0,&& 连接的只要有一个为假,结果一定为假,右边的就不用计算了,a使用完之后再++,a = 1。b,d 不会改变了,所以a,b,c,d 分别等于 1,2,3,4。

        若a初始化的时候为1。

#include <stdio.h>

int main()
{
	int i = 0,a = 1,b = 2,c = 3,d = 4;
	i = a++ && ++b && d++;
	printf("a=%d,b=%d,c=%d,d=%d\n",a,b,c,d);
	return 0;
}

        && 的时候,遇到 0 一定为假,可以不用接着算下去了,反之则要一直算下去才能得到最终结果。

        || 是否也有相似特性呢?

#include <stdio.h>

int main()
{
	int i = 0,a = 1,b = 2,c = 3,d = 4;
	i = a++ || ++b || d++;
	printf("a=%d,b=%d,c=%d,d=%d\n",a,b,c,d);
	return 0;
}

         计算的时候,a++先使用,是1,|| 有短路特性,最左边的表达式是1,|| 连接的只要有一个为真,结果一定为真,右边的就不用计算了,a使用完之后再++,a = 2。b,d 不会改变了,所以a,b,c,d 分别等于 2,2,3,4。

        若a初始化的时候为0。

#include <stdio.h>

int main()
{
	int i = 0,a = 0,b = 2,c = 3,d = 4;
	i = a++ || ++b || d++;
	printf("a=%d,b=%d,c=%d,d=%d\n",a,b,c,d);
	return 0;
}

        运算过程一样,|| 的时候遇到 1, 一定为真,就可以不用接着算下去了。

        条件操作符:exp1 ? exp2 : exp3

        若条件exp1为真,执行exp2表达式,若条件exp1为假,执行exp3表达式。

        逗号表达式:

        下标引用,函数调用,和结构成员:

        1.下标引用操作符

        操作数:一个数组名 + 一个索引值

#include <stdio.h>

int main()
{
	int arr[5] = {0};
	arr[1] = 2;
	2[arr] = 3;
	//arr[1]--->*(arr + 1)--->*(1 + arr)--->1[arr]
	//arr是数组首元素的地址
	//arr + 1 就是跳过1个元素,指向第2个元素
	//*(arr + 1)就是第2个元素
	return 0;
}

        能够成功赋值。

        2. ( ) 函数调用操作符

        接受一个或者多个操作数,第一个操作数是函数名,剩余的操作数就是传递给函数的参数。

        3. 访问一个结构的成员

         .        结构体 . 成员名

        ->        结构体指针->成员名

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

struct Stu
{
	char name[20];
	int age;
	double score;
};
void set_stu(struct Stu s)
{
	strcpy(s.name,"zhangsan");//s.name是字符数组,s.name就是字符串首地址,
	//把字符串"zhangsan"赋值给一个地址,不能单纯的用=赋值,应该使用strcpy()库函数
	s.age = 18;
	s.score = 100;
}
void print_stu(struct Stu s)
{
	printf("name=%s\n",s.name);
	printf("age=%d\n",s.age);
	printf("score=%lf\n",s.score);
}
int main()
{
	struct Stu s = {0};
	set_stu(s);
	print_stu(s);
	return 0;
}

        可以看到,并不能成功修改,这是因为改变形参并不能达到改变实参的效果。

        要想改变实参,应该传递地址,通过地址解引用来访问实参,修改实参。

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

struct Stu
{
	char name[20];
	int age;
	double score;
};
//void set_stu(struct Stu s)
//{
//	strcpy(s.name,"zhangsan");//s.name是字符数组,s.name就是字符串首地址,
//	//把字符串"zhangsan"赋值给一个地址,不能单纯的用=赋值,应该使用strcpy()库函数
//	s.age = 18;
//	s.score = 100;
//}
void print_stu(struct Stu s)
{
	printf("name=%s\n",s.name);
	printf("age=%d\n",s.age);
	printf("score=%lf\n",s.score);
}
void set_stu(struct Stu* s)
{
	/*strcpy((*s).name,"zhangsan");
	(*s).age = 18;
	(*s).score = 100;*/
	strcpy(s->name,"zhangsan");
	s->age = 18;
	s->score = 100;
}
int main()
{
	struct Stu s = {0};
	set_stu(&s);
	print_stu(s);
	return 0;
}

           可以看到,可以成功修改​​​​​,并且(*s).name,s->name两种写法都可以。