Post on 04-Sep-2019
CS110ComputerArchitecture
Lecture3:IntroductiontoC,PartII
Instructor:SörenSchwertfeger
http://shtech.org/courses/ca/
School of Information Science and Technology SIST
ShanghaiTech University
1Slides based on UC Berkley's CS61C
Agenda
• CSyntax• Pointers• CMemoryManagement
2
AFirstCProgram:HelloWorldOriginal C:
main(){printf("\nHello World\n");
}
ANSI Standard C:
#include <stdio.h>
int main(void){printf("\nHello World\n");return 0;
}
3
CSyntax:main
• WhenCprogramstarts– Cexecutablea.out isloadedintomemorybyoperatingsystem(OS)
– OSsetsupstack,thencallsintoCruntimelibrary,– Runtime1st initializesmemoryandotherlibraries,– thencallsyourprocedurenamedmain()
• We’llseehowtoretrievecommand-lineargumentsinmain()later…
4
ASecondCProgram:ComputeTableofSines
#include <stdio.h>#include <math.h>
int main(void){
int angle_degree;double angle_radian, pi, value;/* Print a header */printf("\nCompute a table of the sine function\n\n");
/* obtain pi once for all *//* or just use pi = M_PI, where *//* M_PI is defined in math.h */pi = 4.0*atan(1.0);printf("Value of PI = %f \n\n", pi);
printf("angle Sine \n");
angle_degree = 0;/* initial angle value *//* scan over angle */while (angle_degree <= 360)/* loop until angle_degree > 360 */
{angle_radian = pi*angle_degree/180.0;value = sin(angle_radian);printf (" %3d %f \n ",
angle_degree, value);angle_degree = angle_degree + 10; /* increment the loop index */
}return 0;}
5
SecondCProgramSampleOutput
Compute a table of the sine function
Value of PI = 3.141593
angle Sine 0 0.000000
10 0.173648 20 0.342020 30 0.500000 40 0.642788 50 0.766044 60 0.866025 70 0.939693 80 0.984808 90 1.000000
100 0.984808 110 0.939693 120 0.866025 130 0.766044 140 0.642788 150 0.500000 160 0.342020 170 0.173648 180 0.000000
190 -0.173648 200 -0.342020 210 -0.500000 220 -0.642788 230 -0.766044 240 -0.866025 250 -0.939693 260 -0.984808 270 -1.000000 280 -0.984808 290 -0.939693 300 -0.866025 310 -0.766044 320 -0.642788 330 -0.500000 340 -0.342020 350 -0.173648 360 -0.000000
6
CSyntax:VariableDeclarations
• Allvariabledeclarationsmustappearbeforetheyareused(e.g.,atthebeginningoftheblock)
• Avariablemaybeinitializedinitsdeclaration;ifnot,itholdsgarbage!
• Examplesofdeclarations:– Correct: {
int a = 0, b = 10;...
−Incorrect: for (int i = 0; i < 10; i++)}
7NewerCstandardsaremoreflexibleaboutthis,morelater
CSyntax:ControlFlow(1/2)• Withinafunction,remarkablyclosetoJavaconstructsintermsofcontrolflow– if-else
• if (expression) statement• if (expression) statement1else statement2
– while• while (expression)
statement• do
statementwhile (expression);
8
CSyntax:ControlFlow(2/2)
– for• for (initialize; check; update) statement
– switch• switch (expression){
case const1: statementscase const2: statementsdefault: statements
}• break
9
CSyntax:TrueorFalse
• WhatevaluatestoFALSEinC?– 0(integer)– NULL(aspecialkindofpointer:moreonthislater)– NoexplicitBooleantype
• WhatevaluatestoTRUEinC?– Anythingthatisn’tfalseistrue– SameideaasinPython:only0soremptysequencesarefalse,anythingelseistrue!
10
Coperators
• arithmetic:+,-,*,/,%• assignment:=• augmentedassignment:+=,-=,*=,/=,%=,&=,|=,^=,<<=,>>=
• bitwiselogic:~,&,|,^• bitwiseshifts:<<,>>• boolean logic:!,&&,||• equalitytesting:==,!=
• subexpressiongrouping:()
• orderrelations:<,<=,>,>=
• incrementanddecrement:++and--
• memberselection:.,->• conditionalevaluation:?:
11
Addressvs.Value• Considermemorytobeasinglehugearray– Eachcellofthearrayhasanaddressassociatedwithit
– Eachcellalsostoressomevalue– Foraddressesdoweusesignedorunsignednumbers?Negativeaddress?!
• Don’tconfusetheaddressreferringtoamemorylocationwiththevaluestoredthere
12
23 42 ...... 101 102103104105...
Pointers• Anaddressreferstoaparticularmemorylocation;e.g.,itpointstoamemorylocation
• Pointer:Avariablethatcontainstheaddressofavariable
13
23 42 ...... 101102103104105...
x y
Location(address)
namep
104
PointerSyntax
• int *x;– Tellscompilerthatvariablex isaddressofanint
• x = &y;– Tellscompilertoassignaddressofy tox– & calledthe“addressoperator”inthiscontext
• z = *x;– Tellscompilertoassignvalueataddressinx toz– * calledthe“dereferenceoperator”inthiscontext
14
CreatingandUsingPointers
15
• Howtocreateapointer:& operator:getaddressofavariableint *p, x;
p ? x ?
x = 3; p ? x 3
p = &x; p x 3
•Howgetavaluepointedto?“*” (dereferenceoperator):get thevaluethatthepointerpointsto
printf(“p points to value %d\n”,*p);
Notethe“*”getsused2differentwaysinthisexample.Inthedeclarationtoindicatethatp isgoingtobeapointer,andintheprintf togetthevaluepointedtobyp.
UsingPointerforWrites
• Howtochangeavariablepointedto?– Usethedereferenceoperator* onleftofassignmentoperator=
16
p x 5*p = 5;
p x 3
PointersandParameterPassing• Cpassesparameters“byvalue”– Procedure/function/methodgetsacopyoftheparameter,sochangingthecopycannotchangetheoriginal
void add_one (int x) {x = x + 1;
}int y = 3;add_one(y);
y remainsequalto3
17
PointersandParameterPassing• Howcanwegetafunctiontochangethevalueheldinavariable?
void add_one (int *p) {*p = *p + 1;}
int y = 3;
add_one(&y);
y isnowequalto4
18
WhatwouldyouuseinC++?
Callbyreference:voidadd_one (int &p){p=p+1;//orp+=1;
}
TypesofPointers
• Pointersareusedtopointtoanykindofdata(int,char,astruct,etc.)
• Normallyapointeronlypointstoonetype(int,char,astruct,etc.).– void * isatypethatcanpointtoanything(genericpointer)
– Usevoid * sparinglytohelpavoidprogrambugs,andsecurityissues,andotherbadthings!
19
MoreCPointerDangers• Declaringapointerjustallocatesspacetoholdthepointer– itdoesnotallocatethethingbeingpointedto!
• LocalvariablesinCarenotinitialized,theymaycontainanything(aka“garbage”)
• Whatdoesthefollowingcodedo?
20
void f(){
int *ptr;*ptr = 5;
}
PointersandStructurestypedef struct {
int x;int y;
} Point;
Point p1;Point p2;Point *paddr;
/* dot notation */int h = p1.x;p2.y = p1.y;
/* arrow notation */int h = paddr->x;int h = (*paddr).x;
/* This works too */p1 = p2;
21
Note:Cstructureassignmentisnota”deepcopy”.Allmembersarecopied,butnotthingspointedtobymembers.
PointersinC• Whyusepointers?– Ifwewanttopassalargestruct orarray,it’seasier/faster/etc.topassapointerthanthewholething
– Ingeneral,pointersallowcleaner,morecompactcode
• Sowhatarethedrawbacks?– PointersareprobablythesinglelargestsourceofbugsinC,sobecarefulanytimeyoudealwiththem• Mostproblematicwithdynamicmemorymanagement—comingupnextweek
• Danglingreferencesandmemoryleaks
22
WhyPointersinC?• AttimeCwasinvented(early1970s),compilersoftendidn’tproduceefficientcode– Computers25,000timesfastertoday,compilersbetter
• Cdesignedtoletprogrammersaywhattheywantcodetodowithoutcompilergettinginway– Evengivecompilershintswhichregisterstouse!
• Today’scompilersproducemuchbettercode,somaynotneedtousepointersinapplicationcode
• Low-levelsystemcodestillneedslow-levelaccessviapointers
23
Quiz:Pointersvoid foo(int *x, int *y){ int t;
if ( *x > *y ) { t = *y; *y = *x; *x = t; }}int a=3, b=2, c=1;foo(&a, &b);foo(&b, &c);foo(&a, &b);printf("a=%d b=%d c=%d\n", a, b, c);
24
A:a=3 b=2 c=1B:a=1 b=2 c=3C:a=1 b=3 c=2D:a=3 b=3 c=3E:a=1 b=1 c=1
Resultis:
Administrivia• OHstarted– usewhenyouneedhelp!• QuestionsregardingHW1?
25
iPhone7Teardownifixit.com
26
27
Apple64bitSystemonachip(SoC):quadcore(2highperformance,2lowpower;only2atatime)125 mm2,3.3billiontransistors(includingtheGPUandcaches)2.34GHzARMv8 TSMC16 nm 6-coreGPU4Samsung LPDDR4 RAMchips
28
29
30
CArrays
• Declaration:int ar[2];
declaresa2-elementintegerarray:justablockofmemory
int ar[] = {795, 635};
declaresandinitializesa2-elementintegerarray
31
CStrings• StringinCisjustanarrayofcharacters
char string[] = "abc";
• Howdoyoutellhowlongastringis?– Lastcharacterisfollowedbya0byte(aka“nullterminator”)
32
int strlen(char s[]){
int n = 0;while (s[n] != 0) n++;return n;
}
ArrayName/PointerDuality• KeyConcept:Arrayvariableisa“pointer”tothefirst(0th)element
• So,arrayvariablesalmostidenticaltopointers– char *string andchar string[] arenearlyidenticaldeclarations
– Differinsubtleways:incrementing,declarationoffilledarrays
• Consequences:– ar isanarrayvariable,butworkslikeapointer– ar[0] isthesameas*ar– ar[2] isthesameas*(ar+2)– Canusepointerarithmetictoconvenientlyaccessarrays
33
ChangingaPointerArgument?
• Whatifwantfunctiontochangeapointer?• Whatgetsprinted?
void inc_ptr(int *p){ p = p + 1; }
int A[3] = {50, 60, 70};int *q = A;inc_ptr( q);printf(“*q = %d\n”, *q);
*q = 50
50 60 70
A q
PointertoaPointer
• Solution!Passapointertoapointer,declaredas**h
• Nowwhatgetsprinted?void inc_ptr(int **h){ *h = *h + 1; }
int A[3] = {50, 60, 70};int *q = A;inc_ptr(&q);printf(“*q = %d\n”, *q);
*q = 60
50 60 70
A q q
CArraysareVeryPrimitive• AnarrayinCdoesnotknowitsownlength,anditsboundsarenotchecked!– Consequence:Wecanaccidentallyaccessofftheendofanarray
– Consequence:Wemustpassthearrayanditssizetoanyprocedurethatisgoingtomanipulateit
• Segmentationfaultsandbuserrors:– TheseareVERYdifficulttofind;becareful!
36
UseDefinedConstants• Arraysizen;wanttoaccessfrom0 ton-1,soyoushoulduse
counterANDutilizeavariablefordeclaration&incrementation– Badpatternint i, ar[10];for(i = 0; i < 10; i++){ ... }
– Betterpatternconst int ARRAY_SIZE = 10;int i, a[ARRAY_SIZE];for(i = 0; i < ARRAY_SIZE; i++){ ... }
• SINGLESOURCEOFTRUTH– You’reutilizingindirectionandavoidingmaintainingtwocopiesofthe
number10– DRY:“Don’tRepeatYourself”
37
PointingtoDifferentSizeObjects• Modernmachinesare“byte-addressable”
– Hardware’smemorycomposedof8-bitstoragecells,eachhasauniqueaddress
• ACpointerisjustabstractedmemoryaddress• Typedeclarationtellscompilerhowmanybytestofetchoneachaccessthroughpointer– E.g.,32-bitintegerstoredin4consecutive8-bitbytes
38
424344454647484950515253545556575859
int *x
32-bitintegerstoredinfourbytes
short *y
16-bitshortstoredintwobytes
char *z
8-bitcharacterstoredinonebyte
Byteaddress
sizeof()operator
• sizeof(type)returnsnumberofbytesinobject– Butnumberofbitsinabyteisnotstandardized• Inoldentimes,whendragonsroamedtheearth,bytescouldbe5,6,7,9bitslong
• Bydefinition,sizeof(char)==1• Cantakesizeof(arr),orsizeof(structtype)• We’llseemoreofsizeof whenwelookatdynamicmemorymanagement
39
40
PointerArithmeticpointer +number pointer – numbere.g.,pointer + 1 adds1something toapointer
char *p;char a;char b;
p = &a;p += 1;
int *p;int a;int b;
p = &a;p += 1;
Ineach,p nowpointstob(Assumingcompilerdoesn’treordervariablesinmemory.
Nevercodelikethis!!!!)
Adds1*sizeof(char) tothememoryaddress
Adds1*sizeof(int)tothememoryaddress
Pointerarithmeticshouldbeusedcautiously
41
ArraysandPointers
• Array» pointertotheinitial(0th)arrayelement
a[i] º *(a+i)
• Anarrayispassedtoafunctionasapointer– Thearraysizeislost!
• Usuallybadstyletointerchangearraysandpointers– Avoidpointerarithmetic!
Really int *array
intfoo(int array[],
unsigned int size){
… array[size - 1] …}
intmain(void){
int a[10], b[5];… foo(a, 10)… foo(b, 5) …
}
Must explicitlypass the size
Passing arrays:
42
ArraysandPointersintfoo(int array[],
unsigned int size){
…printf(“%d\n”, sizeof(array));
}
intmain(void){
int a[10], b[5];… foo(a, 10)… foo(b, 5) …printf(“%d\n”, sizeof(a));
}
Whatdoesthisprint?
Whatdoesthisprint?
4
40
...becausearray isreallyapointer(andapointerisarchitecturedependent,butlikelytobe8onmodernmachines!)