C 作用域规则
1.C作用域规则
C语言有三个地方可以声明变量:
1>.在函数或块内部的局部变量。
2>.在所有函数外部的全局变量。
3>.在形式参数的函数参数定义中。
2.局部变量
eg:
#include <stdio.h>
int main ()
{
/* 局部变量声明 */
int a, b;
int c;
/* 实际初始化 */
a = 10;
b = 20;
c = a + b;
printf (“value of a = %d, b = %d and c = %d\n”, a, b, c);
return 0;
}
在这里,所有的变量 a、b 和 c 是 main() 函数的局部变量。
3.全局变量
eg:
#include <stdio.h>
/* 全局变量声明 */
int g;
int main ()
{
/* 局部变量声明 */
int a, b;
/* 实际初始化 */
a = 10;
b = 20;
g = a + b;
printf (“value of a = %d, b = %d and g = %d\n”, a, b, g);
return 0;
}
全局变量可以被任何函数访问。
需要注意的是:
在程序中,局部变量和全局变量的名称可以相同,但是在函数内,局部变量的值会覆盖全局变量的值。
eg:
#include <stdio.h>
/* 全局变量声明 */
int g = 20;
int main ()
{
/* 局部变量声明 */
int g = 10;
printf (“value of g = %d\n”, g);
return 0;
}
该代码返回的结果是:value of g = 10
4.形式参数
eg:
#include <stdio.h>
/* 全局变量声明 */
int a = 20;
int main ()
{
/* 在主函数中的局部变量声明 */
int a = 10;
int b = 20;
int c = 0;
printf (“value of a in main() = %d\n”, a);//10
c = sum( a, b);//10; 20
printf (“value of c in main() = %d\n”, c);//30
return 0;
}
/* 添加两个整数的函数 */
int sum(int a, int b)
{
printf (“value of a in sum() = %d\n”, a);
printf (“value of b in sum() = %d\n”, b);
return a + b;
}
返回的结果:
value of a in main() = 10
value of a in sum() = 10
value of b in sum() = 20
value of c in main() = 30
反馈出的信息:顺序执行。即哪里调用了,就先执行调用函数的内容。
5.初始化局部变量和全局变量
局部变量和全局变量的区别:
当局部变量被定义时,系统不会对其初始化,必须自行对其初始化。
定义全局变量时,系统会自动对其初始化。
数据类型 初始化默认值
int 0
char ‘’
float 0
double 0
pointer NULL
C 数组
1.数组的声明:
类型 数组名字[数组大小]
eg:double balance[10];
2.初始化数组
eg:double balance[5] = {1000.0, 2.0, 3.4, 7.0, 50.0};
如果您省略掉了数组的大小,数组的大小则为初始化时元素的个数。
balance[4] = 50.0;
数组中第五个元素的值赋为 50.0。
数组都是以 0 作为它们第一个元素的索引
3.访问数组元素
数组元素可以通过数组名称加索引进行访问。
eg:double salary = balance[9];
4.C 中数组详解
概念 描述
多维数组 C 支持多维数组。多维数组最简单的形式是二维数组。
传递数组给函数 您可以通过指定不带索引的数组名称来给函数传递一个指向数组的指针。
从函数返回数组 C 允许从函数返回数组。
指向数组的指针 您可以通过指定不带索引的数组名称来生成一个指向数组中第一个元素的指针。
1>.多维数组
一般形式:type name[size1][size2]…[sizeN];
二维数组:type arrayName [ x ][ y ]; //x行y列
eg:
int a[3][4] = {
{0, 1, 2, 3} , /* 初始化索引号为 0 的行 /
{4, 5, 6, 7} , / 初始化索引号为 1 的行 /
{8, 9, 10, 11} / 初始化索引号为 2 的行 */
};
3 行 4 列的二维数组
内部嵌套的括号是可选的,下面的初始化与上面是等同的:
int a[3][4] = {0,1,2,3,4,5,6,7,8,9,10,11};
访问二维数组:
int val = a[2][3];获取数组中第 3 行第 4 个元素
eg:
#include <stdio.h>
int main ()
{
/* 一个带有 5 行 2 列的数组 */
int a[5][2] = { {0,0},
{1,2},
{2,4},
{3,6},
{4,8}};
int i, j;
/* 输出数组中每个元素的值 */
for ( i = 0; i < 5; i++ )
{
for ( j = 0; j < 2; j++ )
{
printf(“a[%d][%d] = %d\n”, i,j, a[i][j] );
}
}
return 0;
}
一般情况下,我们创建的数组是一维数组和二维数组。
2>.传递数组给函数
void myFunction(int param[])
{
.
.
.
}
3>.从函数返回数组
C 语言不允许返回一个完整的数组作为函数的参数。
4>指向数组的指针
balance 是一个指向 &balance[0] 的指针,即数组 balance 的第一个元素的地址。
double *p;
double balance[10];
p = balance;
C 指针
1.什么是指针?
指针是一个变量,它也有类型,指针的类型和该指针指向的变量类型是对应关系,指针变量也在内存中,
一旦声明,内存也会为其分配一个存储空间地址,即 &指针变量 可以显示出内存给其分配的空间地址,
这个空间中存储的是该指针指向的数据类型的变量的地址,若想知道这个变量的地址,可以使用 &变量
或者指针变量,若想知道指针指向的值,则可用 *指针变量。
简单来说,指针指向的是一个数据类型的变量的地址。
2.指针的类型:
eg:
int ip; / 一个整型的指针 */
double dp; / 一个 double 型的指针 */
float fp; / 一个浮点型的指针 */
char ch / 一个字符型的指针 */
星号是用来指定一个变量是指针。
所有指针的值的实际数据类型,不管是整型、浮点型、字符型,还是其他的数据类型,
都是一样的,都是一个代表内存地址的长的十六进制数.
不同数据类型的指针之间唯一的不同是,指针所指向的变量或常量的数据类型不同。
3.如何使用指针?
1>.定义一个指针变量
2>.把变量地址赋值给指针
3>.访问指针变量中可用地址的值。
========================================================================================
指针探究及总结 =
=
1.基本介绍 =
声明 =
eg: =
-
=
int ptr; =
=
int 代表类型为指针类型 =
ptr 一个指针类型的变量ptr =
=
2.举例说明: =
int num = 1; =
int *ptr = # =
=
int *ptr = # =
这段代码代表 指针变量ptr指向了一个int类型的变量的地址。即ptr指向了num的地址。 =
=
要获取ptr的地址,则 &ptr; //内存分配给ptr变量的空间地址 =
要获取在ptr空间地址中存的int类型变量的地址,则 ptr; =
要获取指针变量指向的值,则 ptr; =
=
说明: =
说明1:如果要输出一个变量的地址,使用格式是%p =
说明2:&num表示取出num这个变量对应的地址 =
说明3:我们可以通过ptr=某个数 来修改num的值,但是修改后num的地址不会发生变化。 =
4.C中的NULL指针
在变量声明的时候,如果没有确切的地址可以赋值,为指针变量赋一个 NULL 值是一个良好的编程习惯。
赋为 NULL 值的指针被称为空指针。
NULL 指针是一个定义在标准库中的值为零的常量。
如果要检查一个空指针,则可以使用if语句。
if(ptr) /* 如果 p 非空,则完成 /
if(!ptr) / 如果 p 为空,则完成 */
5.指针详解
概念 描述
指针的算术运算 可以对指针进行四种算术运算:++、–、+、-
指针数组 可以定义用来存储指针的数组。
指向指针的指针 C 允许指向指针的指针。
传递指针给函数 通过引用或地址传递参数,使传递的参数在调用函数中被改变。
从函数返回指针 C 允许函数返回指针到局部变量、静态变量和动态内存分配。
***指向数组的指针、指向结构体的指针、指向共用体的指针 ***
C 字符串
一个以 null 结尾的字符串,包含了组成字符串的字符。
char greeting[6] = {‘H’, ‘e’, ‘l’, ‘l’, ‘o’, ‘’};
char greeting[] = “Hello”;
C 中有大量操作字符串的函数:
序号 函数 目的
1 strcpy(s1, s2); 复制字符串 s2 到字符串 s1。
2 strcat(s1, s2); 连接字符串 s2 到字符串 s1 的末尾。
3 strlen(s1); 返回字符串 s1 的长度。
4 strcmp(s1, s2); 如果 s1 和 s2 是相同的,则返回 0;如果 s1<s2 则返回小于 0;如果 s1>s2 则返回大于 0。
5 strchr(s1, ch); 返回一个指针,指向字符串 s1 中字符 ch 的第一次出现的位置。
6 strstr(s1, s2); 返回一个指针,指向字符串 s1 中字符串 s2 的第一次出现的位置。
eg:
#include <stdio.h>
#include <string.h>
int main ()
{
char str1[12] = “Hello”;
char str2[12] = “World”;
char str3[12];
int len ;
/* 复制 str1 到 str3 */
strcpy(str3, str1);
printf(“strcpy( str3, str1) : %s\n”, str3 );
/* 连接 str1 和 str2 */
strcat( str1, str2);
printf(“strcat( str1, str2): %s\n”, str1 );
/* 连接后,str1 的总长度 */
len = strlen(str1);
printf(“strlen(str1) : %d\n”, len );
return 0;
}
结果:
strcpy( str3, str1) : Hello
strcat( str1, str2): HelloWorld
strlen(str1) : 10
C 结构体
C结构体
C 数组允许定义可存储相同类型数据项的变量。
结构是 C 编程中另一种用户自定义的可用的数据类型,它允许您存储不同类型的数据项。
1.结构的定义:
eg:为了定义结构,必须使用 struct 语句
****** #pragma warning(disable:4996) 加了这句话可以不使用strcpy_s ***********
struct Books
{
char title[50];
char author[50];
char subject[100];
int book_id;
};
2.访问结构成员
为了访问结构的成员,我们使用成员访问运算符(.)。
eg:
#include <stdio.h>
#include <string.h>
int main( )
{
struct Books Book1; /* 声明 Book1,类型为 Book /
struct Books Book2; / 声明 Book2,类型为 Book */
/* Book1 详述 */
strcpy( Book1.title, “C Programming”);
strcpy( Book1.author, “Nuha Ali”);
strcpy( Book1.subject, “C Programming Tutorial”);
Book1.book_id = 6495407;
3.结构作为函数参数
#include <stdio.h>
#include <string.h>
struct Books
{
char title[50];
char author[50];
char subject[100];
int book_id;
};
/* 函数声明 /
void printBook( struct Books book );
int main( )
{
struct Books Book1; / 声明 Book1,类型为 Book */
/* Book1 详述 */
strcpy( Book1.title, “C Programming”);
strcpy( Book1.author, “Nuha Ali”);
strcpy( Book1.subject, “C Programming Tutorial”);
Book1.book_id = 6495407;
/* 输出 Book1 信息 */
printBook( Book1 );
}
void printBook( struct Books book )
{
printf( “Book title : %s\n”, book.title);
printf( “Book author : %s\n”, book.author);
printf( “Book subject : %s\n”, book.subject);
printf( “Book book_id : %d\n”, book.book_id);
}
4.指向结构的指针
为了使用指向该结构的指针访问结构的成员,您必须使用 -> 运算符
eg:
#include <stdio.h>
#include <string.h>
struct Books
{
char title[50];
char author[50];
char subject[100];
int book_id;
};
/* 函数声明 */
void printBook( struct Books book );
int main( )
{
struct Books Book1; / 声明 Book1,类型为 Book */
/* Book1 详述 */
strcpy( Book1.title, “C Programming”);
strcpy( Book1.author, “Nuha Ali”);
strcpy( Book1.subject, “C Programming Tutorial”);
Book1.book_id = 6495407;
/* 通过传 Book1 的地址来输出 Book1 信息 */
printBook( &Book1 );
return 0;
}
void printBook( struct Books *book )
{
printf( “Book title : %s\n”, book->title);
printf( “Book author : %s\n”, book->author);
printf( “Book subject : %s\n”, book->subject);
printf( “Book book_id : %d\n”, book->book_id);
}
5.位域
所谓"位域"是把一个字节中的二进位划分为几个不同的区域,并说明每个区域的位数。
位域的定义:
struct 位域结构名
{
位域列表
};
其中位域列表的形式为:
类型说明符 位域名: 位域长度
eg:
struct bs{
int a:8;
int b:2;
int c:6;
}data;
data 为 bs 变量,共占两个字节。其中位域 a 占 8 位,位域 b 占 2 位,位域 c 占 6 位。
eg2:
struct packed_struct {
unsigned int f1:1;
unsigned int f2:1;
unsigned int f3:1;
unsigned int f4:1;
unsigned int type:4;
unsigned int my_int:9;
} pack;
packed_struct 包含了 6 个成员:四个 1 位的标识符 f1…f4、一个 4 位的 type 和一个 9 位的 my_int。
eg3:
struct bs{
unsigned a:4;
unsigned :4; /* 空域 /
unsigned b:4; / 从下一单元开始存放 */
unsigned c:4
}
对于位域:
1>.一个位域必须存储在同一个字节中,不能横跨两个字节。
2>.由于位域不允许跨两个字节,因此位域的长度不能大于一个字节的长度。
3>.位域可以是无名位域,这时它只用来作填充或调整位置。无名的位域是不能使用的。eg3.
位域的使用
一般形式为:
位域变量名·位域名
C 共用体
C 共用体
1.共用体的定义
为了定义共用体,您必须使用 union 语句,方式与定义结构类似。union 语句定义了一个新的数据类型,带有多个成员。
union [union tag]
{
member definition;
member definition;
…
member definition;
} [one or more union variables];
eg:
union Data
{
int i;
float f;
char str[20];
} data;
2.共用体成员的访问
要访问共用体,我们必须在同一时间只用到一个成员,否则除了最后赋给变量的值能够完好输出外,其他的值都会有损坏。
即访问时应该如下操作:
data.i = 10;
printf( “data.i : %d\n”, data.i);
data.f = 220.5;
printf( “data.f : %f\n”, data.f);
strcpy( data.str, “C Programming”);
printf( “data.str : %s\n”, data.str);
即一个一个访问。